2026-08-12. Corrects /framework/estate-review-2026-08-11 §7.2 and /framework/patch-pack-2026-08-11 §4.
"35 icon-only<button>elements with no accessible name, and roughly six<img>tags built inside JS template strings with noalt. This is the largest concrete a11y debt in the estate."
That was measured with grep. Re-measured by parsing the DOM of static/index.html (744,118 bytes, 11,609 lines):
| Check | Result | |
|---|---|---|
<button> elements | 262 | |
— named by aria-label / title | 55 | |
| — named by visible text content | 207 | |
| — truly unnamed | 0 | |
<img> missing alt | 0 (3 images, all labelled) | |
| Links with no accessible name | 0 | |
<h1> | 1 · lang | en |
There are zero unnamed buttons. The regex counted a button as unnamed whenever the next characters were <svg, but those buttons carry visible text after the icon — a tile with an icon above a caption. The caption is the accessible name.
Adding aria-label to a control that already has a visible text label overrides that label in the accessibility tree. A voice-control user who says "click Collect" stops being understood, because the accessible name is no longer "Collect". That is a WCAG 2.5.3 (Label in Name) failure — introduced by the fix, on a paid product.
Do not apply §7.2 of the review or §4 of the patch pack.
15 controls carry an aria-label that differs from their visible content, e.g. ⌫ → "Backspace", 💾 → "Save red side to log", ✕ → "Clear blue side". These are correct. WCAG 2.5.3 concerns visible text labels; a glyph is not a word a voice user would speak, so a descriptive name is the right call.
17 of 66 form controls have no accessible name — no aria-label, no <label for>, no wrapping <label>, no placeholder.
file (file input) · collBin · collSort · expFmtInv · lpPct · invBin · galBin · galSort · setSort — plus a second file input and the remainder in the same fmtsel family.
These are mostly <select> filters and sort controls. A screen-reader user hears "combo box" with no indication of what it filters. Fix is one attribute each, e.g.:
<select id="collSort" aria-label="Sort collection by">
<select id="collBin" aria-label="Filter collection by bin">
<select id="expFmtInv" aria-label="Inventory export format">
<input id="lpPct" aria-label="Label print scale (percent)" type="number">
<input id="file" aria-label="Choose image to scan" type="file">
Name each one after what it actually controls — confirm against the surrounding panel before writing the string. A wrong name is worse than none.
Accessibility cannot be measured with grep. Counting <button followed by <svg produced a headline finding that was entirely false, and hid a real one. Parse the DOM and query the accessibility properties. The same applies to the "6 images without alt" claim — those were <img inside JS template strings, which grep sees and a parser correctly ignores.