Tokens
Every value lives in one file, the package's tokens.css, on :root. Dark mode is the same inks
lit from the other side. The ratios below are computed at build time from the palette file, so the page
cannot disagree with the numbers.
Colour: riso inks on paper
Light is the default. The dark values follow prefers-color-scheme or data-theme.
- paper #F6F6F3 light #141519 dark Background. Cool off-white in light, a night print in dark.
- ink #18181C light #EDEDE6 dark Text, buttons, linework.
- ink-2 #55565E light #A6A7AE dark Secondary text.
- rule #D9D9D2 light #2C2D33 dark Hairlines. Decoration only.
- riso blue #0070B5 light #5DB8F2 dark Links and focus. AA text.
- pink #FF48B0 light #FF6FC2 dark Strokes and flicks. Decoration only.
- pink ink #D1008A light #FF6FC2 dark Handwritten correction text. AA.
- yellow #FFE800 light #FFE800 dark Highlight behind ink text.
- kintsugi gold #C9A227 light #D8B44A dark Repair lines. Never text.
Contrast, computed at build time
| Pair | Light | Dark | Use |
|---|---|---|---|
| ink on paper | 16.3:1 | 15.5:1 | Body text |
| ink-2 on paper | 6.7:1 | 7.6:1 | Secondary text |
| riso blue on paper | 4.9:1 | 8.3:1 | Links and focus |
| pink ink on paper | 4.8:1 | 7.2:1 | Correction text |
| ink on highlight | 14.2:1 | 12.4:1 | Highlighted phrase |
| ink on pink | 5.7:1 | 7.2:1 | Text on a pink plate |
| pink on paper | 2.8:1 | 7.2:1 | Decoration only, never text |
| gold on paper | 2.2:1 | 9.2:1 | Hairlines only, never text |
AA for body text is 4.5:1. Pink and gold are 3:1 or less on paper, so they are decoration only.
Type: two variable families
Fraunces is for display. Recursive is for text, labels and margin notes. Both are self-hosted and subset to
Latin, with font-display: optional, so a late font never swaps in.
Perfect imperfect Fraunces, WONK 0, SOFT 20
Perfect imperfect Fraunces, WONK 1, SOFT 80
Good software feels obvious. Recursive, CASL 0, MONO 0
Good software feels obvious. Recursive, CASL 1, slnt -8, for margin notes
Label text, numbers and dates: 2026-10-15 Recursive, MONO 1
Heading axes are seeded per heading. Example for this page's title: "SOFT" 60, "WONK" 1.
Spacing
One scale, in pixels. Layout uses these, and the components never invent their own gaps.
- --space-14px
- --space-28px
- --space-312px
- --space-416px
- --space-524px
- --space-632px
- --space-748px
- --space-872px
Tilt, nudge and wobble
The imperfection scales are small on purpose. Tilt is a rotation in degrees and applies to a sheet or a plate, never to text. Nudge is a pixel offset. Wobble is the second ink, the misregistration and the bleed.
- --tilt-xs 0.35degSmallest tilt. Index cards, prints.
- --tilt-sm 0.8degPrints and plates on the desktop.
- --tilt-md 1.6degReserved. Use once, at most.
- --nudge-xs 1pxHover and focus movement.
- --nudge-sm 3pxA card offset.
- --nudge-md 7pxReserved.
- Print --misreg 1.5pxOffset of the second ink. Capped, so it never blurs.
- Ink --ink-bleed 0.6pxStroke on spot shapes, so the ink spreads a little.
- --grain 0.06Opacity of the paper grain behind the page.