T9.5 - C1+S8: the help-tip is real, the audit is written, BL-001 is dead
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>
This commit is contained in:
73
docs/reference/accessibility-audit.md
Normal file
73
docs/reference/accessibility-audit.md
Normal file
@@ -0,0 +1,73 @@
|
||||
# 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>` with `aria-label`, `aria-expanded`, and a
|
||||
`:focus-visible` ring from the shared `--cds-focus` token.
|
||||
- The tooltip is one `role="tooltip"` bubble, viewport-clamped on both axes —
|
||||
which also ended BL-001: the old CSS `::after` escaping 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
|
||||
`KeyboardEvent`s 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 |
|
||||
@@ -302,6 +302,7 @@ Wave 9 adds these:
|
||||
python tests/export_check.py # CR-008/CR-017 - export walk + hours guard 20 checks
|
||||
python tests/sample_check.py # S7 - one sample affordance, confirmed+fenced 10 checks
|
||||
python tests/icon_check.py # S6 - one icon system, no emoji, mapped 5 checks
|
||||
python tests/helptip_check.py # C1/S8 - tips by keyboard+touch, audit greps 13 checks
|
||||
```
|
||||
|
||||
**Three probes were re-pointed at `T7.1`.** `sections_check.py` 5b drove the live
|
||||
|
||||
@@ -54,7 +54,7 @@ deliberately deferred.
|
||||
|
||||
## Found during implementation
|
||||
|
||||
### BL-001 — The creator overflows horizontally at 1440px
|
||||
### BL-001 — CLOSED at T9.5 — The creator overflows horizontally (1440px, then 390px)
|
||||
|
||||
- **Found during:** T0.2
|
||||
- **Where:** `html/wp-creation-index.html` / `html/wp-creation-styles.css`
|
||||
@@ -123,6 +123,13 @@ deliberately deferred.
|
||||
owns this entry now. `tests/form_structure_check.py` reports the measurement on
|
||||
every run, and `tests/frame_check.py` keeps the failure pinned so the entry
|
||||
cannot be closed by silence.
|
||||
- **CLOSED, T9.5.** The `S8` rebuild replaced the escaping CSS `::after` tooltip
|
||||
with a viewport-clamped bubble element, and the creator measures
|
||||
**scrollWidth 390 vs clientWidth 390** at a 390px viewport. `frame_check.py`'s
|
||||
pin flipped: it now asserts the ABSENCE of overflow, so a regression reopens
|
||||
this entry loudly. Three causes in this entry's lifetime - the user-menu run
|
||||
(fixed by `T1.2`), the injected `--nav-w` (spent by `T7.1`), the tooltip
|
||||
(fixed here) - each found only because the measurement kept running.
|
||||
|
||||
### BL-002 — `outline: none` appears three times in the wizard sheet, not once
|
||||
|
||||
@@ -507,3 +514,16 @@ deliberately deferred.
|
||||
- **Why not now:** new scope — needs its own item id per the working rules, and
|
||||
a product conversation about where it displays and who reads it.
|
||||
- **Suggested wave or follow-up:** next revision; needs Nick for placement.
|
||||
|
||||
### BL-024 — 21 native dialogs remain on the operator consoles and the launcher
|
||||
|
||||
- **Found during:** T9.5 (the audit's dialog count)
|
||||
- **Where:** `admin.js` (6), `users.js` (10), `index.html` (5)
|
||||
- **What:** the app-wide native dialog count fell 79 → 21 across `S1`'s two
|
||||
tasks (`T5.8` wizard, `T7.9` creator). The remainder sit on surfaces no `S1`
|
||||
task ever named — admin-only or low-frequency flows, every one a genuine
|
||||
confirm-before-destroy. The T7.9 dialog kit (`wpConfirmDialog`/
|
||||
`wpPromptDialog`) is built and proven; conversion is mechanical.
|
||||
- **Why not now:** converting three more pages inside the audit task is the
|
||||
drive-by CLAUDE.md forbids; the audit's job was to measure and document.
|
||||
- **Suggested wave or follow-up:** next revision, one task, using the T7.9 kit.
|
||||
|
||||
Reference in New Issue
Block a user