Skip to content
Rahul Nainala
LiveOn my own · 2023–now10 / 15

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.