Skip to main content

July 15, 2026

Rebuilding tahmid.space: Next.js to Astro, and why theme switching drove the decision

How a portfolio's light/dark sync bugs exposed an architectural truth — and what moving the presentation layer to Astro islands + Aceternity UI actually changed.


My portfolio has been through four designs this year. The last rewrite wasn’t about looks — it was about an architecture bug I kept patching and never fixing.

The bug that wouldn’t die

The Next.js version kept theme state in a React context. The <html> class, the CSS variables, the three.js scene and the toggle each had their own idea of “current theme”, synchronized by hand. I fixed a first-paint flash, a patchwork transition, and a canvas that stayed in the old theme when your pointer was idle — three real bugs, one root cause: JavaScript owned a piece of state that belongs to the document.

The structural fix

In the Astro rebuild, theme is a data-theme attribute set by a pre-paint inline script. Every color on the site is a --sys-* CSS variable that re-resolves from that attribute. The toggle flips the attribute; nothing else exists. React islands can’t desync because they hold no theme state at all.

What Astro islands changed

The page is static HTML with eight small hydration points — the Aceternity components (navbar, hero effects, timeline, carousels, contact form) hydrate client:visible, so below-fold JavaScript never competes with first paint. The trusted-collaborations wall — 36 brand icons — renders as build-time SVG with a pure CSS marquee: zero JavaScript for the section people scroll past fastest.

Design tokens, Material-style

The other lesson: utility classes without a scale produce “everything seems small and inconsistent” (my own words to the AI pair-programming with me). The fix is a token layer with Material Web’s discipline — color roles with mandatory on- pairs, a five-step typescale, motion tokens — documented on a live /design page that re-renders when the theme flips.

More on the RAG pipelines and the Shopify headless work soon — those posts belong here now that this site finally has a blog it can grow into.