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.

  1. Account createdEmail + phone capturedApr 12, 2026 · 9:14
  2. Identity verifiedEmail + phone OTPs confirmedApr 12, 2026 · 9:21
  3. KYC under reviewDocuments submitted; admissions team reviewingApr 13, 2026 · 11:02
  4. KYC verifiedAccount activated
  5. Application openApply to programs

KYC failure recovery

Failed status colors the dot + connector destructive; the label tone matches.

  1. Documents submittedApr 12, 2026
  2. Reviewer flaggedPhoto blur on the back of the IDApr 14, 2026
  3. Re-submission required

Application — horizontal

Set orientation="horizontal" for in-app progress ribbons. Falls back to vertical at the md breakpoint and below.

  1. StartedMar 1
  2. PersonalMar 1
  3. AcademicMar 3
  4. Programs
  5. Documents
  6. 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 current state get aria-current="step".
  • Dots and connectors are aria-hidden to avoid double-announcing.