Components
Every piece this template is built from, in one place. Copy from here rather than from a page — the pages are arrangements, this is the vocabulary.
Palette
Three values, and that is the entire system. The Tailwind colour scale is replaced rather than extended, so a stray text-blue-500 fails the build instead of quietly reaching a customer.
Ink
#111111
Paper
#FDFCF8
Ink soft
#444444
Type
Handwriting for things you read, monospace for things you compare. Never set data in the hand font — a 3 and an 8 argue with each other and a column will not line up however it is aligned.
Heading — Kalam 36
Subhead — Kalam 24
Label — Kalam 18
Body copy is set in the system sans, not the hand font. A handwriting face at 14px across a full paragraph is a readability problem rather than a style choice.
£48,210.00 · 1,284 · 2026-08-21
MONOSPACE · TABULAR NUMS · RIGHT-ALIGNED IN TABLES
Cards
Four rotations of the asymmetric border radius. Always give neighbouring cards a different index — a repeated irregular corner stops reading as hand-drawn the moment the eye catches the repeat.
Wobble 1
index=0
Hover me — the shadow shrinks and the card presses down.
Wobble 2
index=1
Hover me — the shadow shrinks and the card presses down.
Wobble 3
index=2
Hover me — the shadow shrinks and the card presses down.
Wobble 4
index=3
Hover me — the shadow shrinks and the card presses down.
Stats
Rising
£12,480
12%up
Falling
37
9%down
Unchanged
46%
0.1%flat
Status
There is no red and no green here, so state rides on three channels at once: border style, circle fill, and a word. The word is the one doing the real work — shape alone is not an accessible way to carry meaning when there is no colour to fall back on.
- Paidsolid + filled
- Processingdashed + half
- Awaitingdashed + hollow
- Failedsolid + hollow + ×
Controls
One inverted control per screen. Ink fill is the strongest mark available in a two-colour palette, so it is spent on exactly one thing.
Charts
Rough.js at roughness 1.5, 2px strokes, hachure fill, gap 5. Axes are a single stroke with disableMultiStroke, and the wobble is seeded so charts stay still instead of twitching on every resize.
Bars
Line
Horizontal
Hatch density key
Density carries magnitude as a second channel, so ranking survives a black-and-white printout. Ship this legend with any chart that uses it — a reader has no way to calibrate “dense” otherwise.
- Dense = high
- Medium
- Sparse = low
Tables
No cell borders anywhere. Rows are separated by one dashed rule, which is the only thing holding the grid together — which is exactly why every numeric column is monospace and right-aligned.
| Ref | Name | Qty | Total | State |
|---|---|---|---|---|
| #0001 | Short name | 2 | £48.50 | Paid |
| #0002 | A much longer product name | 17 | £1,204.00 | Processing |
| #0003 | Another | 1 | £9.99 | Failed |
Screens without the sidebar
Sign-in, sign-up, sign-out and the error screens all render on a single centred sheet with no navigation. That is deliberate: a sign-in page listing Orders and Settings invites a click that only bounces back, and a 503 showing full navigation implies the app is healthy when it demonstrably is not.