Accessibility
What has been tested, what it measured, and what has not been tested at all.
Target conformance level: WCAG 2.1 Level AA. This page is not a VPAT. It is the evidence a VPAT would be written from, published while the product is small enough that you can check it yourself.
The last measurement
Run against the live site, in Chrome, at a Chromebook viewport and a phone viewport, on . Re-run on every deploy that changes a page.
The routes checked were: /, /why, /for-educators, /compliance, /privacy, /explore, /record, /accessibility, /work, /work/oh, /talk, /404. A build check fails if a route ships that is not on this list. One of those, /work/[state], is a template that renders a page for every state, so about fifty pages share its code and /work/oh is the one sampled. That is a real limit of this measurement rather than a technicality: a defect present only on a longer state name would not appear in the number above.
- Automated WCAG 2.1 A and AA violations
- 0Checked on all 12 routes at 3 viewports (1366x768, 390x844 and 320x800) in BOTH the light and dark palettes, using axe-core restricted to the wcag2a, wcag2aa, wcag21a and wcag21aa tags. The completed results screen — eighteen occupations, the filter, the state picker — is scanned separately at both viewports and is included.
- Routes with horizontal scrolling
- 0 of 12Measured as scrollWidth minus clientWidth on the document element, at all three viewports. Note what this cannot see: content clipped by overflow:hidden does not overflow, so this figure is not a reflow test. A separate check of truncated text found and fixed nine clipped labels at 320px that this number reported as clean.
- JavaScript console errors
- 6Across 72 page loads. An error here usually means something did not render, which no accessibility rule will catch.
- Sixty questions completed with the keyboard alone
- Yes, in 269 keystrokesTab, Space and arrow keys only, with no pointer at any point, run at BOTH viewports. The run answers a differentiated profile and the pass requires 18 occupations to have actually rendered — not merely that the page changed. An earlier version of this figure ran a straightlined pattern, ended on the screen where the instrument refuses to score, and reported success anyway.
- Focused controls not fully visible on screen
- 0 of 120Measured on the LABEL, which is the control a person sees, at both viewports. The input itself is visually hidden at 1x1px and is always scrolled into view, so measuring it — as this figure previously did — cannot fail. A control that is focused but not visible is a control a sighted keyboard user has lost.
How it was tested
- Chrome, in an isolated browser profile, against the deployed site rather than a local build.
- Three viewports: a Chromebook (1366 by 768), a phone (390 by 844), and 320 by 800, which is what 1280px looks like at 400% zoom and is the width SC 1.4.10 Reflow is written about.
- Both color schemes. The site ships a full dark palette and an earlier version of this measurement never ran against it.
- axe-core, restricted to the WCAG 2.1 A and AA tags, so the number is against the level we claim and not against a broader best-practice set that would flatter it.
- A full sixty-question run driven by keyboard events only, at both device viewports, asserting that occupations rendered rather than that the page changed.
- Color contrast recomputed from the rendered pixels rather than read from the stylesheet — including a pixel diff of each primary control focused against the same control blurred, which is the check that catches a focus ring the same color as the page behind it.
What has NOT been tested, and what an automated pass cannot see
A clean automated run is a floor, not a result. Two defects on this site passed every automated check and were found by computing a value by hand and by looking at the page.
- No screen reader testing. No JAWS, no NVDA, no VoiceOver. The keyboard path and the live-region announcements are verified programmatically, which is not the same as a person using this with speech and telling us it makes sense.
- No third-party audit and no VPAT or Accessibility Conformance Report. We will not send you one we have not earned. When there is a customer to justify the engagement, the remediation is budgeted as the expensive half, before the audit rather than after it.
- Chromium only. No Firefox and no Safari, and half the context we design for is a phone.
- One of the routes above is a template. /work/[state] renders a page per state, so about fifty pages share its code and only /work/oh is sampled. A defect present only on a longer state name would not appear in these numbers.
- An automated pass is blind to whether a control is DISABLED or merely says it is. Swapping a disabled attribute for aria-disabled on this site kept the control active, which pulled its text and its boundary out of two contrast exemptions at once. Both then failed, at 3.23:1 and 1.58:1 against requirements of 4.5:1 and 3:1, and axe reported the rules inapplicable rather than failed.
- It is blind to a focus ring that is the same color as the page. Every primary control on this site shipped with one — measured 1.00:1 against a 3:1 requirement, with the focused and unfocused renderings byte-identical — under a clean axe run, until an auditor diffed the pixels.
- It is blind to meaning. It cannot tell you that a live region announced the same string twice and so said nothing the second time, that a filter replaced eighteen results in silence, or that a discriminator added to defeat that gets SPOKEN as a number. All three shipped here.
- It is blind to a class that styles nothing. Six links used a utility class defined in no stylesheet and rendered as plain text, indistinguishable from the sentence around them, which fails SC 1.4.1. A screenshot caught it.
- No testing with cognitive or learning disability users, and no plain-language review by anyone outside this project. We measured the results page at roughly grade 11 on Flesch-Kincaid and an independent auditor measured 12.9 on the same text, because syllable heuristics differ between implementations. Take the higher one: it is too high for the page a student has to act on, and the cause is unedited O*NET occupation descriptions.
- Voice control and switch access are untested.
Why this is your problem and not only ours
The Department of Justice rule at 28 C.F.R. Part 35, Subpart H requires web content and mobile apps provided by a public entity to conform to WCAG 2.1 Level AA. The compliance dates are 26 April 2027 for public entities serving a population of 50,000 or more and 26 April 2028 for smaller ones.
A vendor’s non-conformance becomes the entity’s own, which is why an evaluator is right to ask for evidence rather than a claim. It is also why we would rather show you a dated measurement with its method attached than a document asserting a conformance level nobody outside this building has checked.
Telling us something is broken
Email david@reddenda.com. Say which page, what you were using, and what happened. A barrier reported by somebody who hit it is worth more than another automated run, and we will tell you what we did about it rather than closing the thread.
Related: what is and is not in place across the rest of the procurement questions, and what happens to student data.