Colophon
This is where I keep an honest account of how this site, and the system behind it, are built - and why I build them the way I do. It spans three domains: the web (this site), the local machines I work on, and the self-hosted stack underneath.
The machine
Web
This site is hand-coded, no framework. One shared stylesheet driven by CSS custom properties, so there is a single place to change colours and fonts. The three typefaces (EB Garamond, Source Serif 4 and Special Elite) are self-hosted and open-licensed, so the site makes zero external requests. It is served by OpenBSD's httpd and relayd on the VPS.
Local
Workstation. Linux Mint, Cinnamon. VSCodium running Claude Code, a terminal and Firefox, plus Chrome for Claude Code's browser plugin. Mail is neomutt with msmtp and mbsync. Calendar and contacts are khal, khard and vdirsyncer. Zotero for research, Calibre for books, and Signal, restic, Tailscale, git and Python throughout.
Laptop. A ThinkPad that mirrors the workstation, so I move between the two without friction - one of the main things I wanted back after leaving the Mac world.
Phone. Was a secondhand Pixel 8 Pro on GrapheneOS with no Play Services. RIP - dropped, unusable. Back to an iPhone Mini on a throwaway Apple account for now. Because every service is local and self-hosted, the switch back took only a few URLs and shortcuts. Win case for the stack.
Elsewhere. A BooX Note Air for reading and annotating, and a 2004 iPod running Rockbox, still the best music player I own.
Stack
The server. Built out of four old PCs. Ubuntu, headless, seventeen containers doing nine jobs: Immich (photos), Vikunja (tasks and the kanban board), Nextcloud (file sync), Jellyfin (film and TV), AudiobookShelf (audiobooks and ebooks), qBittorrent behind Gluetun and ProtonVPN, Listmonk (email lists), ntfy (push notifications), and Dockge to manage all of it.
The VPS. OpenBSD. httpd and relayd serve this site. OpenSMTPD and Dovecot do mail, with rspamd and redis filtering spam. Radicale does CalDAV and CardDAV. A restic repository is the offsite end of the backups.
Built on top. Zotero into markdown; Readwise into the same folder; an offline voice-note pipeline (record on the phone, sync up, transcribe with Whisper on the GPU, land as dated markdown); handwriting via OCR off the BooX; local models (Ollama running Llama 3.3 70B, Qwen and Mistral Small, plus an embedding model for retrieval over the whole notes folder); backups with a watchdog, a heartbeat and an integrity check; and the glue that exports the kanban's deadlines into the terminal calendar and turns an open email into a calendar event.
The thing running all of it. One folder of plain markdown, run by an AI orchestrator I talk to in the terminal, with a team of specialists behind it - each with a written contract and its own journal, all the same model wearing different hats. AI-agnostic; currently Claude Code.
What got killed
Syncthing (replaced by Nextcloud). Fastmail (replaced by my own mail server). Amazon, Audible, Apple, S3, Microsoft, and very nearly Google. And Obsidian, Drafts, Apple Notes and Trilium, all of which went the same way for the same reason.
The why
The machine above is the what. This is the why - the ethos under the Digital Independence and website work. It is the one part of this page I can't write for you: it's yours, and it wants the threads from your journal.
The log
Dated updates. Each tagged web, local or stack.
2026-07-21 web
Changes
- Rebuilt the homepage from a single quote into an h-card with name, bio and social identity.
- Added a /now page.
- Added
meta descriptionandfediverse:creatorso link previews and Mastodon shares show something deliberate. - Restyled the whole site: shared stylesheet, CSS custom properties, one place to change colours and fonts.
- Self-hosted two open-source serifs (EB Garamond and Source Serif 4, both SIL OFL) and set Garamond as the body face.
- Converted Special Elite and veteran typewriter from woff to woff2.
Fixes
- Changed every
style.cssto/style.css, because relative paths break the moment a page lives in a subfolder. - Fixed
src="https:/images/..."(one slash, no host) to/images/.... Two broken dog photos, live since March, and I never noticed. - Retired the deprecated
<center>tags and closed the<li>and<p>tags left hanging in the old pages.
Learned
- Microformats2 is just class names on ordinary HTML.
rel="me"is an identity claim, and it only proves anything when both ends link to each other.- HTML fails silently. I wrote a whole h-card inside a comment and the browser said nothing, it just showed less.
- The three kinds of path (relative, root absolute, absolute) and which one breaks when.
python3 -m http.serveris the whole local dev setup for a hand-coded site.- Variable fonts carry a weight range in one file, and subsetting to Latin cut them by about 40%.
- Special Elite is distributed through Google Fonts but is Apache-licensed, so self-hosting it means zero external requests.
2026-03-08 web
- Added a new page called "last week: this happened..." - less of a change log, more of a weekly recap journal where I talked about what I got up to over the previous seven days. It has since been folded into this page and retired.
- Added the countdown banner tracking how many days until Android becomes a locked-down system. I really hope this doesn't happen. You can find the banner script, and read more about the consequences here.
- Learned how to use
<div>and<float>to wrap text around an<img>, which is how the dog photos sat in that page's March entries. - Also learned how to use
<and>to escape angled brackets! After which it gets a little too inception-y when you have to try and double escape the ampersands!
2026-02-21 web
- Used
style="color:MediumSeaGreen;"to change the text colour and differentiate Linux changes from website changes. - Learned how to insert code snippets using HTML and CSS via the
<code>tag.
2026-02-21 local
- Worked out how to use the CLI and xkeybinds in Linux Mint to set mouse buttons to trigger workspace switching.
2026-02-19 web
- Added an images folder to htdocs and linked the first image (my dog) into a page.
- Fixed a "403 forbidden" where the image would not display, by fixing file permissions.
- Created the first iteration of the sitelog - the ancestor of this page.