Accessibility
Our own audit
We built an accessibility product. Failing accessibility would be indefensible, so here is our audit, generated from the code, including anything it found.
Decisions behind the caller's screen
At most three things on screen.
One idea per line, very large type. Aphasia-friendly formatting and Hick's law both point the same way: fewer choices, faster and surer decisions.
No timer, ever.
A clock on someone who cannot find a word adds pressure and makes the block worse.
No transcript of their own speech.
Seeing your own disfluent speech written out is discouraging, and it is not what the caller needs.
Two real choices, never yes or no.
Buttons 88 pixels tall, at most four words each, plus "Something else".
Atkinson Hyperlegible for everything the caller reads.
Designed by the Braille Institute to make letters hard to confuse.
Stop is on screen whenever it speaks for the caller.
Its own colour token, with contrast checked separately, because it is the one control that must always work.
Sources: Rose et al. 2003, 2011Aphasia Institute, SCAWCAG 2.2
Colour contrast: 28 of 28 pairs pass
Every text and state colour, in both themes, checked against WCAG 2.2. This runs before every build and the build fails on any violation. Last run 2026-09-29.
| Theme | Pair | Ratio | Needed | Purpose | Result |
|---|---|---|---|---|---|
| light | text on bg | 16.51:1 | 7:1 | body text, AAA | Pass |
| light | text on bg-raised | 17.21:1 | 7:1 | body text on cards, AAA | Pass |
| light | text-muted on bg | 7.55:1 | 4.5:1 | secondary text, AA | Pass |
| light | text-muted on bg-raised | 7.87:1 | 4.5:1 | secondary text on cards, AA | Pass |
| light | text-subtle on bg | 5.46:1 | 4.5:1 | captions and metadata, AA | Pass |
| light | accent-fg on accent | 6.3:1 | 4.5:1 | primary button label, AA | Pass |
| light | danger-fg on danger | 6.54:1 | 4.5:1 | Stop button label, AA even though it is large text | Pass |
| light | accent on bg | 6.05:1 | 4.5:1 | links, AA | Pass |
| light | focus-ring on bg | 6.05:1 | 3:1 | focus indicator, non-text 1.4.11 | Pass |
| light | focus-ring on bg-raised | 6.3:1 | 3:1 | focus indicator on cards | Pass |
| light | border-strong on bg | 3.55:1 | 3:1 | borders that carry state, 1.4.11 | Pass |
| light | ev-grounded on bg-raised | 4.42:1 | 3:1 | evidence mark, non-text | Pass |
| light | ev-vetoed on bg-raised | 3.95:1 | 3:1 | evidence mark, non-text | Pass |
| light | ev-inferred on bg-raised | 2.17:1 | 1.9:1 | evidence mark, relieved by label (documented) | Pass |
| dark | text on bg | 17.31:1 | 7:1 | body text, AAA | Pass |
| dark | text on bg-raised | 15.8:1 | 7:1 | body text on cards, AAA | Pass |
| dark | text-muted on bg | 10.41:1 | 4.5:1 | secondary text, AA | Pass |
| dark | text-muted on bg-raised | 9.5:1 | 4.5:1 | secondary text on cards, AA | Pass |
| dark | text-subtle on bg | 7.09:1 | 4.5:1 | captions and metadata, AA | Pass |
| dark | accent-fg on accent | 9.27:1 | 4.5:1 | primary button label, AA | Pass |
| dark | danger-fg on danger | 10.08:1 | 4.5:1 | Stop button label, AA even though it is large text | Pass |
| dark | accent on bg | 9.27:1 | 4.5:1 | links, AA | Pass |
| dark | focus-ring on bg | 9.27:1 | 3:1 | focus indicator, non-text 1.4.11 | Pass |
| dark | focus-ring on bg-raised | 8.46:1 | 3:1 | focus indicator on cards | Pass |
| dark | border-strong on bg | 3.35:1 | 3:1 | borders that carry state, 1.4.11 | Pass |
| dark | ev-grounded on bg-raised | 4.73:1 | 3:1 | evidence mark, non-text | Pass |
| dark | ev-vetoed on bg-raised | 5:1 | 3:1 | evidence mark, non-text | Pass |
| dark | ev-inferred on bg-raised | 5.6:1 | 1.9:1 | evidence mark, relieved by label (documented) | Pass |
The amber “worked out” evidence colour is below 3:1 in light mode. It is never the only signal: every evidence mark also has an icon and a text label, and the colours were chosen with a colour-blindness validator after our first draft, green and red, failed it.
Automated checks: 0 issues found
axe-core 4.13.0 (WCAG 2.2 AA and best-practice rules), run on 2026-09-27 against every page in both themes. Automated tools catch only some real problems, so this is a floor, not a verdict.
| Page | Theme | Rules passed | Issues |
|---|---|---|---|
/ | light | 46 | Pass |
/demo | light | 45 | Pass |
/replay | light | 42 | Pass |
/replay?call=dissent | light | 44 | Pass |
/setup | light | 43 | Pass |
/api | light | 47 | Pass |
/judges | light | 45 | Pass |
/technology | light | 44 | Pass |
/evidence | light | 46 | Pass |
/limits | light | 45 | Pass |
/glossary | light | 40 | Pass |
/accessibility | light | 45 | Pass |
/ | dark | 46 | Pass |
/demo | dark | 45 | Pass |
/replay | dark | 42 | Pass |
/replay?call=dissent | dark | 44 | Pass |
/setup | dark | 43 | Pass |
/api | dark | 47 | Pass |
/judges | dark | 45 | Pass |
/technology | dark | 44 | Pass |
/evidence | dark | 46 | Pass |
/limits | dark | 45 | Pass |
/glossary | dark | 40 | Pass |
/accessibility | dark | 45 | Pass |
Which browsers this was tested in
Everything above was run in Chromium, on Windows, at desktop and phone widths, in both themes. We have no Apple device, so Safari and iOS are untested, and rather than guess we have made sure the part a visitor most needs does not depend on anything exotic.
| What you are doing | What the browser has to support | If it does not |
|---|---|---|
| Reading any page | Nothing beyond HTML and CSS. Every page is server-rendered. | Not applicable. |
| The three recorded calls | One <audio> element playing an MP3. No microphone, no AudioContext, no worklet. | Nothing to fall back to, because there is nothing unusual to fail. |
| Play the recorded call live | AudioContext, to play what the engine sends back. | The call reports the error and the recorded calls remain. |
| Use my microphone | getUserMedia and AudioWorklet, both supported in Safari since 14.5. | The demo hands its slot back at once and points you at the recorded calls, which show the same behaviour. |
The practical consequence: a judge on an untested browser, or one who declines the microphone prompt, still sees three real calls with every event they produced. That path was made to need nothing more than an audio tag precisely because it is the one we cannot verify everywhere.
What we have not done
- No testing with people with aphasia, and no review by a speech-language pathologist. What we did instead is check each design decision against research done by people who worked with them, and say plainly what that does and does not establish: the parameters, against the literature.
- No testing on Safari or iOS, because we have no Apple device. See above for what depends on what.
- No full manual screen-reader walkthrough. Live regions announce the caller's state and the replay captions, but that is not the same as a real audit.
- Voice input only. A caller who cannot speak at all needs a different product.