Compare commits

..

2 Commits

Author SHA1 Message Date
8e8a142465 fix(themes): light themes — readable inactive workspaces + notification hover
All checks were successful
Check / eval (push) Successful in 4m9s
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 <noreply@anthropic.com>
2026-07-18 13:27:43 +01:00
d79ad3517e fix(waybar): #152 — inset the workspace pill, breathe at the bar's ends
The generated bar (every non-whole-swap theme; whole-swaps untouched):

- The active-workspace highlighter filled the bar's full inner height
  and visually overhung the rounded border. The pill now gets a 3px
  vertical inset margin (the boreal whole-swap's proven pattern) and
  the bar grows 34 -> 36 so the inset doesn't cramp the number.
- The end modules sat hard against the bar's rounded corners (the
  power button ~8px from the right curve vs ~28px inter-icon gaps).
  The Nomarchy mark and the power button get wider outer padding
  (14/16px); the item-28c group rhythm is preserved.

Verification: V2. nix flake check --no-build green. §3 protocol:
before/after theme-shot under kanagawa (generated palette) viewed at
2x crops — before: pill overhangs top+bottom, power glyph kisses the
corner; after: pill fully inside the bar, clear end gap
(before /nix/store/iwrvzzdd...theme-shot-kanagawa, after
/nix/store/za...see scratchpad shot-kanagawa-after.path). No-regression
capture under the summer-night whole-swap viewed — its chip identity
unchanged (whole-swaps replace both style and layout, out of scope
per the item). BACKLOG #152 closed: deleted per the finished-items
rule in the next bookkeeping touch of this push.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-18 13:22:52 +01:00
7 changed files with 80 additions and 29 deletions

View File

@@ -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.

View File

@@ -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/<slug>/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,

View File

@@ -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;

View File

@@ -162,7 +162,10 @@ let
# normal tiling. Keep in sync with the whole-swap jsoncs (parity rule).
layer = "bottom";
position = "top";
height = 34;
# 36, not 34: the active-workspace pill is inset 3px top+bottom (CSS
# below) so it can never overhang the bar's border — the extra height
# keeps the pill's text from cramping inside the inset (#152).
height = 36;
margin-top = t.ui.gapsOut;
margin-left = t.ui.gapsOut;
margin-right = t.ui.gapsOut;
@@ -423,14 +426,20 @@ 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 mutedbase, 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
overhangs the rounded border (#152). */
#workspaces button {
padding: 0 8px;
color: @muted;
margin: 3px 0;
color: ${if t.mode == "light" then "@subtext" else "@muted"};
border-radius: ${toString t.ui.rounding}px;
}
@@ -458,7 +467,10 @@ let
color: @accent;
font-family: Nomarchy;
font-size: ${toString (t.fonts.size + 4)}pt;
padding: 0 10px;
/* Wider outer padding: the bar's rounded corner curves into the
end module's box, so the edge glyphs need more room than the
uniform 10px or they look cramped (#152; power button mirrors). */
padding: 0 10px 0 14px;
}
#custom-nomarchy:hover { color: @accentAlt; }
@@ -466,6 +478,7 @@ let
color: alpha(@text, 0.85);
padding: 0 10px;
}
#custom-powermenu { padding: 0 16px 0 10px; }
#custom-powermenu:hover { color: @bad; }
/* Group rhythm (item 28c): a wider breath before each functional

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;