From e1579177972b2acf6ede5b1412b95b8a070eaced Mon Sep 17 00:00:00 2001 From: Miguel Palhas Date: Tue, 25 Aug 2026 18:27:17 +0100 Subject: [PATCH] fix(web): show available state as a check glyph Co-Authored-By: Claude Sonnet 5 --- DESIGN.md | 8 ++++++++ web/src/icons.ts | 1 + web/src/main.ts | 14 +++++++++++++- 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/DESIGN.md b/DESIGN.md index 5752878..9c2eae5 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -174,6 +174,14 @@ not yet found, violet (`--status-airing`) for downloading, neutral for untracked. The word stays present in every chip, so state survives with colour removed. +**Amendment (#253):** a drawn check glyph is a shape, not only a hue, so it +survives the same greyscale read a word does — `mediaStateChip`'s `available` +state is a check glyph instead of the word, word kept in the chip's +`aria-label`. The word-stays-present rule otherwise stands as written, for +every chip whose state is a word with no unambiguous glyph — which is every +status chip this section lists. The exception is scoped to `mediaStateChip`, +not to the derived-status chips above. + Season 0 is invisible to all of it: derived status ignores season 0 episodes entirely, so a manually wanted special cannot pin a series at `incomplete` or hold back `ended`. The accepted consequence is that specials are visible and diff --git a/web/src/icons.ts b/web/src/icons.ts index 4c6cfd4..0eb84a9 100644 --- a/web/src/icons.ts +++ b/web/src/icons.ts @@ -28,6 +28,7 @@ const ICON_PATHS = { "M10.8 3.1l.7 1.7 1.7.7-1.7.7-.7 1.7-.7-1.7-1.7-.7 1.7-.7z", ], warning: ["M8 1.8l6.2 11H1.8z", "M8 5.3v3.4M8 11.2h.01"], + check: ["M3.2 8.4l3 3 6.6-6.8"], } as const; /** Stroke glyph on the shared 16-grid; the control's aria-label carries the meaning. */ diff --git a/web/src/main.ts b/web/src/main.ts index ecf8625..55899ea 100644 --- a/web/src/main.ts +++ b/web/src/main.ts @@ -746,8 +746,20 @@ function chip(text: string, extra?: (chip: HTMLSpanElement) => void): HTMLSpanEl return span; } -/** §4.2 state ramp on a media-state chip; the word carries, colour accelerates. */ +/** + * §4.2 state ramp on a media-state chip. `available` is a drawn check glyph — + * a shape, not only a hue, so it still reads greyscale — with the word kept + * as the chip's aria-label; every other state keeps the word on the chip. + */ function mediaStateChip(state: string, wanted: boolean): HTMLSpanElement { + if (state === "available") { + return chip("", (span) => { + span.replaceChildren(icon("check")); + span.setAttribute("aria-label", state); + span.dataset.movieState = state; + span.dataset.wanted = String(wanted); + }); + } return chip(state, (span) => { span.dataset.movieState = state; span.dataset.wanted = String(wanted);