Foundations
Space and radius
A 4px base and one radius token that everything else multiplies. Both are rendered at true size below. The point of the page is that you can hold a ruler up to it.
Source of truth: varick-site/app/globals.css · varick-charts chart-spec.md §1
Space
4px base. Every gap, pad and inset is a step on this scale. There are no in-between values.
These map one-to-one onto Tailwind’s default scale, so gap-6 is 24px here and 24px in the product. That is the reason to keep the base at 4.
Vertical rhythm
Where the scale actually gets spent.
| Gap | Step | Between |
|---|---|---|
| 4px | 1 | A label and the value under it. |
| 8px | 2 | Items in a tight list. Icon and its text. |
| 12px | 3 | Bullets in a list a reader scans. |
| 16px | 4 | Cards in a grid. Paragraph to paragraph. |
| 24px | 6 | Card padding. Heading to its content. |
| 32px | 8 | Subsection to subsection. |
| 64px | 16 | Section to section. |
| 96px | 24 | Page header to first section, on a long page. |
Radius
Two radii. Small shapes, the things you press and read, take 4px. Containers, the things that hold them, take 8px. Nothing in between.
--radius-sm
4px
Buttons, inputs, chips, badges, checkboxes, tabs, table cells, kbd.
--radius-lg
8px
Cards, panels, menus, dialogs, tiles, the navigation and the search bar.
| Token | Calc | Rendered | Where |
|---|---|---|---|
--radius-sm | 4px | 4px | Buttons, inputs, chips, badges, checkboxes, tabs, table cells, kbd. |
--radius-lg | 8px | 8px | Cards, panels, menus, dialogs, tiles, the navigation and the search bar. |
--radius-sm: 4px; /* controls, chips, badges, cells */
--radius-lg: 8px; /* cards, menus, dialogs, navigation */
--radius: var(--radius-lg);Radius inside a chart
Charts follow the same two values: 8px on the card, 4px on bars, tracks and controls.
| Element | Radius | Note |
|---|---|---|
| Card | 8px | n/a |
| Control, segmented | 4px | n/a |
| Bar | 4px | [4,4,0,0] for columns |
| Track | 4px | n/a |
Never fully pill
Hairlines for structure, shadow for lift
The hairline is still the structural line of the system. Elevation is a separate, and separately tokenised, job.
A hairline says this is a boundary. A shadow says this surface sits above that one. They answer different questions, so the system uses both, and splits them by surface: on the web a card gets a hairline and a low layered shadow. Documents and print stay completely flat, which is why the document palette has no shadow token at all.
--shadow-card
Cards and asset tiles at rest.
--shadow-card-hover
The same surface on hover, to signal it is interactive.
--shadow-tooltip
Chart tooltips and the copy toast. Floats over content.
This rule was amended. It previously read “hairlines, not shadows” with one exception for chart tooltips, which made every card on this site read as a wireframe. Elevation is now tokenised rather than banned, and the ban survives where it was always right: anything that ends up on paper.
Default
#EBEBEB
Every card, table and input.
Hover
#DEDEDE
The border on hover, and where a hairline must assert itself.
Document rules
#D9D9D9
Table strokes inside a .docx.
Grid lines inside a chart are the same colour, dashed 4 4, horizontal only, except on a scatter, where both axes get them.
