Base
Lacquer cutting
Short body copy, one or two sentences.
Read moreDesign system
Every value on this page is read from tokens.json. Nothing here is a literal. One palette, no dark mode — the token file holds a single set of values.
01
Each name is a job, not a value. The -on-contrast keys switch as a set.
surface-bodysurface-subtlesurface-contrastinkink-mutedborderactionaction-hoveron-actionfocusdangersuccesswarning02
One per page. Ground and all three ink tokens switch together, and the class declares color so descendants cannot keep the light ink.
03
Two ramps. Each step ships size, leading and tracking tuned together — use them as a set, never recombine across steps.
title-display
Fired earth
title-xl — h1
Fired earth
title-lg — h2
Fired earth
title-md — h3
Fired earth
title-sm
Fired earth
title-xs
Fired earth
title-2xs — the eyebrow step
Fired earth
text-xl
The kiln holds its heat for a day after the fire goes out.
text-lg — lead
The kiln holds its heat for a day after the fire goes out.
text-md — body default
The kiln holds its heat for a day after the fire goes out.
text-sm
The kiln holds its heat for a day after the fire goes out.
text-xs
The kiln holds its heat for a day after the fire goes out.
--font-text DM Sans — running copy--font-title Stack Sans Notch — headings--font-display Stack Sans Notch — hero only--font-mono JetBrains Mono — code and data04
One ramp for padding, margin and gap alike. Lower half inside a component, 2xl and up for layout.
3xs2xsxssmmdlgxl2xl3xl4xl05
radius-noneradius-smradius-mdradius-lgradius-fullshadow-smshadow-mdshadow-lg07
The base grid unit. The footer link is pinned with margin-top: auto, so links align across a row whatever the body length.
Base
Short body copy, one or two sentences.
Read moreSubtle
The same card on the subtle surface. A longer body, to show the link still lines up with its neighbours.
Read moreBase
The link is optional. Without it the card simply ends after the body.
08
A rule on the inline start edge instead of decorative quote glyphs. The display variant moves that rule to the block start, because a centred column with a left rule reads as misaligned.
We stopped asking what the page should look like and started asking what the next page would inherit from it.
A literal is invisible in review and breaks the moment the palette moves.
09
Running copy sits at text-md and is constrained to the layout-content measure. A paragraph inside .section__inner takes ink-muted, so it steps back from the headings without dropping below the contrast floor.
An inline link takes the action colour. Only unclassed links are targeted, so a button inside prose keeps its own label colour.
The rule above is the --rule composed property: one hairline width, one border colour, declared once.
10
The size follows the heading level, not a class. An h1 here takes the xl step and the wider cap; an h2 takes lg. That is what separates a page title from the section titles under it.
01 — Capability
A short lead, two lines at most. It qualifies the title rather than repeating it.
11
Not the card. This is a borderless cell that expects a ruled grid around it — cells owns every hairline. The link is pinned with margin-top: auto, so links align across a row whatever the body length.
Two or three sentences on what the work actually is.
Scope an engagementThis cell carries more copy than the one beside it, which is the case the pinned link exists for. Both links still sit on the same line.
Read the advisories12
One movement in a sequence. The command line is the heading of the cell but it is a p, not an h3 — a run of shell commands in the heading outline is noise.
kiln@engagement:~$ scope
What happens in this movement, in two sentences.
kiln@engagement:~$ execute
The caption is the shared prompt idiom. Only the space under it belongs to this component.
13
Four cells, fixed. The count is tied to the nth-child border rules — three or five leaves a stray hairline at one breakpoint. The figure takes the title ramp while the label stays mono, and that contrast is the point.
14
The role sits above the name, so the eye can scan roles down a row without reading names. It carries the shared eyebrow class alongside person__role — drop either and it is half styled. The alt text belongs to the instance, never to the recipe.
Principal
A short paragraph on what this person actually does.
Head of research
Two cells, because the grid's border rules count in pairs.
15
An instance is one badge. A set sits in a ul.badges, which carries no margin of its own — the block around it decides the space above. One or two words: a badge holding a sentence stops reading as a badge.
The third is badge--action, for the one badge in a set that is the point of the set. Colour every badge and none of them reads as marked.
16
Three or four assurances that qualify an offer, not running content. The list draws a top rule and every item draws a bottom one, so the last rule is deliberate — it closes the block against whatever follows. Text takes full ink, because these lines are the point rather than support.
One short assurance per line.
Three is the usual count.
Four at most before it reads as a feature list.
17
The unit every form on the site is built from. The control edge uses --color-field-border, not the layout hairline: at 1.19:1 that rule fails the 3:1 WCAG 1.4.11 asks of anything a person operates.
One line saying what to put here, when the label cannot say it alone.
That does not look like an email address.
The invalid state and the select are marked data-delta-component-opt-out: both are deliberate variants, and the swapped tag or the extra class would otherwise report as diverged on every conformance run. A textarea is the same case. The checkbox carries no marker at all — it is field__check, a row rather than the stacked grid, so it is not an instance of this component.
18
Static by design. The script validates and reports; nothing is sent. Wiring it to a real endpoint means replacing that script, not adding to it. Submit it empty to see the error state, or fill it to see the message.
kiln@intake:~$ new-engagement
Field ids are prefixed here because this page carries a second form above. The script binds by class across every .intake, delegated at the document, so two forms on one page are safe — but two sets of matching id and for values are not.
19
The markup ships with no hidden attribute on any panel, so with Javascript off every panel stays readable. The script adds hidden on load. Roving tabindex: only the selected tab is reachable with Tab, and Left, Right, Home and End move between them.
First panel. The row never wraps — it scrolls sideways instead, so a set that does not fit stays on one line.
Second panel. The selected state is the tab's own bottom border in the action colour, sitting on the container rule.
Third panel. Ids are per instance: two sets on one page sharing ids would drive each other.
20
Decorative, and the whole strip is aria-hidden — the text is duplicated, so a screen reader would otherwise read every fragment twice. Exactly two runs with identical content: the track shifts by half its width, so a third run or a differing copy makes the loop jump. Hover pauses it, and under prefers-reduced-motion the animation stops and the second run is hidden.