Skip to main content
Back to home

Accessibility statement

Accessibility is the work on display here, so this page is held to the same standard as the code: every factual claim on it traces to an artifact in the site's public repository or to a ticket named inline.

This statement covers michaelstates.com — every page served on this domain — and the component library the site is built from, which is developed and audited in the same repository.

Last reviewed: July 24, 2026.

Conformance target

This site is built and tested against WCAG 2.2, Level AA. Every UI change is verified against that bar before it's considered done.

During design I also use APCA as a readability aid, but I claim no WCAG 3 or APCA conformance — WCAG 3 is still a draft.

How conformance is enforced

A page can't ship on this site without an accessibility audit. Every route must be registered in a test manifest, and a parity check fails the build if a page appears in the build output without an entry — including this one.

Every registered route gets a full axe scan against the complete WCAG 2.0, 2.1, and 2.2 A and AA rule set — deliberately not narrowed — and the suite requires zero violations. The scans run against the built HTML, the same output that deploys, not a dev server. The suite also asserts each page's document contract — HTTP status, exact title, the expected level-one heading, a main landmark, a skip link — and drives the skip link by keyboard: first Tab stop, visible on focus, at least 24 by 24 pixels, and Enter moves focus into the main content.

Lighthouse audits every built page, three runs each, and an accessibility score of 1.0 is required — an error-level assertion, not a dashboard number. Linting includes eslint-plugin-jsx-a11y across the interactive components.

All of this runs on every pull request and every push to main, and the production branch is protected: a change can't land on main until those checks pass. The case study — how this site was built accessibly — tells the longer story of why the machinery is shaped this way.

Beyond automation

Automated checks catch only a minority of real accessibility issues; I treat them as the floor, not the ceiling. The component library's primitives — button, heading, link, text field — each have a recorded WCAG 2.2 AA review committed to the repository, with per-criterion verdicts and their open items written down rather than rounded off. During development, every component story is also axe-checked in the workbench, with violations surfaced as errors.

Every normative foreground/background color pair on this site ships with a computed contrast ratio recorded against the WCAG floors.

Known limitations

An honest statement says what hasn't been done yet. As of the review date above:

  • No recorded manual screen-reader pass yet. I haven't yet run and recorded a full VoiceOver and NVDA pass of the live site. The checklist is committed at docs/a11y/manual-testing.md; the work is tracked as INC-206.
  • One open high-priority component finding. The text-field component keeps its error live region mounted even when empty, and NVDA with Firefox can miss the first error announcement in that pattern. The axe suite passes — this is dynamic screen-reader behavior axe can't detect — so manual verification is tracked as INC-219 (docs/a11y/textfield.md, Issue #1). No page on this site renders a text field today, so this is a component-library limitation rather than a live barrier.
  • Forced-colors mode is unverified. Focus-indicator behavior in Windows High Contrast Mode hasn't been verified by a human yet; it's a manual-only item on the same checklist.
  • Smaller open audit notes. The component reviews carry a few hardening items — guards for icon-only accessible names, an empty-heading guard — none of which affects anything currently shipped. They're indexed in docs/follow-ups.md.

This is a living page. When one of these items closes, the statement and its review date update with it — the point of the list above is to shrink.

Feedback

If something on this site doesn't work for you, I want to know. Email hello@michaelstates.com or use the contact section on the homepage. A barrier you report is treated as a bug, not feedback.