A winter roost at dusk, made from arithmetic instead of choreography.
VESPERS is a fictional field study of the starlings that roost beneath the Old Chain Pier. The single job of the page is to make one idea felt in the body before it is read: that the vast, turning shape overhead has no author — it is thousands of birds each obeying three tiny rules, and fear (your cursor) rewriting them in real time. Everything else on the page stays quiet so the sky can be loud.
Dusk, reserved for the sky
Because ember is bright enough to fail contrast as text, the interface carries two dedicated ink tokens — a lighter ember #F0B978 and rose #E4A4AB — for any accent that has to be read. Muted labels sit at 58% paper over slate, which clears 4.5:1.
A soft-serif for the birds, a grotesk for the facts
The signature: a real flock, not a loop
Every bird is a point with a position and velocity in flat Float32Array buffers. Each frame, all birds are hashed into a uniform spatial grid (cell = perception radius) using an allocation-free linked-list (a head/next pair), so a bird only ever tests neighbours in its own cell and the eight around it — the difference between an O(n²) toy and three thousand birds at sixty frames.
From those neighbours each bird computes the three classic Reynolds steers — alignment (match nearby headings), cohesion (drift to the local centre) and separation (hold a wingspan) — plus a slow wandering wind so the idle flock wheels. The peregrine is your cursor: birds within its fear radius get a flee force and a local rewrite of the weights — cohesion is multiplied up and separation relaxed, so the flock genuinely packs into a dark ball on the far side, then shears open along the falcon's line and heals behind it. A click triggers a stoop that punches harder. None of it is scripted; the shapes are emergent.
Path2D fills per frame.hidden and off-screen (IntersectionObserver), clamped delta on resume.What changed, honestly
Craft
- Caught the recurring failure: the muted label token was 40% paper, computing to ~3.3:1 over slate. Raised to 58% (≈5:1) and lifted the bravery caption to 64%.
- Reserved ember strictly for lines and marks; gave readable accents their own lighter ink tokens.
- Softened the pier: pilings were reading like a fence. Replaced flat black with a graded deck, receding piling opacity, and a warm horizon haze so birds no longer meet a hard edge.
- Added a text-shadow to labels sitting over the animated sky.
Depth
- Enriched the signature with a fading ember dive-trail behind the peregrine, so a fast sweep reads as a stoop.
- Second-read detail: a handful of birds perched on the rail that occasionally lift off and rejoin the flock — noticed only if you linger.
- Micro-interaction: the rule cards grow an ember underline and shift their numeral to rose on hover.
- Tuned the fear response so cohesion overpowers separation under threat — the ball now forms and shears cleanly.
Hardening
- 375px: the nav overran the viewport but was masked by
overflow-x— the classic false pass. Section anchors now hide below 560px, leaving Guide + Index fully in-box (verified by geometry, not scrollWidth). - Confirmed the reduced-motion path renders a settled, non-blank knot and never starts the loop.
- Verified DPR cap, resize re-population, visibility + off-screen pause with clamped delta on resume.
- Chanel rule — removed the hard sun disc; the radial afterglow alone reads more like a sun that has just gone.
- Final copy read: specific nouns, active voice, no filler.