Le guide · Notes de fabrication
How the site
learned to wear scent
SILLAGE is a demonstration template built on one idea: a perfume house should not show you its perfumes, it should put them on. As you scroll, the whole page re-tints to each extrait's palette while the photography melts from one tableau to the next. Here is the entire machine.
The tinting system
Every color on the page, background, ink, accents, hairlines, is a CSS custom property. Each chapter of the site redefines those five variables under a body attribute, and a 1.4 second transition rides along:
body[data-chapter="3"] { /* Marée: low tide */
--paper: #DCE2E4; /* cold porcelain */
--ink: #1C272B;
--accent:#40606B; /* slate teal */
}
Changing one attribute (data-chapter) re-colors hundreds of elements in a
single move. No JavaScript touches a color; the stylesheet is the perfumer.
The dissolve
The arched window is a WebGL canvas, about two hundred lines of it, no libraries. Both the outgoing and incoming photographs are loaded as textures, and a third texture holds soft procedural noise. During a transition each pixel asks the noise field when it should switch:
float d = texture2D(uDisp, vUv).r; // 0..1 noise
float m = smoothstep(d - edge, d + edge, p2);
gl_FragColor = mix(imageA, imageB, m);
Dark parts of the noise switch early, bright parts late, so the change arrives like smoke rather than like a slideshow. Both images are also pushed apart along the noise while it happens, which is what gives the dissolve its pulled, liquid feel.
The noise texture is baked in JavaScript at load, three octaves of value noise, so the effect ships with zero image assets beyond the photography itself.
The photography
Every tableau was generated with gpt-image-2, then color-managed into the palette system. Consistency across nine images comes from prompt discipline: one identical sentence describes the flacon in every prompt ("a minimal rectangular clear-glass perfume flacon with a thick heavy glass base and a plain pale travertine-stone cap, unlabeled"), while a shared art-direction suffix pins the light, the film grain, and the negative space.



The arch crop does quiet work here: AI photography can drift at its edges, and the chapel-window mask keeps every image composed around its center, where these models are strongest.
The chapter engine
The scrollable page is six invisible full-height sections; everything you see lives in one fixed stage. Scroll position rounds to a chapter index, and one function fans that index out to the body attribute (tint), the text column (page-turn), the canvas (dissolve), and the progress ticker.
const i = Math.round(scrollY / innerHeight);
body.dataset.chapter = i; // re-tint everything
articles[i].classList.add('active');
dissolve.show(i); // melt the photograph
Because state is a single integer, the site is trivially deep-linkable and
debuggable: /?c=3 pins the page to Marée for design review.
Type and layout
Boska carries the maison's voice: a sharp, fashion-grade serif whose italics do the flourishes; Satoshi does the quiet work of prose and labels. The layout is one asymmetric editorial spread, image arch left, text right, that the chapters reuse, so the design reads as one continuous object rather than five pages.
Accessibility is kept intact under the theatrics: real headings, real definition
lists for the note pyramids, visible keyboard focus, and
prefers-reduced-motion swaps the dissolve for a hard cut and stills every
transition.
Build your own
- Pick the one idea. Ours is "the site wears the scent". Every technique serves it; anything that does not is cut.
- Put every color behind a variable from the first line of CSS. Theming, dark mode, and this entire effect become one attribute swap.
- Generate imagery with a fixed subject sentence and a shared art-direction suffix; vary only the scene. Consistency is prompt discipline.
- Write the dissolve yourself. Two textures, one noise field, one smoothstep. It is a first WebGL project, and it looks like a studio built it.
- Keep state to one integer. Scroll rounds to a chapter; everything else is a pure function of that number.