Motion Without a Framework
Rebuilding this portfolio with CSS-only motion — why I dropped the animation libraries and what the site got in return.
The previous version of this site shipped a 3D hero, a scroll-reveal library, and a motion engine. It looked alive. It also asked every visitor to download a small framework before the first screen settled. For the redesign I set a harder constraint: no animation dependencies at all. Everything moves with CSS.
The Constraint Did the Design Work
Removing the libraries was not a sacrifice — it was a brief. When the only tools are transitions, keyframes, and transforms, you stop reaching for spectacle and start reaching for restraint. The marquee is one @keyframes rule. The menu overlay is an opacity and visibility transition with a staggered translateY on its children. The card hovers are border-color shifts. None of it needs JavaScript to exist.
Where JavaScript Still Earns Its Place
A few things genuinely need the client:
- The live New York clock — an interval and a
mountedguard so the server and client agree on first paint. - The hero spotlight — a
pointermovelistener that writes two CSS custom properties, throttled throughrequestAnimationFrame. - The menu overlay state — a single boolean.
That is the whole budget. The spotlight does not animate in JavaScript; it just moves the origin of a CSS radial gradient. The browser does the rest.
const onMove = (e: PointerEvent) => {
cancelAnimationFrame(raf);
raf = requestAnimationFrame(() => {
el.style.setProperty("--mx", `${e.clientX - rect.left}px`);
el.style.setProperty("--my", `${e.clientY - rect.top}px`);
});
};Reduced Motion Is the Real Test
Every motion in the site has an off switch. prefers-reduced-motion collapses transition and animation durations to nearly zero, the marquee stops, smooth scrolling becomes instant, and the spotlight listener never attaches. If a motion cannot be turned off cleanly, it should not be there.
What the Site Got Back
First-load JavaScript dropped to almost nothing. The page is mostly server-rendered HTML and CSS. It still feels considered — the type still scales, the overlay still sweeps in — but the visitor does not pay a framework tax for it. Interactivity is cheapest when it is honest about how little it actually needs.