From 6384e5ec62bab711cea0902c541c2e949f8da70a Mon Sep 17 00:00:00 2001 From: Owen McGirr Date: Fri, 25 Sep 2026 11:40:43 +0100 Subject: [PATCH 1/3] Keep toggles and colour swatches visible under forced colours A dark mode and forced-colours pass over every view found two controls that forced colours erased: toggle tracks and knobs are drawn only with backgrounds, so they vanished, and every colour swatch and the highlight sample flattened to the same empty shape. Toggles now draw with system colours, including checked and disabled states, and swatches keep their real colours because the colour is the choice being made. Closes #890 Co-Authored-By: Claude Opus 5.5 (1M context) --- src/ui/app.css | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/ui/app.css b/src/ui/app.css index f379afcd..9e3253e0 100644 --- a/src/ui/app.css +++ b/src/ui/app.css @@ -603,10 +603,22 @@ fieldset:disabled :is(.color-options, .scanner-colours) label:not(:has(input:che .btn { transition: none; } } +/* Forced colours flatten backgrounds, which would erase the toggle track and + knob and turn every colour swatch into the same empty circle. Draw the + toggle with system colours, and let swatches and the highlight sample keep + their real colours, since the colour is the choice being made. */ @media (forced-colors: active) { .btn.nav-button[data-active="true"] { outline: 2px solid Highlight; outline-offset: -2px; } /* Focus must still read as focus on the current page's own button. */ .btn.nav-button[data-active="true"]:focus-visible { outline: 3px solid CanvasText; outline-offset: 3px; } + .toggle, .toggle::after { forced-color-adjust: none; } + .toggle { border: 2px solid CanvasText; background: Canvas; } + .toggle::after { top: 1px; left: 1px; background: CanvasText; } + .toggle-row input:checked + .toggle { border-color: Highlight; background: Highlight; } + .toggle-row input:checked + .toggle::after { background: HighlightText; } + .toggle-row[data-disabled="true"] .toggle { border-color: GrayText; } + .toggle-row[data-disabled="true"] .toggle::after { background: GrayText; } + .color-swatch, .scanner-sample { forced-color-adjust: none; } } /* --- Responsive --------------------------------------------------------------- */ From b3d5d283d1ecc9daf5972e5dad54ba3ee0038b29 Mon Sep 17 00:00:00 2001 From: Owen McGirr Date: Fri, 25 Sep 2026 11:54:45 +0100 Subject: [PATCH 2/3] Close the remaining forced-colours gaps Disabled toggles now look disabled whether checked or not, and toggle focus uses CanvasText instead of the page's blue. Swatches get a CanvasText edge so white and yellow stay visible on a light Canvas, the chosen colour chip and selected practice block are marked with Highlight, and the setup step rail is drawn with system colours. Co-Authored-By: Claude Opus 5.5 (1M context) --- src/ui/app.css | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/ui/app.css b/src/ui/app.css index 9e3253e0..b9158923 100644 --- a/src/ui/app.css +++ b/src/ui/app.css @@ -616,9 +616,21 @@ fieldset:disabled :is(.color-options, .scanner-colours) label:not(:has(input:che .toggle::after { top: 1px; left: 1px; background: CanvasText; } .toggle-row input:checked + .toggle { border-color: Highlight; background: Highlight; } .toggle-row input:checked + .toggle::after { background: HighlightText; } - .toggle-row[data-disabled="true"] .toggle { border-color: GrayText; } - .toggle-row[data-disabled="true"] .toggle::after { background: GrayText; } + /* Same specificity as the checked rules and later, so disabled wins. */ + .toggle-row[data-disabled="true"] input + .toggle { border-color: GrayText; background: Canvas; } + .toggle-row[data-disabled="true"] input + .toggle::after { background: GrayText; } + .toggle-row[data-disabled="true"] input:checked + .toggle { background: GrayText; } + .toggle-row[data-disabled="true"] input:checked + .toggle::after { background: Canvas; } + /* Opting out of forced colours would also keep the page's focus blue. */ + .toggle-row input:focus-visible + .toggle { outline-color: CanvasText; } .color-swatch, .scanner-sample { forced-color-adjust: none; } + /* A white or yellow swatch would vanish on a light Canvas without an edge. */ + .color-swatch { border: 2px solid CanvasText; } + .color-options label:has(input:checked), .scanner-colours label:has(input:checked) { border-color: Highlight; } + .switch-practice-blocks li[data-selected="true"] { border: 4px solid Highlight; } + /* The step rail is drawn with backgrounds only. */ + .setup-progress span { forced-color-adjust: none; background: GrayText; } + .setup-progress span[data-active="true"] { background: Highlight; } } /* --- Responsive --------------------------------------------------------------- */ From 40c75cca6a668789f1b9e158cefa0cd359fc4df0 Mon Sep 17 00:00:00 2001 From: Owen McGirr Date: Fri, 25 Sep 2026 12:01:40 +0100 Subject: [PATCH 3/3] Give the white swatch the same high-contrast edge in dark themes Co-Authored-By: Claude Opus 5.5 (1M context) --- src/ui/app.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/app.css b/src/ui/app.css index b9158923..7bca89db 100644 --- a/src/ui/app.css +++ b/src/ui/app.css @@ -625,7 +625,7 @@ fieldset:disabled :is(.color-options, .scanner-colours) label:not(:has(input:che .toggle-row input:focus-visible + .toggle { outline-color: CanvasText; } .color-swatch, .scanner-sample { forced-color-adjust: none; } /* A white or yellow swatch would vanish on a light Canvas without an edge. */ - .color-swatch { border: 2px solid CanvasText; } + .color-swatch, .color-swatch.white { border: 2px solid CanvasText; } .color-options label:has(input:checked), .scanner-colours label:has(input:checked) { border-color: Highlight; } .switch-practice-blocks li[data-selected="true"] { border: 4px solid Highlight; } /* The step rail is drawn with backgrounds only. */