How this page is built

The [homepage](/) is a business card: a name, a photo, some links. It could be one HTML file written in an afternoon. It is one HTML file. The afternoon part didn't work out.

This is what happens when you ask "how far can one page be pushed?" and then keep going after the honest answer became "too far".

The numbers

One file, one round trip

A new connection sends about ten packets, roughly 14 KB, before it waits for the first answer. Whatever fits into that first flight renders without another round trip. So the build has one job: fit.

No analytics

From 2023 the page ran Google Analytics. It was removed in October 2026, for two reasons:

Removing it also removed the reason for a cookie banner. The cost: no idea how many people read this. That seems fair.

The photo

The photo is the only thing on the page that isn't text, so naturally it got the most engineering.

Layout math

The text is a Markdown document dressed up as source code. It must never wrap on a desktop, never shrink below 12 px, and the photo must never be cut off by the edge of the screen like a mole emerging from the ground.

So the text size is a formula ([the stylesheet](https://github.com/mayrsascha/homepage/blob/master/src/style.css)):


--fs: clamp(.75rem, min(
  (100vh - 6.25rem - 21rem) / 33.7,      /* fit the height */
  (100vh - 6.25rem) / 49.9,              /* ...at big text sizes */
  (100vw - 48px - var(--pw)) / 50.5,     /* fit the width */
  .8125rem + max(0px, (100vw - 1440px) / 64)  /* grow on big screens */
), 1.75rem);

Dark mode, the hard way

Security for a page with nothing to steal

The policy, as sent with every response:


default-src 'none'; script-src 'sha256-…' 'sha256-…' …; style-src 'sha256-…' …;
img-src 'self' data:; connect-src 'self'; base-uri 'none'; form-action 'none';
frame-ancestors 'none'; require-trusted-types-for 'script'; trusted-types 'none'

Accessibility

The checks that keep it honest

Every push runs ([the workflow](https://github.com/mayrsascha/homepage/blob/master/.github/workflows/check.yml)):

New dependency versions wait seven days before they're even proposed, pnpm refuses anything younger than three days, and every GitHub Action is pinned to a commit. The Lighthouse tooling alone used to account for most of the 313 packages the repo installed. It now runs from a pinned action, and the repo installs 24.

How it got this way

Built together with AI, which is how software gets built now. I made the calls: what the page is (a business card, not a CV), what it must never do (cut the photo in half, drop the URLs on a desktop, track anyone), and when a suggestion was wrong. Claude wrote most of the code. Reviews came from AI agents told to find "the top 10 things to improve".

Each round got fixed, then reviewed again. The first rounds found real problems. Later rounds found problems in the checks written to prevent the earlier problems. Round twelve found a bug in the code that checks the code that checks the colours. That seemed like a good moment to write this page instead. It's [Markdown too](https://github.com/mayrsascha/homepage/blob/master/src/how-its-built.md), turned into HTML by the build, naturally.

What's left

[Back to the homepage](/) · [The source on GitHub](https://github.com/mayrsascha/homepage)