Status Timeline
Vertical or horizontal progress display with four states per item: pending, current, completed, failed. Each item is an ordered list entry with an aria-label naming both the label and the status, so screen readers announce both. Timestamps are passed as strings or pre-resolved Dates to keep the prerendered HTML deterministic.
User status — happy path
The five-state user-status machine from data-model.md. Renders the current state as the in-progress item; completed states sit above with green dots.
- Account createdEmail + phone capturedApr 12, 2026 · 9:14
- Identity verifiedEmail + phone OTPs confirmedApr 12, 2026 · 9:21
- KYC under reviewDocuments submitted; admissions team reviewingApr 13, 2026 · 11:02
- KYC verifiedAccount activated
- Application openApply to programs
KYC failure recovery
Failed status colors the dot + connector destructive; the label tone matches.
- Documents submittedApr 12, 2026
- Reviewer flaggedPhoto blur on the back of the IDApr 14, 2026
- Re-submission required
Application — horizontal
Set orientation="horizontal" for in-app progress ribbons. Falls back to vertical at the md breakpoint and below.
- StartedMar 1
- PersonalMar 1
- AcademicMar 3
- Programs
- Documents
- Submit
SSG safety
Pass timestamps as strings (already-formatted) or as pre-resolved Dates that are themselves stable across renders. The default formatter handles both. Avoid passing new Date() from render — that diverges between prerender and hydration. The component itself never reads Date.now().
Accessibility
- Renders as an
<ol>for natural reading order. - Each item has
aria-label="{label} — {status}"so SRs announce both. - Items in the
currentstate getaria-current="step". - Dots and connectors are
aria-hiddento avoid double-announcing.