Guide · how it was made
the hour, explained
Vespertine is a fictional maison de parfum selling three extraits for the hours after sunset. The audience is fragrance-literate and allergic to hard selling; the page's single job is to make each scent feel like a specific depth of evening — before a single price is read.
Concept
Scent is invisible, so the site renders it as the one thing dusk actually gives you: colour losing its edges. Every fragrance is a chord — a set of six colours with its own breathing tempo — and the entire page sits on one continuous colour-field that reorchestrates as you scroll from perfume to perfume. Nothing is photographed because nothing could be: the product is an hour.
Palette
Type
Cormorant Garamond · italic 300 — display & body
Pénombre, Braise Rose
Fashion-house display serif set enormous, tight and italic. The light weight at huge sizes reads as vapour — the letterforms themselves thin out like scent. Body copy runs at 400–500 so it stays solid at reading sizes.
Jost · 400 — letterspaced caps labels
Sunset +0:22 · Civil dusk
Geometric sans tracked out to .3em for eyebrows, hours, prices and the sunset ticker. It plays the role of the blind-embossed hour on the flacon: quiet, exact, tactile.
Techniques
The signature — the breathing colour-field. A single fixed canvas renders six orbs as additive radial gradients (globalCompositeOperation:'lighter'). The canvas is deliberately tiny — about a sixth of viewport resolution — then upscaled and blurred 42–84px in CSS, so the GPU does the softening and the raster cost stays trivial. Each orb breathes on its own sine phase; each fragrance is a chord object of six colours plus a tempo (Pénombre breathes slow, Braise Rose quick, Ambre Nocturne slowest). An IntersectionObserver watches a centre band of the viewport and, per section, eases every orb's RGB and the global tempo toward the new chord with exponential smoothing — the reorchestration is a crossfade in colour and rhythm, never a cut.
Around it: GSAP + ScrollTrigger choreograph one reveal sequence per section (rise + fade, power3.out, 0.11s stagger) and a slow parallax on fragrance names; note pyramids are translucent backdrop-blur veils that stack like layered organza; buttons are magnetic via gsap.quickTo; grain is a 140px canvas-generated noise tile; hovering any raw material flares a soft orb of that note's colour into the field. No raster assets anywhere — canvas, CSS gradients and type only. The page stays fully readable if GSAP or canvas fail.
Iteration log
-
Pass 1Craft
- Lifted the hero gradient endpoint from 50% to 55% alpha mauve so the dimmest letters of “vespertine” hold 3:1 against the base at display size.
- Unified the veil hairlines onto the single border token — they had drifted to their own rgba value — and pushed all Cormorant reading copy (descriptions, notes, atelier facts) from 400 to 500, because the face goes vaporous below display sizes over an animated field.
- Evened the vertical rhythm: the atelier's top padding was 20vh against the fragrances' 16vh for no arguable reason; now one value.
- Added the missing theme-colour meta so the browser chrome sits in the same near-black.
-
Pass 2Depth
- Chord preview: hovering a fragrance in the hero index now rehearses that perfume's chord in the field, and releases back to the scroll-position chord on leave — you can “smell” all three from the top of the page.
- The hero word now arrives blur-to-focus (16px → 0 over 2.2s) alongside its rise — dusk resolving into a word.
- Enlarged fragrance names to 9.5vw with a −22% overhang margin so “Braise Rose” genuinely crosses into its note pyramid at desktop widths — the overlap was theoretical before.
- Retuned section reveals from power3/1.25s/0.11 to power4.out/1.4s/0.13 — a longer glide with a softer landing.
-
Pass 3Hardening
- 375px: names drop their overhang, pyramids tighten their step from 7% to 4% so the base veil keeps a readable measure, ticker hides, grids collapse.
- Added min-width:0 to both grid children so the oversized names overflow by design instead of silently widening the track; svh gets a vh fallback.
- Reduced motion re-verified: no rAF loop at all — the field paints one static frame per chord change; flares, preview, magnetics and parallax never bind.
- Chanel rule: removed the glow shadow under the hero chord dots — the field behind them already glows; the ornament was repeating it.