Engineering
How this portfolio is built
Warm print design, OKLCH color, and a content pipeline that is just TypeScript.
What this site is for
A portfolio is a claim you have to back up.
This site says I build software carefully. That claim is cheap unless the site itself is evidence, so I treat it as a small production project: measured performance, tested accessibility, and a public repository anyone can read. This post is the story of how it is built, including the parts I later ripped out.
The design: warm print
Paper, ink, and one green voice.
The current design borrows its rules from print. The background is a warm paper tone with a faint grain, the text is a near-black ink, and a single forest green carries every accent: links, eyebrows, buttons. Rules are hairlines, corners are square, and there is no dark mode, because a printed page does not have one.
Type does most of the work. Source Serif 4 sets the headings, IBM Plex Sans carries the body, and IBM Plex Mono handles the apparatus: labels, tags, file names. Every color on the site is defined in OKLCH, which gets its own post.
Content is TypeScript
The compiler replaced the content pipeline.
The first version of this blog ran on Velite: posts were MDX files, frontmatter was validated with Zod schemas at build time, and a prebuild step compiled everything into a typed data file. It worked, but it was a second build system to maintain, and every custom component had to pass through an MDX component registry.
The current version deletes all of that. A post is a plain TSX module: a typed metadata object and a React component, collected in a small registry array. The type checker validates the metadata, the bundler compiles the body, and interactive components are ordinary imports.
export type WorkMeta = Readonly<{
title: string;
subtitle: string;
slug: string;
date: string;
timeline: string;
role: string;
techStack: ReadonlyArray<string>;
liveUrl?: string;
summary: string;
outcome: string;
}>;
export type Work = Readonly<{
meta: WorkMeta;
body: () => ReactNode;
}>;The trade
How it ships
Agents write the code. Gates decide.
Agents write most of the code on this site, under the same rules as every repository I run: strict TypeScript, Biome with warnings treated as errors, and a Playwright suite that scans every route against the full WCAG 2.2 AA rule set. The gates fail closed. If a check cannot run, the change does not ship.
Those rules are public and versioned in their own repository, and every project syncs from it. The site you are reading passed them.
Read the source
The repository behind this site is public, gates and all.