rahulnainala.com
This site: server-first Next.js with CSS-only motion, a dark theme that passes AA, and an e2e suite over every page.
Overview
The site is the one project whose code I can walk through line by line, so it's built to the bar I hold at work. Pages and sections are server components; the only client JavaScript is a handful of small islands. There's no animation library: the request trace, the reveals and these project drawings are CSS, and page transitions use React's View Transitions. One dark token set keeps every text pair at WCAG AA, and a Playwright + axe suite checks every page at five widths in Chromium and WebKit.
Problem → built → result
- Problem
- A portfolio has to show the craft, not claim it.
- Built
- Server-first Next.js 16, CSS-only motion, an AA-checked dark theme, Playwright + axe on every page.
- Result
- 5 widths × 2 engines, axe-clean
Features
- Server components by default; client JavaScript only for small islands: the header's scroll-spy, the ⌘K palette and the motion observers
- No animation library: the request trace, scroll reveals and these project drawings are CSS keyframes and scroll-driven animations, each with a reduced-motion rest state
- One dark token set (Ops Console); every text pair passes WCAG AA on every surface
- Playwright + axe on every page from 320 to 2560px, in Chromium and WebKit, plus 44px touch-target checks and a no-JavaScript pass
- Strict TypeScript end to end, a CI gate (lint, typecheck, format, dead code) and a Content-Security-Policy with HSTS on every response
Why it's shaped this way
Every effect has a reduced-motion rest state and the content survives without JavaScript, so the site reads the same to a screen reader, a scraper and a phone on a slow connection.