BLUR TO FOCUS
INTERACTION_031CSS
Blur To Focus Reveal
Copy resolves from a soft blur into perfect focus as it enters view.
Text / LightView
A fixed window shows one label at a time as the stack slides vertically. Showing the first label only, the rest translated below before the trigger; translating the stack by one row height each cycle once an interval of 2.4 seconds, paused off-screen.
/* Sliding Text Window — A fixed window shows one label at a time as the stack slides vertically. */
.sliding-text-window {
--dur: 620ms;
--ease: cubic-bezier(0.22, 1, 0.36, 1);
--stagger: 60ms;
will-change: transform, opacity;
}
.sliding-text-window > * {
opacity: 0;
transform: translateY(14px);
animation: sliding-text-window-in var(--dur) var(--ease) forwards;
animation-delay: calc(var(--i, 0) * var(--stagger));
}
/* showing the first label only, the rest translated below -> translating the stack by one row height each cycle */
@keyframes sliding-text-window-in {
to {
opacity: 1;
transform: none;
filter: none;
}
}
@media (prefers-reduced-motion: reduce) {
.sliding-text-window > * {
opacity: 1;
transform: none;
animation: none;
}
}import { useEffect, useRef } from "react";
/** Sliding Text Window — trigger: an interval of 2.4 seconds, paused off-screen */
export function SlidingTextWindow({ 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="sliding-text-window" 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.
Sentences in a block arrive one at a time with a calm rhythm.