Accessibility conformance statement
Last updated
We target WCAG 2.2 Level AA. Everything on this page is either enforced by a named test that fails our build, or listed as not verified — there is no third category, and nothing is claimed here because it is probably true. No third-party audit has been carried out, which is exactly why each claim names the check behind it.
What a buyer is usually asking
“Is it accessible?” is four questions, and answering them separately is more useful than a single letter grade:
- Can somebody who cannot see the screen use it? — screen reader support.
- Can somebody who cannot use a mouse use it? — keyboard and pointer.
- Can somebody who cannot see it well use it? — contrast, text size, motion.
- Can you prove any of it? — the column that is usually empty.
The table below is our answer to the fourth. It applies to the Loonext web application, and to the Android and iOS apps where stated.
Verified by a test
Each row fails a build if it stops being true. This is the whole table; there is nothing we count as verified that is not here. Every one of these has been proven by breaking it — the rule removed from the product, the check observed to fail, the removal reverted. A check that has only ever passed is not evidence.
| Criterion | What holds | Enforced by |
|---|---|---|
| 1.4.3 Contrast (Minimum) | Text token pairs recomputed from the actual hex values in globals.css, in both themes | apps/web/src/app/globals.contrast.test.ts |
| 1.4.3 Contrast, rendered | Rendered text measured against its actual background on real pages, both themes | scripts/theme-audit.mjs (CI) |
| 2.3.3 Animation from Interactions | One base rule zeroes motion under prefers-reduced-motion; the rule cannot be weakened or deleted | apps/web/src/app/reduced-motion.test.ts |
| 2.5.7 Dragging Movements | Every file that starts a drag records the code implementing its single-pointer alternative — on all three clients | apps/web/src/app/dragging-alternatives.test.ts, scripts/check-gesture-alternatives.mjs |
| 2.4.7 Focus Visible | Every control reached by pressing Tab has an outline or a ring, measured on the rendered page in both themes | scripts/theme-audit.mjs (CI), apps/web/src/app/focus-appearance.test.ts |
| 1.4.11 Non-text Contrast — focus | That indicator clears 3:1 against the surface behind it, with its alpha composited rather than assumed away | scripts/theme-audit.mjs (CI), apps/web/src/app/focus-appearance.test.ts |
| 2.4.11 Focus Not Obscured (Minimum) | The focused control is not entirely covered by a sticky header or overlay, sampled from the compositor rather than computed from rectangles | scripts/theme-audit.mjs (CI), apps/web/src/app/focus-appearance.test.ts |
| 2.5.8 Target Size (Minimum) | Interactive targets measured at 375px against 2.5.8's 24px floor; .tap-target (44px) credited above it | scripts/theme-audit.mjs (CI) |
| 4.1.2 Name, Role, Value — names | Interactive elements have an accessible name, computed the way an AT computes it | scripts/theme-audit.mjs (CI) |
| 4.1.2 Name, Role, Value — roles | role="tab" carries aria-selected; role="tablist" contains real tabs; aria-live states its politeness | apps/web/src/app/layout-v2-roles.test.ts |
| 4.1.3 Status Messages | Incoming messages announce politely; the composer's send state is announced rather than only styled | apps/web/src/app/layout-v2-roles.test.ts |
Not verified
No TalkBack or VoiceOver pass has been performed, on any flow, on either phone app. Every icon-only control has an accessible name and a build fails if one loses it — but a name is necessary and nowhere near sufficient. Reading order, whether a live region speaks at the right moment, whether a custom control exposes the right role and state, and whether a whole task can be driven by a screen reader all need a person with a phone. None of that is claimed here.
Text scaling is enforced as a mechanism on both phones: every font is declared in a unit that carries the reader’s font scale. Android’s layout at 200% text is rendered on every test run; iOS has no equivalent render, so its matching fix rests on the two apps having had identical measurements rather than on a second picture.
Known gaps
Stated plainly, because a buyer who finds one of these themselves stops believing the rest of the page.
- The thread panel’s resize handle offers arrow-key resizing and a double-click reset. The double-click is the single-pointer path but reaches only one width; an arbitrary width without dragging is keyboard-only.
- No third-party audit has been carried out. Everything here is first-party, which is why each claim names the check behind it.
- Native screen-reader flows are untested end to end, as above.
- iOS is not rendered at 200% text anywhere.
Contact
If something here blocks you, or you need this statement in another format, write to support@loonext.com and say what you were trying to do. An accessibility problem that stops somebody working is treated as a broken feature, not as feedback.