Colour shifts between sections, clip-path text reveals, staggered entrances. Heyday designed it. I built the animation layer in native CSS — no library.

See the highlights
Approach
The default agency choice in 2019 would have been GSAP. But this didn't need timeline control — it needed scroll-triggered reveals, colour transitions, and a consistent rhythm. That work belonged in CSS.
JavaScript toggled classes. CSS handled the movement.
Design decisions
The design called for palette shifts between sections — mood changes within a single scroll. Each section had its own colour character. The transition between them had to feel continuous, not switched.
Text reveals used clip-path masks. Staggered entrances used animation delays baked in at compile time. CSS custom properties at :root carried the animation character — durations, easing, delays — as a single source of control. Both decisions came from reading what the design was trying to feel, not just what it looked like.
Where design met code
The design called for the site to change colour as you scrolled — not a fade between pages, but a continuous mood shift within a single canvas. Each section had a distinct palette. The transition between them was part of the experience, not just a state change.
Intersection Observer watched when each section entered the viewport. A class toggled on the root element. CSS transitions — defined as custom properties — handled the colour shift. JavaScript watched. CSS moved.
Outcome
Best UI Design, Best UX Design, and Best Innovation at the CSS Design Awards 2019. Delivered without a single animation library dependency.
CSS Design Awards 2019. One of three awards the site received.
CSS Design Awards 2019. Recognised alongside UI and Innovation.
CSS Design Awards 2019. All three delivered without a single animation library dependency.
Reflection
Good frontend work does not just implement a design. It protects the feeling of it.
I'd make the same call again. But now I'd define the boundary earlier: native CSS for rhythm and mood, a library only when the sequence demands precise timeline control.
When the implementation is right, the design arrives intact. That's the argument.