One family, two voices: Archivo for prose and headings, IBM Plex Mono for data. Both are SIL Open Font License fonts, self-hosted. Radius is zero. Borders are full boxes or absent.
Color
Swatch
Token
Value
Use
--paper
#F9F8F5
Page
--paper-2
#EEEDE8
Tinted panels, table header rows
--ink
#1C1E22
Text, primary box borders
--ink-2
#4B4F57
Secondary text
--rule
#B9BBC0
Grid borders, non-text
--redline
#D8381B
Identity, primary button, redline strokes
--redline-text
#B52C13
Red text at 15px
--review-text / --review-fill
#7F5800 / #F2E3B8
REVIEW only
--ready-text / --ready-fill
#1F6B45 / #D6EADF
READY only
--block-fill
#F6D9D2
BLOCK fill
Type, px at desktop / tablet / mobile
Role
Size
Setting
Display
72 / 56 / 44
Archivo 600, line 1.02, cover headline only
H1
44 / 36 / 32
Archivo 600, line 1.08
H2
30 / 28 / 26
Archivo 600, line 1.15
H3
22 / 21 / 20
Archivo 600, line 1.25
Lead
21 / 20 / 19
Archivo 400, line 1.4
Body
17
Archivo 400, line 1.55, max 68ch
Meta, labels, captions, chips
15
IBM Plex Mono 500, caps, tracking 0.06em
Floor
15
Nothing renders smaller, at any size
Spacing runs on 8px: section rhythm 96 / 64 / 48, stacks at 32 and 16. A 12-column grid, 24px gutters on desktop, 16px gutters and side padding on phones, 1632px container.
02
Components
Live examples below. The large components run on sheet 02 with real data.
Full grid, sticky caption, cards under 620px of container
Ledger, TracePanel
Findings with status, notes, SQL rows
RuleCard
Rule, SQL twin, UAT scenarios
SqlBench, SchemaPanel
SQLite in WebAssembly, loaded on demand
MappingTable
Legacy to target with transforms and live counts
DriftTable, SignOffChecklist
Parallel run and release paperwork
Exercise
Task, control, hint, check, answer, explanation
03
Motion
Motion shows state change and nothing else. No scroll-linked effects, no parallax, no preloader, nothing longer than one second.
Motion specification
Element
Trigger
Transform and timing
Reduced motion
Cover ruler
First paint, once per session
Axis draws left to right 900ms, gate diamonds fill 120ms each, 40ms stagger, cubic-bezier(0.22, 1, 0.36, 1)
Static, fully drawn
Verdict chip
Status change
Fill and text crossfade, 180ms ease-out
Instant
Ledger row
Status change
Background to the verdict fill and back, 620ms ease-out
Instant
Trace panel, desktop
Open or close
translateX(16px) and fade, 240ms cubic-bezier(0.2, 0, 0, 1)
Instant
Trace sheet, mobile
Open or close
translateY(100%) to 0, 260ms cubic-bezier(0.2, 0, 0, 1)
Instant
Index overlay
Open or close
Opacity, 200ms ease-out
1ms
Buttons and links
Hover
Fill darkens, underline 2px to 3px, 120ms ease-out
Instant
Route change
Navigation
Focus moves to the sheet title, scroll to top
Same
04
Accessibility
Landmarks: header, main with one h1 per sheet, footer. A skip link comes first.
Every control works from the keyboard, with a visible 2px focus ring.
The sheet index is a native modal dialog: focus stays inside, Esc closes, focus returns to the Index button.
Figures carry a text alternative and a hidden data table for screen readers.
Color never carries meaning alone. Every chip has text, every redline has a rule tag.
Touch targets are 44px or larger. Nothing needs a swipe or a hover.
Reduced motion removes every animation except the index fade, cut to 1ms.
05
Adapting the set for the next project
The drawing-set shell
TitleBlock, SheetIndexOverlay, SheetFooter, AboutThisSheet, and figure numbering. Change the sheet list in src/app/sheets.ts, the mark, and the tokens in src/styles/tokens.css. The shell fits any multi-sheet application site.
The SQL twin pattern
A rule carries TypeScript and SQL, and a test proves agreement. Add tables in src/sql/tables.ts and rules in src/engine/rules with a matching .sql file.
The UAT generator
Scenarios come from each rule's Given, When, Then fields. Edit the rule and the test plan follows.
The Exercise component
Task, control, hint, check, answer, explanation. New exercises go in the Workbook sheet with their own check function.
The sample data contract
A generator with a fixed seed proves the clean plan has zero findings, then seeds known defects. Every figure and table header carries the sample data tag.