The to-be system, as plain CSS. Start from bolster.css (everything) or import files one by one. Decisions behind each value are in docs/decisions.md; interaction contracts in docs/interactions.md.
Status quo · October 2026
This is the baseline to build on: warm in light (cement neutrals on a paper canvas), cool in dark (Bolster's greys), and the list page as the first page type made from it. It may still change a lot; until it does, new work starts here, and anything that disagrees with it is a change to make here first (D33).
Foundations
Page types
List page
Jobs, invoices, customers, the catalog: the page, its parts and behaviour, live at desktop and phone width.
patterns/list-page.css
List recipe
The rules every list follows and the description Claude fills from a screenshot and a short survey.
recipes/list · rules.json · schema.json · check.mjs
List page parts
Summary cards
KPIs or the lifecycle: cards that filter, and one insight card (D67).
components/summary-cards.css
Table card
The header (filter, search, dates, display), chips, the table, phone rows with four corners.
toolbar.css · chip.css · data-table.css
Record
One row's details beside the list, or a side sheet.
components/record.css
Floating bar
Bulk actions for ticked rows; select mode on phones.
components/floating-bar.css
Popover
Menus and panels under their trigger; bottom sheets on phones.
components/popover.css
States
What a list shows when it has nothing to show.
components/states.css
Components
Button
Five roles with a body that lifts and sinks, a quiet danger, four sizes, loading, icon-only.
components/button.css
Badge
Job status with status marks, feedback tones, counts.
components/badge.css
Field
Text, text area, native select, money and search inputs, with label and helper.
components/field.css
Checkbox, radio, toggle
Native inputs, one "on" colour.
components/choice.css
Segmented control
Modes and views, as native radios.
components/segmented-control.css
Tabs
Panels of one page, arrow-key navigation.
components/tabs.css
Tooltip, menu, dialog
popover and <dialog>: Escape, focus and stacking from the platform.
tooltip.css · menu.css · dialog.css
Data table, cards, avatars, thumbnails
Keyboard-reachable rows, cards with a body, avatars for people and thumbnails for things; the first draft's filter cards.
data-table.css · card.css · avatar.css · thumbnail.css
Icon vocabulary
One meaning, one icon: every field and action's icon, from the vocabulary, never per page (D58).
model/icons.json · recipes/icons.mjs
Toast
One live region; errors stay, others leave after 5 seconds.
components/toast.css
Calendar
October 2026
| S | M | T | W | T | F | S |
|---|---|---|---|---|---|---|
A month to click or arrow through, and the date range picker on it: presets, From and To, two months.
components/calendar.css
From the audit to here
| As-is (audit/components) | To-be |
|---|---|
| Button: 8 severities, 364 instances, 257 with local overrides, no focus ring | Button: 6 roles, 4 sizes, visible focus |
| Clickable surfaces: filter cards, action rows, onboarding cards | Summary cards on lists, linked cards |
| Navigation: rail, section sidebar, top bar, bottom bar | App shell |
| Badge: status pills, tags, counts | Badge with status tokens |
| Data list row: div rows, double-click to open | Table card with row links, a record beside the list, rows with four corners on phones |
| Field: four search designs, 40/48px mix | Field, one frame, three sizes |
| Select: tertiary button + bottom-right sheet | native select, or the picker sheet dialog |
| Segmented control (SelectButton) | Segmented control |
| Checkbox, radio, toggle: three "on" colours, no focus | Choice controls |
| Modal: the job workspace | Dialog, workspace variant |
| Avatar: generated colours, one failing contrast | Avatar, 8 AA colours |
| Toast: persistent error, misspelled copy | Toast |