← Studio library

Documentation design

Reference notes. Source retained; historical claims may need rechecking.

Studio reference illustration

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).

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
Related Studio referencer/UXDesign - "Top-notch UI/UX for documentation on the web" Keep - the spine of this digest Named exemplars + the reading/orientation patterns below
Related Studio referenceSemantic UI Borrow the vocabulary, not the framework Segment, callout, steps, statistic, description list, divider, label - as hand-written CSS. The class-naming lesson.
Related Studio referenceuibakery - 6 top HTML UI libraries Confirms hand-written wins Three ideas only: Bulma .content, Tailwind prose measure, Bootstrap .alert/.lead
Related Studio referencescreensdesign.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 Related Studio referenceFomantic-UI. 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


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.

.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.

.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.

.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.

: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.

.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.

h2 .anchor { opacity:0; margin-left:.4em; color:var(--ink-soft); text-decoration:none; }
h2:hover .anchor, h2:focus-within .anchor { opacity:1; }

7. The top menu (the Studio pattern, made a rule 03-08-2026 by Frank's verdict). Every multi-section document opens with ONE sticky bar: left, the collection name in the accent color plus › the page's name (uppercase, small); right, the links: the document's own sections for a long single page, or the collection's sibling pages for a booklet. One line, wraps on phones, no logo clutter. It replaces the old "slim sticky header" and complements the on-this-page rail (short documents can then drop the rail). Proven across the whole UI-UX Studio; the ready component is .topnav in the kit.

.topnav { position:sticky; top:0; z-index:60; background:var(--paper); border-bottom:1px solid var(--line); }
.topnav-inner { display:flex; justify-content:space-between; align-items:center; gap:var(--space-3); flex-wrap:wrap; }
.topnav .brand { font-weight:700; font-size:var(--scale-0); letter-spacing:.08em; text-transform:uppercase; }
.topnav .brand .home { color:var(--accent); }

8. Container / reading column. Cap the page width, and cap the prose column tighter inside it. Kennedy's "generous whitespace" as 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).

.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.

.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.

.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.

.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.

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.

.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.

.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.

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).

.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).

.compare { display:grid; grid-template-columns:1fr 1fr; gap:2rem; }
@media (max-width:700px){ .compare{ grid-template-columns:1fr; } }

D. Three 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.)

: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.

21. No stray value in an inline style - snap it to the nearest token, and scope the class. token-audit.py reads inline style= attributes as well as the <style> block, so a hand-tuned .82rem or .7rem is a violation wherever it sits. Two things to know when clearing them (learned on documentation-compendium.html, 03-08-2026):

Verify by measuring, not by eye: read getBoundingClientRect() and the computed style of every touched element before and after, and confirm the line count of each paragraph is identical.


Anti-patterns - what makes a document tiring


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.

Source previewDownload original source