Back to Decode
Engineering

The website was finished. The system wasn't.

From hand-built pages to a portfolio engine: what rebuilding my own site taught me about content UX, maintainability, and the difference between a website that looks finished and a system that stays useful.

  • Systems
Format Article
Topics Systems
Focus Engineering
Updated 02 July 2026
On this page
  1. Three goes at the same problem
  2. Where it stopped scaling
  3. One model, many shapes
  4. A design system, not a stylesheet
  5. Places for different kinds of work
  6. Built to be found, by people and machines
  7. What it cost, and what I will open up
  8. What I took from it

When I first built a case study for a local tyre business, the whole thing lived inside one HTML file. The problem statement, my role, the deliverables, every paragraph of prose: all of it typed directly into the template. To change a heading I edited markup. To add a project I wrote a new view, a new route and a new template by hand.

The same case study today is a record in a database. I open the admin, compose it from blocks (a metrics band, a two-column section, a flow diagram, a pull quote) and publish. No code, no deploy. That shift, from content baked into pages to content as data, is what this piece is about.

Three goes at the same problem

I have rebuilt my portfolio three times. The first two were from when I was learning web development, so they reflected where I was, and each one did its job. Each project page was its own hand-written template, positioned by hand in CSS, with the content sitting inside the markup. Later I got more ambitious and added GSAP scroll animation, but it was still all hand-built. Getting a version up and running took me weeks.

The third version, the one that has been live, kept that same hardcoded core and grew around it. I bolted on experiments, including an AI sandbox, but the portfolio itself never really changed shape. It worked, but it had stopped being something I could build on.

Where it stopped scaling

Four things, specifically.

The content was hardcoded. Every project was markup, so every change was an edit to code. There was no separation between what I wanted to say and how it was shown.

It did not scale. The data model was thin, and structure was duplicated by hand rather than defined once, so adding anything meant copying a pattern each time rather than extending a system.

Mobile was a compromise. The animation-led design was built for big screens; mobile deserved a first-class treatment the hand-built version was never going to give it.

It could not be found. The overall SEO was optimised but nothing to help more recent language models understand the site. No sitemap worth the name, no machine-readable version of the work, nothing.

One model, many shapes

The rebuild starts from a single idea: one content model that can take different shapes.

Everything is a Post with a type (a case study, an essay, a note, a log) and a layout. The case studies are composed from a small set of building blocks: text, two columns, a pills row, a metrics proof-band, a quote, an outcome list, a flow diagram, a prompts row, an "ask me about" panel. Nine block kinds, each rendering its own small partial. I assemble a case study the way you would build with parts, not by writing a fresh page each time.

The effect on the work is the point. A new piece of content is now a record I create in the admin, not a branch I deploy. The body even generates its own section anchors and reading time. I built this version in about a week, working with AI support, and with far less effort on my side than any of the hand-built ones, because I was no longer writing every page by hand.

A design system, not a stylesheet

The old site was a single stylesheet of around 1,500 lines, full of class names tied to specific pages. The rebuild uses a set of 35 design tokens (colour, ink, paper, type, spacing, radius, motion) defined once. The accent colour is injected at runtime from a single admin field, so the whole site can be re-themed without touching CSS. The same codebase is built to run as a different person's site by changing data, not code.

Places for different kinds of work

The old portfolio had a content system underneath it that I never really used, because I had no clear idea of what went where. The rebuild fixes that by giving different work its own home.

There are streams for the things I am actively playing with: building, making, learning, moving. That is where experiments and works-in-progress live, low ceremony, updated often. Separately there is a writing track for longer pieces, the kind of content I can grow over time and, in time, build something on. Keeping the two apart means the playful work stays playful and the considered work has room to be considered.

Built to be found, by people and machines

This is the part I care about most, because it reflects how I think the web is changing.

The engine ships a proper discovery layer. A sitemap covering the static pages, the case studies and the writing. A robots file and an RSS feed. A schema.org description of me and of each article, so search engines understand the structure. And two things aimed squarely at language models: an llms.txt index of the site, and a plain-markdown version of every post at its own address, so a model can read the work cleanly rather than scraping a page of layout.

None of the earlier versions had any of this. Optimising a portfolio for people is table stakes. Optimising it so that the systems people increasingly ask about your work can actually read it is, for now, an edge.

What it cost, and what I will open up

I want to be straight about effort. This version took less of it than the hand-built ones, because most of the work went into the system once, and the system now does the repetitive part. That is the whole argument for building things this way.

When everything was hand-built, the cost of a feature was not just writing it. It was deciding, up front, whether it was worth the days it would take. Scope was rationed by effort. A lot of the design work was really triage: what to cut so the build stayed finishable at all. That constraint has mostly gone. Composing a case study from blocks, or adding a new kind of content, now costs hours, not weeks.

That changes which question is the hard one. When building was expensive, the interesting problem was how to build the thing. Now that building is cheap, the interesting problem is what to build, and for whom. The bottleneck moved from execution to judgment, from solving the problem to choosing the right problem to solve. That shift is the one I actually care about, and it is the same shift I look for in product work.

The plan is to run this as open-core: the engine itself open and reusable, with a premium layer of paid features released later. The value I am offering is not really the code. It is the thinking behind it and the service around it. The code is the proof.

What I took from it

The throughline across all three rebuilds is the same one I bring to client work: turning something vague into a system that runs. The early versions taught me how much hand-built effort hides in a design that has no model underneath it. The rebuild is what happens when you put the model first, let the content be data, and design the thing to be read by both people and machines. Same instinct as before. Less effort, more leverage, and now with AI in the loop rather than bolted on the side.

Related

More to read