The problem
I needed a portfolio that looked like 2026, not 2018. Recruiters spend 30 seconds on a portfolio at most, and an engineering manager who clicks through wants to know how I think, not just what I've built. Most templates do one or the other.
Approach
I designed the site as a single-page hub for the 30-second scan, with dedicated case-study pages for the engineers who want depth. The aesthetic is intentionally restrained: mono base, electric blue accent, Geist Mono for display type. The signal is taste, not novelty.
Architecture
- Next.js 16 App Router: React Server Components by default; client components only where they earn it (theme toggle, contact form, scroll-fade wrapper, the projects filter UI).
- Tailwind v4 with
@themedesign tokens defined in CSS rather thantailwind.config.ts. - Content is git: flagship case studies are MDX files in
content/projects/; non-flagships, skills, and experience are typed TypeScript files. MDX is rendered with Shiki via rehype-pretty-code so code blocks match the site theme. - Projects explorer: a dedicated
/projectspage, faceted by category and by tech with live counts and an All reset, deep-linkable through query params, and instrumented so I can see which filters people actually use. - Architecture diagrams: real system diagrams authored in Mermaid and committed as SVGs, generated by a local script kept off the deploy path so a build never spins up a browser.
- Generated CV: a noindex
/resumeroute rendered from the same content files, then printed to a one-page PDF with Playwright by a local script. The CV is a committed artifact, so it never drifts from the site. - Contact form posts to a Route Handler that validates with the same Zod schema used on the client, rate-limits via Upstash Redis, and delivers via Resend.
- SEO and analytics: per-project CreativeWork structured data, a generated sitemap and robots, plus Vercel Analytics and Speed Insights.
- Performance budget: Lighthouse ≥ 95 across the board. Self-hosted Geist via
next/font, all images vianext/image, zero client-side data fetching on the home page.
What I'd do differently
This section will grow as the site does. Capture decisions I revisited later here.
