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

01 — The 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.

02 — How 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.

03 — The 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.