Guide · Site 03 of 25
How Lumina Flora was made
A night conservatory whose central trick is treating darkness as a first-class design token — one CSS variable that the whole page, and its particle system, obey.
The concept
Bioluminescence only reads against real darkness, so the site commits to a near-black indigo (#05070f) and spends its entire contrast budget on glow: teal for the plants, violet for the sky, one firefly gold for events. Typography is Marcellus — a roman capital with lantern-light dignity — over Manrope at weight 300. The fiction (lottery tickets, wax-sealed phone pouches, the Pollen Hour) does as much atmospheric work as the code.
Technique 1 — the firefly swarm
A fixed, pointer-transparent <canvas> runs ~110 particles. Each has a wobble phase (its own meander), a twinkle phase (brightness on a squared sine, so flashes feel biological rather than sinusoidal), and one of three palette colors. The signature part: fireflies inside a 170px radius are gently attracted to your cursor — acceleration toward the pointer with a hard velocity clamp, so they orbit and trail rather than snap. It reads as curiosity, not physics.
var dx=mouse.x-f.x, dy=mouse.y-f.y, d2=dx*dx+dy*dy;
if(d2 < 170*170 && d2 > 20*20){
var d=Math.sqrt(d2);
f.vx += dx/d*.012; f.vy += dy/d*.012; // pull, softly
}
if(speed > .55) clamp(...) // never let them dart
Each firefly is drawn twice — a radial-gradient halo and a small white core — which is what sells "point of light" instead of "moving dot."
Technique 2 — dark adaptation as a CSS variable
The slider writes one custom property, --adapt (0–1), on :root. The hero photograph's filter: brightness(), every species image, and the canvas particles' alpha all derive from it. One variable, page-wide consequence — the visitor literally adjusts the exhibit's eyes. This is the cheapest kind of interactivity to build and the most memorable kind to use: state lives in CSS, JS only writes a number.
Technique 3 — the scroll-drawn night walk
The itinerary's winding path is an SVG whose geometry is rebuilt from the list's real height on resize, then animated with the classic stroke-dasharray / stroke-dashoffset draw, driven by scroll progress. Each timeline stop "lights" (box-shadow bloom on its node) as it crosses 75% of the viewport — the page walks the mile with you.
Technique 4 — atmosphere details
- The hero photograph drifts on a 26s
transformloop — slow enough to be felt, not seen. - Glow ratings are five dots with real
box-shadowlight, not icon-font stars. - The moon in the closing section is a pure-CSS radial gradient breathing on a 7s cycle.
prefers-reduced-motionstops the swarm, the drift and the path-draw entirely; the page holds still and lets the photography glow.
The photography
All four photographs (two garden establishing shots, two impossible macro blooms) were generated with Higgsfield Soul 2 from written art direction, delivered as 90–250KB WebP. The invented species were then written to match the pictures — fiction reverse-engineered from imagery.
How it was made
Written by Claude (Fable 5) as one hand-authored HTML file — vanilla HTML/CSS/JS, no framework, no build step, no particle library. Part of the Fable 25, a 25-site showcase deployed on Cloudflare Pages.
Steal this
- Make your theme a number. One
--variablethat images, text and canvas all read beats twenty scattered tweaks. - Clamp velocity, not acceleration in particle systems — that's the difference between creatures and confetti.
- Draw lights twice: big soft gradient + tiny hard core.
- Square your sine waves (
pow(sin, 2.2)) for organic twinkle — pure sine reads mechanical. - Let dark sites be dark. Resist lifting the blacks; spend contrast on one or two glow hues instead.