MAKE IT
FEEL PREMIUM.
INTERACTION_036CSS
Clip Path Heading Reveal
A heading wipes into view as its clip rectangle opens left to right.
Text / LightView
The whole string shuffles and settles like a mechanical board. Shuffled characters at reduced opacity before the trigger; settling each character into position with a fading opacity ramp once hover on desktop, entry on mobile.
/* Scrambled Text Reveal — The whole string shuffles and settles like a mechanical board. */
.scrambled-text-reveal {
--dur: 700ms;
--ease: cubic-bezier(0.22, 1, 0.36, 1);
--stagger: 60ms;
will-change: transform, opacity;
}
.scrambled-text-reveal > * {
opacity: 0;
transform: translateY(14px);
animation: scrambled-text-reveal-in var(--dur) var(--ease) forwards;
animation-delay: calc(var(--i, 0) * var(--stagger));
}
/* shuffled characters at reduced opacity -> settling each character into position with a fading opacity ramp */
@keyframes scrambled-text-reveal-in {
to {
opacity: 1;
transform: none;
filter: none;
}
}
@media (prefers-reduced-motion: reduce) {
.scrambled-text-reveal > * {
opacity: 1;
transform: none;
animation: none;
}
}import { useEffect, useRef } from "react";
/** Scrambled Text Reveal — trigger: hover on desktop, entry on mobile */
export function ScrambledTextReveal({ children }: { children: React.ReactNode }) {
const ref = useRef<HTMLDivElement>(null);
useEffect(() => {
const el = ref.current;
if (!el) return;
if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
el.dataset["state"] = "in";
return;
}
const io = new IntersectionObserver(
([entry]) => {
if (entry?.isIntersecting) {
el.dataset["state"] = "in";
io.unobserve(el);
}
},
{ threshold: 0.2 },
);
io.observe(el);
return () => io.disconnect();
}, []);
return (
<div ref={ref} className="scrambled-text-reveal" data-state="out">
{children}
</div>
);
}A heading wipes into view as its clip rectangle opens left to right.
Copy resolves from a soft blur into perfect focus as it enters view.
Each line slides up from behind an invisible mask, one after the other.
Words fade up in sequence so the sentence assembles as you read it.