The starter template that every site this pipeline produces is generated from. Drives Lighthouse 95+/100/100 builds out of the box, ships ~zero JS by default, and takes its content from a single brief.json.
template/
├── astro.config.mjs # site URL from env, sitemap + tailwind integrations
├── tailwind.config.mjs # CSS-variable-driven brand colours
├── tsconfig.json # strict mode + @/ path aliases
├── lighthouserc.cjs # Perf >=95, SEO/A11y =100 build gate
├── brief.schema.json # JSON Schema for brief.json
├── brief.schema.md # human-readable explainer
├── brief.example.json # working sample (gavingeorge.co.uk)
├── public/
│ └── robots.txt
└── src/
├── components/
│ ├── SEO.astro # title, meta, canonical, OG, Twitter
│ ├── JsonLd.astro # generic schema.org JSON-LD emitter
│ └── LeadForm.astro # markup-only form (Worker comes Wed 2026-05-13)
├── content/
│ ├── config.ts # locations, services, blog collection schemas
│ ├── locations/example.md
│ ├── services/example-service.md
│ └── blog/welcome.md
├── layouts/
│ └── BaseLayout.astro # uses SEO + JsonLd, sticky mobile phone CTA
├── pages/
│ ├── index.astro # WebSite + LocalBusiness JSON-LD
│ ├── about.astro
│ ├── contact.astro
│ ├── 404.astro
│ ├── services/{index,[slug]}.astro # Service + FAQPage JSON-LD
│ ├── locations/{index,[slug]}.astro # LocalBusiness JSON-LD per area
│ └── blog/{index,[slug]}.astro # Article JSON-LD
└── styles/
└── global.css # Tailwind directives + brand tokens + reduced-motion
npm install # one-time
npm run dev # local dev server
npm run build # static build to dist/
npm run preview # preview the built dist/
npm run build:gated # build + run Lighthouse CI assertions (Phase 1+ only)The site-generator script (Mon 2026-05-11) takes a brief.json, clones this template, populates the content collections, replaces brand tokens, and commits a fresh repo. Until then, manually edit:
- Brand:
tailwind.config.mjs(CSS-variable defaults already wired) andsrc/styles/global.css(:roottokens). - NAP / phone / email:
.envwithPUBLIC_SITE_NAME,PUBLIC_PHONE,PUBLIC_EMAIL,PUBLIC_TAGLINE.astro.config.mjsreadsSITE_URLfor the canonical base. - Pages: Markdown files in
src/content/{locations,services,blog}/. Frontmatter shape is enforced bysrc/content/config.ts.
See brief.schema.md for the full brief shape.
- Per-page
<title>, meta description, canonical URL, OG, Twitter —src/components/SEO.astro. - JSON-LD per page type:
WebSite+LocalBusinesson home,Service+FAQPageon service pages,LocalBusinessper location,Articleper blog post —src/components/JsonLd.astro. sitemap-index.xml+sitemap-0.xmlgenerated by@astrojs/sitemap.robots.txtallows everything and points at the sitemap.- Lighthouse CI gate in
lighthouserc.cjsblocks builds below 95/100/100.
LeadForm.astro posts to /api/lead (a Cloudflare Pages Function — wired Wed 2026-05-13). Includes:
- Honeypot field (
company_website) - Cloudflare Turnstile mount point (sitekey injected at deploy time)
- Required-on-client validation, autofill hints
- Privacy-notice microcopy + 1-working-day promise
| Layer | When |
|---|---|
| Cloudflare Pages deploy wiring | Thu 2026-05-07 |
| Form Worker (CF Pages Function → Emailer + LeadCatcherCore) | Wed 2026-05-13 |
generate_site.py script that consumes brief.json |
Mon 2026-05-11 |
/web-new, /web-deploy, /web-audit skills |
2026-05-15 onward |
| GEO content rules (capsule guard, two-layer context scaffolding) | Mon 2026-05-18 |
webdev-architect agent (Phase 1/2/3 content generation) |
Wed 2026-05-20 |
| Claude Design / Stitch / Nano Banana stage docs | Mon 2026-05-25 |
| GSAP hero animation component | Wed 2026-05-27 |
| Decap CMS overlay (saleable sites only) | Deferred |
The spine ships when:
npm install && npm run buildproduces a cleandist/✓ (done 2026-05-04)- Every page in
dist/has title + meta + canonical + OG + the right JSON-LD type ✓ - Sitemap and robots are generated ✓
- The site can deploy to Cloudflare Pages and load over HTTPS — due Thu 2026-05-07
- Lighthouse CI passes 95/100/100 against the deployed URL — due Fri 2026-05-08
Steps 1–3 done. 4–5 are this week's targets.