Bolster design system

List concept List page

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

Tokens

AaColourType4px grid

Colour (light and dark), type roles, spacing, radius, depth, layers, motion.

tokens.css · base.css · utilities.css

App shell

Top barRailSidebarBottom bar

Top bar, rail, section sidebar, page header, action bar, bottom tab bar, at every breakpoint.

components/shell.css

Page types

List page

PendingBookedTable card

Jobs, invoices, customers, the catalog: the page, its parts and behaviour, live at desktop and phone width.

patterns/list-page.css

List recipe

RulesColumn typesDescription

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

In progressWin rate 73%

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

BookedActivityActions

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

Filter optionsDisplay settingsBottom sheet

Menus and panels under their trigger; bottom sheets on phones.

components/popover.css

States

LoadingEmptyNo resultsError

What a list shows when it has nothing to show.

components/states.css

Components

Button

PrimaryBrandSecondary

Five roles with a body that lifts and sinks, a quiet danger, four sizes, loading, icon-only.

components/button.css

Badge

BookedPendingOverdue

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

Help

popover and <dialog>: Escape, focus and stacking from the platform.

tooltip.css · menu.css · dialog.css

Data table, cards, avatars, thumbnails

MKDCIn progress

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

Proposal sent

One live region; errors stay, others leave after 5 seconds.

components/toast.css

Calendar

October 2026

SMTWTFS

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 ringButton: 6 roles, 4 sizes, visible focus
Clickable surfaces: filter cards, action rows, onboarding cardsSummary cards on lists, linked cards
Navigation: rail, section sidebar, top bar, bottom barApp shell
Badge: status pills, tags, countsBadge with status tokens
Data list row: div rows, double-click to openTable card with row links, a record beside the list, rows with four corners on phones
Field: four search designs, 40/48px mixField, one frame, three sizes
Select: tertiary button + bottom-right sheetnative select, or the picker sheet dialog
Segmented control (SelectButton)Segmented control
Checkbox, radio, toggle: three "on" colours, no focusChoice controls
Modal: the job workspaceDialog, workspace variant
Avatar: generated colours, one failing contrastAvatar, 8 AA colours
Toast: persistent error, misspelled copyToast