Accessibility baseline: no headings, div buttons, sub-AA contrast #102
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?
Severity: MEDIUM
The problem
docs/circa-ui-spec.md§12 commits to semantic labels, contrast, and keyboard operability "fromthe start." The current baseline:
h1-h6elements in the entire application.card-title,page-title, andlogin-titleare all divs or spans.PhotoBrowserPage.tsx:27-28,64-75usesdiv role="button"with Enter-onlyhandling and no Space support.
ReviewWorkspacePage.tsx:510-523has norole="tab"oraria-selected.colour; the rescan flag uses a bare glyph and colour.
--text-muted#8c857a on #fffdf9 is about 3.6:1; the pending badge#8a7a1a on #faf5d0 is about 3.9:1. Both fail AA's 4.5:1, at small sizes.
font-size: 14pxmakes.badgeand.text-xs0.75rem = 10.5px.:focus-visiblestyling on buttons — browser default only.Why now
None of this blocks a sighted mouse user today. But every month of new UI built on a heading-free,
div-button foundation raises the retrofit cost, and #45's keyboard work will land on whatever focus
semantics exist at that point. The surface is currently five pages — this is the cheapest it will
ever be.
Scope
<button>and<Link>for tiles and filter rows. ALinkon photo tiles also restoresmiddle-click and open-in-new-tab for free.
aria-pressedon the front/back toggle; proper tab ARIA.--text-mutedto around #6f6a5e and fix the yellow badge pair.:focus-visiblering using--accent.Done when
References
frontend/src/pages/PhotoBrowserPage.tsx:27-28,64-75frontend/src/pages/ReviewWorkspacePage.tsx:510-523frontend/src/styles.css(tokens at :6-44)docs/circa-ui-spec.md§12Done in
afdafdd, alongside #97, #103 and #104. CI run #59 green.Done when:
The proposed
--text-mutedvalue does not work, and this is the finding worth keeping. The issue suggests darkening#8c857ato "around#6f6a5e". Measured against every ground it actually appears on:#6f6a5e#68635a--bg-panel#fffdf9--bg-card#faf7f2--bg-app#f3f0e8--bg-rail#e6dfd2It clears AA on three grounds and fails on the nav rail, which is the darkest surface in the application and the one the proposal was not checked against.
#68635ais the minimum darkening that clears 4.5:1 on all four while holding hue and saturation constant.The original was worse than the issue states, too:
#8c857aon the rail is 2.76:1, below even the 3:1 floor for large text.--orange(3.61) and--yellow(3.78) were corrected the same way, to#a15d17and#7c6d17. The badges needed separate values again, because they sit on their own tints rather than on the page: pending 3.90 → 4.51, needs review 3.54 → 4.51, approved 4.35 → 4.52. Disputed already passed at 4.60 and was left alone. Badge text went 10.5px → 13px.Everything else in scope: real
h1/h2elements where the application had zero headings; the status filter rows became real<button>s (so Space works, which the Enter-only handler never did); photo tiles became<Link>s, which restores middle-click and open-in-new-tab — a reviewer comparing two prints can now put them side by side, which was impossible before; evidence rows added in #96 became real buttons too;role="tablist"/role="tab"/aria-selected/role="tabpanel"; and a single:focus-visiblerule covering every focusable element, where only form inputs had one.Two honest deviations.
There is no
h3. The only candidate was the notes revision list, and anh3there would read in the outline as a child ofTools— the lasth2before the tab strip — because a tab label is not a heading. A shallow-but-correct outline beat a deeper wrong one. If a third level is wanted, the clean way is to give the tabbed region its ownh2.No
aria-pressedon the rescan button. Its accessible name already flips between "Flag Rescan" and "Clear Rescan", so a pressed state announces the same fact twice and contradicts it once. The front/back toggle keeps stable names, soaria-pressedis correct there and is applied. The rescan flag also already had visible text — the colour-alone part was real and the glyph is nowaria-hidden, with the words carrying the meaning.Still open, flagged not fixed: superseded evidence is distinguished by 40% opacity alone. Same family as "no status by colour alone", not named in this issue, and fixing it means new copy on the row. Worth its own issue.