Docs
Accessibility
Agent apps ask people to make decisions. Everyone should be able to make them, with any input and any setting.
What every component does
- Works with the keyboard alone, with a visible focus ring from
--ring. - Uses native elements first (buttons, checkboxes, radios) and ARIA roles where there is no native one (radiogroup, timer, meter, log).
- Never uses colour alone: risk, status and validity always have text or an icon too.
- Announces changes politely (
aria-live) without stealing focus. - Checks
prefers-reduced-motion: loops stop, springs become fades, and canvases draw one still frame. - Meets WCAG AA contrast with the default tokens in both themes.
Keyboard shortcuts
- Approval Card: A approve, R reject, while focus is inside the card.
- Approval Inbox: j/k move, x select, a/r decide.
- Mode Switch: arrow keys move and select.
Per component
Approval Card
- Card is a group labelled by its title.
- Countdown has role=timer and an aria-label with seconds left.
- Stamp is announced via role=status.
Mode Switch
- role=radiogroup with role=radio buttons and roving tabindex.
- Arrow keys move and select.
- Hint is aria-live=polite.
Cost Meter
- Budget bar is role=meter with min, max and current value.
- Sparkline is decorative (aria-hidden).
Tool Call Viewer
- Header is a button with aria-expanded / aria-controls.
- Payload tabs use role=tablist / tab / tabpanel.
Run Timeline
- Ordered list; the active step has aria-current=step.
- List is aria-live=polite so screen readers hear progress.
Agent Chat
- Message list is role=log, aria-live=polite.
- Input has a visually hidden label.
Audit Log
- Status chip is role=status.
- Each row ends with a valid/invalid label, not colour alone.
Policy Prompt
- role=alertdialog with label and description.
- Native checkboxes and radios, so keyboard and screen readers work as expected.
Task Board
- Columns announce their task count.
- Each card is a button whose label says where it will move.
Swarm Map
- SVG has role=img with a summary label.
- Agents are focusable buttons with name and role.
- Packets stop under reduced motion.
Knowledge Graph
- Nodes are focusable buttons with label and type.
- Legend uses text, not colour only.
Voice Input
- Mic is a toggle button with aria-pressed and a changing label.
- Transcript is aria-live=polite.
- Waveform is decorative.
Agent Status
- Each avatar is a button whose label includes name, state and task.
- Counts are aria-live=polite.
Handoff Banner
- Region with a label; timer has role=timer.
- Collapsible list uses aria-expanded.
- Result line is role=status.
Diff Review
- File list is a nav; current file has aria-current.
- Toggles use aria-pressed.
- Status line is role=status.
Eval Card
- Bars are role=meter with values.
- Pass/fail is text, not colour only.
Memory Inspector
- Search has a label; filters use aria-pressed.
- Confidence has a text label.
- Undo bar is role=status.
Budget Guard
- Bucket is role=meter.
- State chip is role=status.
Plan Stepper
- Progress bar has aria values.
- Status line is aria-live.
Approval Inbox
- List is focusable with keyboard instructions in its label.
- Every row has labelled checkbox and buttons.
- Toast is role=status.
Hero Mesh Gradient
- Canvas and the dot-grid overlay are aria-hidden; only real text and links are in the accessibility tree.
- Headline is a single <h1>; CTAs are real <a> elements with visible focus rings from the design system.
- Contrast of headline and body text against the gradient is kept high by layering a background/background-gradient scrim under the text column.
Your part
- Give each component a meaningful
titleor label in real use; the demo text is generic. - Don't auto-approve on a timer in production. The countdown should expire to “expired”, which is the default.
- Test with your screen reader of choice after wiring real data.