From 205f18a2e1c3e1ff58d0ecccafce72a843752833 Mon Sep 17 00:00:00 2001 From: npeter83 Date: Sat, 8 Aug 2026 09:28:23 +0200 Subject: [PATCH] fix(a11y): address R9 code-review findings (glass shadow, focus dedup) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - #1: remove the 9 dead `shadow-*` from glass surfaces instead of letting them override the tuned glass box-shadow. The @layer components move made a JSX shadow-* win AND atomically drop the glass inset top-edge highlight; deleting the (always-dead) utilities keeps the intended glass depth incl. the inset sheen. Verified in-browser: a .glass box-shadow again includes its inset segment. - #3: drop the per-element focus-visible outlines from the rail chrome buttons and SavedViews action buttons — the global button:focus-visible fallback already draws the identical 2px accent ring, so they were redundant. Verified: the pin button rings from the global rule alone. - #5: unify the focus-within outline offset (offset-2) on the SearchBar and ShareDialog pills. - #2 (double outline on the pill when an inner button is focused): NOT fixed — the clean fix (has-[input:focus] so only the input rings the pill) does not generate under Tailwind v4 (measured: no rule emitted). Kept the working focus-within, which is a11y-correct (every element still shows a focus indicator); the overlapping ring is an accepted cosmetic edge-case. - #4 (weak ring on solid-fill selected items): deferred to R10 with the selected-paint tokenisation. Gate green (tsc/eslint/prettier/knip/vitest 79). --- frontend/src/components/AddToPlaylist.tsx | 2 +- frontend/src/components/BackToTop.tsx | 2 +- frontend/src/components/ChatDock.tsx | 2 +- frontend/src/components/DownloadCenter.tsx | 2 +- frontend/src/components/GlassTuner.tsx | 2 +- frontend/src/components/Modal.tsx | 4 +--- frontend/src/components/NavSidebar.tsx | 8 ++++---- frontend/src/components/PlayerModal.tsx | 2 +- frontend/src/components/SavedViewsWidget.tsx | 12 ++++++------ frontend/src/components/SearchBar.tsx | 2 +- frontend/src/components/ShareDialog.tsx | 2 +- frontend/src/components/ui/DraftSaveBar.tsx | 2 +- frontend/src/index.css | 9 +++++---- 13 files changed, 25 insertions(+), 26 deletions(-) diff --git a/frontend/src/components/AddToPlaylist.tsx b/frontend/src/components/AddToPlaylist.tsx index 7e3a548d..0cfc74c2 100644 --- a/frontend/src/components/AddToPlaylist.tsx +++ b/frontend/src/components/AddToPlaylist.tsx @@ -98,7 +98,7 @@ export default function AddToPlaylist({ - + {/* A React portal still propagates events up the REACT tree, so a click inside this panel would otherwise reach the feed card that hosts the trigger and start playback. */}
e.stopPropagation()}> diff --git a/frontend/src/components/BackToTop.tsx b/frontend/src/components/BackToTop.tsx index 8a888244..ec9ff758 100644 --- a/frontend/src/components/BackToTop.tsx +++ b/frontend/src/components/BackToTop.tsx @@ -51,7 +51,7 @@ export default function BackToTop({ dep, threshold = 600 }: { dep?: unknown; thr return createPortal( @@ -290,7 +290,7 @@ export default function NavSidebar({ onClick={onOpenAbout} title={t("header.account.about")} aria-label={t("header.account.about")} - className="p-2 rounded-lg text-muted hover:text-fg hover:bg-card transition outline-hidden focus-visible:outline-2 focus-visible:outline-accent/60" + className="p-2 rounded-lg text-muted hover:text-fg hover:bg-card transition" > @@ -298,7 +298,7 @@ export default function NavSidebar({ onClick={logout} title={t("header.account.signOut")} aria-label={t("header.account.signOut")} - className="p-2 rounded-lg text-muted hover:text-fg hover:bg-card transition outline-hidden focus-visible:outline-2 focus-visible:outline-accent/60" + className="p-2 rounded-lg text-muted hover:text-fg hover:bg-card transition" > diff --git a/frontend/src/components/PlayerModal.tsx b/frontend/src/components/PlayerModal.tsx index 6187ec42..f429e7d3 100644 --- a/frontend/src/components/PlayerModal.tsx +++ b/frontend/src/components/PlayerModal.tsx @@ -916,7 +916,7 @@ export default function PlayerModal({
e.stopPropagation()} >
@@ -296,7 +296,7 @@ function ViewRow({ onClick={onApply} title={t("views.apply")} aria-current={active ? "true" : undefined} - className={`flex-1 min-w-0 text-left text-xs py-1 truncate rounded-sm outline-hidden focus-visible:outline-2 focus-visible:outline-accent/60 ${ + className={`flex-1 min-w-0 text-left text-xs py-1 truncate ${ active ? "text-accent font-medium" : "text-fg" }`} > @@ -306,7 +306,7 @@ function ViewRow({ diff --git a/frontend/src/components/SearchBar.tsx b/frontend/src/components/SearchBar.tsx index 2694d3bb..aa4f1af7 100644 --- a/frontend/src/components/SearchBar.tsx +++ b/frontend/src/components/SearchBar.tsx @@ -31,7 +31,7 @@ export default function SearchBar({ if (onGo && !goDisabled) onGo(); }; return ( -
+
{open && filtered.length > 0 && ( -
+
{filtered.map((u) => (