diff --git a/.agents/agents/design-system-keeper.md b/.agents/agents/design-system-keeper.md
index 959beaa..a239273 100644
--- a/.agents/agents/design-system-keeper.md
+++ b/.agents/agents/design-system-keeper.md
@@ -20,11 +20,13 @@ palettes and a broken `@font-face`. **Load skills**: `design-tokens`,
`--paper`, `--muted`, `--line`, `--gold` likewise. Most deltas are
sub-perceptual and can be canonicalized. `--blue` (`#527f9f` vs `#215675`) is
visibly different — screenshot both and get a human decision.
-2. **The fonts have never rendered.** The `@font-face` in `styles.css:1` points
- `src:` at a Google Fonts _stylesheet_, so Manrope and DM Mono have always
- fallen back to Arial and generic monospace. Self-hosting them is a redesign,
- not a refactor. Default: delete the dead rule, declare the stacks that
- actually render. Escalate if someone wants the real fonts.
+2. ~~**The fonts have never rendered.**~~ **Settled 2026-09-05 — do not
+ reopen.** The malformed `@font-face` was escalated and the human chose the
+ real fonts. Manrope and DM Mono are self-hosted in `public/fonts/`, wired
+ through `public/fonts/fonts.css`, which `BaseLayout.astro` links and the
+ legacy root `styles.css` `@import`s. **Do not delete these faces and do not
+ replace the stacks with `Arial`/`ui-monospace`** — that instruction is
+ obsolete. You may add `--font-sans` / `--font-mono` tokens pointing at them.
## You own
diff --git a/.agents/context/design-system.md b/.agents/context/design-system.md
index e7f770f..49579c8 100644
--- a/.agents/context/design-system.md
+++ b/.agents/context/design-system.md
@@ -8,18 +8,18 @@ files, not assumed.
The same semantic names carry different values depending on which stylesheet
loaded them:
-| Token | `styles.css`, `rules/styles.css` | `chapters.css`, `skills-review/styles.css` | `hands-on/*/styles.css` |
-| --- | --- | --- | --- |
-| `--paper` | `#f5f4f1` | `#f6f3ed` | `#f4f3ef` |
-| `--ink` | `#172f42` | `#122534` | `#173044` |
-| `--muted` | `#697b89` | `#65717a` | `#687d8c` |
-| `--line` | `#d8dee2` | `#d0d5d2` | `#d5dde1` |
-| `--blue` | `#527f9f` | `#215675` | `#5683a1` |
-| `--gold` | `#efc76b` | `#ebbf58` | `#efc86d` |
-| `--accent` | `#7c78a8` | — | — |
-| `--deep` | `#102536` | — | — |
-| `--red` | — | `#a7483f` (chapters only) | — |
-| `--violet` | — | `#6b668f` (review desk only) | — |
+| Token | `styles.css`, `rules/styles.css` | `chapters.css`, `skills-review/styles.css` | `hands-on/*/styles.css` |
+| ---------- | -------------------------------- | ------------------------------------------ | ----------------------- |
+| `--paper` | `#f5f4f1` | `#f6f3ed` | `#f4f3ef` |
+| `--ink` | `#172f42` | `#122534` | `#173044` |
+| `--muted` | `#697b89` | `#65717a` | `#687d8c` |
+| `--line` | `#d8dee2` | `#d0d5d2` | `#d5dde1` |
+| `--blue` | `#527f9f` | `#215675` | `#5683a1` |
+| `--gold` | `#efc76b` | `#ebbf58` | `#efc86d` |
+| `--accent` | `#7c78a8` | — | — |
+| `--deep` | `#102536` | — | — |
+| `--red` | — | `#a7483f` (chapters only) | — |
+| `--violet` | — | `#6b668f` (review desk only) | — |
Most deltas are a few units per channel — drift, not intent. `--blue` is the
exception: `#527f9f` vs `#215675` is a visible difference and may be deliberate.
@@ -34,35 +34,36 @@ exception: `#527f9f` vs `#215675` is a visible difference and may be deliberate.
Do not "just pick one" silently in the middle of another task. This is its own
reviewed change with visual diffs attached.
-## The typography you see is not the typography that was written
+## The typography — fixed 2026-09-05
-`styles.css` line 1:
+`styles.css` line 1 used to read:
```css
-@font-face{font-family:Manrope;src:url('https://fonts.googleapis.com/css2?family=DM+Mono&family=Manrope:wght@400;600;700;800&display=swap')}
+@font-face {
+ font-family: Manrope;
+ src: url('https://fonts.googleapis.com/css2?family=DM+Mono&family=Manrope:wght@400;600;700;800&display=swap');
+}
```
-`src:` points at a **CSS stylesheet**, not a font file. No browser can load a
-font from that, so:
+`src:` in an `@font-face` must point at a font binary. That URL returns a CSS
+stylesheet, so no browser could load a face from it. For the whole life of the
+site, every `font-family:Manrope,Arial,sans-serif` rendered as **Arial** and
+every `font:… 'DM Mono',monospace` rendered as the **generic monospace** face —
+`'DM Mono'` was never declared as a family at all.
-- every `font-family:Manrope,Arial,sans-serif` renders as **Arial**
-- every `font:… 'DM Mono',monospace` renders as the **generic monospace** face
-- there are no `@font-face` blocks anywhere else and zero font files in the repo
-- `scripts/audit-ui.mjs` only rejects external ``/`