Batch of accessibility and touch fixes from the audit

- Esc closes whichever panel a card has open and returns focus to the cell that
  owns it; opening a confirm row moves focus to its primary button, so the
  announcement is deterministic and tab order stays inside the confirm.
- The inline error scrolls itself into view and no longer self-destructs after
  5s: this reader gets interrupted mid-tap, and an expiring notice left a failed
  write with no trace at all. It clears on the next request from that card.
- Every tab clears 44px wide (All was 15.25); desktop action cells go 40 -> 44.
- login.html's error gets role="alert".
- The card monogram carries its own aria-hidden — Chromium exposes it through
  the cover link's, because that link is programmatically focusable.
- The busy bar ends its travel flush with the card edge, so .card.htmx-request
  no longer needs overflow: hidden and cannot clip a panel mid-request.

Verified at 390 and 1280 in both themes; detector over templates+static reports
only the two known Instrument Serif false positives.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-30 19:14:59 +07:00
parent 264cf21960
commit f22db44c35
4 changed files with 48 additions and 11 deletions
+4 -1
View File
@@ -7,7 +7,10 @@
<a class="cover" href="{{.ContinueURL}}" target="_blank" rel="noopener noreferrer"
tabindex="-1" aria-hidden="true">
{{if .Cover}}<img src="{{.Cover}}" alt="" loading="lazy">
{{else}}<span class="monogram">{{.Initial}}</span>{{end}}
{{/* aria-hidden on the cover link is not enough — Chromium still exposes
the letter because the link is programmatically focusable — so the
monogram carries its own, same as the recent strip's. */}}
{{else}}<span class="monogram" aria-hidden="true">{{.Initial}}</span>{{end}}
{{if and (eq .Status "reading") .HasNewChapter}}<span class="foot-rule"></span>
{{else if .Favorite}}<span class="foot-rule brass"></span>{{end}}
</a>