9cb9b51b41
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>