IInbox
Composed

Effects

Scramble text, spotlight cards, marquee, grain, magnetic hover and count-up — built without driving per-frame work through React state.

Six effects that show up on nearly every developer-tool landing page. The interesting part is not what they do, it is what they avoid.

Live at /lab/effects.

Installation

npx shadcn@latest add https://ui.whoisroktim.lol/r/effects.json

The rule they all follow

Nothing pointer-driven goes through React state. A spotlight card built with onMouseMove={e => setPos(...)} re-renders on every pointer event to move a gradient — sixty renders a second, per card, to change one background position. These write to CSS custom properties on the node instead, so the browser does the compositing and React never hears about it.

el.style.setProperty("--mx", `${e.clientX - r.left}px`);

Working before the script does

ScrambleText and CountUp both render their real content in the markup and only animate once an IntersectionObserver fires.

<ScrambleText text="Landing page furniture" />
<CountUp to={32} />

That ordering matters more than it looks. Build the scramble from an empty span that script fills in, and the text is missing for anyone whose script fails, whose observer never fires because they never scrolled, or who is reading the page through a search index. Same for a counter that starts at 0 — the number on the page should be the true one, with the animation as decoration on top. Both are asserted in tests/dom/effects.test.tsx.

Details worth keeping

The marquee renders its children twice and translates exactly -50%. That is what makes the wrap seamless; animating a single copy from 100% to -100% leaves a visible gap every cycle, which is the tell on most implementations. The duplicate is aria-hidden — a screen reader announcing every logo twice is a real cost for no gain — and both edges are masked so the loop point never shows.

The spotlight has an edge. Two layers: a soft fill inside the card, and a brighter ring masked to the border with mask-composite. A glow without that ring reads as a smudge rather than as light catching a surface.

Grain is inline SVG turbulence, not a PNG. A few hundred bytes, no network request, and it never blurs at high DPR. It animates by stepping background-position between whole-pixel offsets, so the tile moves without any of it being resampled.

Magnetic pull eases to zero at the edge of its field. A linear pull with a hard cutoff snaps when the pointer crosses the boundary, which is what makes most magnetic buttons feel jumpy.

Reduced motion

Every one of these has a defined answer, and for most of them it is show the end state: the text is already decoded, the number is already correct, the magnet does not move. The marquee stops. Nothing here hides content when motion is turned down.