ACCESSIBILITY CONFORMANCE REPORT · VPAT 2.5
Accessibility Conformance Report
accessibility.chat (web platform, including the Luke assistant) evaluated against WCAG 2.2 Level AA. Every row names the evidence behind it, and the rows nothing measured say so.
How to read this report
Most rows below say Partially Supports, and that is deliberate. Automated tooling detects roughly a third of WCAG issues. Where a criterion passed automated checks but no person verified it, this report says Partially Supports rather than Supports, because “the checker found nothing” and “this criterion is met” are different claims.
No criterion is marked Supports on the strength of a clean automated run alone. Where a row does say Supports, something was measured directly — contrast per text node against its resolved background, target size with the spacing exception computed rather than assumed, focus geometry at every tab stop. In 2025 the FTC fined an accessibility vendor $1M because its claims were not supported by competent and reliable evidence. This is the document where that standard applies, so it is written to survive being checked.
Two rows previously said Supports and were wrong, which is worth stating rather than quietly correcting. A hostile review on 31 August 2026 measured five blocks of text below the contrast minimum — the worst at 1.44:1, and an entire author route rendering white text on white cards — and found one focus indicator that never became visible. Both rows now rest on measurements taken across every route rather than the eleven the earlier sweep had enumerated.
Product and report information
| Product | accessibility.chat (web platform, including the Luke assistant) — Public beta |
|---|---|
| Report date | 2026-08-31 |
| Standard evaluated | WCAG 2.2 Level AA |
| Also relevant | Section 508 (Revised, 2017); EN 301 549 v3.2.1 |
| Report format | VPAT® 2.5 (ITI, November 2023) structure |
| Evaluated by | accessibility.chat engineering. This is a self-assessment; no independent audit has been commissioned. |
| Contact | accessibility@accessibility.chat |
Summary
- 23Supports
- 21Partially Supports
- 0Does Not Support
- 8Not Applicable
- 3Not Evaluated
55 success criteria assessed across WCAG 2.2 Level A and Level AA.
Evaluation methods
axe-core 4.13 in Chromium, colour contrast enabled
tests/a11y/browser-audit.mjs. 11 pages at 1280×900 and at 320×512, the viewport SC 1.4.10 specifies for 1280px at 400% zoom. WCAG 2.0/2.1/2.2 A and AA rulesets.
0 violations across 22 page/viewport combinations.
Programmatic focus-indicator check
Every focusable control on each page receives focus; computed outline, box-shadow, border, background and text-decoration are compared before and after.
470 of 470 controls change appearance on focus.
Reflow measurement
Document scrollWidth against clientWidth at 320px on every page.
0 pages scroll horizontally.
Streaming-answer contract guard
tests/browser/answer-contract.mjs. Asserts the answer container is not a live region, that announcements stay under 8 per answer, that start and completion each announce once, that focus never lands on <body>, and that a stop control exists.
Passing. Announcements per answer went from 3,399 to 2 when this was introduced.
Automated coverage limit
Automated tooling detects roughly a third of WCAG issues. Nothing here substitutes for manual review or for testing with assistive-technology users.
Neither manual audit nor assistive-technology user testing has been performed.
WCAG 2.2 Level A
| Criterion | Conformance | Evidence | Remarks |
|---|---|---|---|
| 1.1.1Non-text Content | Partially Supports | axe-core image-alt: no violations. Alt text quality is not machine-checkable. | Every image carries an alt attribute and decorative icons are aria-hidden. Whether each alt text conveys the right meaning has not been reviewed by a human. Article hero images use author-supplied alt text that is not editorially checked. |
| 1.2.1Audio-only and Video-only (Prerecorded) | Not Applicable | No prerecorded audio-only or video-only content is published. | Voice input is live speech recognition, not prerecorded media. |
| 1.2.2Captions (Prerecorded) | Not Applicable | No prerecorded video content. | Will require re-evaluation if video is added. |
| 1.2.3Audio Description or Media Alternative | Not Applicable | No prerecorded video content. | — |
| 1.3.1Info and Relationships | Partially Supports | axe-core landmark, heading-order, list and table rules: no violations across 42 route and viewport combinations. The earlier fix had been applied to pages but not to the eight components that render their own <main>, so /studio and /contribute still carried two main landmarks; those components now render a div. | Structure is conveyed programmatically. Whether every visual relationship has a programmatic equivalent has not been manually reviewed. |
| 1.3.2Meaningful Sequence | Partially Supports | axe-core (Chromium, 11 pages × 2 viewports): no violations. Not manually verified. | DOM order matches visual order in the layouts tested. The article rail is a sticky grid column placed after the article in source order, so reading order is preserved. |
| 1.3.3Sensory Characteristics | Not Evaluated | No manual audit and no assistive-technology user testing has been performed. | Requires human review of instruction wording. Not yet performed. |
| 1.4.1Use of Color | Partially Supports | Reviewed during the evidence-card work: authority tier carries a text label, not colour alone. | Source cards state "PRIMARY AUTHORITY" and "Luke wrote this, not a regulator" in text. A full page-by-page review for colour-only meaning has not been done. |
| 1.4.2Audio Control | Not Applicable | No audio plays automatically. | Spoken answers are user-initiated and can be stopped. |
| 2.1.1Keyboard | Partially Supports | The Luke workspace was walked end to end with a scripted keyboard on 31 August 2026, which found three defects now fixed: the capabilities dialog never received focus and its trap did nothing, so six Tab presses walked into the page behind it while aria-modal claimed that page was inert; the dialog body scrolled but held nothing focusable, so PageDown moved it zero pixels; and answer tables scrolled sideways with no way to reach the columns off the right edge. Re-measured: focus enters the dialog, stays inside it, PageDown scrolls the body, and Escape returns focus to the opener. | The cause of the dialog defect was an inline onClose in a dependency array, which re-ran the mount effect on every render and restored focus to the trigger each time. The same mistake was present in the hook four Studio dialogs share and has been fixed there too, though those are behind sign-in and were verified by code review rather than in a browser. No screen-reader user has walked this. |
| 2.1.2No Keyboard Trap | Partially Supports | The canvas drawer closes on Escape and returns focus; verified in code and by test. | Not verified by a manual pass through every dialog. |
| 2.1.4Character Key Shortcuts | Supports | No single-character key shortcuts are implemented. | — |
| 2.2.1Timing Adjustable | Supports | No time limits are imposed on reading or input. | Answer generation can be stopped by the user at any point. |
| 2.2.2Pause, Stop, Hide | Supports | Streaming answers have a Stop control. prefers-reduced-motion is honoured globally. | — |
| 2.3.1Three Flashes or Below | Supports | No flashing content is used. | — |
| 2.4.1Bypass Blocks | Supports | A skip link is present, and the duplicate <main> landmarks that undermined it on eight pages have been removed. axe landmark rules: no violations. | — |
| 2.4.2Page Titled | Supports | axe document-title: no violations. Each route sets its own metadata title. | — |
| 2.4.3Focus Order | Partially Supports | axe tabindex rule: no positive tabindex anywhere. Focus returns to the composer after submit. | Order has not been walked manually on every page. |
| 2.4.4Link Purpose (In Context) | Partially Supports | axe link-name: no violations. Link names were also compared across each page: the research and article cards repeated "Read Full Research Synthesis" and "Ask Luke About This Paper" across every card, so both now carry the item title in the name. | That closes the in-context criterion and most of 2.4.9, which asks the same of the link text alone. Not every name has been read for meaning by a person. |
| 2.5.1Pointer Gestures | Supports | No multipoint or path-based gestures are required. | — |
| 2.5.2Pointer Cancellation | Partially Supports | Controls are native buttons and links, which activate on up-event by default. | Custom drag interactions in the sidebar have not been individually reviewed. |
| 2.5.3Label in Name | Partially Supports | axe label-content-name-mismatch: no violations. Visible labels were also compared against accessible names by hand, which axe cannot do where the label is dynamic: the workspace status chip read "Public Workspace" and was named "Preview ready", the quota chip was named from a different string than the one it displayed, and a button reading "Capabilities & Limits" was named "View Luke AI Capabilities and System Constraints". All three now contain their visible text. | Buttons that show their own text no longer carry an aria-label at all. Not every label on every authenticated surface has been compared. |
| 2.5.4Motion Actuation | Not Applicable | No motion-actuated functionality. | — |
| 3.1.1Language of Page | Supports | axe html-has-lang: no violations. <html lang="en">. | — |
| 3.2.1On Focus | Supports | No context change occurs on focus. | — |
| 3.2.2On Input | Supports | No form submits or navigates on input alone. | — |
| 3.2.6Consistent Help | Supports | Contact and methodology links appear in the footer in the same position on every page. | — |
| 3.3.1Error Identification | Partially Supports | Form errors are rendered as text adjacent to the control. | Error handling across the Luke workspace has not been systematically audited. |
| 3.3.2Labels or Instructions | Partially Supports | axe form-field-multiple-labels and label rules: no violations. | Sufficiency of instructions is a human judgement and has not been reviewed. |
| 3.3.7Redundant Entry | Supports | No multi-step flow re-asks for information already provided in the same session. | — |
| 4.1.2Name, Role, Value | Partially Supports | axe ARIA rules: no violations across 42 route and viewport combinations. Roles were also driven from the keyboard to check they keep the contract they announce, which axe cannot do. Four did not: three menus with no arrow keys, no roving tabindex and no Escape; a tab list containing exactly one tab; a role="feed" with none of the posinset, setsize or paging the pattern requires; and two aria-labels on bare divs, where naming is prohibited and the browser discards it. | All five were removed rather than completed, because each was a disclosure or a list in behaviour and the native semantics say so without any ARIA. The one menu that does implement the pattern kept its roles. Custom composite widgets have still not been verified against a screen reader. |
WCAG 2.2 Level AA
| Criterion | Conformance | Evidence | Remarks |
|---|---|---|---|
| 1.2.4Captions (Live) | Not Applicable | No live audio content is broadcast. | Speech input transcribes the user’s own voice; it is not a broadcast. |
| 1.2.5Audio Description (Prerecorded) | Not Applicable | No prerecorded video content. | — |
| 1.3.4Orientation | Supports | No orientation lock is applied; layout is responsive and was measured at 320px. | — |
| 1.3.5Identify Input Purpose | Partially Supports | axe-core autocomplete-valid: no violations. | The email subscription field uses an appropriate autocomplete token. Not every input collecting user information has been individually reviewed. |
| 1.4.3Contrast (Minimum) | Supports | axe-core colour-contrast with layout enabled, plus a per-node measurement of every text element against its resolved background: 0 nodes below 4.5:1 across 21 routes at two viewports. | This row read Supports while five blocks of text were failing, because the earlier sweep did not enumerate /authors/[slug] or /luke/beta. It does now. The worst was the Terms disclaimer at 1.44:1 and every card on an author page at 1:1 — light-theme CSS overriding the components on a dark page. Contrast is now held to 7:1. |
| 1.4.4Resize Text | Supports | Measured at 320px with no loss of content; viewport allows scaling to 5x with no maximum-scale lock. | The root size is now a percentage (112.5%) rather than 18px. An absolute pixel value on <html> discards the size a reader has set in their own browser, which is a poor trade on this site in particular; a percentage keeps both. |
| 1.4.5Images of Text | Supports | No images of text are used for content; all text is live text. | Logotype is exempt. |
| 1.4.10Reflow | Supports | Measured: scrollWidth minus clientWidth is 0 on all 11 pages at 320×512. Wide tables scroll inside their own keyboard-reachable container. | 320px is 1280px at 400% zoom, the condition the criterion specifies. |
| 1.4.11Non-text Contrast | Partially Supports | axe-core: no violations. Icon-only controls and field borders were measured directly and four sets were below 3:1 — the voice toggles at 2.60:1, the sidebar delete icon at about 1.6:1, and every input border in two forms at 1.53:1. All now clear 3:1. | axe does not cover every graphical object, and custom graphics have still not been individually measured. That is why this stays Partially Supports. |
| 1.4.12Text Spacing | Supports | The four spacing overrides the criterion specifies — line height 1.5, letter spacing 0.12em, word spacing 0.16em, paragraph spacing 2em — applied to every page and every element re-inspected for clipped or overlapping content. No loss on any route. | Article teasers use a line clamp, so they show fewer words at the larger spacing. The full text is on the page the teaser links to, so no content is lost. |
| 1.4.13Content on Hover or Focus | Partially Supports | Reviewed for the article rail and evidence cards: no hover-only content that obscures. | Dropdown menus dismiss on Escape. A full inventory of hover-triggered content has not been made. |
| 2.4.5Multiple Ways | Supports | Site search, category navigation, author indexes, sitemap and RSS are all present. | — |
| 2.4.6Headings and Labels | Partially Supports | axe heading-order and form label rules: no violations after the footer heading-level fix. | Descriptiveness is a human judgement and has not been reviewed. |
| 2.4.7Focus Visible | Supports | A scripted keyboard walk of 11 routes recorded the computed outline and geometry at every stop: 314 of 314 render a 3px outline, and none is smaller than 2px in either dimension while focused. | This row read Supports while one stop failed: the skip link inside the Luke sidebar stayed 1x1 and clipped while focused, because an unlayered .sr-only in globals.css beat Tailwind's focus:not-sr-only. The duplicate rule is gone. Note also that the indicator is the global outline, not the focus-visible:ring the styles suggest — the 196 inert focus:outline-none declarations that implied otherwise were removed. |
| 2.4.11Focus Not Obscured (Minimum) | Partially Supports | The sticky article rail occupies its own grid column and cannot overlap content; verified by measuring bounding boxes at six viewports. | The site header is fixed. Whether it can obscure a focused control on long forms has not been measured across every page. |
| 2.5.7Dragging Movements | Partially Supports | The Luke sidebar supports drag-and-drop to move a conversation into a project. The menu-based alternative this row previously named as the intended remedy is now in the code: a "Move to project" button opens a keyboard-operable menu that files or unfiles a conversation without any drag, and it is the one menu on the site that implements the full pattern — first item focused on open, arrow keys, Home and End, Escape, and focus returned to the trigger. | Not raised to Supports. Confirming it end to end needs a saved conversation and a project present at once, and that state could not be reproduced in the test harness, so the alternative is verified by code review only. It should be exercised by a person before this row moves again. |
| 2.5.8Target Size (Minimum) | Supports | Every visible control on 16 routes was measured, and the spacing exception computed rather than assumed — for each undersized target, whether a 24px circle centred on it intersects another target's circle. 0 failures. | SC 2.5.5, the AAA target size of 44 by 44, is also met for every control that is not a link inside a sentence. Links inside a sentence take the criterion's inline exception; the link lists in the footer columns are spaced well beyond the 24px the AA criterion asks. |
| 3.1.2Language of Parts | Not Evaluated | No manual audit and no assistive-technology user testing has been performed. | Content is English throughout; quoted foreign-language passages have not been audited for lang attributes. |
| 3.2.3Consistent Navigation | Supports | Header and footer are rendered by a shared AppShell on every route. | — |
| 3.2.4Consistent Identification | Partially Supports | Accessible names were collected for every control on 16 routes and grouped by the function they perform. One conflict: the same capabilities dialog was opened by three controls under three different names. It now has one name wherever it appears. | Names were compared across the public routes. Authenticated Studio surfaces were not included, so this stays Partially Supports. |
| 3.3.3Error Suggestion | Not Evaluated | No manual audit and no assistive-technology user testing has been performed. | Requires manual review of each error path. |
| 3.3.4Error Prevention (Legal, Financial, Data) | Not Applicable | No legal commitments, financial transactions or irreversible data deletions are offered. | There is currently no purchase or billing flow. |
| 3.3.8Accessible Authentication (Minimum) | Supports | Sign-in is federated through Google; no cognitive function test is imposed. | No CAPTCHA is used on the authentication path. |
| 4.1.3Status Messages | Partially Supports | tests/browser/answer-contract.mjs asserts start and completion each announce exactly once and that the streaming container is not a live region. Announcements per answer were measured at 3,399 before this work and 2 after. A live-region census then found a second one competing: the thinking indicator carried role="status" while its text rotated on a 2,200ms interval, so it spoke a new sentence every 2.2 seconds for the length of an answer. It is no longer a live region. | One further correction: a form status region declared role="alert" and aria-live="polite" together, and the explicit attribute overrode the role back to polite, so submission errors queued. The completion criterion for all of this is confirmation from a real screen reader user, which no automated measurement can supply. That has not happened. |
What this report does not cover
- No testing with assistive-technology users has been performed. Automated checks and developer review cannot substitute for it, and several rows above say so directly.
- No independent third-party audit has been commissioned.
- Automated tooling detects roughly a third of WCAG issues, so the clean automated result is a floor on quality, not a ceiling. The 31 August 2026 pass makes the point: the two worst defects it found — a modal that never took focus, and an entire route of white text on white cards — were both invisible to the route list the automated sweep had been running, and were found by driving the interface instead.
- The single-pointer alternative to dragging a conversation into a project (SC 2.5.7) is implemented but has not been exercised end to end by a person.
- Authenticated Studio surfaces — the editor, publish sheet and revision history — were reviewed as source but not driven in a browser, because the sign-in gate could not be passed in the test harness.
- Alt-text quality, plain-language reading level, and whether any instruction depends on a sensory characteristic all need a human reader and have not had one.
Reporting a barrier
If something here is wrong, or you hit a barrier this report does not describe, tell us at accessibility@accessibility.chat. We treat a reported barrier as a defect with a named owner, not as feedback.
See also our accessibility statement, security and data handling, and research methodology.