The page background and accent color smoothly transition as each section enters view. One palette per section — and the navbar, CTAs, and dot indicator all update in lockstep.
Each section of the page has its own palette. As you scroll, the body background and accent color of all UI chrome (navbar, buttons, glowing dot) animate smoothly to the next section's colors. The effect: the page itself feels like it's morphing through a story — each scene gets its own mood. Used by Apple product pages, Stripe Sessions microsites, Spotify Wrapped, almost any modern long-scroll narrative.
Each section element has data-bg, data-fg, and data-accent attributes. An IntersectionObserver watches them — when a section becomes the most-visible one, JS sets corresponding CSS custom properties (--bg, --fg, --accent) on a high-level container with a transition. Because every UI element references those vars, the entire chrome morphs in one go with a single 0.45s transition. The clever bit is just: store the palette on the section, let the section announce itself when in view.
Scroll inside. Background, navbar, accent dot, and CTA all morph at each section.
Deep violet stage with lilac accent. The mood shifts.
See features →Marine teal with electric cyan accent — cooler, sharper.
Run a benchmark →The page flips to a warm cream finale. Editorial closer.
Create one →Build a long-scroll page where the background, text color, and accent color morph as each section enters view. The page root has CSS custom properties --bg, --fg, --accent with a transition:background 0.45s ease, color 0.45s ease on it. Every chrome element references those vars — the sticky navbar uses var(--bg) + var(--fg) + var(--accent); the section CTA buttons use background:var(--accent) color:var(--bg). Each section element has data-bg, data-fg, data-accent attributes carrying its palette. Sections: (1) HERO — black + warm gold; (2) FEATURES — deep violet + lilac; (3) SPEED — marine teal + electric cyan; (4) CLOSING — warm cream + deep red. Use IntersectionObserver (threshold:0.55) on every section — when a section becomes the most-intersecting one, read its data-* attributes and assign them to the root's --bg/--fg/--accent CSS variables. Show a small "Section N / 4" chip in the navbar that updates with the section's name. The whole chrome (background, headlines, navbar, dot indicator, CTA button) animates together in a single 0.45s ease transition — feels like the page changes scene.