LUMEN is a fictional deep-sea institute that studies bioluminescence, and its page has one job: make you feel the descent. Scrolling is a dive — the water darkens from surface teal to true black across 10,910 metres, a live instrument cluster reads out depth, pressure, temperature and photon flux, and the fauna drifting through the canvas change species as you pass through each pelagic zone. The audience is anyone who has ever wanted a window seat on a submersible.
01Palette
Every colour is water or light — nothing else was allowed in. The background is a single channel that runs from sunlit teal to black; the only two hues that sit on top of it are the cyan of living light and, once, the amber of the anglerfish lure. Amber appears in exactly one zone so it lands like a warning.
#0E3B43surface teal — the last daylight, 0 m
#04121Fmidnight blue — 3,000 m, no sun ever
#000103hadal black — the floor, not quite void
#7FFFE0glow cyan — every living light
#FFB454anglerfish amber — one zone only
#D9E7E2ink — body copy, ≥ 9:1 on the water
02Type
Two voices: the institute and its instruments. Space Grotesk carries the narrative — its slightly engineered curves feel like scientific equipment without turning cold. IBM Plex Mono is the readout voice: the depth gauge, specimen tags, data tables and eyebrows, always small, uppercase and letterspaced wide, the way text is printed on a pressure housing.
Space Grotesk · displayWhere the sun gives up.
IBM Plex Mono · instrumentDEPTH 4,116 M · PRESS 410 BAR · PHOTON 0 %
The scale is deliberate: 10.5px letterspaced mono micro-labels, 17px body, a clamp-driven display step for zone titles, and the typographic bravery moment — outlined depth numerals (−4000 m) set at up to 12.5rem in stroked Space Grotesk 600, ghosts of numbers you scroll straight past.
03Techniques
Canvas 2D particle field with glow compositing. All bioluminescence is drawn with pre-rendered radial-gradient sprites blended in lighter mode — plankton motes, marine snow, lanternfish photophores, siphonophore chains, the lure. No raster assets anywhere.
Piecewise scroll→depth mapping. Each section declares its metre range (data-d0/data-d1); scroll position is interpolated through those breakpoints so the gauge always agrees with the copy beside it.
Scroll-driven colour interpolation. The water column is eight RGB stops lerped by depth and painted as the canvas background each frame, with a fading light-from-above gradient that dies by 700 m.
GSAP + ScrollTrigger. One hero timeline (clipped wordmark rise, expo ease), once-only section reveals, and scrubbed parallax on the giant depth numerals.
The signature element — the depth gauge and its fauna — is one system. A fixed instrument cluster shows a moving 100 m tick tape, smoothed depth, pressure, temperature, photon flux and live descent rate, all derived from the same smoothed depth value that drives the water colour and the species. Each organism has a visibility window in metres (lanternfish 220–1,150, siphonophores 1,100–4,400, anglerfish below 4,300) faded in and out with smoothstep ramps, so the ecosystem hands over exactly where the copy says it should. The cursor is a submersible hull: motes scatter and flare, the lanternfish school breaks, the siphonophore chain flashes segment by segment, and the anglerfish kills her lure and darts.
04Iteration log
Pass 1 · Craft
Muted label colour failed 4.5:1 on the surface teal — lightened #7E9793 → #8CA6A1 (≈4.6:1 at the worst point, higher everywhere below).
Zone numerals were inconsistent (“0–200” range vs “–1000” target) and used en dashes — unified to floor depths with a true minus sign: −200, −1000 … −10910.
Data-table labels at 9.6px were below reading size — raised the table to 12px with 10.5px labels.
Rewrote the muddled lanternfish opening claim into one clean comparison; added a thousands separator to the pressure readout so gauge and copy agree at 1,086 bar.
Pass 2 · Depth
Added a live RATE ▾ m/s readout to the gauge, derived from the smoothed depth delta — the instrument now tells you how fast you are sinking.
Added the second-read detail: CONTACT-01. After long enough in the hadal zone, a string of seven lights crosses the dark and switches itself off mid-crossing — exactly what the Zone V copy describes.
Fast cursor movement now sheds single bioluminescent sparks (disturbed plankton trail); clicking open water spawns a full burst.
Retimed the hero: wordmark letters now rise on a longer expo.out instead of power4, which reads as buoyancy rather than a bounce.
Pass 3 · Hardening
375px: the gauge collapses to a bottom instrument bar; TEMP hides under 480px so the bar never wraps; verified zone numerals and wordmark fit the column.
Reduced motion: no rAF loop — a single static frame is redrawn on scroll, GSAP never registers, CSS animations are killed, and the gauge still reads correctly.
Gauge DOM writes are now skipped when the rounded depth and rate strings haven't changed, keeping scroll frames layout-free.
Chanel rule: removed the lanternfish eye-glow dot — counter-illumination is a belly story, and the silhouettes read cleaner without it. Final copy pass done.
Built with canvas 2D, GSAP 3.12.5 + ScrollTrigger, Space Grotesk & IBM Plex Mono. No images, no build step.
Designed & built by Sapience Analytics — one of 25 sites · the dive · index