S8, finished where the plan said it would be: every .help-tip badge is a <button> - upgraded by the component itself at load (help.js), with helpTipUpgrade() for late renders, so a badge added tomorrow is born reachable. The count the task warned about came true: 15 at wave 0, 18 at the wave 6 exit, 20 at the start of this task - all 20 buttons now, and the fix being in the component is what stops the number growing again. One viewport-clamped role=tooltip bubble serves every badge: focus shows it, Escape hides it, tap toggles it, tap-elsewhere closes it - the touch path Field View's tablets never had. The injected styles now use theme tokens (four raw hexes of the S5 kind, gone). BL-001, CLOSED after three causes and nine waves: the old CSS ::after escaped its badge to the right and was the creator's last 390px overflow. The clamped bubble ends it - scrollWidth 390 vs clientWidth 390 - and frame_check's pin FLIPPED, exactly as designed: it asserted the failure until the fix landed, and now asserts the fix so a regression reopens the entry loudly. The audit (docs/reference/accessibility-audit.md), every number probe-backed: - div/span click handlers: 12/2 at wave 0 -> 0 (the wizard's constraint library entries and the dashboard chips became buttons here; the comments backdrop stopped pretending to be a control) - outline:none without replacement: 0 (wp-chrome's one is the documented S12 exception - its ring is on :focus-within, one ring not two) - aria-live: every toast system and banner announces - native dialogs: 79 -> 21, all on surfaces no S1 task named (admin, users, launcher) - documented as BL-024 with the T7.9 kit ready for them - keyboard-only primary flow: covered leg by leg by the probes that dispatch real CDP key events, cited in the document Three stale count-pins re-pointed to the numbers this task reached (stepper's baseline-minus-10, form_structure's one-span-left, frame_check's BL-001 pin) - each now pins the TARGET so slack cannot hide a regression. Verification (each probe run alone): NEW tests/helptip_check.py 13/13. Regressions: a11y_check 22/22, stepper_check 71/71, form_structure_check 50/51 (BL-022's product question), pipeline_check 44/44, frame_check 38/38. Items: C1, S8 (BL-001 closed, BL-024 opened) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
4.5 KiB
Accessibility audit — C1 + S8 (T9.5, 2026-08-19)
Approved Aug 14 2026 (C1): any component rebuilt ships accessible or it is not done. This document records the audit at the end of wave 9 against the wave 0 baseline, per CLAUDE.md's rules. Every number below is re-measured by a probe on every run — the citations name which one.
The metrics
| Metric | Wave 0 baseline | Now | Target | Verified by |
|---|---|---|---|---|
<div> / <span> with onclick |
12 / 2 | 0 | 0 | helptip_check.py (grep, comments stripped) |
.help-tip unreachable by keyboard |
15 (18 by wave 6) — re-measured at T9.5 start: 20 | 0 | 0 | helptip_check.py (driven with real keys and taps) |
aria-live regions |
0 | ≥1 per toast system and banner (login, both toasts, release banner, autosave indicator, list-import reports, field toast) | ≥1 each | a11y_check.py, warning_check.py, creator_dialogs_check.py |
| Text below 4.5:1 | present | none found on the audited surfaces | 0 | a11y_check.py (creator sweep), frame_check.py BL-013 note |
outline: none without replacement |
present | 0 (grep with replacement detection) | 0 | helptip_check.py |
| Native dialogs | 79 | 21 | 0 or documented | creator_dialogs_check.py prints the count; see the gap below |
The count went up before it went down, exactly as the task predicted: the
wave 6 exit counted 18 unreachable help-tips; at the start of T9.5 there were
20 (T6.x and wave 7/8 tasks reused the component as designed). All 20 are
buttons now — the fix is in the component (help.js upgrades every badge at
load and exposes helpTipUpgrade() for late renders), so a badge added
tomorrow is born reachable.
The documented gap — 21 native dialogs
admin.js (6), users.js (10), index.html (5). These are the operator
consoles and the launcher — surfaces no S1 task ever named (S1's two
halves were the wizard, T5.8, and the creator, T7.9; both measure 0). They are
admin-only or low-frequency flows, every one a genuine confirm-before-destroy.
Logged as BL-024 for conversion to the T7.9 dialog kit rather than done
here: converting three more pages inside the audit task is the drive-by
CLAUDE.md forbids.
The help-tip component (S8)
- The badge is a
<button>witharia-label,aria-expanded, and a:focus-visiblering from the shared--cds-focustoken. - The tooltip is one
role="tooltip"bubble, viewport-clamped on both axes — which also ended BL-001: the old CSS::afterescaping its badge was the creator's last 390px overflow. - Paths: keyboard (focus shows, Escape hides), touch (tap toggles, tap
elsewhere closes), pointer (hover shows). Driven at 390px by
helptip_check.py. - The injected styles now use theme tokens; the block previously carried four raw hexes of the kind S5 counted.
Keyboard-only primary flow
Sign in → pick a project → SOP wizard → create a work package → issue it.
Covered by probes that dispatch real CDP key events (synthetic
KeyboardEvents never reach native activation — the wave 5 lesson, recorded
in form_structure_check.py):
| Leg | Probe |
|---|---|
| Sign in | server/smoketest.py (form submit), login.html roles verified in a11y_check.py |
| Launcher → project | launcher_check.py (B3, keyboard section) |
| SOP wizard steps | stepper_check.py (A4/S9: ten real buttons, keyboard operable) |
| Creator sections + save | form_structure_check.py §7 (Tab/Enter/Space on rail and headings), creator_dialogs_check.py (validation focus order) |
| Issue | hold_check.py (the status control end to end) |
Per-page results
| Page | Interactive elements | Announcements | Focus | Notes |
|---|---|---|---|---|
| login.html | native form controls | role="alert"/role="status" (the app's reference pattern) |
visible | the pattern every other page copies |
| index.html (launcher) | buttons/links | status line announced | visible | 5 native dialogs → BL-024 |
| work-package-suite.html (wizard) | 0 div/span handlers; library entries are buttons (T9.5) | wp-toast role-differentiated |
T3.4 ring | 0 native dialogs |
| wp-creation-index.html (creator) | 0 div/span handlers; chips are buttons (T9.5) | toast + release banner + field errors, all live regions | ring on all 120+ focusables (a11y_check) |
0 native dialogs |
| field.html | buttons throughout, 44px targets | role="status"/alert toast |
visible | offline drawings reachable (files_check) |
| admin.html / users.html | buttons | banners | visible | 16 native dialogs → BL-024 |