The brief, and the idea it became
The brief asked for a fictional perfume house — AMBRE ROUGE, an extrait — rendered as "molten luxury": a full-bleed amber-liquid video hero, a top/heart/base "notes pyramid", gold-leaf text that shimmers on scroll, and a palette of amber, oxblood, black and champagne. The one word the brief kept returning to was slow.
So the organising idea I committed to was firelight. Not "expensive" as gloss and reflection — expensive as warmth: a dark room, a single source of light, everything moving at the speed of something molten. Every decision after that had a test to pass: does this feel like it was lit by a flame, or by a screen?
The assets decided the palette before I wrote a line — the liquid loop and both bottle stills already lived on black with warm rim-light, so the site's job was to not break that spell.
Opulent, slow, expensive
Typography as the jewellery
One display face doing almost all the work: Cormorant Garamond,
set enormous and light for the hero ("Ambre / Rouge"), with the
italic weight reserved for accents so the roman feels composed and the italic
feels indulgent. Body and all-caps labels are Jost — a
geometric sans with wide letter-spacing (.42em) so
eyebrows read like the foil stamping on a box, not like UI.
Restraint as the flex
Luxury is what you leave out. Sections breathe with large vertical rhythm, the spec list is generous to the point of empty, and there is exactly one accent gesture per section rather than five. Nothing pulses for attention; the page trusts you to slow down.
Colour discipline
Everything is driven by CSS custom properties on a near-black
(#0a0705)
ground — warm, not neutral. Amber and gold carry the light; a single oxblood
is held back for the heart note and the acquire glow, so when red finally
appears it means something.
Signature techniques
Video hero with a poster fallback
The molten-amber loop plays muted, looped and inline behind the type. The bottle still is the poster, so on a slow connection — or before the video decodes — the hero is never empty, it's already a lit bottle. A scrim gradient keeps the serif legible over the brightest frames.
<video class="hero-video" autoplay muted loop playsinline poster="assets/bottle-1.webp"> <source src="assets/amber-loop.mp4" type="video/mp4"> </video>
In JS it pauses on visibilitychange
and freezes on the poster frame under prefers-reduced-motion —
motion you never paid for is motion you can turn off.
The notes-pyramid parallax
Each note is a hover-lit panel, and the hero video drifts on scroll — a slow, rAF-throttled translate so the liquid moves fractionally slower than the page. Subtle enough that you feel it before you see it.
window.addEventListener("scroll", () => { if (ticking) return; ticking = true; requestAnimationFrame(() => { const y = Math.min(scrollY, innerHeight); video.style.transform = `scale(1.06) translateY(${y * 0.12}px)`; ticking = false; }); }, { passive: true });
SVG turbulence oud smoke
The base note's "smoke" is not a GIF or a video — it's an SVG path bent by an
animated feTurbulence
displacement filter. The noise frequency itself animates, so the curl never
loops visibly; it just keeps rising from the ember.
<filter id="smoke"> <feTurbulence type="fractalNoise" baseFrequency="0.012 0.03" numOctaves="3"> <animate attributeName="baseFrequency" dur="18s" values="0.012 0.03; 0.02 0.05; 0.012 0.03" repeatCount="indefinite"/> </feTurbulence> <feDisplacementMap in="SourceGraphic" scale="26"/> </filter>
The gold-leaf shimmer
When the perfumer's-note statement centres in the viewport, an
IntersectionObserver adds a .lit
class and a champagne-to-gold gradient sweeps across the text — clipped to
the letterforms so the words themselves look gilded.
.shimmer .line.lit { background: linear-gradient(100deg, #5a3413, var(--gold) 40%, var(--gold-hi) 50%, #5a3413 80%); background-size: 220% 100%; -webkit-background-clip: text; color: transparent; animation: leaf 6s linear infinite; }
A fifth gesture crept in during iteration: a candlelight radial glow
that follows the cursor with a soft-light
blend — fine-pointer only, so touch devices never get a dead effect.
Where the pixels came from
Every asset is generated, then treated for the web. Nothing is stock; nothing is placeholder.
- Bottle stills
- Two flacon photographs (
bottle-1.webp,bottle-2.webp) generated with Higgsfield nano_banana_2 — amber glass, brushed-brass cap, condensation on dark slate. One cinematic-cool, one warm-halo backlit. - Liquid loop
- The 5-second macro amber loop generated as text-to-video with Kling 3.0 Turbo — molten gold and oxblood on pure black, engineered to tile seamlessly.
- Video encode
- Transcoded for the web with
ffmpeg— H.264,CRF 26, muted, at 1280×720. Small enough to autoplay, dark enough to sit behind type. Final file: ~590 KB. - Ingredient art
- The bergamot wheel, saffron threads and oud smoke are hand-coded SVG — gradients, arcs and an animated turbulence filter. No raster, no external requests.
- Type
- Cormorant Garamond + Jost, via Google Fonts (
preconnect+display=swap). JetBrains Mono here in the field notes only.
Three passes
The protocol is: screenshot top / mid / bottom at 1440 and 390, read every shot like a hostile art director, fix what's broken, and add one deliberate complexity upgrade each pass.
The bones stand up
Found: the hero, notes pyramid and product sections landed strong on first build — but the mobile scroll-cue crowded the meta line, nearly touching it at 390px.
Increased hero bottom padding, lowered the cue, and hid it entirely on short mobile viewports.
Upgrade: a self-drawing gilded hairline divider — a stroke-dashoffset animation with a diamond lozenge that scales in behind it.
Reading the dead zones
Found: the spec list left a large empty gap before the next section. Interrogated it — and decided the silence was correct for "slow, expensive", so it stayed. The shimmer statement, caught mid-reveal in one screenshot, proved it needed verifying at rest, not in motion.
Confirmed the gold sweep fully lights the statement once centred; kept the generous whitespace as intentional.
Upgrade: the cursor-following candlelight glow — the site's signature "lit by a flame" interaction.
The last millimetre
Found: on mobile the email input stretched tall — a flex: 1 1 220px growing to fill the column axis.
Reset the input to a fixed height in the mobile query. Re-shot every view — zero console errors, no horizontal scroll, all three note-panels rendering their SVG art.
Result: a hero, a pyramid, a gilded statement and an acquire flow that hold from 1440 down to 390.
Reproduce this
The checklist for a "molten luxury" page that doesn't read as an AI default:
- Let the assets set the palette — sample the hero media, don't invent a scheme beside it.
- One display serif, set genuinely large and light; reserve the italic for accents only.
- Drive every colour from CSS custom properties on a warm near-black, never pure grey.
- Full-bleed muted-loop video with the key still as its
poster, plus a legibility scrim. - One accent gesture per section; hold your single red back until it means something.
- Build ornament in SVG (turbulence smoke, arc-segment citrus) — no raster, no external requests.
- Throttle every scroll handler through
requestAnimationFrame; pass{ passive:true }. - Honour
prefers-reduced-motionandpointer:fine— reduce, never break layout. - Screenshot at 1440 and 390 each pass, read the shots, and let real whitespace stay whitespace.