Seven rules, each with its reason.
Every rule here is a claim you can check against a page. When two rules disagree, the lower number wins.
The rules7
The page is a drawing sheet.
Content sits in a rail framed by vertical hairlines; rows are separated by full-width hairlines, sections by a lattice band. Figures are numbered and sections are labelled like sheets.
A reader can find anything by its sheet and figure number, as on a drawing.
Every value is on the scale.
Spacing, type, radius, size and colour come from the tokens. A value that is not a token is out of tolerance: snap it to the nearest step, or make it a token with a usage note.
A system stays consistent only while nobody invents numbers.
Contrast is computed, not eyeballed.
Every colour that can carry words has a measured ratio on every ground it may sit on. Words only go where the ratio is 4.5:1 or more.
A rule anyone can check scales. Taste in one person's head does not.
One spot of yellow.
Everything is ink, grey and hairline on paper. Pineapple is a fill, never words, and appears once per screen in one of seven listed places.
An accent that appears everywhere stops pointing at anything.
Hairlines frame, space groups.
Lines draw the sheet: the rail, rows, bands and figure frames. Inside a row, group with space and weight, not another line. No shadows, almost no radius.
On a drawing every line means something, so a decorative line is noise.
Readable by everyone.
Colour never carries meaning alone. Every interactive element shows a 2px ink focus ring. Motion stops under reduced motion. Layouts hold at 200% text.
Readers with an accessibility setting turned on are the audience, not an edge case.
Real numbers or none.
Charts show real values or say they are illustrative. Counts on this site are derived from the source, never typed by hand.
The sheet's authority comes from its numbers being true.
Where words may go
WCAG 2 ratios of each text colour on each ground, computed from the token values when the site is built. Words go only where a cell says PASS. Lighter tokens (line-strong, line, pineapple) never carry words.
| Text colour | on paper | on surface | on heat-0 | on pineapple-pale | on pineapple |
|---|---|---|---|---|---|
| ink | 19.4 PASS | 19.9 PASS | 17.0 PASS | 16.2 PASS | 11.1 PASS |
| graphite | 10.2 PASS | 10.4 PASS | 8.9 PASS | 8.5 PASS | 5.8 PASS |
| text | 7.5 PASS | 7.7 PASS | 6.6 PASS | 6.3 PASS | 4.3 LINES ONLY |
| rind | 6.2 PASS | 6.3 PASS | 5.4 PASS | 5.1 PASS | 3.5 LINES ONLY |
| text-muted | 5.2 PASS | 5.3 PASS | 4.5 PASS | 4.3 LINES ONLY | 3.0 LINES ONLY |
| text-faint | 2.5 LINES ONLY | 2.6 LINES ONLY | 2.2 LINES ONLY | 2.1 LINES ONLY | 1.4 LINES ONLY |
The places yellow may go7
On the scale or out of tolerance
Any space-*, radius-* or size token, a type style, a colour token, the hairline.
padding: var(--space-4) var(--space-6);color: var(--text-muted);A raw pixel for spacing, a hex colour, a font size that is no type style. Snap it, or promote it to a token with a usage note. On this site a lint check fails the build.
padding: 9px 12px; /* → var(--space-2) var(--space-3) */color: #777; /* → var(--text-muted) */Motion and access
Four uses: content rises 10px on load, 90ms apart; a curve draws in over 1.6s; the caret blinks at 1s; the loader turns every 1.6s. Hover is an instant inversion. All of it stops under reduced motion.
Every interactive element on the sheet shows the same ring on keyboard focus: buttons, links, nav, facts, article rows and heatmap tabs.
A loss carries a minus sign, risk carries hatching, live carries a label. Pages reflow at 200% text without sideways scrolling.