# Documentation design - the didactic-page layer

The layer Kennedy leaves open. Kennedy's rules (`kennedy/`) is about **app screens** - one job, one control, one state to manage. Frank's pages are **didactic documents**: teaching pages, one-pagers, explainers read calmly by UN partners and government teams. This digest is the missing body - how a *document* reads well - and it sits under the same two lenses as everything in this folder: the **Teletubbies principle** (the page speaks to the eye before it is read) and the **Kennedy method** (one job, hierarchy by de-emphasis, grayscale first, colour last, double the whitespace).

Captured 2026-07-19 from four sources Frank gave, mined by four agents. Paraphrased in our vocabulary with attribution. All CSS below is hand-written on house-token variables - **no framework, no dependency** - because a self-contained teaching page must stay one file.

---

## The four sources - verdict

| Source | Verdict | What we took |
|---|---|---|
| [r/UXDesign - "Top-notch UI/UX for documentation on the web"](https://www.reddit.com/r/UXDesign/comments/1nush9h/topnotch_uiux_for_documentation_on_the_web/) | **Keep - the spine of this digest** | Named exemplars + the reading/orientation patterns below |
| [Semantic UI](https://semantic-ui.com/) | **Borrow the vocabulary, not the framework** | Segment, callout, steps, statistic, description list, divider, label - as hand-written CSS. The class-naming lesson. |
| [uibakery - 6 top HTML UI libraries](https://uibakery.io/blog/6-top-html-ui-libraries) | **Confirms hand-written wins** | Three *ideas* only: Bulma `.content`, Tailwind `prose` measure, Bootstrap `.alert`/`.lead` |
| [screensdesign.com](https://screensdesign.com/) | **Skip** | App-paywall gallery; zero transfer to documents |

**On Semantic UI:** the framework is 2013-era, jQuery-based, and effectively dead - its own community redirects to the live fork **[Fomantic-UI](https://fomantic-ui.com/)**. Neither belongs *inside* a teaching page (≈500 KB CSS+JS + jQuery for a one-pager is the wrong tool). But its element vocabulary - segment, message, step, statistic - **is** the grammar of a good document. We stole the ideas as a dozen lines of CSS each. See §Blocks.

---

## Named exemplars - the doc sites that read well

- **[LaTeX.css](https://latex.vercel.app/)** - a single `<link>` turns plain semantic HTML into a book-like page: serif type, centred title block, numbered contents, one red accent. Proof that **typography and spacing alone - zero components - can look finished.** The closest reference to what Frank actually needs.
- **[MDN Web Docs](https://developer.mozilla.org/)** - the reference everyone converged on. Persistent "In this article" rail, breadcrumb above the title, soft-tinted status callouts, grey inline `code` chips. Reads well because **the page never makes you guess where you are.**
- **[Stripe docs](https://docs.stripe.com/api)** - three panes (nav · prose · matching example), colour used only as a functional signal. Borrow selectively - the community also called it "getting a little too technical."
- **[Astro Starlight](https://starlight.astro.build/)** - grouped collapsible sidebar, "On this page" control, coloured-left-border admonitions (note/tip/caution/danger). The clean reference for the orientation patterns.
- **[GitHub Markdown CSS](https://sindresorhus.com/github-markdown-css/)** - the "semi-nice baseline" everyone measures against.
- **Vercel · Tailwind · Prisma · Supabase · Radix · Anthropic docs** - named as the current frontier (dev-tool companies competing hard on doc quality). Take the layout discipline, not the specific typeface.
- **Confluence** - named only as the anti-example: wiki chrome, not a designed page. What NOT to imitate.

---

## A. Reading - how prose itself reads well

**1. Reading measure (line length).** Cap body text at **66–72 characters**, never full viewport width. Short lines let the eye find the return path; wide lines lose it on every wrap.
```css
.prose { max-width: 68ch; margin-inline: auto; }
```

**2. Two body regimes.** Reading prose at **18px / 1.6**; dense reference (tables, specs, definitions) at **14–16px / 1.4**. A teaching paragraph and a data table are different reading modes - they should look different. Never mix them in one block.
```css
.prose { font-size: 18px; line-height: 1.6; }
.dense { font-size: 15px; line-height: 1.4; }
```

**3. Generous paragraph rhythm.** ~24–32px between paragraphs, more before headings - roughly double the browser default. Silence between ideas reads as "organised," not "empty." This is the whitespace half of Kennedy.
```css
.prose p  { margin-bottom: 1.6em; }
.prose h2 { margin-top: 3em; }
```

**4. Three fonts, no more - and each has a job.** A serif or humanist sans for **body**, a plain sans for **UI/labels/nav**, a monospace for anything **literal** (code, IDs, field names). The font tells the eye "prose" vs "control" vs "literal value" before the words are read - pure Teletubbies. Set once at `:root`.
```css
:root { --font-body:'Georgia',serif; --font-ui:system-ui,sans-serif; --font-mono:'SF Mono',monospace; }
```

---

## B. Orientation - never let a long page lose the reader

**5. "On this page" rail.** A short list of the page's own `<h2>`s, sticky beside the content; collapses to a `<details>` toggle on narrow screens. Answers "where am I / how much is left" without scrolling blind.
```css
.on-this-page { position: sticky; top: 2rem; font-size: 14px; }
.on-this-page a { display:block; padding:.25rem 0; color:var(--ink-soft); text-decoration:none; }
.on-this-page a:hover { color:var(--accent); }
@media (max-width:800px){ .on-this-page{ position:static; } } /* wrap in <details> here */
```

**6. Anchor links on headings, revealed on hover.** A quiet `#` appears next to a heading on hover, giving every section a citable address ("see the section on X"). Each heading needs an `id`.
```css
h2 .anchor { opacity:0; margin-left:.4em; color:var(--ink-soft); text-decoration:none; }
h2:hover .anchor, h2:focus-within .anchor { opacity:1; }
```

**7. Sticky section header.** A slim one-line bar (page title or breadcrumb) that stays while scrolling a long page. Re-orients without demanding attention. One line, no logo clutter.
```css
.page-header { position:sticky; top:0; background:var(--paper); border-bottom:1px solid var(--line); padding:.6rem 0; }
```

**8. Container / reading column.** Cap the page width, and cap the prose column tighter inside it. Kennedy's "generous whitespace" as CSS.
```css
.container { max-width:1120px; margin:0 auto; padding:0 1.5rem; }
.text-column { max-width:700px; margin:0 auto; }
```

---

## C. Blocks - the document's vocabulary (stolen from Semantic UI, made native)

**9. Segment - the topic block.** A bordered, padded box grouping related content; optionally raised with a soft shadow. **The single most useful idea** - it turns a wall of text into visibly separate topics before a word is read (Teletubbies test).
```css
.segment { background:#fff; border:1px solid var(--line); border-radius:4px; padding:1.5rem 2rem; margin:1.5rem 0; }
.segment.raised { box-shadow:0 2px 6px rgba(0,0,0,.08); }
```

**10. Callout / admonition - the one place colour earns its keep.** A tinted box with a left accent, pulling out one sentence the reader must not miss. Everything else stays grayscale; the callout is the scarce accent (Kennedy). **2–3 meanings max - never a rainbow.**
```css
.callout { border-left:4px solid var(--accent,#888); background:#f7f7f7; padding:.9rem 1.2rem; margin:1.25rem 0; border-radius:0 4px 4px 0; }
.callout.info    { --accent:#2b6cb0; background:#eef4fb; }
.callout.warning { --accent:#b7791f; background:#fbf3e6; }
.callout.success { --accent:#2f855a; background:#eaf7ef; }
```

**11. Steps - the procedure row.** A row of numbered stages, each with a title and short description. Turns "first… then… finally" into something scannable in two seconds. The shape for every "how this works" page.
```css
.steps { display:flex; border:1px solid var(--line); border-radius:4px; overflow:hidden; }
.step { flex:1; padding:1rem 1.25rem; border-right:1px solid var(--line); }
.step:last-child { border-right:none; }
.step .num  { font-size:1.4rem; font-weight:600; color:#999; }
.step.active .num { color:var(--ink); }
.step .title{ font-weight:600; margin-top:.25rem; }
.step .desc { color:var(--ink-soft); font-size:.9rem; }
```

**12. Statistic - the big number.** A large numeral with a small caption. Lands the one figure a page wants remembered ("47 countries", "3 steps", "€0 cost"). De-emphasis by contrast: everything around it stays quiet.
```css
.stat .value { font-size:2.75rem; font-weight:700; line-height:1; color:var(--ink); }
.stat .label { font-size:.85rem; text-transform:uppercase; letter-spacing:.05em; color:var(--ink-soft); margin-top:.35rem; }
```

**13. Definition pairs.** Term + one-line meaning, structurally paired. Didactic pages constantly need "here is a word, here is what it means" - native `<dl>` says it structurally, which a callout can't. Use the real tags.
```css
dl.desc-list dt { font-weight:600; margin-top:1rem; }
dl.desc-list dd { margin:.15rem 0 0 0; color:var(--ink-soft); }
```

**14. Divider - named section break.** A rule, optionally with a word centred in it ("Step 2", "Or"). Splits a long page without a full heading.
```css
.divider { display:flex; align-items:center; color:#999; margin:2rem 0; }
.divider::before, .divider::after { content:""; flex:1; border-bottom:1px solid var(--line); }
.divider span { padding:0 .75rem; font-size:.85rem; }
```

**15. Label - the status tag.** A tiny rounded tag ("Draft", "Required", "Step 2 of 4"). One grey + one accent cover a document's needs - skip Semantic's dozen variants.
```css
.label { padding:.2em .6em; border-radius:3px; font-size:.75rem; background:#eee; color:var(--ink-soft); }
.label.accent { background:color-mix(in srgb,var(--accent) 15%,white); color:var(--accent); }
```

**16. Code / example blocks - label, don't just colour.** A small language tag or filename above the block, monospace, horizontal scroll (never wrap - wrapping destroys the indentation, which is itself information). A block distinguished by background colour alone is invisible without colour vision.
```css
figure.code figcaption { font:12px var(--font-mono); color:var(--ink-soft); background:#f2f2f0; padding:.3rem .8rem; border:1px solid var(--line); border-bottom:none; border-radius:4px 4px 0 0; }
figure.code pre { margin:0; overflow-x:auto; padding:1rem; background:#fafafa; border:1px solid var(--line); border-radius:0 0 4px 4px; }
```

**17. Tables - sticky header, zebra rows, scroll in their own box.** Long reference tables keep the header visible; alternate tint aids row-tracking; on small screens the table scrolls sideways inside its wrapper rather than squeezing (the same rule Frank applies to artifacts).
```css
.table-wrap { overflow-x:auto; }
.table-wrap thead th { position:sticky; top:0; background:var(--paper); }
.table-wrap tbody tr:nth-child(even) { background:#faf9f7; }
```

**18. Before/after & two-column comparison.** Wrong-way beside right-way, or old beside new, in matched columns with equal visual weight. Comparison is instant in two columns and slow in prose - the eye sees the difference before reading why (Teletubbies).
```css
.compare { display:grid; grid-template-columns:1fr 1fr; gap:2rem; }
@media (max-width:700px){ .compare{ grid-template-columns:1fr; } }
```

---

## D. Two meta-rules that make all the above cheap to change

**19. Palette as variables, up front.** One `:root` block, not hex scattered through the file. Then "one accent colour" or "double the whitespace" is a two-line edit, not a search-and-replace. (Frank's house rule is **light theme only** - so no `prefers-color-scheme`; but the variable discipline the dark-mode sites use is worth keeping.)
```css
:root { --ink:#1a1a1a; --ink-soft:#666; --paper:#fdfdfb; --line:#e4e4e0; --accent:#b3261e; }
```

**20. Grayscale-first review.** Every pattern above must carry its hierarchy in black/white/grey; colour is added only where it means something (a warning, a link, a status). Review by dropping `filter:grayscale(1)` on `<body>` - anything that loses hierarchy was leaning on colour to do structural work that size, weight and space should have done. This is the Kennedy method, made a checkable step.

---

## Anti-patterns - what makes a document tiring

- **Full-width body text** - no measure cap; the eye loses its place on every wrap.
- **Colour-only signalling** - a code block or status told apart purely by hue; invisible without colour vision or on a poor screen.
- **Font tourism** - 3+ display fonts on one page (the "tired of Geist" complaint is over-designed type, not the font).
- **Loud saturated callouts** - filled high-chroma boxes for routine notes; everything screams, so nothing lands.
- **No local orientation on a long page** - no rail, no sticky header, no anchors; a scroll of unknown length.
- **Reading prose and dense reference at the same size/weight** - a paragraph and a data table fighting for one register.
- **Word-wrapped code** - long lines wrap and break the code's own structure.
- **Confluence-style wiki chrome / marketing-page hero type** - nav, tags, "last edited by", oversized display headings competing with the content for the first five seconds. A document's job is to be read calmly, not to sell.

---

## The semantic-naming lesson (free, no framework)

Semantic UI's real contribution isn't its CSS - it's the naming discipline: classes read like English (`raised segment`, `info message`, `three column grid`), so markup is self-documenting. Adopt the habit for hand-written pages: name a div `class="callout warning"` or `class="step active"`, never `class="box-3 c-blue"`. Anyone opening the file later - Frank in a year, or a partner's developer - reads intent straight off the tag. Costs nothing, needs no framework.

---

## Delta vs our rules

**CONFIRMS**
- **Reading measure + two body regimes + double rhythm** = the typography rules already in the system doc, now with named px/ch numbers for documents specifically.
- **Callout / statistic / steps = colour and size as scarce, meaningful signal** - the Kennedy de-emphasis rule made into concrete blocks.
- **Grayscale-first review** = our existing grayscale check, now with the `filter:grayscale(1)` mechanic.
- **Segment / comparison / big-number** all pass the Teletubbies 5-second test by construction - the eye sees structure before reading.

**ADDS (new to the folder - Kennedy didn't cover documents)**
- **The orientation kit** - on-this-page rail, hover anchors, sticky header. Kennedy has nothing on long-read navigation; teaching pages need it.
- **The block vocabulary as native CSS** - segment, callout, steps, statistic, description list, divider, label, labelled code block. A ready shelf to lift from, on house tokens.
- **The "borrow the vocabulary, refuse the dependency" rule** - the honest answer to "should we adopt Semantic UI / Bootstrap / Tailwind": no - steal the idea, hand-write the CSS, keep the page one file.
- **The semantic-naming habit** - self-documenting class names, portable to every page.

---

## Next (proposed, not built)

1. **`documentation-kit.css`** - consolidate every snippet above into one self-contained, house-token stylesheet a session can paste into a page and delete what it doesn't use. This digest is the *why*; the kit would be the *ready material*.
2. **Wire this into Angel's hook** so any session writing HTML receives it automatically (move 2 of the plan).
3. **A `/ui-doc` skill** that loads this digest + the kit on demand (move 3).
