Reference · accessibility
Built for people who are unwell
What accessibility means on this site in practice, and where we are still short.
Reference · accessibility
Built for people who are unwell
Cognitive fog, joint pain, light sensitivity and exhaustion are symptoms of the illness this platform is for. Accessibility here is not a compliance exercise bolted on at the end — the people who need this most are frequently the people least able to fight an interface.
What we commit to
AA contrast on every pairing
Not “on the palette” — on each actual combination of ink and ground, measured where it sits. Body text clears 4.5:1 and large text 3:1; white on a dark surface comes from a ladder of three tested values rather than ad-hoc transparency. Muting text with opacity counts as failing it.
A stated floor on type size
Body copy is 15px and its quieter voice 14px, both at a line height of 1.7 or more, because reading with fog is slower than reading without it. The smallest label in the system is 10px — a floor we are not happy with, and one of the shortfalls named below.
Reachable by keyboard alone
Interactive controls are real buttons and links, not clickable containers, so they can be reached with Tab and operated with Enter or Space. Expandable sections announce whether they are open, the first Tab press on any page reveals a skip link, and the focus outline is never removed.
A 44px floor on hit targets
Tremor and joint pain make small targets genuinely unusable rather than merely annoying, so 44px is the rule for anything new. The controls still under it are named in the table below rather than left for you to find.
Motion is decorative and stoppable
Nothing that carries meaning animates, and every animation stops when your system asks for reduced motion — including hover transforms, staggered delays and scripted smooth scrolling, which is where it had leaked. The animated hero renders one still frame instead of vanishing. With motion off, or with JavaScript off entirely, every page is readable immediately.
Colour never carries meaning alone
Every state that uses colour also uses a word or a shape: evidence tiers carry their label, record status carries its word, a completed step carries a tick. The two places that still lean on hue alone are in the table below.
Low cognitive load is a requirement
Generous spacing, short line lengths, clear hierarchy, no walls of text. Where a page has a long form and a short one, the short one is the default, and every guide carries a “Larger, easier text” control. It makes the type bigger; it does not yet shorten the page, and it says so.
Reflows rather than shrinks
Layouts reflow instead of scaling down, text follows your browser or system font size, and the site works zoomed in. An entire card is the link, not just its title.
WCAG 2.1 AA · criterion by criterion
Last full audit · 28 August 2026A table, not a badge. We aim to meet WCAG 2.1 Level AA across the site. We are not claiming conformance — that requires an independent audit we have not commissioned. So the column below is not a verdict: it says what looks at each criterion, how often, and what it has found. 4 of the 12 rows are held by a script that fails when the rule is broken — how often each one runs is under “How it is actually enforced” below; the rest were measured once, on the date above, or are open.
| SC | Criterion | Checked by | How · what falls short |
|---|---|---|---|
| 1.4.3 | Contrast (minimum) | enforced | Every text-and-surface pairing in the system is graded against 4.5:1 on each run, using the colour tokens the product actually renders rather than a remembered copy of them. Pairings that once failed are kept as permanent witness rows, so an all-clear run is distinguishable from arithmetic that can no longer produce a failing number. What it cannot see: a colour written as a literal instead of a token.How this is enforced: scripts/check-contrast.mjs |
| 1.4.11 | Non-text contrast (focus indicators) | enforced | Every interactive element on a sweep of public and signed-in routes is focused in a real browser. Transitions are zeroed so the settled state is read rather than a frame of a cross-fade; whichever property is the indicator is resolved, its colour composited, and the result graded at 3:1 against both surfaces it abuts.How this is enforced: scripts/check-focus.mjs |
| 2.4.7 | Focus visible | enforced | The same sweep asserts that something visible changes on focus. It exists because two finished pages had over a hundred interactive elements between them and not one visible focus indicator — no screenshot can photograph a missing focus ring, because a ring exists only while an element is focused. |
| 2.4.1 | Bypass blocks | enforced | The skip link is asserted to be the first tab stop, to be visible while focused, and to move focus into the main region when activated. There was no skip link at all on this site before 28 August 2026.How this is enforced: scripts/check-a11y.mjs |
| 4.1.3 | Status messages | partial | Every async outcome — a failed sign-in, “Saved.”, a consent flip, a refused request — now mounts a live region, and a script watches a real failed sign-in produce one. Not done: no form field carries aria-invalid or an aria-describedby pointing at its error, so a screen-reader user hears the error only if they go looking for it. |
| 2.1.1 · 2.1.2 | Keyboard · no keyboard trap | audited | Real-Tab walks of about 2,300 tab stops across every public route and the patient, provider, researcher and admin surfaces on 28 August 2026; no traps found, and eight keyboard-unreachable scroll regions were made focusable in the same pass. Walked once, on a production build — not re-run on every change. |
| 2.2.2 · 2.3.3 | Pause, stop, hide · animation from interactions | audited | The whole site was re-rendered under emulated reduced motion on 28 August 2026 with zero surviving animations. Decorative motion that has not been asked to stop still starts on its own, which is a queued decision rather than a fixed one. |
| 1.4.10 | Reflow | audited | Measured at 320px on every route on 28 August 2026: clean but for two sites, both fixed in that pass. The caveat is ours to own — a blanket horizontal-overflow clip on the body means a future overflow is hidden rather than visible, so the next one will not announce itself. |
| 1.3.1 | Info and relationships | partial | Landmarks, list semantics, table header scopes, empty headings and six pages of nested <main> were corrected. Heading order is the class that remains: the shared figure frame hard-codes an h3, which lands directly under the h1 on figure-led pages. axe holds those routes at a named ceiling rather than calling them clean, and the fix is a design decision about whether figures belong in the outline. |
| 2.5.8 | Target size (minimum) | partial | The floor is 44px for new work. Below it today: the nav hamburger and the drawer’s close button at 36px — and on phones the hamburger is the only route into navigation — plus a few text-only controls inside the app, including the onboarding skip and the link into consent settings, which are smaller still. |
| 1.4.1 | Use of colour | partial | The rule is that colour never carries meaning alone, and most states now carry a word or a mark. Two do not: the course quiz signals right from wrong largely by fill colour, and the onboarding progress list marks its current step by colour without aria-current. Both are open. |
| 4.1.2 | Name, role, value — as heard, not as coded | not tested | Semantics, labels and landmarks are written deliberately and axe checks that they exist. Whether they make sense read aloud is the one thing no instrument in this repo can measure, and nobody who uses a screen reader daily has walked this product. Until one has, the word on this page is “target”, never “conformant”. |
How it is actually enforced
Three of these are checkable by machine. The text-contrast check runs automatically on every pull request; the other two need a production build and a real browser, so they are run by hand rather than automatically. The rest are review rules a person applies, which is worth saying plainly rather than implying a robot has it covered.
- Contrast is computed, not eyeballedThe audit imports the palette the product renders instead of a hand-typed copy, because the copy is always the stale one — for a while the one check whose job was to notice a bad colour could not notice a colour changing. It also keeps the pairings that failed as permanent rows, so it can still prove it is capable of saying no.
- The focus ring is graded on the surface it sits onA ring that changes is not the same as a ring you can see. A forest-green ring on the ink footer measured 1.39:1, and a check that only asked “did anything change?” called it green for months. Indicators are now resolved to a composited colour and graded against both surfaces they touch, because clearing either one is what the standard asks.
- The automated sweep is a ratchet, not a scoreAny route-and-rule pair not explicitly listed must be at zero violations. Every listed ceiling is a named, queued decision with its question written down, and a run that comes in under its ceiling asks to have the ceiling tightened. Adding a ceiling to quiet a red run is the exact failure this shape exists to prevent.
- Tokens carry the accessible variantWhere a colour cannot pass on a dark ground, the token set ships the variant for that ground rather than leaving each page to improvise: the focus ring flips to a green glow inside dark containers, and white-on-dark text comes from a three-value ladder instead of whatever opacity looked right.
- The pages that matter printThe clinician brief, the tick-bite record, the coverage and denial guides are laid out for paper: navigation and floating controls drop out, shadows fall back to hairlines, and checklists do not split across a page break. A printout is what works in a waiting room.
Where we currently fall short
Naming these is the point of the page. A statement that lists only successes is marketing, and a statement listing no problems is either untrue or untested. We know of 8.
- The site has not been tested end to end with screen readers (NVDA, JAWS, VoiceOver). The 2026-08-28 automated audit is not a substitute for that — a machine can verify that announcements exist, not that they make sense by ear — and it is scheduled before public launch.Still true when the automated audit last looked · 28 August 2026
- It has not been reviewed by an accessibility specialist or by disabled users. Tremor, brain fog and photophobia are this product’s core audience, and their judgement beats every checklist here. Both reviews are planned.Still true when the automated audit last looked · 28 August 2026
- The light-grey label colour the 2026-08-28 audit found being used as real text at about 2.5:1 was swept to a passing grey that day, and the automated sweep now measures that rule at zero on every route it covers. One field’s placeholder — the tick-bite form’s — was missed and still carries it. Placeholder text is not exempt from the contrast floor; it is the only label some fields have while empty.
- The smallest metadata type on the site — eyebrows, breadcrumbs, column headers, review labels — sits at 10 to 11px. Each has a larger equivalent within reach, but the floor is lower than we would like and lower than some readers can manage. Raising it is a change to the type scale, not a per-page fix.
- The site offers no high-contrast control of its own, and its only text-size control is the guides’ “Larger, easier text”, which works with scripting off. Otherwise it respects the size, contrast and motion preferences your browser and operating system already carry. Where a page has a long form and a short one is promised, the short one is not written yet.
- Maps and charts lean on shape and colour. Every one of them has a table or a written reading beside it that answers the same question, and the figures carry descriptions of the fact rather than the picture — but the graphic itself is not independently accessible, and the sparkline’s description names its peak without its trajectory.
- Some pages are still being converted from earlier prototypes. Converted pages meet the standards above; the remainder are being brought up to them.
- Emoji are used as decorative icons in a few marketing surfaces. They are hidden from assistive technology so they are not read aloud, but a small number of older screen-reader and browser combinations may still announce them.