From 8e8a142465b0d51c2acf6f83361514d26d63d4d4 Mon Sep 17 00:00:00 2001 From: Bernardo Magri Date: Sat, 18 Jul 2026 13:27:43 +0100 Subject: [PATCH] =?UTF-8?q?fix(themes):=20light=20themes=20=E2=80=94=20rea?= =?UTF-8?q?dable=20inactive=20workspaces=20+=20notification=20hover?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two hardware-reported contrast bugs, both the same family: surfaces that fell back to something designed on dark. 1. Inactive workspace numbers unreadable on every light theme. - Generated bar: the @muted dim role is floor-gated at only 2.0:1 — fine as "dim" on dark, washed out at number size on light. Light mode now promotes inactive buttons to @subtext (3.0 floor, typically 4-7:1); dark themes keep @muted. - boreal-dawn + kiln-clay whole-swaps: same @muted -> @subtext (6.4:1 / 6.6:1). - summer-day whole-swap: had NO button color rule at all — the container's @fg does not inherit into GTK buttons, so the numbers took the GTK default over the cream chip. Explicit @fg_dim (= the palette's subtext, 4.0:1) added. - executive-ivory already used @subtext; untouched. 2. Notification popup unreadable on hover (bg turns dark, text stays dark). Root cause found by probing, not guessing: the popup body is one big GTK button (.notification-default-action) and swaync's DEFAULT stylesheet — still loaded under our style.css — hovers it to rgb(56,56,56). Our sheet never overrode that node (only the control-center row), so the default bled through; on light themes dark @text sat on it. Now the body + action buttons + close button are re-pinned to the palette's alpha(@text) tint construction — mode-proof by construction. The first fix attempt (row-level hover) was probed, SHOWN insufficient, and replaced. Verification: V2. nix flake check --no-build, theme-wholeswap, theme-contrast green. §3 evidence viewed: a purpose-built VM hover probe under summer-day (notify-send -u critical, cursor parked ON the popup, screenshot) — before: dark card, drowned text (reproduces the report exactly, /nix/store/q1qf67fl...notify-shot-summer-day); after: cream card + faint tint, fully readable (shot-notify2). Bar renders verified under catppuccin-latte (generated light path incl. the mode branch) and summer-day (edited whole-swap). An inactive-number visual needs two live workspaces — VM shows one — so the on-hardware confirmation is queued (HARDWARE-QUEUE light-theme refits entry); the ratio change itself is machine-checked. Bookkeeping riding along: BACKLOG #152 deleted (shipped in d79ad35). Co-Authored-By: Claude Fable 5 --- agent/BACKLOG.md | 18 ---------------- agent/HARDWARE-QUEUE.md | 8 +++++++ modules/home/swaync.nix | 39 +++++++++++++++++++++++++++++++++-- modules/home/waybar.nix | 12 ++++++----- themes/boreal-dawn/waybar.css | 4 +++- themes/kiln-clay/waybar.css | 4 +++- themes/summer-day/waybar.css | 9 ++++++++ 7 files changed, 67 insertions(+), 27 deletions(-) diff --git a/agent/BACKLOG.md b/agent/BACKLOG.md index 4bef0ff..17c293b 100644 --- a/agent/BACKLOG.md +++ b/agent/BACKLOG.md @@ -33,24 +33,6 @@ flake pin are different root causes even when they show up on the same machine. ## NEXT -### 152. Generated waybar polish: bar height vs workspace highlighter, right-edge icon spacing - -Bernardo, 2026-07-17. Two visual fixes to the **generated** bar (the one -every theme without a `waybar.jsonc`/`waybar.css` whole-swap gets — the -4 whole-swap themes are out of scope unless the parity rule drags them in): -- **Bar height:** make the bar a bit taller so the selected-workspace - highlighter no longer renders taller than the bar itself (today it - visually overflows/clips the bar edge). -- **Right-module spacing:** the icon distances on the right cluster look - uneven — e.g. the power button sits too close to the screen edge; give - the cluster consistent inter-icon spacing and sane end padding. - -This is §3 visual-protocol work (agent/THEME-DESIGN.md + VERIFICATION §3): -before/after screenshots, two themes (one generated palette + one -whole-swap for the no-regression side), scripted checks first, actually -view the captures. Waybar CSS ↔ tray-menu gotchas in agent/MEMORY.md -apply (never scope `*`). - ### 151. `[human]` v1 launch plan — devise with Bernardo (includes the GitHub move) Bernardo, 2026-07-17: before tagging v1, sit down and devise the launch plan. diff --git a/agent/HARDWARE-QUEUE.md b/agent/HARDWARE-QUEUE.md index 41adc82..acd6551 100644 --- a/agent/HARDWARE-QUEUE.md +++ b/agent/HARDWARE-QUEUE.md @@ -42,6 +42,14 @@ Everything else below stays open; order is convenience, not a gate. four (the `*`-reset counter-rules). If a VM-rendered preview looks off in the theme-picker grid next to the hardware-captured ones, recapture that preview on hardware into themes//preview.png. +- [ ] **Light-theme contrast refits (2026-07-18 report)** — under any + light theme: (1) with two workspaces open, the inactive number is + readable on the bar (subtext, not the washed-out grey); (2) hover a + notification popup — background stays the theme's light card with a + faint tint, text readable (the swaync default's dark + .notification-default-action hover is now overridden); close + button matches the palette. VM-verified with a hover probe under + summer-day; this is the on-hardware confirmation of the report. - [ ] **Auto-theme pair flip on hardware** — set `settings.autoTheme.{day,night}` to one of the new pairs (e.g. kiln-clay / kiln), force sunrise/sunset around the current time, diff --git a/modules/home/swaync.nix b/modules/home/swaync.nix index c15a73e..051e168 100644 --- a/modules/home/swaync.nix +++ b/modules/home/swaync.nix @@ -71,12 +71,47 @@ in font-size: ${toString t.fonts.size}pt; } - .control-center .notification-row:focus, - .control-center .notification-row:hover { + /* Unscoped on purpose: the floating popup wraps .notification in + a .notification-row too, and swaync's DEFAULT stylesheet (still + loaded underneath this one) paints that row dark on hover — on + light themes the theme's dark @text then sat on the default's + dark hover, unreadable. The same alpha(@text) tint as + everywhere else overrides it in both surfaces. */ + .notification-row:focus, + .notification-row:hover { background: alpha(@text, 0.1); border-radius: ${r}px; } + /* The REAL popup-hover culprit: the notification body is one big + GTK button (.notification-default-action), and the default + sheet hovers IT to rgb(56,56,56) — on light themes that put + dark @text on a dark chip (unreadable, hardware report + 2026-07-18). Re-pin body + action buttons to the palette's + tint construction; hover stays a tint of @text, so it works + in both modes by construction. */ + .notification-default-action, + .notification-action { + background: transparent; + color: @text; + } + .notification-default-action:hover, + .notification-action:hover { + background: alpha(@text, 0.08); + } + + /* Same default-stylesheet leak: swaync ships a dark close-button + chip; re-pin both ends to the palette's tint construction. */ + .close-button { + background: alpha(@text, 0.1); + color: @text; + border-radius: ${r}px; + } + .close-button:hover { + background: alpha(@text, 0.2); + color: @text; + } + .widget-title { color: @text; font-weight: bold; diff --git a/modules/home/waybar.nix b/modules/home/waybar.nix index 9aa65c1..146724c 100644 --- a/modules/home/waybar.nix +++ b/modules/home/waybar.nix @@ -426,10 +426,12 @@ let border-radius: ${toString t.ui.rounding}px; } - /* Dim states use the palette's @muted role: since item 28b it is - floor-guaranteed legible on @base in every theme (muted/base >= - 2.0, gated by tools/check-theme-contrast.py) — the palettes that - once made it vanish (gruvbox muted≈base, item 27) were retuned. + /* Dim states use the palette's @muted role on DARK themes: since + item 28b it is floor-guaranteed legible on @base (muted/base >= + 2.0, gated by tools/check-theme-contrast.py). On LIGHT themes that + 2.0-floor grey washes out at number size — inactive workspace + numbers were unreadable on every light palette — so light mode + promotes them to @subtext (>= 3.0 floor, typically 4-7:1). Secondary-but-not-dim stays alpha(@text, 0.85). */ /* 3px vertical margin insets the active pill INSIDE the bar — without it the filled button spans the bar's full inner height and visually @@ -437,7 +439,7 @@ let #workspaces button { padding: 0 8px; margin: 3px 0; - color: @muted; + color: ${if t.mode == "light" then "@subtext" else "@muted"}; border-radius: ${toString t.ui.rounding}px; } diff --git a/themes/boreal-dawn/waybar.css b/themes/boreal-dawn/waybar.css index 651d7dc..8ac2dc4 100644 --- a/themes/boreal-dawn/waybar.css +++ b/themes/boreal-dawn/waybar.css @@ -120,7 +120,9 @@ window#waybar { #workspaces { padding: 0 2px; } #workspaces button { - color: @muted; + /* @subtext, not @muted: on a light pill the 2.0-floor grey washes out + at number size — inactive workspaces must stay readable (6.4:1). */ + color: @subtext; padding: 0 9px; margin: 3px 1px; border-radius: 9px; diff --git a/themes/kiln-clay/waybar.css b/themes/kiln-clay/waybar.css index 2058d49..4c086b1 100644 --- a/themes/kiln-clay/waybar.css +++ b/themes/kiln-clay/waybar.css @@ -117,7 +117,9 @@ window#waybar { #workspaces { padding: 0 2px; } #workspaces button { - color: @muted; + /* @subtext, not @muted: on the cream plank the 2.0-floor grey washes + out at number size — inactive workspaces must stay readable (6.6:1). */ + color: @subtext; padding: 0 9px; margin: 3px 1px; border-radius: 6px; diff --git a/themes/summer-day/waybar.css b/themes/summer-day/waybar.css index 5d73404..ddee237 100755 --- a/themes/summer-day/waybar.css +++ b/themes/summer-day/waybar.css @@ -18,6 +18,7 @@ @define-color grey0 #a6b0a0; @define-color grey1 #939f91; /* overlay */ @define-color grey2 #829181; /* muted */ +@define-color fg_dim #6e828a; /* subtext */ /* margin: top right bottom left */ /* Spacing outside the element */ @@ -79,6 +80,14 @@ window#waybar { padding: 0px; } +/* Inactive workspace numbers: without an explicit rule the GTK default + button color leaks in (the container's @fg does NOT inherit into + buttons) and the numbers vanish on the cream chip. @fg_dim = the + palette's subtext (4.0:1) — dim but readable. */ +#workspaces button { + color: @fg_dim; +} + /* The power-profile speedometer glyph renders small in its em box. */ #custom-powerprofile { font-size: 20px;