Stepper
Every mark in the progress family is a tonal disc with one glyph from one set: done is a tick on the success tint, refused a cross on the danger tint, stopped short a ! on the warning tint, skipped a dash on a dashed disc. The current step is the one in the action colour. The glyph is centred on the marker by construction, not nudged.
Stepper — with descriptions
Stepper — compact
Stepper — a sequence that stopped
A step that was attempted and refused is neither current nor complete. Without a word for it the step sits at current forever or is marked done, which is a lie about what happened. The connector stays neutral: nothing left that step.
Stepper — vertical, all six states
The line runs from just under one marker to just above the next, through whatever height a description gives the step. Skipped is passed over on purpose, so the line leaving it fills; stopped is interrupted rather than refused, so it is warning rather than danger.
Stepper — vertical, compact
Stepper — the rail form
Same states and the same data-state, drawn as segments of the family’s bar: the 4px track, the 2px gap and the state colours of a segmented bar. A marker and its label are a pair, and the pairing breaks when a sequence spans a page. Use the markers when each step is an act a reader performs; use the rail when the sequence is a position they are somewhere in.
Stepper — the rail, ended badly
A segment that ended carries its glyph beside its label, so the rail never rests on colour.
Stepper — the rail, with what is behind retinted
--stepper-complete is declared nowhere and referenced with a fallback, which is this system’s signal for a property the caller sets. Here what is behind is filled in the progress colour rather than the success tint.
Progress — labelled
128 of 206 files · about a minute left
Label at the start, value at the end, helper underneath — the one rule every labelled indicator in the family follows. Values are tabular figures, so a moving number does not shimmer.
Progress — sizes
Three track thicknesses: 4px inline or in a row, 6px by default, 8px for a bar that is the subject of its region.
Progress — ended
Saved to Reports / Q3
Cancelled by Dana Whitfield at 45%
The connection closed. Nothing was saved.
A tone replaces the progress colour only when the task has ended, and it always arrives with its glyph and its word.
Progress — indeterminate
Counting what to include
Under reduced motion the bar does not slide across the track. A third of it appears at the start, then the middle, then the end, fading out between places — still visibly getting somewhere, with nothing travelling across the screen.
Progress — inline
Circular progress — sizes
16, 24, 32, 48 and 64px, and the stroke is always an eighth of the diameter. The value goes inside at 48px and up; below that it goes beside the ring. The hole is cut by a mask, so the ring sits on any ground.
Circular progress — centre: icon, none, indeterminate
Circular progress — with its words
4 min in
§2.5 being written
Spinner
The spinner is the indeterminate ring at 16, 24 and 32px: the same track, the same arc colour, the same stroke rule. Under reduced motion it keeps turning, slowly, because a frozen spinner reads as hung.
Segmented progress
One track split by status. Its value is how many have finished, however they finished; its value text is the breakdown in words — “6 done, 1 failed, 1 in progress, 2 to go” — and the legend says the same on screen, so nothing rests on telling green from red.
Checklist progress
- Connect the repository, Done
- Import the control set, Done212 controls from the 2025 framework
- Map controls to systems, Done
- Assign owners, In progressReading the org chart
- Wire the webhook, FailedThe organisation refused the request. Ask an admin to allow the app.
- Import last year’s record, SkippedNo prior record
- Send evidence requests, Queued
- Ready for sign-off, Queued
Work the system does while the reader watches: setup, onboarding, an agent’s run. The running task’s mark is the spinner, and the list is aria-busy while one runs. A task failing is announced; finishing the whole list is announced; nothing else is. Not for a list the reader ticks — that is .checklist.
File transfer
- Q3 access review.xlsx62%
2.1 MB of 3.4 MB
- Change log export.csvWaiting
822 KB
- Vendor contracts.pdf: UploadedVendor contracts.pdfUploaded
12 MB
- Board minutes, September.docx: FailedBoard minutes, September.docxFailed
The connection closed at 38%. Nothing was saved.
- Screenshots.zipCancelled
55 MB
Name and percent above a 4px track, the size or the reason below, and one action at the end of the row. Arriving and failing are said once; the percentage is not read aloud.
Progress inside a button was considered and left out: .btn.is-loading already holds a button’s label and width while it waits, and a long action reports its progress where its result will land.
Skeleton
Pagination
Timeline
14:02 · today
Control review opened
Assigned to the delivery lead.
09:40 · today
Scope countersigned
16 Aug
Engagement created
Feed — who did what
- Dana Whitfield
Opened a finding14:02
AU-6 has no evidence for Q3.Attached evidence13:48
Q3 review log.xlsx
- Sam Okafor
Answered
Scope confirmed with the client.Answered
Retention period is seven years.Answered
A timeline with people in it. The actor heads a run of what they did, once, so the boundary between two people is in the layout rather than in a name repeated on every row.
Step position is carried by data-state and aria-current="step",
so the marker, the connector and the announcement read one source. Every progress element is a real
role="progressbar" with aria-valuenow — the bar is not decoration.