Colophon

How this site is built - just an accurate record of the stack in case it's useful to anyone building something similar.

Last updated

Framework & hosting

Framework
Astro 6.3 - static, no adapter. Pages are pre-rendered at build time and served as static files. No server-side rendering, no edge Worker running per request. This keeps cold starts at zero and the performance budget honest.
Hosting
Cloudflare Workers (Static Assets binding) - the @astrojs/cloudflare adapter is absent because there are no dynamic routes yet. Static files are served directly from Cloudflare's edge without a Worker script in the hot path.
Deploy
Wrangler - wrangler deploy pushes the dist/ build to Cloudflare. No Pages, and CI (GitHub Actions) runs type-check, lint, tests, a build, and Lighthouse on every push; the deploy itself stays a manual step.

Styling

CSS engine
Tailwind CSS v4 CSS-first config - the design tokens live in a @theme {} block in global.css, not a JS config file. Tailwind's utilities reference the same custom properties that raw CSS and React islands use. One source of truth.
Colour space
oklch - perceptually uniform, P3 gamut support, better interpolation than sRGB hex. The dark background is oklch(16.36% 0.0067 178.64); the teal accent is oklch(69.71% 0.108 186.44).
Type scale
Fluid clamp() scales computed on a 1.25 ratio (major third), running from 320px to 1240px viewports. Type and spacing scale continuously - no breakpoint jumps. Inspired by Utopia.
Scoped styles
Each .astro component carries its own <style> block - Astro scopes these at build time. Global utilities (tokens, base resets, the skip link) live in global.css only. Nothing leaks.

Typography

Display / headings
Fraunces - a "wonky" optical-size serif with soft, considered letterforms. Variable font (weight + optical size axes). Used for headings, the home positioning line, and OG card titles.
Body
Inter - high-readability sans, variable font. 18px / line-height 1.6 on desktop; 16px on mobile. Measure held at 65ch.
Mono
JetBrains Mono - code blocks, inline code, and the "currently building" card. Part of the visual identity, not just a fallback.
Loading
Astro 6's built-in Fonts API - self-hosted, subset, font-display: swap, preloaded above the fold. No external font requests at runtime. Zero layout shift from font loading.

Content

Format
MDX - essays and case studies are .mdx files in src/content/, version-controlled in git. No CMS. No database. Editing means editing a file and committing it.
Code blocks
Expressive Code - line numbers, language labels, hover-copy button, and a custom syntax palette derived from the site's tokens. Not a stock rainbow theme.
Reading time
Calculated at build via a remark plugin - adjusted for code blocks and figures, not raw word count ÷ 200. Small integrity signal.

Performance & SEO

Lighthouse
100/100/100/100 on home, /writing, an essay, and /work. Performance is part of the argument - a slow site undermines the credibility it's trying to build. Targets are enforced at each phase gate, not audited at launch.
OG images
astro-og-canvas - per-entry cards generated at build via Skia (canvaskit-wasm). Fraunces title on a dark background with the teal left border. Static files, no runtime Worker.
View transitions
Native cross-document CSS View Transitions - the @view-transition { navigation: auto; } rule in global.css opts the site in. The motion is CSS; the only JavaScript is a ~25-line inline hint that tags each navigation forward, back, or morph so the page slides the right way. Graceful degradation in browsers that don't support it.
AEO / LLM-legibility
Semantic HTML5 landmarks, JSON-LD (Person, BlogPosting, CreativeWork, BreadcrumbList), /llms.txt + /llms-full.txt, and raw-markdown endpoints at /writing/[slug].md. Astro's static output puts content in the markup - the biggest single AEO win, no JS hydration required to extract text.
Analytics
Cloudflare Web Analytics - privacy-respecting, no cookie banner, no Google. The site doesn't track visitors to sell them things.

A few deliberate choices

  • Dark is default. prefers-color-scheme is respected, with a persisted manual toggle. Light mode is first-class - the same tokens, just swapped at a semantic layer.
  • The Now page is never stale. The "last updated" timestamp on the about page is pulled from git history at build time, targeting the about file specifically. Edit the file, commit, the timestamp updates automatically. Calls the bluff of every dead "Now" page online.
  • prefers-reduced-motion everywhere. Not a checkbox - all animations and transitions respect it, including the cross-document view transitions and the home type reveal.
  • No front-end framework. The main site ships zero React - no islands, no hydration. The interactive bits - search, the theme toggle, footnote popovers - are a few KB of vanilla JS. The React work lives in a separate /lab app, kept out of the main bundle.
  • Icons are inline SVG. Lucide via astro-icon - inlined at build, sized by token, no runtime JS.