Component Gallery

Every component, in every state. Nothing ships until it appears here.

Form kit Permission matrix Delete safety kit Contrast report Token hygiene check Every message ← Back to Clients

1 · Colour, from one file

Every swatch below is derived from about twelve values in shared/tokens/brand.css. Hover, tinted and border variants are calculated by mixing — nobody picks them by hand. Change a seed there and every one of these moves.

Brand

seed-charcoal seed-red · identity only

Roles

primary success danger warning info neutral purple

Derived from primary — none of these were chosen by hand

primary primary-hover primary-active primary-subtle primary-border

Surfaces and text

canvas surface surface-sunken surface-hover border border-strong text-primary text-secondary text-tertiary

2 · Type

33 · Hero figure

25 · Key figure

21 · Page title

17 · Section heading

15 · Emphasis body

14 · Body default — forms, buttons, menus

13 · Grid cell default

12 · Column headers and chips

Numbers must line up — tabular figures, slashed zero

1,240,905.00 USD
−980.50 USD
1,111,111.11 USD
0.00 USD
CLI-1000-0042

Zero renders as 0.00, never blank. Blank means “unknown”, and in finance that is a different fact.

3 · Buttons

The primary action is blue, never the brand red. In a trading system red means loss, rejection and danger — spending it on ordinary buttons trains operators to stop reading it (ADR-0006).

4 · Status, risk and tags

Client status

Active Pending Dormant Suspended Closed Blacklisted On hold

Risk level — note these sort by rank, not alphabetically

Low Medium High Critical

Tags, avatars

VIPHigh Volume+3 AL YS SM KT

5 · Form controls

Enter a valid email address

Checkbox · one-time password

6 · Filter controls

All four emit the same event, so a column can change filter type without the grid changing at all. Open them — every one is fully keyboard operable, including the date range picker (arrows move by day, Page Up and Page Down move by month).

Search box

Single select

Multi select

Date range

7 · Feedback

A message that disappears cannot be an error message. Errors stay until dismissed; an Undo you cannot reach in time is not an Undo, so its timer pauses under the pointer.

8 · Grid states

Every data component implements all of these in the same pass. Note that “nothing exists” and “filtered to nothing” are different states needing opposite actions — one says create something, the other says undo something.

Loading — a skeleton matching the real layout, never a spinner

Empty — nothing exists yet

Empty — filtered to nothing

Error

9 · Modal dialogue

A dialogue is for a decision that must be made before continuing. If it has only one button it is not a decision — that is a banner or a toast. Built on the browser's own <dialog>, so focus trapping, Escape and an inert background are the browser's job, not ours.

Every one of these returns focus to the button that opened it. Press Escape and watch the focus ring come back.

10 · Export, on a grid that is not Clients

The proof that export is a grid capability and not a Clients feature. The grid below has four columns of its own and knows nothing about the export dialogue. Its heading and its filename come from its grid identifier, so wiring it took one import and one line — the same line the Clients page uses.