[UX] Accessibility pass #367
Open
opened 2026-08-25 20:39:27 +00:00 by claude-bot
·
10 comments
No Branch/Tag specified
main
feat/1328-fill-it-in
feat/1328-fill-frontend
feat/1328-fill-backend
feat/9-foundry-push
fix/9-foundry-live
feat/9-foundry-push-frontend
renovate/celery-5.x
feat/5-foundry-connect
feat/9-foundry-push-backend
feat/9-foundry-push-module
feat/5-foundry-frontend
feat/5-foundry-backend
feat/5-foundry-module
release/v4.8.0-rc1
docs/d341-convert-draft
feat/958-update-to-version
feat/958-convert-sheet
feat/958-pathbuilder-import-frontend
fix/1360-heading-order
feat/958-pathbuilder-import-backend
feat/11-weekly-digest
feat/1341-auto-update
docs/d332-superseded
chore/1345-names-cleanup
feat/1342-mentioned-pages
feat/1328-recipes
fix/1346-pgdg-key
perf/1247-shared-recording-stream
chore/132-gitleaks-allowlist
release/v4.7.1
spike/foundry-module
release/v4.7.1-rc1
docs/decisions-d332-d337
fix/bot-certifi
chore/release-4.7.0
chore/release-4.7.0-rc4
chore/deps-4.7.0
chore/release-4.7.0-rc3
fix/1280-quote-must-say-it
fix/1257-names-row-squeeze
chore/release-4.7.0-rc2
fix/1245-pg-upgrade-count
chore/release-4.7.0-rc1
feat/1257-names-in-prep
feat/1257-be
feat/1257-fe
feat/1257-rating-fixes
design/1328-fill-it-in
feat/1257-name-splits
fix/1326-redis-503
feat/1280-fact-suggestions
feat/1280-be
feat/1280-fe
design/1280-fact-suggestions
feat/1279-infobox
feat/1279-be
feat/1279-fe
feat/1321-shelf-copies
design/1279-infobox
feat/1243-table-find
feat/1257-who-rated
feat/1243-prep-drawer
feat/1243-sheet-pickers
design/1243-browse-in-place
feat/1315-hotwords-default
feat/1242-system-filters
feat/1257-more-name-styles
feat/506-leg3-hotwords
design/1242-system-filters
fix/1302-packs-polish
feat/1241-rules-library
design/1241-rules-library
feat/1245-postgres-18
integ/4.6.2
fix/1263-map-ui-2
fix/1263-map-server
fix/1263-map-ui-1
fix/1261-editor-link-menu
fix/1229-axe-4.14-name-mismatch
renovate/axllent-mailpit-1.x
renovate/eslint-monorepo
renovate/authlib-1.x
chore/release-4.6.0
chore/release-4.6.0-rc2
fix/460-rc2-screens
fix/460-rc2-server
fix/release-prerelease-exit
chore/release-4.6.0-rc1
feat/125-campaign-templates
feat/126-calendar
feat/1181-pictures-and-files
feat/1190-event-people
integ/4.6.0
feat/1191-line-of-the-night
feat/1200-starter-packs
chore/bot-multidict-and-playwright-group
fix/1202-this-week-answered-count
fix/122-124-leftovers
fix/1178-get-routes-that-write
fix/1203-journeys-check-names
design/125-campaign-templates
feat/126-calendar-engine
design/126-in-world-calendar
fix/1189-cited-stamp-in-range
fix/1189-v4-looser-check
fix/1189-richer-beats
fix/1113-export-bind-lists
fix/1154-release-notes-by-file
chore/release-4.5.0
chore/release-4.5.0-rc12
fix/1135-wiki-markup-as-text
fix/demo-usage-cost-in-window
chore/release-4.5.0-rc11
fix/1121-sheet-consistency
fix/1121-sheet-5e-terms-and-card-hp
copy/1122-busiest-pages
fix/1121-relevant-choices
fix/1121-wiki-create-npc-save-sheet-links
fix/1029-menu-stays-on-screen
docs/prototype-transcript-bin-wording
fix/1023-editor-save-row-back-scroll
fix/1020-search-exact-first
fix/1020-table-prep
fix/1020-shell-wordmark-footer-bell
fix/1020-wiki-article-party
fix/872-admin-kept-until-phone-tables
feat/l13-milestone-level-waiting
fix/1000-1001-bell-older-setup-context
fix/999-pronouns-in-prompts
fix/l19-other-class-feats
fix/1010-transcript-window-ordinary-confirm
docs/d254-d269-decisions
fix/702-member-search
fix/680-transcript-bin
fix/993-unidentified-prompts
fix/841-redis-timeouts
fix/990-binned-not-exported
fix/830-export-prep-shelf
fix/deps-audit-2026-10-01
fix/877-title-reads
fix/798-audio-received-at
build/lane11-17-j7
build/lane11-16-levelup
build/lane11-14-seams
build/lane11-14-seed
build/lane11-15-start
build/lane11-13-old-block-out
fix/980-review-r3
build/lane11-12-block
build/lane11-8-packs
fix/demo-seed-canonical-names
build/lane11-11-hot-half
docs/l11-decisions
build/lane11-7-convert
build/lane11-10-editing
fix/npm-audit-brace-expansion
build/lane11-9-sheet-page
fix/bot-pyjwt
build/lane11-6-content
fix/lane11-rank-names
build/lane11-2b-language
build/lane11-4-js-evaluator
build/lane11-3-server
build/lane11-5a-pf2e
build/lane11-5b-5e
feat/design-admin
build/lane11-2-evaluator
build/lane11-1-sheet-pieces
build/lane11-0-drawing
fix/943-quest-objectives-fk
fix/prepsheet-shelf-flake
fix/945-leftovers
build/demo-gm-copy
fix/901-email-landings
build/lane10-8-journeys
build/demo-seed-lanes-8-10
fix/887-gm-own-confirmation
build/lane9-5-j1-admin
fix/918-audience-click
fix/useasync-overtaken
ci/939-critical-path
test/937-backend-suite-speed
chore/claude-orchestration
fix/924-xp-gm-only
fix/session-stale-poll
docs/decisions-d239-d242
fix/930-pypdf
build/lane8-journeys
build/925-quest-editor
fix/894-private-page-pictures
build/lane8-p4-drafts
build/lane8-p7-map
build/lane8-p6-handouts-rules
fix/wiki-fixture-names
build/lane10-d227-test-usage
fix/rsvp-horizon-test-tuesday
fix/media-volume-owner
build/lane8-p3-editor
fix/912-unidentified-rename
build/lane8-p5-party-quests
build/lane8-handout-takeback
build/lane10-pickers
build/lane8-p2-article
build/lane8-6-map
build/lane10-7b-email-pages
build/lane8-5-handouts
build/lane10-7a-test-the-bot-pages
build/lane8-p1-pages
build/lane8-4-quests
build/lane8-2b-feeds
build/lane8-3-parties
build/lane8-2a-links
build/lane10-5-commands
build/lane9-6-seed
build/lane10-4b-reactions
build/lane9-4d-pages
build/lane9-4c-pages
build/lane10-4a-posts
build/lane10-3-email
fix/891-web-fonts
build/lane9-4b-pages
build/lane10-6-test-the-bot
build/lane10-2-notify-out
build/lane8-1-wiki-text
build/lane9-4a-frame
design/lane10-drawings
fix/j6-budget
fix/j5-phone-flake
fix/869-test-leaks
fix/843-record-start-followups
build/lane7-all
build/lane6-all
build/lane9-b2-server
chore/changelog-fragments
docs/decisions-d218
build/lane9-a-owner-overview
fix/rule-card-level-label
fix/834-retention-semantics
fix/o3c-record-without-announcement
docs/decisions-d179
docs/decisions-d131-d170
fix/851-commit-before-response
build/lane6-j3-seed
build/lane9-b1-d67-identity
fix/841-blocking-loop
build/lane9-c-backups-audit
fix/vote-race-and-start-commit
fix/recording-announcement
fix/proposal-read-leak
fix/last-admin-guard
build/lane6-p4c-planning
build/lane6-p4b-margin
build/lane6-p4a-sheet
build/lane5-j4-seed
build/lane6-base
build/lane7-pages-talk
build/lane5-pages
build/lane7-pages-safety
build/lane7-p3-safety
build/lane7-p2-notify
build/lane6-p3-planning
build/lane6-p2-history
build/lane6-p1b-items
build/lane7-p1-threads
build/lane5-p6-faces
build/lane6-p1a-sheet
build/lane5-p5-find
build/lane5-p4a-board
build/lane5-p4b-scenes
build/lane5-p3-live
build/lane5-base
build/lane5-p2-cards
docs/lane5-decisions
build/review-r2-wide
fix/review-r1
build/lane5-p1-scenes
build/demo-seed
build/lane4-journeys-j5
build/lane4-page-review-b
build/lane4-page-review-a
build/lane4-page-read
build/lane4-journeys
build/lane4-page-sess2
build/lane4-page-sess1
build/lane4-notes
build/lane4-discord-on-approval
build/lane4-scheduling
build/lane4-versions
build/760-session-number
build/lane4-decisions
build/797-erase-no-regenerate
build/test-race-audit
build/lane3-completions
build/794-dark-only
build/796-titles-scroll
build/791-retention-anchor
build/a11y-sweep
build/shell-followups
build/retention-preview
build/753-backup-readback
docs/d91-d93
build/lane3-j1
build/ci-harness-paths-selftest
fix/useauth-test-race
build/ci-harness-paths
build/777-ai-settings-read
build/lane3-settings-c
build/lane3-settings-b
build/lane3-j6
build/lane3-sessionform
build/lane3-settings-a
build/lane3-members
build/lane3-thisweek
build/lane3-story
chore/87-align-python-3.12
v4.8.0-rc1
v4.7.1
v4.7.1-rc1
v4.7.0
v4.7.0-rc4
v4.7.0-rc3
v4.7.0-rc2
v4.7.0-rc1
v4.6.2
v4.6.2-rc4
v4.6.2-rc3
v4.6.2-rc2
v4.6.2-rc1
v4.6.1
v4.6.1-rc1
v4.6.0
v4.6.0-rc2
v4.6.0-rc1
v4.5.3
v4.5.3-rc1
v4.5.2
v4.5.2-rc1
v4.5.1
v4.5.1-rc2
v4.5.1-rc1
v4.5.0
v4.5.0-rc12
v4.5.0-rc11
v4.5.0-rc10
v4.5.0-rc9
v4.5.0-rc8
v4.5.0-rc7
v4.5.0-rc6
v4.5.0-rc5
v4.5.0-rc4
v4.5.0-rc3
v4.5.0-rc2
v4.5.0-rc1
v4.4.1
v4.4.0
v4.3.0
v4.2.3
v4.2.2
v4.2.1
v4.2.0
v4.1.2
v4.1.1
v4.1.0
v4.0.1
v4.0.0
v3.11.4
v3.11.3
v3.11.2
v3.11.1
v3.11.0
v3.10.0
v3.9.1
v3.9.0
v3.8.0
v3.7.0
v3.6.1
v3.6.0
v3.5.0
v3.4.1
v3.4.0
v3.3.0
v3.2.0
v3.1.0
v3.0.0
v2.1.0
v2.0.0
v1.1.0
v1.0.0
v0.12.0
v0.11.0
v0.10.0
v0.9.1
v0.3.3
v0.9.0
v0.8.0
v0.3.2
v0.3.1
v0.3.0
v0.7.0
v0.6.0
v0.5.0
v0.4.0
v0.2.1
v0.2.0
v0.1.1
v0.1.0
Labels
Clear labels
backend
Issue related to the backend
bot
Issue related to the bot
bug
Something is not working
duplicate
This issue or pull request already exists
enhancement
New feature
frontend
Issue related to the frontend
help wanted
Need some help
invalid
Something is wrong
question
More information is needed
recording
Issue related to the recording system
security
Security hardening / vulnerability work
wontfix
This won't be fixed
No labels
backend
bot
bug
duplicate
enhancement
frontend
help wanted
invalid
question
recording
security
wontfix
Milestone
Clear milestone
No items
Projects
Clear projects
No items
No project
Assignees
Clear assignees
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".
No due date set.
Dependencies
No dependencies set
Reference
rbrooks/Quest-Board#367
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Found in the August 2026 session lifecycle review (#319). Not separately audited in the review — filed because the rebuild is the moment it is cheap, and because several findings point at it directly.
Why
The review surfaced accessibility-adjacent problems incidentally rather than by looking for them: touch targets well under any usable minimum throughout, core Session Shelf interactions available only via keyboard with no alternative, disabled states explained only by
title=tooltips (invisible on touch and to screen readers), status conveyed by colour alone in the voting grid, and a "Wiki" control styled exactly like a tab that actually opens a new browser tab.None of that was the audit's focus, so the real state is unknown. That is itself the finding.
What
A genuine pass during the rebuild rather than a retrofit: keyboard navigability of every flow, focus management in modals and after navigation, semantic landmarks and headings, form labelling and error association, colour contrast and non-colour status encoding, screen-reader announcement of async state changes (a summary finishing processing should be announced, not silently swapped in), and honest interactive semantics — a link that opens a new tab should say so.
Set a target standard explicitly rather than leaving it implied.
Acceptance criteria
Addition (owner, 2026-09-15; decision D4 in the surface catalogue, #659): Quest Board gets an accessibility statement page (catalogue surface PUB-10), public and linked from the account menu and the Help pages. It states:
Keep its known-gaps list true to what this pass finds. The catalogue also lists #367's other user-visible requirements under the shared patterns (SH-7): skip link, announcements when async work finishes, status never shown by colour alone, and focus management.
The standard is chosen: WCAG 2.2 AA (build plan §5, 2026-09-21), and it is checked three ways rather than once at the end:
eslint-plugin-jsx-a11yin the frontend lint job, from lane 0 (#364);@axe-core/playwright) on every page a journey visits, inside the journeys suite (#726), so a violation fails the PR that introduced it;What stays for this issue at the end: the manual screen-reader pass of the seven journeys, focus management on modal open and close and on route change (a rule of the
Modaland page components in lane 0), and status announcements for async changes (theBusyandSaveStatecomponents carry live regions). Umbrella: #366.Picking up the automatable part (3 October, while the owner is away). A code audit against comment 42364's standard found these gaps. The manual screen-reader pass and the real-device check stay the owner's.
Fixing now (branch
fix/367-a11y-gaps):TranscriptState.jsxputs the status title outside any live region, so a transcript that finishes or fails is not announced; only the innerBusyis live, and it unmounts. The wrapper becomes the persistentrole=status. This is the very example in this issue's body.PublicFrame(/,/login,/help…,/accessibility,/privacy,/licences,/join/:code,/setup) never callsuseRouteFocus, so client-side navigation there leaves focus where it was.ContentsSheetmoves focus in, restores it and closes on Escape, but does not contain focus: Tab walks into the page behind the scrim. It gets the same containment asModal.Modal. It returns focus to<body>when its trigger was removed while it was open, for example a deleted row's button. It falls back to the page's heading or<main>. Its first-focus selector also skips disabled controls./privacy,/accessibilityand/licences(the j0w loop loads them and never scans them), plus/help, the 404 and/auth-error.Not in this branch. Each needs a render check or the owner:
Map.css:242), and standalone.linkishbuttons have no padding. Both need sizing to at least 24 px, and that changes layout.MapCanvas.jsx:102), so that line may be stale; it needs checking in a browser before rewording.BusyandBanner: whether it is needed is the manual pass's call.First slice merged: PR #1049, 2026-10-03. CI was green twice: on its own base, and again after merging main, since main had changed
AppFrame.jsxin the meantime. All six items from comment 51371 are in:role=statusModalfalls back to the page heading when its opener is gone, and skips disabled controls/help,/auth-errorand the 404Not on dev yet: it lands on dev with the next prerelease. To look at there: the account-menu row, and the focus outline after following a public link.
Second slice under way: axe scans for the routes no journey reaches (campaign settings and prep, wiki map, history, edit, new and the rest, the admin sub-pages, the session edit page,
/profile/plan), with fixes for what they find.Still the owner's: the manual screen-reader pass, the real-device check, and anything whose fix changes layout. That includes the map markers and the standalone
.linkishbuttons.Second slice merged: PR #1050, 2026-10-03, CI green on a head carrying main.
Every route in
App.jsxthat no journey scanned now gets an axe scan. That is 34 campaign, wiki, session, profile and admin pages, in three read-only specs (a11y-campaign-pages,a11y-wiki-pages,a11y-admin-pages), plus the public pages from #1049.The scans found four real violations. All are fixed, and no rule is disabled:
link-in-text-block.textlinkstyle: underlined,--accent-ink.scrollable-region-focusableLeft, for the owner or later:
.tscrollgaps inAdminHealth,AdminNoticesandAdminUsers, if their content overflows. They pass with the seeded data..linkishbuttons).On dev:
v4.5.0-rc2(2026-10-03) carries #1049, #1050 and #1051. #1051 gave the last four admin tables (Health, Notices, Backup, a person's campaigns) the same keyboard-scrollable region the axe pass required on Usage.Dev was deployed from the published images: every service healthy,
/api/metareturns4.5.0-rc2, and no tracebacks since.To look at on dev:
Still the owner's: the screen-reader pass, the real-device check, and the layout-changing fixes listed above.
Owner's answers, 2026-10-04 (Questions page, both as recommended):
Both are being built now. With them, what is left on this issue is the manual screen-reader pass and the real-device check.
D277 and D278 built: PR #1071, merged to main. CI was green on the PR's head.
src/ui/base.css; menus, lists, navigation, cards and buttons are left alone.Left open on this issue
target-sizerule. The statement names it.D287 (the owner's answer to Q159, 2026-10-05), built in PR #1097 and merged. CI was green on the PR's head.
The accessibility statement no longer lists "The map" as a known gap: the owner judged it no longer describes a gap worth listing. Four gaps remain, "Map markers" among them.
Left on this issue, and needing a person: a pass with a screen reader, and a real phone at 375 px.
Reaches dev with the next prerelease.
Moved to v4.7.0 (owner, 17 Oct 2026, closing the v4.5.0 milestone). Built and on prod: links, pressable areas and map markers (#1071), and the accessibility statement as you approved it (Q159). Still needs a person: a screen-reader pass, and a real phone at 375 px. v4.7.0 is the review pass before others run Quest Board, which is where this belongs.