BLUR TO FOCUS
INTERACTION_031CSS
Blur To Focus Reveal
Copy resolves from a soft blur into perfect focus as it enters view.
Text / LightView
Sentences in a block arrive one at a time with a calm rhythm. Each line at 0 opacity, 16px down before the trigger; lifting each line into place in document order once the block reaches 25% visibility.
/* Staggered Sentence Reveal — Sentences in a block arrive one at a time with a calm rhythm. */
.staggered-sentence-reveal {
--dur: 420ms;
--ease: cubic-bezier(0.22, 1, 0.36, 1);
--stagger: 110ms;
will-change: transform, opacity;
}
.staggered-sentence-reveal > * {
opacity: 0;
transform: translateY(14px);
animation: staggered-sentence-reveal-in var(--dur) var(--ease) forwards;
animation-delay: calc(var(--i, 0) * var(--stagger));
}
/* each line at 0 opacity, 16px down -> lifting each line into place in document order */
@keyframes staggered-sentence-reveal-in {
to {
opacity: 1;
transform: none;
filter: none;
}
}
@media (prefers-reduced-motion: reduce) {
.staggered-sentence-reveal > * {
opacity: 1;
transform: none;
animation: none;
}
}import { useEffect, useRef } from "react";
/** Staggered Sentence Reveal — trigger: the block reaches 25% visibility */
export function StaggeredSentenceReveal({ 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="staggered-sentence-reveal" data-state="out">
{children}
</div>
);
}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.
The workhorse: a paragraph lifts gently into place with no drama.