Skip to content

Step 1: Scaffolding

The repo root is an Astro static site; docs/ (this site) is a second, independent Astro + Starlight project.

astro.config.mjs — static output; inlineStylesheets: 'never' so the CSP can forbid inline styles entirely.

src/styles/tokens.css — design tokens. Every color pair is WCAG AA checked; changing brand colors happens here and nowhere else.

src/layouts/Base.astro — semantic landmarks (header, nav, main, footer), a skip link for keyboard users, per-page title and description.

src/content.config.ts — the blog content schema. Invalid frontmatter fails the build, so bad content cannot deploy. Alt text is mandatory whenever a cover image is present.

public/_headers — Cloudflare Pages security headers: a strict CSP for the site, a slightly relaxed one scoped to /admin/*, plus HSTS, X-Frame-Options, Referrer-Policy, and Permissions-Policy.

public/admin/ — Decap CMS. The bundle is self-hosted (vendor/) rather than loaded from a CDN, so script-src stays 'self' and no third party can change the admin code out from under us.

A static site plus git-based CMS means the only things that can be attacked are the CMS login (delegated to GitHub OAuth) and — later — small serverless form handlers. Everything else is inert files on a CDN.