Colophon

How this site was built

This site is a static page with one server endpoint, built and deployed the way I would build a small production service: content and layout separated, everything validated in CI, secrets kept out of the repository, and the whole thing reproducible from a git clone. The source is public at github.com/husterk/keith-huster-dot-com-site.

🚵 Banff to Antelope Wells in six scenes, one Worker, and about 190 KB.

  • 191 KBcold load of the homepage, fonts included
  • 7requests on that first load
  • 0.9 sproduction build, second of two runs
  • 100Lighthouse in all four categories, median of three

The kit

  • GeneratorAstro 7Static output, zero JavaScript by default. Content collections validate every YAML and Markdown file at build time.
  • ContentYAML + MarkdownUpdating a role or a number is a one-line commit, and the schema catches mistakes before they ship.
  • StylingPlain CSSThe design is expressed as about thirty custom properties. No framework needed.
  • IllustrationsInline SVGSix scenes and the bikepacker, recolorable from one CSS variable, lighter than a photograph.
  • FontsSelf-hostedBarlow, Barlow Condensed and Spline Sans Mono. No third-party requests; the headline face is preloaded.
  • HostingCloudflare WorkersStatic assets from the edge and one Worker for the contact endpoint, custom domain on the apex.
  • Contact formTurnstile + ResendHoneypot, per-address rate limit, Turnstile, then Resend. Spam is handled at the edge.
  • AnalyticsCloudflare Web AnalyticsCookieless, no consent banner, injected at the edge.
  • ToolingBun + miseBun for packages and scripts, Node underneath, both pinned by mise. One command sets up a clone.
  • CI/CDGitHub ActionsType and schema checks, Playwright, axe, Lighthouse CI; a preview per pull request; deploy on merge.
  • Secrets1PasswordA service account; Worker secrets synced on every deploy. GitHub holds a single token.
  • UpkeepRenovateDependencies move on their own and CI is the gate.

Decisions

Why not React
There is one interactive element on the page, the phone menu, and one form. A framework runtime would be the largest asset on the site and would buy nothing. Astro leaves the door open for an island if that changes.
Why the illustrations are code
The six scenes and the bikepacker are SVG, so the whole route from Banff to Antelope Wells weighs less than one photograph, scales to any screen, and picks up the accent color from CSS. On phones each scene re-frames around the rider instead of shrinking.
How content updates work
Edit a YAML file, open a pull request, get a preview URL, merge. If a field is missing or a date is malformed, the build fails with a message pointing at the line.
How the contact form stays quiet
A request has to pass a content-type check, an origin check, a per-address rate limit, a hidden field that humans never see, field validation and a Turnstile verification before Resend sends anything. The endpoint logs one line per request and never the message.
What I would change at scale
For a multi-author site I would add a CMS; for a product I would add an image pipeline and a real design system. For one person and one page, this is the right amount of machinery.

The route, section by section

Why a bike route on an engineering site? In 2025 I rode the Tour Divide, 2,745 miles of dirt from Banff, Alberta to the Mexican border at Antelope Wells, self-supported, in 27 days. It is the best picture I have of how I work: plan carefully, keep things running when nobody can hand you the problem, and finish. The homepage follows that route north to south, one scene per section, and the map on this page is the whole thing.

  1. BanffHero
  2. MontanaExperience
  3. WyomingImpact
  4. ColoradoLeadership
  5. New MexicoPatents
  6. Antelope WellsContact

Credits

Design iterated with Claude on a design canvas over three rounds of direction, copy and responsive review, then built with Claude Code from a written plan. Fonts by their foundries under the SIL Open Font License. Hosted on Cloudflare.

Updated September 19, 2026