WAKE.

Colophon · No. 76 · Second Person

Making the wake

A dark sea that is glass until you move it, and forgets you when you stop. Every ripple on the page is a real fluid, and the only thing that ever moves it is your hand.

The concept

You are the boat

WAKE is the seventy-sixth site in the Generative Assets collection and the first of Wave Four — "Second Person", where the page is inert until you drive it. There are no controls and no autoplay. A dark expanse of water fills the screen; your cursor is a hull that displaces a real height-field fluid and leaves a persistent V-wake that spreads, reflects off the edges, and interferes with itself. The single job of the page is to make you realise, in the first two seconds, that the sea only exists where you have been.

Palette — moonlit water at night

Four colours, argued from the subject

Bright accent reserved for lines and marks only; small text uses foam or a dark gold ink so nothing drops below AA on the water.

Abyss
#0A1A22
The deep, still water. The whole page floats on it.
Moon-slick
#3E6B78
The cold sheen of the moon's reflection down the water.
Foam
#DCEBEF
Crests and body text — the white the wake throws up.
Buoy-lamp
#F2B23C
The one warm light. Kept to glints, rules and marks — never body text.

Type

Fraunces & IBM Plex Mono

Technique

How the water works

The sea is a GPU height-field wave simulation running in WebGL — no library, hand-written GLSL. Two floating-point textures ping-pong through a fragment shader that integrates the 2D wave equation each frame:

StateOne texture holds R = height, G = velocity per cell (RGBA16F on WebGL2, half-float on WebGL1).
StepThe Laplacian of neighbouring heights accelerates velocity; velocity integrates into height; both damp slightly so the wake fades over seconds, not instantly.
Your hullThe segment from your previous cursor position to the current one presses a Gaussian trough into the field, scaled by your speed — so a still cursor injects nothing and the sea goes glassy.
The VBecause the source moves, its expanding wavefronts constructively interfere along two lines behind it: a real Kelvin wake. Clamped edges reflect the waves back so they cross their own memory.
ShadingA display shader reads the field, builds a surface normal from the height gradient, and lights moonlit water: a reflection column, foam on the crests, and sharp gold lamp-glints confined to the moon's path.
The buoysA third pass packs height + slope + energy into a small RGBA8 buffer that is read back to the CPU each frame. The three buoy cards sample the true water beneath them and bob and tilt in your wake; the same buffer feeds the live energy readout.

Discipline: device-pixel-ratio capped at 2, simulation grid fixed near 470px on its long side (independent of screen size), the render loop paused on document.hidden, and a static CSS moonlit-sea fallback if WebGL is unavailable.

The build log

Three passes, each driving the water

Per the collection's rule, every pass actually moved a synthetic cursor across the field in headless Chrome and asserted the wake responded — not merely that the page loaded.

Pass 1 — Craft · rhythm, contrast, copy

Drove a diagonal mouse sweep and confirmed wake energy rose from a flat ~0 baseline, then decayed toward glass when the cursor held still — the core promise verified before polishing anything.

Tuned the type scale so the mirrored wordmark reflection reads as water, not a bug; tightened the moon column so the gold glints stay on the reflection and never wash the copy; rewrote the buoy soundings to specific, unmarketable lines ("fourteen fathoms · returning"). Set a dark scrim behind every text block so nothing sits on bare animated water.

Pass 2 — Depth · enrich the signature

Added the readback pass so the buoys physically bob and tilt in the real field, and wired the same buffer into the Soundings instrument — hull speed in knots, a live wake-energy meter, and a stillness timer that names the state ("cutting water" → "wake thinning" → "glass — it has forgotten you"). Second-read detail: the panel's lamp only lights while the water actually holds your line, and the reflected wordmark below the title brightens and sharpens in proportion to the wake you are making.

Made "you are the boat" tangible with a bow glow — a foam bloom and a small warm lamp-core carried at your cursor, the light of your own hull — and switched to adaptive damping so a fast stroke throws a clean, persistent Kelvin V while a lifted hand settles to glass within about two seconds. Re-drove the interaction each time to confirm the energy metric tracks cursor speed and then decays.

Pass 3 — Hardening · 375px, reduced motion, focus

Verified the 375px layout with buoys stacked, the wordmark and nav fully inside the viewport, and zero horizontal overflow — a stray scrim that had bled 41px past the edge was reined back in. Reduced-motion renders a single settled glassy frame with the loop and all injection disabled; visibility change pauses and resumes the loop; touchmove drives the wake on phones and the prompt becomes "drag your finger across the water". Resize was hammered across five viewports with no errors as the simulation textures reallocate.

Applied the Chanel rule: the crests carried two separate gold terms, so the redundant one came off, leaving a single disciplined specular glint as the only warm accent on the water. Confirmed zero console errors while driving real pointer events end to end.