Skip to content
All projects
Open source · You're looking at itCase study

This portfolio.

A production-grade Next.js site — every effect hand-rolled, every page statically generated.

This site is its own case study: a fully static Next.js 15 app with a custom cursor engine, a procedural three.js hero and a ⌘K palette — built to prove visual ambition and engineering discipline aren't in tension.

Role
Design + engineering, solo
Type
Open source
Stack
Next.js 15 · React 19 · Tailwind 4
Hosting
Vercel · fully static
Next.js 15React 19TypeScriptTailwind CSS 4MotionThree.js / R3F

01The goal

The goal

A portfolio has one job — get a recruiter to "I want to talk to this person" in under a minute — and one trap: demoing animation libraries instead of engineering judgment. My constraint was that every effect had to be written from scratch, and none of it could cost the first paint anything.

02How it's built

How it's built

A Next.js 15 App Router app that renders to fully static output. All copy lives in one typed content layer, so every section, this case study, the resume and the metadata generate from a single source of truth. Interactive surfaces are client components at the leaves; everything else is a server component.

One typed content layer

Copy, projects and case studies are TypeScript modules — the compiler catches a missing field before a recruiter sees a broken card.

Server by default

Only the pieces that need the DOM — cursor, palette, 3D, reveals — opt into the client. Every route pre-renders at build time.

Motion is a garnish

Every reveal honors prefers-reduced-motion and collapses to instant. Keyboard-navigable, focus-styled, skip-link'd throughout.

03The performance budget

The performance budget

The three.js particle sphere is the most expensive thing here, so it's treated like a liability: dynamically imported with SSR off, downloaded only after hydration, mounted only on desktop. First paint is pure HTML and CSS. Fonts load with swap so text renders immediately; animations run on transforms and opacity only; the aurora, grain and marquees are pure CSS at zero JavaScript cost. A portfolio that claims to care about performance while scoring poorly is self-refuting — keeping it static and lazy was the whole point.

If you only remember four things

  • Fully static Next.js 15 output — no runtime dependencies, instant first paint.
  • three.js hero lazy-loaded post-hydration, desktop-only.
  • Reduced-motion aware, keyboard navigable, SEO-complete.
  • One typed content layer drives every page, including this one.