Fix the accessibility findings from the audit
Contrast: --mute-2 and --trash both failed AA in both themes — every 10px mono label (recent chapter, section headings, chapter hint) sat between 2.5:1 and 3.7:1, and the trash icon, the one irreversible control, was the least visible thing in the strip. Retuned per theme: labels now 4.8-5.2:1, trash 4.3-4.5:1 against a 3:1 requirement. Focus: the search input clears its own outline and the underline lives on the parent, so :focus-within on .searchbar carries the ring. The inline error slot gets role=status, so a failed write is announced rather than looking like an ignored tap. The tab strip drops role=tablist/tab: these are real links that change the URL, and the roles promised a tabpanel contract that was never implemented, leaving aria-selected unset on every one. aria-current carries the state instead. prefers-reduced-motion now names pseudo-elements — `*` does not match them, so the busy bar and the error dot, both ::before, kept animating for the users who asked them not to. Log out was a 54x15 target; an ::after pad makes it 78x45 without moving the label. Also: the two dark-tuned hex borders in the desktop block become theme-aware tokens, and the preload swaps mono for DM Sans, the larger face and the one the body text needs. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -8,7 +8,9 @@
|
||||
<title>mangaBookmark</title>
|
||||
<link rel="stylesheet" href="/static/style.css">
|
||||
<link rel="preload" href="/static/fonts/instrument-serif-400-latin.woff2" as="font" type="font/woff2" crossorigin>
|
||||
<link rel="preload" href="/static/fonts/ibm-plex-mono-500-latin.woff2" as="font" type="font/woff2" crossorigin>
|
||||
{{/* Body text before meta lines: DM Sans is the biggest face and the one
|
||||
most of the page is set in; the mono is small and arrives from CSS. */}}
|
||||
<link rel="preload" href="/static/fonts/dm-sans-var-latin.woff2" as="font" type="font/woff2" crossorigin>
|
||||
<script src="/static/htmx.min.js" defer></script>
|
||||
<script src="/static/filter.js" defer></script>
|
||||
</head>
|
||||
@@ -31,21 +33,29 @@
|
||||
autocomplete="off" aria-label="Search titles">
|
||||
</div>
|
||||
|
||||
<nav class="tabs" role="tablist">
|
||||
<a role="tab" href="/?tab=all" class="{{if eq .Tab "all"}}active{{end}}"
|
||||
{{/* These are real links with real hrefs that change the URL, so they are
|
||||
navigation, not an ARIA tablist — aria-current carries "which bucket am
|
||||
I in" without owing a tabpanel contract we do not implement. */}}
|
||||
<nav class="tabs" aria-label="Bookmark buckets">
|
||||
<a href="/?tab=all" class="{{if eq .Tab "all"}}active{{end}}"
|
||||
{{if eq .Tab "all"}}aria-current="page"{{end}}
|
||||
hx-get="/ui/list?tab=all" hx-target="#list" hx-swap="innerHTML"
|
||||
hx-push-url="/?tab=all" hx-on::after-request="setActiveTab(this)">All</a>
|
||||
<a role="tab" href="/?tab=new" class="tab-new {{if eq .Tab "new"}}active{{end}}"
|
||||
<a href="/?tab=new" class="tab-new {{if eq .Tab "new"}}active{{end}}"
|
||||
{{if eq .Tab "new"}}aria-current="page"{{end}}
|
||||
hx-get="/ui/list?tab=new" hx-target="#list" hx-swap="innerHTML"
|
||||
hx-push-url="/?tab=new" hx-on::after-request="setActiveTab(this)">Updated{{if .NewCount}}
|
||||
<span class="count">{{.NewCount}}</span>{{end}}</a>
|
||||
<a role="tab" href="/?tab=fav" class="{{if eq .Tab "fav"}}active{{end}}"
|
||||
<a href="/?tab=fav" class="{{if eq .Tab "fav"}}active{{end}}"
|
||||
{{if eq .Tab "fav"}}aria-current="page"{{end}}
|
||||
hx-get="/ui/list?tab=fav" hx-target="#list" hx-swap="innerHTML"
|
||||
hx-push-url="/?tab=fav" hx-on::after-request="setActiveTab(this)">Favourites</a>
|
||||
<a role="tab" href="/?tab=archived" class="{{if eq .Tab "archived"}}active{{end}}"
|
||||
<a href="/?tab=archived" class="{{if eq .Tab "archived"}}active{{end}}"
|
||||
{{if eq .Tab "archived"}}aria-current="page"{{end}}
|
||||
hx-get="/ui/list?tab=archived" hx-target="#list" hx-swap="innerHTML"
|
||||
hx-push-url="/?tab=archived" hx-on::after-request="setActiveTab(this)">Archived</a>
|
||||
<a role="tab" href="/?tab=finished" class="{{if eq .Tab "finished"}}active{{end}}"
|
||||
<a href="/?tab=finished" class="{{if eq .Tab "finished"}}active{{end}}"
|
||||
{{if eq .Tab "finished"}}aria-current="page"{{end}}
|
||||
hx-get="/ui/list?tab=finished" hx-target="#list" hx-swap="innerHTML"
|
||||
hx-push-url="/?tab=finished" hx-on::after-request="setActiveTab(this)">Finished</a>
|
||||
</nav>
|
||||
|
||||
@@ -131,6 +131,8 @@
|
||||
<button type="button" onclick="toggleConfirmRow('{{.Key}}', 'remove')">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
<p class="error-inline" hidden></p>
|
||||
{{/* role=status announces a failed write; without it the tap just looks
|
||||
ignored to a screen reader. */}}
|
||||
<p class="error-inline" role="status" hidden></p>
|
||||
</article>
|
||||
{{end}}
|
||||
|
||||
Reference in New Issue
Block a user