Accessibility
Make every screen work for everyone.
Built to WCAG 2.2 AA, a widely used accessibility standard, and checked with the tests listed below. We have not had a manual conformance audit.
Built in
- Every button with only an icon needs a label. The label is its name for screen readers and its tooltip.
- The message list is a role="log" that announces new replies politely, so screen readers do not read every word as it appears.
- While a reply is being written, the message is marked aria-busy and the state shows in words, not only in the blinking caret.
- You can always see where you are: a 1.5px ring, charcoal on paper and lime on charcoal.
- Sections that open and close use aria-expanded and aria-controls. Choose-one groups use role="radiogroup" with aria-checked.
- The message box sends on Enter and adds a new line on Shift+Enter. It never sends while a person is still typing with an input method, such as for Japanese or Chinese.
- Animation stops when a person asks for less motion: caret, shimmer, typing dots and headline typing. One rule in the token stylesheet does this for every part, so the stylesheet must be loaded.
- Formatted text is built safely, so AI text cannot add harmful markup. Links can only be http, https or mailto.
What we test and how
The components are built to WCAG 2.2 AA and checked with the tests below. We have not had a manual audit, so we do not claim a conformance level. Run npm run build first, then any of these.
- Axe-core on every page, in light and dark. It checks WCAG 2.0 to 2.2 A and AA plus best practices, and fails on serious or critical findings. Run npm run check:a11y. npm run check:a11y-matrix repeats it in every colour theme and updates the table below.
- A keyboard walk. It presses Tab up to 120 times on the main pages and on the interactive component pages. At each stop it checks that the element has a name, shows a visible focus indicator and is not a trap, and that no tabindex is above zero. It also checks that the skip link comes first and works, that Shift+Tab goes back one stop, and that Escape closes the details drawer and returns focus to the button that opened it. Run npm run check:keyboard.
- Reflow at 320px wide. Key pages must not scroll sideways.
- Text spacing. We apply the WCAG 1.4.12 spacing (line height 1.5, letter spacing 0.12em, word spacing 0.16em) and check that no button, link or field newly cuts off its text.
- Forced colors, the Windows high contrast mode. Form fields and switches must still show an edge when backgrounds and shadows are removed.
- Touch target size. On site navigation, 24px is the minimum (WCAG 2.2). On a phone we also check for 44px, which is our own stricter rule. Small targets pass the 24px check only when nothing else sits within 24px, as the standard allows.
- Reduced motion. The axe run and the other browser checks run with reduced motion on, so animations do not hide problems. Components stop animating under prefers-reduced-motion.
- Interactions. npm run check:interactions drives popovers, menus, the diff view, the permission prompt, the variant grid and feedback with the keyboard and pointer.
- The checks are run with: npm run check:a11y (set MODE=axe,spacing,reflow,forced,target to pick some), npm run check:keyboard and npm run check:interactions.
- These checks found and fixed real problems, among them a light text color at 4.17:1, scrolling code and tables that keyboards could not reach, an 18px AI label too small to tap, white text on the dark-mode danger color, text fields with no clear focus ring, a switch that vanished in forced colors, and a drawer that did not return focus to its opener.
Results by theme
The axe check runs on every documentation page in each colour theme, in light and in dark, because a colour that passes in one theme can fail in another. This is the latest run.
| Theme | Light | Dark |
|---|---|---|
| Lime | No findings | No findings |
| Teal | No findings | No findings |
| Indigo | No findings | No findings |
| Harbor | No findings | No findings |
| Plum | No findings | No findings |
| Graphite | No findings | No findings |
| Terminal | No findings | No findings |
Checked on 2026-10-20 against Tattva 0.26.0, with axe-core 4.13.0 on 94 pages: 7 themes, light and dark, 1316 page checks in all. "No findings" means axe found nothing at the WCAG 2.0 to 2.2 A and AA levels or in its best practices. It does not mean a person has checked every page. To repeat it, run npm run build, then npm run check:a11y-matrix.
What we do not test
- We have not done a manual pass with real screen readers (VoiceOver, NVDA, JAWS, TalkBack). The names and roles are checked by code, but how they sound is not.
- We have not tested with voice control, switch devices or screen magnifiers.
- We do not check color-blind modes automatically. The only related check is the validation of the chart palette. Status also carries an icon, shape or label, but that is by design and review, not by test.
- The keyboard walk covers the main pages and the interactive component pages, not every page, and it does not try every key on every widget. Arrow keys, typing and shortcuts are covered only where check:interactions has a test.
- Focus inside an embedded frame is not checked. The frame's own content is responsible for it.
- We do not test on real phones, real zoom to 400 percent or every browser. The checks run in Chromium.
- Automated checks catch only part of the problems. The reading order, the wording of labels and the quality of announcements still need people to check.
- Pages and examples in other people's products that use these components are not covered.
Color and contrast
- Body and secondary text have a 4.5:1 contrast ratio on their backgrounds in both themes.
- Status never uses color alone. Success, error and confidence always have an icon, shape or label.
- Amber always comes with words that say what to do.
- Lime has charcoal text on top and is never a text color on paper.
For browser agents and assistive tools
Some visitors are not looking at the screen. A screen reader reads it aloud. A browser agent, which is an AI that uses a website for a person, reads the page structure instead of the picture. Both depend on the same things being right in the code.
- Use the plain browser element first: a real button, link, select, input or dialog. Add extra accessibility attributes only to fill a gap.
- Give every control a name that a screen reader or agent can read. An icon-only button needs a label.
- Date pickers, dropdowns with search and multi-selects are where agents and keyboards most often get stuck. Always let people type the answer as text too, such as a date typed in a field.
- Put state in the page code, not only in color. Mark a bad field with aria-invalid and link its error text. Mark a loading area with aria-busy. Announce results like "Saved" in a live region.
- Say the effect on a destructive button: "Delete project Atlas", not "Delete".
- Never hide instructions in visually hidden text. Agents read it, and it can be used to steer them. Hidden text is only for short labels that match what is on screen.
Why this matters: in one published benchmark, an AI model completed 83.1% of tasks on common interface parts when it could read the page structure, and 48.9% when it had to work from a picture and screen positions. This is one benchmark and one model, so treat it as a strong hint, not a rule. Parts that draw only on a canvas, such as charts, still need a text version.
Your checklist when composing
- Give every form field a label, on screen or for screen readers.
- Keep the order in the code the same as the order on screen.
- Add alt text to generated images and say they were made by AI.
- Announce results like copied, saved or sent to screen readers, not only with a color change.
- Test with only a keyboard: Tab order, Escape on popups, and Enter and Space on custom controls.
Keyboard map
| Where | Key | Result |
|---|---|---|
| Composer | Enter | Send the message |
| Composer | Shift+Enter | Insert a new line |
| Buttons, switches, tiles | Space or Enter | Use it |
| Sections that open, thinking, steps taken | Space or Enter | Open or close |
| Choice grid | Arrow keys, Home, End | Move to a tile and pick it |
| Permission prompt | Esc | Deny |
| Permission prompt | N | Open the note box |
| Menus and pickers | Arrow keys, Home, End | Move between items |
| Menus and pickers | Escape or Tab | Close and go back to where you were |