Patterns
Collections, detail surfaces, forms, overlays, charts, and states.
Rule
Recurring interface problems have one canonical answer. Lists are the default for collections. Tables are for comparison. Detail surfaces show identity, intent, then history. Forms keep labels above controls and replace helper text with announced error text. Overlay choices follow this order: inline expansion, side panel, dedicated route, then dialog.
Every collection ships empty, loading, error, and success behavior together:
- Empty names what belongs there and offers one primary action.
- Loading uses a skeleton shaped like the arriving content, with no layout shift.
- Error states say what happened, expose the machine
code, state retryability, and name the next legal action. - Success renders the record and its state without hiding provenance.
Charts repeat their numbers as text because an agent cannot reliably read a canvas.
Token contract
Collections consume components.table-row, components.table-header-cell, and the
components.badge-* state recipes. Detail intent uses typography.body-md; ids,
versions, cursors, and timestamps use typography.data-md. Form controls consume
components.input-field*. Raised and overlay surfaces consume
components.popover-surface and components.dialog-surface.
Correct example
A Task detail begins with name, id, written status, version, lease, and legal next
states. The brief follows in reading type. The append-only event history ends the page
with mono timestamps. A failure includes invalid_transition, says it is not retryable,
and offers only legal transitions.
Rejected example
A Task detail hides identity behind a tab, encodes status only with a dot, shows a spinner for the entire page, and reports a generic failure with a retry button. The reader cannot determine the record, the cause, or whether retrying is safe.
Reasoning
The full pattern decisions live in UI patterns. Error language is specified in copy and voice.