fix(player): what is chosen on the player chrome is marked amber, not written in the accent

A light theme's accent as text on the always-dark chrome was 2.84:1 (Slate). `--chosen` is the
accent unless a scope names its own; `media-marks` (was media-focus) points it, with the focus
ring, at the media amber. A chosen track stays white with an amber tick (MenuCheck reads
`text-chosen`); a chosen settings tab or toggle is white with an amber underline (MEDIA_CHOSEN).
The theme contract test holds the token, the tick and the player components free of accent text.
This commit is contained in:
2026-10-10 21:56:47 +02:00
parent e1d325b942
commit 8312c6d592
13 changed files with 85 additions and 49 deletions
+10 -13
View File
@@ -113,12 +113,13 @@ const BACK_TO_PREV_S = 3;
// inside the window skips again (the keyboard keeps ← / → at the viewer's own step).
// The player's menus sit on the always-dark media chrome, under white text, in every theme.
const PLAYER_MENU =
"rounded-xl border border-white/15 bg-media-chrome/95 media-focus text-sm text-white shadow-2xl";
"rounded-xl border border-white/15 bg-media-chrome/95 media-marks text-sm text-white shadow-2xl";
const PLAYER_ROW = "block w-full rounded-lg px-2 py-1.5 text-left hover:bg-white/10";
// A track choice: the chosen one wears the tick in the leading slot (DESIGN "one of several"), which
// the highlight's white text cannot wash out the way it did the accent-coloured label.
// A track choice: white like the rest, the chosen one marked by the tick in the leading slot (DESIGN
// "one of several"), which `media-marks` paints the media amber — a light theme's accent as the
// label's colour was dark on the chrome (Slate 2.84:1), and the highlight's white washed it out.
const TRACK_ROW =
"flex w-full min-h-9 items-center gap-2 rounded-lg px-2 py-1.5 text-left hover:bg-white/10";
"flex w-full min-h-9 items-center gap-2 rounded-lg px-2 py-1.5 text-left text-white hover:bg-white/10";
const TAP_SKIP_S = 10;
const DOUBLE_TAP_MS = 300;
@@ -1191,7 +1192,7 @@ export default function PlexPlayer({ itemId, onClose, queue, fromStart = false }
return createPortal(
<div
ref={wrapRef}
className="media-focus fixed left-0 top-0 z-overlay bg-black flex items-center justify-center select-none"
className="media-marks fixed left-0 top-0 z-overlay bg-black flex items-center justify-center select-none"
onPointerDown={(e) => {
pointerRef.current = e.pointerType;
}}
@@ -1677,9 +1678,7 @@ export default function PlexPlayer({ itemId, onClose, queue, fromStart = false }
checked={(audioOrd ?? 0) === a.ord}
label={audioName(a)}
onSelect={() => changeAudio(a.ord)}
className={`${TRACK_ROW} ${
(audioOrd ?? 0) === a.ord ? "text-accent" : "text-white"
}`}
className={TRACK_ROW}
>
<MenuCheck kind="one" on={(audioOrd ?? 0) === a.ord} />
<span className="truncate">{audioName(a)}</span>
@@ -1696,7 +1695,7 @@ export default function PlexPlayer({ itemId, onClose, queue, fromStart = false }
checked={subOrd == null}
label={t("plex.player.subOff")}
onSelect={() => changeSubtitle(null)}
className={`${TRACK_ROW} ${subOrd == null ? "text-accent" : "text-white"}`}
className={TRACK_ROW}
>
<MenuCheck kind="one" on={subOrd == null} />
<span className="truncate">{t("plex.player.subOff")}</span>
@@ -1709,9 +1708,7 @@ export default function PlexPlayer({ itemId, onClose, queue, fromStart = false }
checked={subOrd === sub.ord}
label={subtitleName(sub)}
onSelect={() => changeSubtitle(sub.ord)}
className={`${TRACK_ROW} ${
subOrd === sub.ord ? "text-accent" : "text-white"
}`}
className={TRACK_ROW}
>
<MenuCheck kind="one" on={subOrd === sub.ord} />
<span className="truncate">{subtitleName(sub)}</span>
@@ -1840,7 +1837,7 @@ export default function PlexPlayer({ itemId, onClose, queue, fromStart = false }
}}
>
<div
className="my-auto w-full max-w-3xl rounded-2xl border border-white/15 bg-media-chrome/95 media-focus shadow-2xl"
className="my-auto w-full max-w-3xl rounded-2xl border border-white/15 bg-media-chrome/95 media-marks shadow-2xl"
onClick={(e) => e.stopPropagation()}
>
<Suspense fallback={null}>