fix(plex): an error over the picture is readable on any frame

The error line kept the theme's red, which a light theme makes dark: 1.6:1 on the 75 % panel over a
white frame. The panel is now black 85 % under media-scope, so the error is the media red in both
themes (5.47:1 at worst, white text too); a contract test measures it on the composited panel.
This commit is contained in:
2026-11-07 22:04:22 +01:00
parent 872b583f06
commit 4d058cba81
3 changed files with 171 additions and 157 deletions
+11
View File
@@ -59,6 +59,17 @@ describe("the media colours", () => {
// accent for what must be seen: a light theme's are dark (#b91c1c 2.8:1, Slate's accent 2.8:1 on
// the chrome). Its error edge and text take the media red, and every focus ring in it — the base
// ring and a field's focus edge both read --focus — the media amber. [WCAG 1.4.11, 1.4.3]
// Text over the picture sits on a black panel the frame shows through: its worst ground is a white
// frame. The error line on it is the media red (a light theme's danger was 1.6:1 there). [WCAG 1.4.3]
it("an error over the picture holds 4.5:1 on its panel over a white frame", () => {
const player = readFileSync(new URL("../modules/plex/PlexPlayer.tsx", import.meta.url), "utf8");
const over = /const OVER_VIDEO =\s*"([^"]+)"/.exec(player)?.[1] ?? "";
expect(over.split(" ")).toContain("media-scope"); // --danger is the media red under it
const alpha = Number(/\bbg-black\/(\d+)\b/.exec(over)?.[1]) / 100;
const ground = mixHex("#000000", "#ffffff", alpha);
expect(hexContrast(media()["media-danger"]!, ground)).toBeGreaterThanOrEqual(4.5);
expect(hexContrast("#ffffff", ground)).toBeGreaterThanOrEqual(4.5);
});
it("a form on the player chrome says an error and a focus in colours that hold there", () => {
expect(hexContrast(media()["media-danger"]!, media()["media-chrome"]!)).toBeGreaterThanOrEqual(
4.5,
+4 -2
View File
@@ -120,8 +120,10 @@ const PLAYER_MENU =
const PLAYER_ROW = "block w-full rounded-lg px-2 py-1.5 text-left hover:bg-white/10";
// Text over the picture (the loading/stall/error overlay, the subtitle notice, the track OSD) sits on
// its own dark panel: bare white or red text was unreadable over a bright frame (measured live on a
// white-lit scene). The shape (pill or panel) is each site's own.
const OVER_VIDEO = "border border-white/15 bg-black/75 text-white shadow-2xl";
// white-lit scene). Black 85 % and `media-scope` (its --danger is the media red) keep the white text
// and an error line over 4.5:1 even on a white frame (theme.contract.test.ts): at 75 % with a light
// theme's dark red the error was 1.6:1. The shape (pill or panel) is each site's own.
const OVER_VIDEO = "media-scope border border-white/15 bg-black/85 text-white shadow-2xl";
// 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.