fix: light mode theming

This commit is contained in:
2026-10-05 12:30:43 +02:00
parent 4274971337
commit a56d4d1c20
6 changed files with 92 additions and 3 deletions
+4 -2
View File
@@ -1,6 +1,5 @@
from fabric.widgets.box import Box from fabric.widgets.box import Box
from fabric.widgets.label import Label from fabric.widgets.label import Label
from fabric.widgets.image import Image
from fabric.widgets.overlay import Overlay from fabric.widgets.overlay import Overlay
from fabric.widgets.datetime import DateTime from fabric.widgets.datetime import DateTime
from fabric.widgets.centerbox import CenterBox from fabric.widgets.centerbox import CenterBox
@@ -142,7 +141,10 @@ class StatusBar(Window):
center_children.append(self.active_window) center_children.append(self.active_window)
start_container_children = [ start_container_children = [
Image(name="nixos-label", icon_name="nix-snowflake-white", icon_size=20), # Nerd Font glyph (nf-linux-nixos) rather than the nix-snowflake-white
# icon: that SVG is hard-coded white and vanishes on light themes,
# while a glyph follows the CSS `color`.
Label(name="nixos-label", label="\uf313"),
self.workspaces, self.workspaces,
self.player_small, self.player_small,
] ]
+1 -1
View File
@@ -137,7 +137,7 @@ class NotmuchService:
class NotmuchWidget(Button): class NotmuchWidget(Button):
def __init__(self, **kwargs): def __init__(self, **kwargs):
# Create the widget content # Create the widget content
self.icon = Image(icon_name="mail-unread-symbolic", icon_size=16) self.icon = Image(name="notmuch-icon", icon_name="mail-unread-symbolic", icon_size=16)
self.label = Label("0", name="unread-count") self.label = Label("0", name="unread-count")
# Container for icon and label # Container for icon and label
+80
View File
@@ -60,6 +60,58 @@ def resolve_colors(mode: str | None = None) -> dict[str, str]:
return colors return colors
def is_light(colors: dict[str, str]) -> bool:
"""Whether the palette is a light one, judged by base00's relative
luminance (so light base schemes work without `variants` too)."""
def channel(c: int) -> float:
c = c / 255
return c / 12.92 if c <= 0.04045 else ((c + 0.055) / 1.055) ** 2.4
hex_bg = colors["base00"].lstrip("#")
r, g, b = (channel(int(hex_bg[i : i + 2], 16)) for i in (0, 2, 4))
return 0.2126 * r + 0.7152 * g + 0.0722 * b > 0.5
# Accent "status pills": (widget selector, child selectors, base16 slot). Later
# entries win over earlier ones at equal specificity, mirroring org.css and
# notmuch.css (debt state overrides unread, in-progress+next overrides both).
ACCENT_PILLS = [
("#org-widget.has-in-progress", ("#org-icon", "#org-count"), "base0E"),
("#org-widget.has-next", ("#org-icon", "#org-count"), "base0D"),
("#org-widget.has-in-progress.has-next", ("#org-icon", "#org-count"), "base0C"),
("#notmuch-widget.has-unread", ("#notmuch-icon", "#unread-count"), "base0D"),
("#notmuch-widget.debt-warn", ("#notmuch-icon", "#unread-count"), "base09"),
("#notmuch-widget.debt-alarm", ("#notmuch-icon", "#unread-count"), "base08"),
]
def accent_pill_css(colors: dict[str, str]) -> str:
"""Org/notmuch alert pills. Dark palettes get a solid accent fill with
background-colored text (pastel accents carry that well); light palettes
get a pale accent tint with accent-colored text, since a solid fill of a
light scheme's saturated accents is far louder than the rest of the bar."""
light = is_light(colors)
rules = []
for widget, children, slot in ACCENT_PILLS:
accent = f"#{colors[slot]}"
if light:
bg, hover_bg, fg = (
f"alpha({accent}, 0.18)",
f"alpha({accent}, 0.30)",
accent,
)
else:
bg, hover_bg, fg = accent, f"shade({accent}, 1.12)", f"#{colors['base00']}"
child_sel = ",\n".join(f"{widget} {c}" for c in children)
rules.append(
f"{widget} {{\n background-color: {bg};\n}}\n\n"
f"{widget}:hover {{\n background-color: {hover_bg};\n}}\n\n"
f"{child_sel} {{\n color: {fg};\n}}\n"
)
return "\n".join(rules)
def generate_stylix_css(mode: str | None = None) -> str | None: def generate_stylix_css(mode: str | None = None) -> str | None:
"""Generate CSS using Stylix colors (for `mode`, if variants are set)""" """Generate CSS using Stylix colors (for `mode`, if variants are set)"""
if not STYLIX.get("enable", False): if not STYLIX.get("enable", False):
@@ -170,8 +222,36 @@ def generate_stylix_css(mode: str | None = None) -> str | None:
/* NixOS label */ /* NixOS label */
#nixos-label {{ #nixos-label {{
color: #{colors["base0D"]}; color: #{colors["base0D"]};
font-size: 20px;
}} }}
/* CPU/RAM pies: the RAM pie (underneath) draws a faint full-circle track in
`color` so the usage wedge reads as a pie instead of a stray triangle; the
CPU pie on top keeps a transparent track. */
#ram-progress-bar {{
color: alpha(#{colors["base03"]}, 0.4);
}}
/* System tray: match the other bar pills */
#system-tray {{
background-color: #{colors["base01"]};
padding: 2px 6px;
border-radius: 12px;
}}
/* Org / notmuch pills */
#org-widget,
#notmuch-widget {{
background-color: #{colors["base01"]};
}}
#org-widget:hover,
#notmuch-widget:hover {{
background-color: #{colors["base02"]};
}}
{accent_pill_css(colors)}
/* Date time */ /* Date time */
#date-time {{ #date-time {{
color: #{colors["base05"]}; color: #{colors["base05"]};
+2
View File
@@ -125,6 +125,8 @@
#nixos-label { #nixos-label {
color: var(--blue); color: var(--blue);
font-size: 20px;
margin: 0 2px 0 4px;
} }
#capture-widget { #capture-widget {
+3
View File
@@ -46,8 +46,11 @@
min-width: 16px; min-width: 16px;
} }
#notmuch-widget.has-unread #notmuch-icon,
#notmuch-widget.has-unread #unread-count, #notmuch-widget.has-unread #unread-count,
#notmuch-widget.debt-warn #notmuch-icon,
#notmuch-widget.debt-warn #unread-count, #notmuch-widget.debt-warn #unread-count,
#notmuch-widget.debt-alarm #notmuch-icon,
#notmuch-widget.debt-alarm #unread-count { #notmuch-widget.debt-alarm #unread-count {
color: var(--background); color: var(--background);
} }
+2
View File
@@ -38,7 +38,9 @@
min-width: 16px; min-width: 16px;
} }
#org-widget.has-next #org-icon,
#org-widget.has-next #org-count, #org-widget.has-next #org-count,
#org-widget.has-in-progress #org-icon,
#org-widget.has-in-progress #org-count { #org-widget.has-in-progress #org-count {
color: var(--background); color: var(--background);
} }