This site is a Next.js portfolio whose tile grid background repaints per section, whose projects are one JSON file, and which ships an MCP server so an agent can edit that file locally or through GitHub in production.
The site you are reading. Next.js 16 on the App Router with Turbopack, React 19, TypeScript, Tailwind v4, and shadcn/ui, deployed on Vercel. One page carries Welcome, Projects, and About; every project also gets its own page at /projects/<slug>.
Behind everything is a field of animated tiles that flips to a new color as you move between sections. Which section owns the viewport is decided by an IntersectionObserver keyed to the center of the screen, and the flip sweeps from whichever corner matches the direction you travelled, so moving down and moving back up do not look the same. Tile size is expressed as a fraction of vmin rather than a pixel count, which is what keeps the grid stable under zoom: zooming rescales the tiles instead of adding more of them.
The Projects grid is driven entirely by a single data file, src/data/projects.json, typed by src/types/project.ts. Tags are free form by design: a tag exists exactly as long as some project uses it, and the filter is built from whatever the projects currently carry, so there is no vocabulary to keep in sync. A focus picker in the hero lets a visitor say whether they are reading as CS, EE, Computer Engineering, or Teaching; choosing one reorders the grid and swaps in copy for that reader without hiding anything.
Editing that data file is itself a feature. The repo ships an MCP server exposing list/get/create/update/delete/reorder tools over the projects, with validation that runs before anything is written: slugs are lowercase and hyphenated and immutable, and a project's color must clear a WCAG contrast of 3.0 against white, because every project page renders white text on it. The same tools are served two ways: a stdio transport that edits the working tree file so `next dev` hot reloads the change, and an authenticated HTTP route at /api/mcp on Vercel that commits through GitHub instead, guarded by a constant time bearer check that disables the endpoint outright when no token is set.