# Concepts Aftercare is a static site generator built for a specific agency workflow: **ship the design once, then let an LLM maintain the content.** ## The problem Agencies often rebuild the same marketing site pattern for clients, then get pulled back for copy tweaks, new FAQ answers, and page reorders. A traditional CMS adds login theater and layout drift. Handing clients the full React theme invites breakage. ## The Aftercare split | Layer | Who owns it | What lives there | |---|---|---| | **Theme** | Agency | React layout, section components, CSS, `defineSection` contracts | | **Content** | Site owner (often via an LLM) | Site name, nav, page copy, section props in TOON/JSON | | **Agent surface** | Generated | `AGENTS.md`, schemas, Cursor skills — compiled from contracts | The theme is locked after handoff. Content is the only mutable surface for maintenance. ## Contracts as source of truth Every section is a **contract**: ```ts defineSection({ type: "hero", // id used in content files description: "…", // one line for agents props: z.object({…}), // Zod schema → validation + JSON Schema component: Hero, // React renderer example: { type: "hero", … }, guidance?: "…", // optional longer owner instructions }) ``` From that single definition, Aftercare: 1. **Validates** content against the Zod schema 2. **Renders** the matching React component at build time 3. **Syncs** agent docs so an LLM knows which section types exist and which props they accept You do not maintain a separate CMS schema or a hand-written agent guide. ## Build output `aftercare build` produces plain static HTML in `dist/`: - One HTML file per page (`/` → `index.html`, `/about` → `about/index.html`) - Theme stylesheet copied into `dist/` - `public/` assets copied as-is There is no runtime CMS, Node server, or client-side content API. Host the folder anywhere. ## TOON vs JSON Content may be **TOON** (preferred) or **JSON**. TOON is denser—fewer tokens for LLM edits—while remaining human-readable. Both decode to the same structures; validation does not care which format you use. ## Sync vs build vs doctor | Command | Role | |---|---| | `sync` | Regenerate agent files from theme contracts | | `validate` / `doctor` | Check content, routes, images, contracts | | `build` | Sync (unless skipped) → doctor → static HTML | | `watch` | On theme/content/public change: sync, validate, rebuild | `doctor` is the actionable health report. Builds refuse to publish when doctor reports errors (broken props, duplicate routes, missing local images, and similar). ## Who edits what after handoff **Site owner agent** (follow generated `AGENTS.md`): - May edit `content/site.toon` and `content/pages/*.toon` - Must not edit `theme/**`, `aftercare.config.ts`, or generated `agent/` / `.cursor/skills/aftercare-*` files **Agency developer**: - Owns the theme and contracts - Runs `watch` or `sync` so the owner agent surface stays current when sections change ## Next - [Getting started](./getting-started.md) - [Theme development](./theme.md) - [Plugins & client scripts](./plugins.md) - [Content](./content.md)