Each word sits in an overflow:hidden box and slides up from 105%. The mask is the parent, not a gradient — the letters are genuinely clipped by the line above, the way a printed slug would be. Staggered by index on a long expo curve.
Characters resolve out of noise, left to right, each settling at its own moment. One requestAnimationFrame loop over a string — no library, and no per-character DOM node churn.
It inverts
mix-blend-mode: difference on a sticky headline. Four panels scroll underneath and the type inverts against every one — black on paper, white on ink, the exact complement over red and blue. No colour swapping, no scrim, and not one line of JavaScript. Three declarations of CSS.
Weight and colour move together as the line crosses the viewport centre. The eye reads the heaviest line first regardless of where it sits — which is why a weight ramp beats a size ramp when vertical space is tight.
Kinetic typography that survives a real content workflow — copy that changes, translations that run longer, and a client who will paste in a sentence twice the length of the one it was designed around.
Most kinetic type splits a headline into one DOM node per character and animates each. That breaks text selection, confuses screen readers, churns hundreds of nodes on every resize, and shatters the moment the copy changes length.
Reveals use real overflow masks on word wrappers, so
letters are genuinely clipped by the line above the way a printed slug
would be. The decode runs one requestAnimationFrame loop
over a string — no per-character nodes at all. The inversion is
mix-blend-mode: difference on a sticky headline: three
declarations, and not one line of JavaScript touches it.
Difference blending needs a two-colour ground. It is exact over flat panels and turns to mud over photography, so it is a deliberate choice for a controlled palette rather than a general-purpose technique. The text is also readable before any script runs — JS arms the hidden state, never the reverse.