A three-app monorepo built around a single 200-line stylesheet of design tokens, a paper palette, and a quiet refusal to use stock components.
This site is three small Next.js apps sharing one tiny package of design tokens. The main site is for the people who already know who I am. The blog is for the words. The lab — the place you're reading right now — is for the things I'd be embarrassed to put on a CV but proud to show a friend.
The whole visual system fits in roughly 30 CSS custom properties,
defined once in packages/ui/css/tokens.css and imported by every
app:
--paper, --paper-2, --paper-3) for warm
off-white surfaces--ink, --ink-2, --ink-3) for type--a1 (warm orange), --a2 (deep amber),
--a3 (rose) — used sparingly and never together at the same weightEverything else — the tape strips, the wavy underlines, the chip shapes, the placeholder hatch — is built on top of those tokens with plain CSS. No design system library. No component kit. The result is small enough that I can read every rule in one sitting.
The portfolio. Hero, about, work, gallery, contact. It links out to this site and to the blog rather than carrying their content inline, which keeps the main page's payload tiny and lets each subdomain deploy independently on Vercel.
Posts authored as markdown files committed to the repo, parsed with
gray-matter and rendered with marked. Filtering by tag,
category, and free-text search. No CMS. No database. The next move is
an importer that takes Obsidian vault notes and produces these
front-matter-blessed markdown files — but that's a different repo.
What you're reading. Each project is a single markdown case study with structured front-matter — stack, status, year, links, and a row of stats — rendered through a thin React server component.
The goal was a site that looks designed, not assembled.
I'd start with the monorepo. The main app spent its first life as
a single Next.js project, and the migration to apps/main plus
apps/blog plus apps/lab was the kind of work that's only fun
once it's over.