writing

Notes on building keoir.dev

This site is deliberately small. One binary builds it, it ships as static files, and it has no runtime dependencies. Here is what is under the hood and why.

The generator is Hugo. It is a single Go binary with no node_modules and no build server to keep alive, which matches how I run everything else. The output is plain HTML and CSS that a web server hands out as files.

The CSS is hand written against a set of custom properties: colors, a type scale, spacing, and motion durations all live in one token file, and nothing downstream hardcodes a hex value. There is no Tailwind and no framework. Light and dark modes both read from prefers-color-scheme, with a manual toggle that persists in localStorage.

There is almost no JavaScript. The theme toggle is a few lines of vanilla JS, and the home page signature animation is an SVG that draws itself with CSS. With JavaScript disabled the whole site still renders and reads correctly.

Every font is self hosted and subset. No Google Fonts, no analytics, no third party script of any kind. That keeps the home page under the performance budget and, as a side effect, means there are no cookies and no consent banner to show.

Because nothing loads from another origin, the Content Security Policy is strict by default: default-src 'self'. The one inline script that sets the theme before first paint is allowed by its hash rather than by opening up the policy.

The whole thing is served from my own network over dual stack IPv6, HTTP/3 with an HTTP/2 fallback, and TLS 1.3. Deploys are a git push. That is the entire stack, and I would rather keep it that boring.