How this site works

This page exists because I like knowing how the tools I use work, and I figure some visitors do too. Everything below is accurate as of this deploy, not an aspirational spec.

Stack

  • Next.js 15, App Router, React 19, TypeScript
  • Tailwind CSS v4 plus a hand-rolled design token system in styles/globals.css
  • Supabase (Postgres) for content, read through lib/database.ts via supabase-js
  • Prisma as the schema and migration tool only, the runtime never touches the Prisma client
  • No client-side animation library. CSS transitions and native <dialog> do the work

Rendering per route

RouteStrategyRevalidate
/ISR1 hour
/projects/[slug]SSG + ISR1 minute
/open-source/[slug]SSG + ISR1 hour
/achievements/[slug]SSGon demand
/blogISR1 hour
/blog/[slug]SSGon demand
/aboutStaticbuild time
/contact301 -> /about#contactn/a
/api/*Dynamic (server-rendered)n/a

Type and color

Switzer for prose, JetBrains Mono for anything meant to read like an instrument readout: dates, metrics, tags, section labels. Both are self-hosted as static woff2 files rather than pulled from a font CDN.

The palette is a warm paper light theme and a blue-black dark theme, built around one accent (deep teal in light mode, phosphor teal in dark) rather than a wide brand palette. Every skill tag gets its own hue, spaced by the golden angle around the color wheel so adjacent tags never read as the same color, verified programmatically to meet WCAG AA contrast rather than eyeballed.

This deploy

commit 379796b · source on GitHub