Components · Workflow
A record's state machine, made legible. The ordered states render as a connected chip row — passed states filled + checked, the current state solid accent with a ring halo, upcoming states muted — with off-track terminals hanging off a branch. Below it, an allowed-transitions row: only the states reachable from here are live buttons; illegal jumps render disabled with the reason. This is the adoption-application status flow.
Application #AP-0488. Submitted is passed (accent-strong check + accent connector); Screening is aria-current="step" — solid accent with the ring halo; Approved → Fostering → Adopted are muted upcoming. Declined / Withdrawn hang off the branch as terminal states reachable from almost anywhere but not part of the happy-path row.
From Screening you can move to
Only legal edges are enabled. Approve is the forward action (primary); Request more info is a self-loop back through Screening; Decline is a terminal off-ramp. Adopted is disabled — you can't skip Approved and the home visit — with the reason on hover.
The transition row is the machine's outgoing edges for the current node — driven by the same allow-list that guards the write on the server, so the UI can never offer an illegal move. A disabled edge keeps its label + reason instead of vanishing, so the rule is visible.
State[] along the happy path — { id, label, kind } with kind passed | current | upcoming. Passed fills accent-strong + check; current is solid accent + ring (aria-current); upcoming stays a muted outline.Declined = bad, Withdrawn = neutral) hang off a dashed branch — reachable from many states but not part of the linear row.disabled (with a title reason), never hidden — the allow-list mirrors the server guard.<ol> with aria-current="step" on the active node; each node has a status-suffixed aria-label. The transition cluster is a labelled role="group"; blocked buttons are aria-disabled. Status is never color-only — every chip is labelled text.Source · workflow family (src/components/ds/workflow) — feeds TitleBar's status slot and the record header; the chip row composes the Surface primitive + the good/warn/bad + accent tokens from globals.css. The transition allow-list is the presentational mirror of the server-side state-machine guard.