Colophon
I value simplicity and efficiency, and I enjoy setting up the processes that keep a system that way as it grows. This site is a small, low-stakes example of those habits.
None of the choices below are about the frontend in particular. They are about keeping one source of truth, making checks automatic, and making change cheap. The same approach applies to a data pipeline or a payment service; the site is just where it is easiest to show.
Every change ships from a pull request
The site lives in a Git repository and is deployed by Cloudflare Workers Builds. Each pull request gets its own preview deployment, and Cloudflare posts the preview URL back to the pull request as a comment, so a change can be reviewed in a real environment before anyone reads the diff. Previews sit behind Cloudflare Zero Trust and are visible only to my team; merging to the main branch is what publishes.
The build refuses to complete if the generated design tokens have drifted from their configuration. Formatting, linting, and the build itself are scripted with a pinned toolchain, so they run the same way on every machine. The rule is that anything a machine can check, a machine checks, so review time goes to intent rather than mechanics.
Static output, almost no JavaScript
Pages are generated at build time with Astro and served as plain HTML from Cloudflare's edge. There is no server to operate, patch, or scale. The only site-wide script is the analytics integration; everything else, including the animated greeting on the homepage and the code highlighting in articles, is HTML and CSS produced during the build.
The homepage document, with its inline CSS, is kept below 50 KiB compressed. Text renders immediately with system fallback fonts while the web fonts load.
One source of truth for the design
Type sizes and spacing are fluid tokens generated with
Utopia from a single configuration file; the generated CSS is
committed and checked against that file on every build. Components use semantic names such as
--text-lead or --space-region rather than raw scale steps, so the scale
can change without touching every rule.
There is no CSS framework. Styles follow CUBE CSS and Every Layout principles and are organised into explicit cascade layers, so the order in which rules win is declared once instead of being fought over with specificity. Layouts respond to their content rather than to viewport breakpoints, which is easier to see than to describe:
The clip is generated, not captured by hand. A script in the repository steps the built site through time one frame at a time in headless Chromium, 60 frames per second at twice the pixel density, so nothing is dropped or blurred, and encodes one high-resolution master that is stored in Cloudflare R2. Cloudflare Media Transformations resizes that master on request and caches the result, so each device downloads a version sized for its screen without a player library. The only script on this page starts the clip when it scrolls into view and lets you tap it to pause.
Type
The typeface is IBM Plex: Plex Sans for body text and interface, Plex Sans Condensed for headings, Plex Serif for article titles and long-form prose, and Plex Mono for code and the split-flap greeting. Fonts load through Google Fonts and are proxied by Cloudflare Fonts so the requests stay on this domain.
Measure a few things on purpose
I use PostHog to answer three questions: are the right people finding the site, which writing earns attention, and does the consulting page lead to contact. Generic click capture is turned off; only a small set of intentional events is recorded, such as opening an article or a contact link. Visitors are not identified: there is no login, no form, and the site does not ask for personal information.
Local development sends nothing. If you would rather not be counted, a content blocker that blocks PostHog will do it, and the site works exactly the same.
Writing
Posts are Markdown files with frontmatter, validated at build time. The writing index also lists articles first published on LinkedIn and Substack, and the RSS feed includes both.
Found a problem with the site, or want to talk about setting up processes like these for your team? Email me.