Colophon

How this site is built and why. Everything on this page can be checked with your browser's developer tools.

Stack

Framework
Astro, static outputEvery page is plain HTML built ahead of time. No server, nothing to patch at runtime.
Interactivity
React islandsOnly the stack map and the command palette use React, and the palette loads on first use.
Styling
Tailwind CSS and CSS custom propertiesDesign tokens are CSS variables, so light and dark mode are one attribute change.
Type
IBM Plex Sans, self-hostedNo font CDN: better privacy and a stricter security policy.
Content
Markdown and YAML with Zod schemasContent is validated at build time; a typo in a date fails the build instead of the page.
Editing
Keystatic, local onlyA friendly editor while developing. It is not part of the published site.
Quality
Vitest, Playwright, axe, Lighthouse CIEvery route is tested for accessibility, console errors and CSP violations on each change.
Hosting
Cloudflare Workers static assets (Vercel as alternative)Deployed by the host from Git; CI verifies but never deploys, so no tokens exist.

Decisions

Each decision is recorded as an architecture decision record (ADR).

  • Static outputThe production build is plain files with no server code.
  • Git-based content, Keystatic in development onlyContent is versioned in Git; the editor never ships.
  • Host-agnostic hostingThe same build and headers work on Cloudflare and Vercel.
  • Content Security PolicyHash-based policy from Astro plus a header policy for framing and plugins. No unsafe-inline.
  • Zero secretsNothing in the repository or CI needs a credential.
  • Custom SVG stack mapA small component instead of a graph library, readable without JavaScript.
  • Tooling versionsPinned where the ecosystem has not caught up yet.
  • Command palette on demandPages without islands stay nearly JavaScript-free.
  • Motion without a libraryScroll-driven CSS, view transitions and SVG animation; everything pauses on request.

How content is edited

Content lives as Markdown and YAML files next to the code. I edit it in Keystatic while running the site locally, or directly in a text editor, then commit and push. The host rebuilds the site from Git. Drafts never reach the published site, and clients are described rather than named unless they have agreed.

Security headers

Sent with every response. Scripts and styles are also restricted by a per-page policy of exact hashes.

Strict-Transport-Security
Browsers only ever connect over HTTPS for the next two years, including subdomains.max-age=63072000; includeSubDomains
Content-Security-Policy
Forbids framing, plugins, foreign form targets and <base> hijacking. Script and style hashes live in a per-page meta policy generated by Astro.frame-ancestors 'none'; base-uri 'self'; form-action 'self'; object-src 'none'; upgrade-insecure-requests
X-Content-Type-Options
Stops browsers guessing file types, so a file is never executed as something it is not.nosniff
Referrer-Policy
Other sites only learn the origin a visitor came from, never the full path.strict-origin-when-cross-origin
Permissions-Policy
Turns off browser features this site never uses: camera, microphone, location, payment, USB and more.accelerometer=(), autoplay=(), camera=(), display-capture=(), encrypted-media=(), geolocation=(), gyroscope=(), hid=(), idle-detection=(), magnetometer=(), microphone=(), midi=(), payment=(), publickey-credentials-get=(), screen-wake-lock=(), serial=(), usb=(), xr-spatial-tracking=()
Cross-Origin-Opener-Policy
Isolates the browsing context from pages opened in other tabs or pop-ups.same-origin
X-Frame-Options
Legacy clickjacking protection for browsers that ignore frame-ancestors.DENY

Next step

Let's talk

Interested in a case study, how I approach full-stack development, software architecture, AI-enabled applications or something I've built?

Get in touch or explore my work and projects.