fix(a11y): address R9 code-review findings (glass shadow, focus dedup)

- #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).
This commit is contained in:
2026-08-08 09:28:23 +02:00
parent c11e2822e9
commit 205f18a2e1
13 changed files with 25 additions and 26 deletions
+6 -6
View File
@@ -288,7 +288,7 @@ function ViewRow({
{...attributes}
{...listeners}
title={t("views.reorder")}
className="p-1 text-muted/60 hover:text-muted cursor-grab touch-none shrink-0 rounded-sm outline-hidden focus-visible:outline-2 focus-visible:outline-accent/60"
className="p-1 text-muted/60 hover:text-muted cursor-grab touch-none shrink-0"
>
<GripVertical className="w-3.5 h-3.5" />
</button>
@@ -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({
<button
onClick={onToggleDefault}
title={view.is_default ? t("views.isDefault") : t("views.makeDefault")}
className={`p-1 rounded outline-hidden transition focus-visible:outline-2 focus-visible:outline-accent/60 ${
className={`p-1 rounded transition ${
view.is_default
? "text-accent"
: "text-muted opacity-0 group-hover:opacity-100 group-focus-within:opacity-100 hover:text-accent"
@@ -317,21 +317,21 @@ function ViewRow({
<button
onClick={onShare}
title={t("views.share")}
className="p-1 rounded-sm text-muted opacity-0 group-hover:opacity-100 group-focus-within:opacity-100 hover:text-fg transition outline-hidden focus-visible:outline-2 focus-visible:outline-accent/60"
className="p-1 rounded-sm text-muted opacity-0 group-hover:opacity-100 group-focus-within:opacity-100 hover:text-fg transition"
>
<Share2 className="w-3.5 h-3.5" />
</button>
<button
onClick={onStartRename}
title={t("views.rename")}
className="p-1 rounded-sm text-muted opacity-0 group-hover:opacity-100 group-focus-within:opacity-100 hover:text-fg transition outline-hidden focus-visible:outline-2 focus-visible:outline-accent/60"
className="p-1 rounded-sm text-muted opacity-0 group-hover:opacity-100 group-focus-within:opacity-100 hover:text-fg transition"
>
<Pencil className="w-3.5 h-3.5" />
</button>
<button
onClick={onDelete}
title={t("views.delete")}
className="p-1 rounded-sm text-muted opacity-0 group-hover:opacity-100 group-focus-within:opacity-100 hover:text-red-400 transition outline-hidden focus-visible:outline-2 focus-visible:outline-accent/60"
className="p-1 rounded-sm text-muted opacity-0 group-hover:opacity-100 group-focus-within:opacity-100 hover:text-red-400 transition"
>
<Trash2 className="w-3.5 h-3.5" />
</button>