DRIPSTONE grows a cave column in front of you: a stalactite and its stalagmite reaching toward one another, calcite ring by calcite ring. Each mineral-laden drip forms at the tip, falls, and lands with a resonant plink synthesised live in WebAudio — adding a micron of stone while a millennia counter climbs. It is a fictional teaching page for a speleology collection: one temporal process, made watchable.
01Palette
Four colours pulled straight out of a lit cave. A near-black stone dark, the warm ivory of wet calcite, one lamp-flame gold, and a darker flowstone brown for banding. Because the ground is almost black, body copy runs in a dedicated warm off-white ink that clears 4.5:1 everywhere; the lamp gold is held back for the wordmark, rules, the live numerals and the drip itself — never small text.
02Type
Spectral · display & prose
Dripstone
one drip per century
Spectral is a screen-first serif with a deep, calm italic. The wordmark hangs its italic stone a fraction lower than the upright Drip, so the name itself seems to droop under its own slow weight. It carries every heading and all the body prose.
JetBrains Mono · instrument
41.80 ka
A monospace with tabular figures keeps the live counter from jittering as it climbs. It sets the millennia and millimetre readouts, the eyebrows, the step indices and the navigation — the measured, instrument voice against the serif's warmth.
03Technique
- Canvas 2D speleothem. One
<canvas> draws both forms from tapered radius profiles, filled with a cross-axis calcite gradient and clipped so horizontal ellipse strokes read as accretion bands — the "layer by layer" of the concept — with a lamp-lit wet sheen down the near side and a glossy cap where drips land.
- A single drip state machine. Each drip runs
form → fall → settle: a bead swells at the tip, falls on a gravity ease to the stalagmite crown, and on contact deposits stone, splashes, ripples the pool and plinks. Nothing is pre-baked; the cycle simply repeats.
- WebAudio plink, no files. A sine with a fast up-then-settle pitch glide through a resonant band-pass, plus a high-passed noise tick for the contact, all fed to a synthesised convolution reverb (an exponential-decay noise impulse) for the cave echo. It is created only on the first tap of Sound — never at load — and muted with a single gain ramp.
- Deep-time bookkeeping. Each landing advances the clock a compressed century and nudges both towers a fraction of a millimetre closer, so the millennia counter climbs and the gap narrows in real time — the column visibly grows the longer you stay.
The signature: a column that builds itself, audibly
The whole page is one honest loop. A drip forms at the stalactite's wet tip, detaches, and falls the last few millimetres of a forty-thousand-year gap; where it lands it leaves a micron of calcite on both the ceiling straw above and the mound below, and sounds a single resonant plink into the cave reverb. The millennia readout ticks up a century, the gap in millimetres ticks down, and the two towers of the same water inch toward the join. Roughly one drip in nine carries a fleck of iron — it lands warmer and lower — a rust-stained century amongst the pale ones.
04Build log
Pass 1 · Craft
Spacing, scale, contrast, copy
- Contrast discipline first. The concept named a dark flowstone brown for small text — unreadable over a near-black cave. Kept that brown for the banding rings and card rules only, and gave every label and paragraph a warm off-white ink (#ECE4D6) that clears 4.5:1, holding the lamp gold for the wordmark, numerals and drip.
- Drove the drip, not the load. Watched a full cycle and confirmed the readouts move: the millennia counter climbs a century and the millimetre gap narrows on every landing, with drips-this-visit proving the loop is live rather than a static hero.
- Type scale & bravery. Set a deliberate ramp from 11px tracked mono eyebrows to a clamped 58–182px wordmark, and let the italic "stone" hang below the baseline as the one typographic move — the name dripping.
Pass 2 · Depth
Second read, motion, micro-interaction
- The rust-stained century. Added the ~1-in-9 iron drip — warmer bead, ochre splash and pool ripple, and a lower-pitched plink — a second-read detail called out in the field notes for anyone who lingers.
- Depth in the dark. Faint background speleothems, a lamp pool offset to one side, a still-pool sheen along the floor and a soft vignette give the single column a room to stand in rather than floating on flat black.
- Motion timing. Tuned the cycle to ~2.1s — an unhurried form, a quick gravity-eased fall, a held settle — and gave the bead a specular highlight and a motion-blur streak so the fall reads as water, not a dot.
Pass 3 · Hardening
375px, reduced motion, resilience
- Reduced motion. With
prefers-reduced-motion the loop never starts: a single settled frame paints the near-joined column with a bead mid-forming, the counter parked at its resting value, and no audio — verified against a non-blank canvas and zero console errors.
- Mobile. Checked at 375px that the wordmark, nav and the three-metric readout sit fully inside the viewport, with the column re-centred and the least-critical nav link dropped rather than wrapped.
- Resilience. DPR capped at 2, canvas re-sized to its container on resize, the rAF loop and the audio context both suspended on tab-hide and resumed cleanly, and a CSS cave gradient behind the canvas as a no-JS fallback. Audio is constructed only on the first user gesture, so nothing throws an autoplay error on load.