Every other entry here is a thing I built and then wrote up. This one is the write-up itself, which makes it the only project on the site where you can check the claims by pressing Ctrl+U.

So it should be the one that’s most honest about how it was made. The note above is the short version. Here’s the longer one.

What I actually did

I didn’t write this code. I specified it, reviewed it, and rejected a great deal of it.

That turns out to be most of the work, and it’s the part I’d stand behind in an interview. A few of the decisions on this site, and why:

Three views, not three sites. The switch in the header — Home, Timeline, Game Dev — isn’t three sections of content. It’s three lenses over the same body of work. Home is the complete view. Game Dev is a deep read of one part of it, with its own navigation and its own hero. Timeline is everything in date order. A game shows up on two of the three and keeps one canonical URL, because splitting it into two pages would split its search ranking to solve a problem nobody has.

One place decides what’s visible. Content used to carry its own flags — includeInCV, featured, draft — scattered across every file. Now a single visibility layer answers “does this appear, and where”, per entry and per surface. Absent configuration means visible, so a new project is never invisible because I forgot to list it somewhere.

The CV is a contract, not a scrape. The site emits spec-compliant JSON Resume at build time. A CV generator fetches that one URL and never touches the HTML, which means I can redesign the entire site without breaking it. Contact details are deliberately withheld from it — it’s a public endpoint, and public JSON endpoints get scraped.

Bad content fails the build. Every piece of content is validated against a shared schema. A date written as “Summer 2024” doesn’t render oddly, it stops the build — because free-text dates are the single most common reason a resume parser drops an entry entirely.

The part that’s uncomfortable

The obvious objection to a portfolio like this is that it’s evidence of nothing. If the code is generated, what’s being demonstrated?

That’s the right question, and the games are the answer to it. Every other project here is code I wrote, and the Unity and Unreal work is where to look if you want to know whether I can build things. This site answers a narrower question: whether I can decide what should exist, hold a structure in my head, and tell the difference between output that’s right and output that merely runs.

Those are different skills. Both are real. Conflating them is how you end up with a portfolio full of work nobody can vouch for, and that’s the specific outcome the note at the top exists to prevent.

Built with

Astro with MDX and view transitions, TypeScript throughout, Zod for the content schema, deployed on Vercel. It’s a monorepo: the site, a shared schema package that the future CV service will import directly, and a small companion app for editing content and toggling visibility without hand-editing JSON.