Why this exists
I spent about a year and a half building platforms that I cannot show you the code for. Client work, employer work, systems holding real people’s data. The result was a strange situation: a lot of shipped software and almost no public evidence of it.
This site is the answer to that. The code belongs to whoever paid for it, but the decisions are mine, and decisions turn out to be the more interesting half anyway. Nobody was ever hired because of a repository. People get hired because someone read how they think.
So this is a portfolio in the honest sense: not a gallery, a place where I explain choices and admit what went wrong.
How it is built
Astro with the Fuwari theme, Tailwind for styling, a few Svelte islands for the interactive parts, deployed to Cloudflare.
The parts worth mentioning:
- Content collections with Zod-validated frontmatter. Posts are markdown files with a typed schema. A malformed date or a missing title fails the build instead of shipping a broken page, which is exactly where I want that error.
- An extended markdown pipeline: admonitions (the coloured callout blocks you see in these pages), GitHub repository cards, KaTeX for maths, automatic reading time, and excerpt generation.
- Build-time search with Pagefind. The search index is generated during the build, so full-text search costs nothing at runtime and needs no server. For a static site this is the right trade: slightly slower builds, free search forever.
- Page transitions with Swup, which has one consequence worth knowing about: every client script has to tolerate being executed again on navigation, because the page never actually reloads.
- A separate data module for these project cards, which is honestly a design I intend to change. See below.
The thing I would fix
Right now the project listing lives in a TypeScript data file and the detail pages live in markdown, linked by an optional slug. Two sources for one concept.
The better design is a single content collection with a Zod schema, where adding a project means creating one markdown file and nothing else. It is on the roadmap. I am describing it here rather than quietly fixing it because a portfolio that admits its own known issues is more credible than one that pretends to be finished.
The other outstanding item: several images on this site are hosted on an external image host, which is a single point of failure I do not control. They belong in the repository, optimised at build time.
A bug worth rememberingThis site once stopped building entirely, with exit code 1 and no error output at all. The cause had nothing to do with the code: I had renamed the project folder, and the package manager’s dependency links still pointed at the old absolute path. Every dependency was a dangling link. The fix was one reinstall, and the lesson was that a tool failing silently is a worse problem than a tool failing loudly.
What is here
- Posts about engineering decisions, the tools I use, how I organise work, and how I actually use AI day to day.
- Projects, these pages.
- An about page, which I keep meaning to rewrite.
Status
Live, and permanently unfinished in the way personal sites are.
