Step 1: Scaffolding
What exists after this step
Section titled “What exists after this step”The repo root is an Astro static site; docs/ (this site) is a second,
independent Astro + Starlight project.
The main site, piece by piece
Section titled “The main site, piece by piece”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.
Lessons captured
Section titled “Lessons captured”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.