Skip to content
All writing

How I built this site

Jun 19, 2026

I build go-to-market systems for a living, which mostly means wiring tools together until pipeline comes out the other end. So when I finally built my own site, I gave myself one rule: no framework, no build step, nothing I would have to babysit at 11pm on a Sunday. Just files I can read. Here is what it is actually made of, and the one bug that briefly made me question my entire career.

The whole stack fits in a sentence

HTML and CSS. That is the stack. No React, no Next, no bundler, no node_modules folder quietly eating half a gigabyte on my laptop. The site is a handful of static files and two stylesheets, and it will outlive every JavaScript framework I have ever been talked into using.

  • It loads instantly and hosts anywhere.
  • There is no build to break.
  • Every page is a plain file I can open and understand.

A design system doing the heavy lifting

None of this would look like much without the part I did not want to improvise: the design system. It is a small editorial kit I call Mosaic Press. Cream paper, ink-black panels, and a violet accent that is, deliberately, a touch too loud.

The trick is that nothing is hardcoded. Every colour, font, and spacing step is a CSS custom property, so the whole site reads from one set of tokens:

:root {
  --color-paper:  #f2ead8;
  --color-ink:    #101010;
  --color-violet: #5b3fff;
  --font-display: "Instrument Serif", serif;
}

Change one variable and the entire site moves with it. Headings use Instrument Serif because serifs read like they have finished a book. Everything else is Inter Tight.

Depth comes from colour blocking, not glassy shadows.

Claude Code did most of the typing

I did not hand-write every tag. I described what I wanted to Claude Code, usually across four terminal tabs because my attention works best when it has somewhere to wander, and it wrote the markup while I argued about spacing. When I want a new post, I copy a template file, fill in the words, and add a card to the index. This post started life as exactly that template.

A contact form with no server

I wanted a real contact form without standing up a backend just to receive a handful of emails a month. Web3Forms handles that: the form posts to their API, a little JavaScript catches the response, and you get an inline confirmation without ever leaving the page.

It also handed me a lesson in humility. The form went completely dead on the live site. The button would darken, and then nothing. I blamed Cloudflare. I blamed caching. I blamed the universe. The actual culprit was this innocent-looking line:

var status = document.getElementById('formStatus');

In the global scope, status quietly aliases the browser's built-in window.status, which only holds text. My form element got coerced into the string "[object HTMLParagraphElement]", and the handler threw before it ever sent anything. One renamed variable and it worked. I can automate your growth. I apparently cannot always name a variable.

Writing for the robots too

More than half of the visitors who find this site will not be people. So it ships the boring, important stuff: Open Graph tags so links look right when I drop them on LinkedIn, structured data so search engines understand who I am, a sitemap, and an llms.txt that hands AI crawlers a plain-language summary. If a model is going to describe me, it can at least get the facts straight.

Shipping it

It lives on GitHub Pages, pointed at my own domain through Cloudflare. A few DNS records, a CNAME file, HTTPS switched on, done. The whole thing deploys when I push to main, which is the only build step I am willing to tolerate.

Add it up and the running cost is the part I like most. GitHub Pages hosts the files for nothing, Cloudflare handles DNS and HTTPS on its free plan, and Web3Forms catches the contact form without a server. The only thing I actually pay for is the domain. A whole site, a real contact form, and a global CDN, for the price of a coffee a year.


The point of all this is that you do not need much. A few files, a design system, and a tool that types faster than you. I can wire up a site, a CRM, and a small army of agents. The printer, however, remains undefeated.