From 377889db8cff9cb3d9f1cd8291c76bdcbad9b2cd Mon Sep 17 00:00:00 2001 From: Makesesama Date: Mon, 9 Nov 2026 23:29:01 +0100 Subject: [PATCH] feat: unified bar styling - semantic tokens (accent/surface/hairline/text-muted) derived from the palette so they follow stylix in light and dark mode - every bar module is a uniform 28px rounded chip; one accent for active state, tints for attention, solid fill only for mail-debt alarm - workspaces as dots with a stretching accent pill - mic/cpu-ram/tray/battery grouped into one chip; cpu/ram as concentric rings with tooltip; clock split into bold time + muted date - stylix provider only sets palette + font; scope its font-size so the bar's own CSS sizes are no longer flattened - drop inline widget styles, 16px tray icons, fix broken menu.css selector --- sims/main.py | 2 +- sims/modules/bar.py | 71 ++++++---- sims/modules/microphone.py | 1 - sims/modules/stylix.py | 266 ++----------------------------------- sims/styles/bar.css | 231 +++++++++++++++++++++----------- sims/styles/calendar.css | 16 --- sims/styles/colors.css | 23 +++- sims/styles/main.css | 8 +- sims/styles/menu.css | 46 +++---- sims/styles/notmuch.css | 51 ++++--- sims/styles/org.css | 49 +++---- sims/styles/workspaces.css | 46 ++++--- 12 files changed, 326 insertions(+), 484 deletions(-) diff --git a/sims/main.py b/sims/main.py index 308441c..a445ef9 100644 --- a/sims/main.py +++ b/sims/main.py @@ -48,7 +48,7 @@ from gi.repository import GLib, Gtk from fabric.notifications import Notifications -tray = SystemTray(name="system-tray", spacing=4) +tray = SystemTray(name="system-tray", spacing=2, icon_size=16) get_i3_connection() # Subscribe before the main loop runs so fenster's replayed capture state # (sent right after SUBSCRIBE) is not missed. diff --git a/sims/modules/bar.py b/sims/modules/bar.py index 7fbeef5..1f2c3b3 100644 --- a/sims/modules/bar.py +++ b/sims/modules/bar.py @@ -1,8 +1,10 @@ +import time + from fabric.widgets.box import Box from fabric.widgets.label import Label from fabric.widgets.overlay import Overlay -from fabric.widgets.datetime import DateTime from fabric.widgets.centerbox import CenterBox +from fabric.utils import invoke_repeater from sims.modules.player import Player, PlayerSmall from sims.modules.battery import Battery from sims.modules.control_center import ControlCenter @@ -55,12 +57,10 @@ class StatusBar(Window): spacing=4, ) - datetime_widget = DateTime(name="date-time", formatters="%d %b - %H:%M") self.date_time = Button( name="date-time-button", - child=datetime_widget, + child=Clock(), on_clicked=self._on_date_time_clicked, - style="background: transparent; border: none; padding: 0; margin: 0; box-shadow: none;", ) self.control_center = control_center @@ -69,22 +69,21 @@ class StatusBar(Window): self.active_window = FensterActiveWindow( name="active-window", max_length=50, - style="font-size: 14px; font-weight: bold;", ) + # CPU/RAM as concentric "activity rings": outer = RAM, inner = CPU. + ring = dict(line_width=3, start_angle=-90, end_angle=270, + h_align="center", v_align="center") self.ram_progress_bar = CircularProgressBar( - name="ram-progress-bar", pie=True, size=24 + name="ram-progress-bar", size=18, **ring ) self.cpu_progress_bar = CircularProgressBar( - name="cpu-progress-bar", pie=True, size=24 - ) - - self.progress_label = Label( - "", style="margin: 0px 6px 0px 0px; font-size: 12px" + name="cpu-progress-bar", size=8, **ring ) self.progress_bars_overlay = Overlay( + name="system-stats", child=self.ram_progress_bar, - overlays=[self.cpu_progress_bar, self.progress_label], + overlays=[self.cpu_progress_bar], ) self.player = Player() self.player_small = PlayerSmall(monitor=monitor) @@ -110,11 +109,18 @@ class StatusBar(Window): self.microphone = MicrophoneWidget() + # One chip for the ambient system state; attention items (org, + # mail, screen share) stay separate so they can light up. + status_children = [self.microphone, self.progress_bars_overlay] + if self.system_tray: + status_children.append(self.system_tray) + if self.battery: + status_children.append(self.battery) self.status_container = Box( name="widgets-container", - spacing=4, + spacing=6, orientation="h", - children=[self.microphone, self.progress_bars_overlay], + children=status_children, ) end_container_children = [] @@ -122,17 +128,11 @@ class StatusBar(Window): if self.org is not None: end_container_children.append(self.org) - end_container_children.append(self.status_container) - if self.system_tray: - end_container_children.append(self.system_tray) - - if self.battery: - end_container_children.append(self.battery) - if self.notmuch: end_container_children.append(self.notmuch) end_container_children.append(self.capture) + end_container_children.append(self.status_container) end_container_children.append(self.date_time) @@ -155,7 +155,7 @@ class StatusBar(Window): name="sims-inner", start_children=Box( name="start-container", - spacing=6, + spacing=8, orientation="h", children=start_container_children, ), @@ -167,7 +167,7 @@ class StatusBar(Window): ), end_children=Box( name="end-container", - spacing=4, + spacing=6, orientation="h", children=end_container_children, ), @@ -218,7 +218,32 @@ class StatusBar(Window): def update_progress_bars(self, service, cpu_percent, memory_percent): self.cpu_progress_bar.value = cpu_percent self.ram_progress_bar.value = memory_percent + self.progress_bars_overlay.set_tooltip_text( + f"CPU {cpu_percent * 100:.0f}% · RAM {memory_percent * 100:.0f}%" + ) def _on_date_time_clicked(self, _button=None): if self.control_center is not None: self.control_center.toggle() + + +class Clock(Box): + """Bold time + muted date, e.g. `20:26 Mon 22 Jul`.""" + + def __init__(self, **kwargs): + self._time = Label(name="clock-time") + self._date = Label(name="clock-date") + super().__init__( + name="date-time", + orientation="h", + spacing=8, + children=[self._time, self._date], + **kwargs, + ) + invoke_repeater(1000, self._update) + + def _update(self) -> bool: + now = time.localtime() + self._time.set_label(time.strftime("%H:%M", now)) + self._date.set_label(time.strftime("%a %d %b", now)) + return True diff --git a/sims/modules/microphone.py b/sims/modules/microphone.py index e3f9b8c..27e2341 100644 --- a/sims/modules/microphone.py +++ b/sims/modules/microphone.py @@ -27,7 +27,6 @@ class MicrophoneWidget(Box): name="microphone-button", child=self.icon_label, on_clicked=self.on_clicked, - style="background: transparent; border: none; margin: 0; box-shadow: none;", ) self.add(self.button) diff --git a/sims/modules/stylix.py b/sims/modules/stylix.py index fce4d74..7890d66 100644 --- a/sims/modules/stylix.py +++ b/sims/modules/stylix.py @@ -60,58 +60,6 @@ def resolve_colors(mode: str | None = None) -> dict[str, str]: 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: """Generate CSS using Stylix colors (for `mode`, if variants are set)""" if not STYLIX.get("enable", False): @@ -144,129 +92,27 @@ def generate_stylix_css(mode: str | None = None) -> str | None: {palette} -/* Apply Stylix font */ +/* Apply Stylix font. This provider sits in front of main.css and GTK lets + the first provider that sets a property win regardless of selector + specificity, so a blanket `* {{ font-size }}` here would flatten every + size in the bar's own CSS. The bar (window#sims) therefore only gets the + size on its toplevel and inherits it; other windows keep the blanket + rule they were designed against. */ * {{ font-family: "{font_family}", sans-serif; +}} + +window, +tooltip {{ font-size: {font_size}px; }} -/* Bar styling */ -#sims-inner {{ - padding: 4px; - border-bottom: solid 2px; - border-color: #{colors["base02"]}; - background-color: #{colors["base00"]}; - border-radius: 0; - transition: border-radius 200ms ease; -}} - -#sims-inner.rounded-bottom {{ - border-radius: 0 0 28px 28px; -}} - -#center-container {{ - color: #{colors["base05"]}; -}} - -.active-window {{ - color: #{colors["base05"]}; - font-weight: bold; -}} - -/* Battery */ -#battery-widget {{ - background-color: #{colors["base01"]}; - padding: 4px 8px; - border-radius: 12px; -}} - -#bat-icon {{ - color: #{colors["base0D"]}; - margin-right: 2px; -}} - -#bat-label {{ - color: #{colors["base05"]}; +window:not(#sims) * {{ font-size: {font_size}px; }} -#bat-label.battery-low {{ - color: #{colors["base08"]}; - font-weight: bold; -}} - -/* Progress bars */ -#cpu-progress-bar, -#ram-progress-bar, -#volume-progress-bar {{ - color: transparent; - background-color: transparent; -}} - -#cpu-progress-bar {{ - border: solid 0px alpha(#{colors["base0E"]}, 0.8); -}} - -#ram-progress-bar, -#volume-progress-bar {{ - border: solid 0px #{colors["base0D"]}; -}} - -/* Widgets container */ -#widgets-container {{ - background-color: #{colors["base01"]}; - padding: 2px; - border-radius: 16px; -}} - -/* NixOS label */ -#nixos-label {{ - 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 {{ - color: #{colors["base05"]}; - background-color: #{colors["base01"]}; - padding: 4px 8px; - border-radius: 12px; -}} - -#date-time-button {{ - background: transparent; - border: none; - padding: 0; - margin: 0; - box-shadow: none; -}} +/* Bar widgets are styled purely in the static styles/ css through the palette + above (see styles/colors.css for the semantic tokens). */ /* Generic popup styling */ .popup-window, @@ -370,92 +216,6 @@ def generate_stylix_css(mode: str | None = None) -> str | None: opacity: 0.8; }} -/* Tooltips */ -tooltip {{ - border: solid 2px; - border-color: #{colors["base02"]}; - background-color: #{colors["base00"]}; - color: #{colors["base05"]}; - border-radius: 16px; -}} - -tooltip>* {{ - padding: 2px 4px; -}} - -/* Workspaces */ -#workspaces {{ - background-color: #{colors["base01"]}; - padding: 6px 6px; - border-radius: 16px; -}} - -#workspaces>button {{ - background-color: #{colors["base05"]}; -}} - -#workspaces>button.empty:not(.active):not(.visible) {{ - background-color: #{colors["base03"]}; -}} - -#workspaces>button.visible:not(.active) {{ - background-color: #{colors["base0E"]}; -}} - -#workspaces>button.active {{ - background-color: #{colors["base0D"]}; -}} - -#workspaces>button.urgent {{ - background-color: #{colors["base08"]}; -}} - -/* Workspace shown on a different monitor than this bar — dim it. */ -#workspaces>button.foreign {{ - opacity: 0.45; -}} - -#workspaces>button>label {{ - font-size: 0px; -}} - -/* Compact MPRIS player */ -#player-small {{ - background-color: #{colors["base01"]}; - padding: 6px; - border-radius: 100px; -}} - -#compact-mpris-icon, -#compact-mpris-button {{ - background: transparent; - border: none; - padding: 0 4px; - margin: 0; - box-shadow: none; - min-height: 0; - min-width: 0; -}} - -#compact-mpris-button-icon, -#compact-mpris-fallback {{ - color: #{colors["base05"]}; -}} - -#compact-mpris-button:hover #compact-mpris-button-icon {{ - color: #{colors["base0D"]}; -}} - -#compact-mpris-fallback {{ - opacity: 0.7; -}} - -#compact-mpris-label {{ - color: #{colors["base05"]}; - font-size: {font_size}px; - margin: 0 6px; -}} - /* Quick Menu styling */ #quick-menu-container {{ background-color: #{colors["base00"]}; diff --git a/sims/styles/bar.css b/sims/styles/bar.css index 0054b7b..89f8661 100644 --- a/sims/styles/bar.css +++ b/sims/styles/bar.css @@ -1,8 +1,18 @@ +/* ------------------------------------------------------------------------ + Bar shell + + One visual language for every module: + - "chips": --surface fill, same height (bar height minus the 6px + vertical padding below), fully rounded, 10px side padding. + - a single accent color for "this is active" (workspace, play state), + tinted chips for "needs attention", solid fill only for alarms. + - text is foreground / --text-muted, icons are 16px. + ------------------------------------------------------------------------ */ + #sims-inner { - padding: 4px; - border-bottom: solid 2px; - border-color: var(--border-color); + padding: 6px 12px; background-color: var(--window-bg); + border-bottom: solid 1px var(--hairline); border-radius: 0; transition: border-radius 200ms ease; } @@ -11,19 +21,31 @@ border-radius: 0 0 28px 28px; } -#center-container { - color: var(--foreground); +/* Shared chip look (workspaces.css applies the same to #workspaces) */ +#player-small, +#widgets-container, +#org-widget, +#notmuch-widget, +#date-time { + min-height: 28px; + padding: 0 10px; + border-radius: 14px; + background-color: var(--surface); + transition: background-color 150ms ease; } -.active-window { - color: var(--foreground); - font-weight: bold; +#org-widget:hover, +#notmuch-widget:hover, +#date-time-button:hover #date-time { + background-color: var(--surface-hover); } -#battery-widget { - background-color: var(--module-bg); - padding: 4px 8px; - border-radius: 4px; +/* ---- left ------------------------------------------------------------- */ + +#nixos-label { + color: var(--accent); + font-size: 18px; + padding: 0 6px 0 2px; } #buddy-container, @@ -34,125 +56,172 @@ #buddy-button { padding: 0; margin: 0 2px; - background: transparent; - border: none; } -#bat-icon { - color: var(--blue); - margin-right: 2px; +/* Compact player chip: circular cover hugging the left edge */ +#player-small { + padding: 0 6px 0 3px; } -#bat-label { +#compact-mpris-icon, +#compact-mpris-button { + padding: 0; + margin: 0; + min-height: 0; + min-width: 0; +} + +#compact-mpris-label { color: var(--foreground); - font-size: 14px; + font-weight: 500; + margin: 0 8px; } -#bat-label.battery-low { - color: var(--red); - font-weight: bold; +#compact-mpris-fallback { + color: var(--text-muted); + margin: 0 3px; } -#microphone-icon { - color: var(--foreground); - font-size: 20px; +#compact-mpris-button-icon { + color: var(--text-muted); + transition: color 150ms ease; +} + +#compact-mpris-button:hover #compact-mpris-button-icon { + color: var(--accent); +} + +/* ---- center ----------------------------------------------------------- */ + +#active-window, +.active-window { + color: var(--text-muted); + font-weight: 500; +} + +/* ---- right ------------------------------------------------------------ */ + +/* System cluster: mic, cpu/ram rings, tray, battery in one chip */ +#widgets-container { + padding: 0 8px; } #microphone-button { - min-width: 28px; - padding: 0 6px; + padding: 0 4px; + border-radius: 10px; +} + +#microphone-icon { + color: var(--text-muted); + font-size: 16px; +} + +#microphone-button:hover #microphone-icon { + color: var(--foreground); } #microphone-icon.muted { color: var(--red); } -#cpu-progress-bar, +/* CPU / RAM "activity rings": outer ring = RAM, inner ring = CPU. + CircularProgressBar draws its track with `color` and progress with + `border-color`; the border *width* must stay 0 or it inflates the line. */ +#system-stats { + padding: 0 4px; +} + #ram-progress-bar, -#volume-progress-bar { - color: transparent; - background-color: transparent +#cpu-progress-bar { + background-color: transparent; + color: alpha(var(--foreground), 0.12); + border: solid 0 transparent; +} + +#ram-progress-bar { + border-color: var(--accent); } #cpu-progress-bar { - border: solid 0px alpha(var(--violet), 0.8); + border-color: var(--violet); } -#ram-progress-bar, -#volume-progress-bar { - border: solid 0px var(--blue); +#system-tray { + padding: 0 2px; } -#widgets-container { - background-color: var(--module-bg); - padding: 2px; +#system-tray > button { + padding: 0 3px; + border-radius: 8px; } -#player-small { - background-color: var(--module-bg); - padding: 6px; - border-radius: 100px; +#system-tray > button:hover { + background-color: var(--surface-hover); } -#compact-mpris-icon, -#compact-mpris-button { - background: transparent; - border: none; - padding: 0 4px; - margin: 0; - box-shadow: none; - min-height: 0; - min-width: 0; +#battery-widget { + padding: 0 2px 0 4px; } -#compact-mpris-button-icon { +#bat-icon { + color: var(--text-muted); +} + +#bat-label { color: var(--foreground); + font-feature-settings: "tnum"; } -#compact-mpris-button:hover #compact-mpris-button-icon { - color: var(--blue); -} - -#compact-mpris-fallback { - color: var(--foreground); - opacity: 0.7; -} - -#compact-mpris-label { - color: var(--foreground); - font-size: 13px; -} - -#nixos-label { - color: var(--blue); - font-size: 20px; - margin: 0 2px 0 4px; +#bat-icon.battery-low, +#bat-label.battery-low { + color: var(--red); + font-weight: bold; } +/* Screen-share indicator: a bare red dot, only visible while sharing */ #capture-widget { - background: transparent; - border: none; padding: 0 6px; margin: 0; - box-shadow: none; } #capture-dot { color: var(--red); - font-size: 14px; + font-size: 12px; } #capture-summary { - font-size: 12px; + color: var(--text-muted); margin-right: 6px; } -tooltip { - border: solid 2px; - border-color: var(--border-color); - background-color: var(--window-bg); +/* Clock: bold time, muted date */ +#date-time-button { + padding: 0; + margin: 0; } -tooltip>* { - padding: 2px 4px +#date-time { + padding: 0 12px; +} + +#clock-time { + font-weight: bold; + font-feature-settings: "tnum"; +} + +#clock-date { + color: var(--text-muted); + font-feature-settings: "tnum"; +} + +/* ---- tooltips --------------------------------------------------------- */ + +tooltip { + background-color: var(--window-bg); + border: solid 1px var(--hairline); + border-radius: 10px; +} + +tooltip > * { + padding: 4px 8px; } diff --git a/sims/styles/calendar.css b/sims/styles/calendar.css index ff6a103..94f198a 100644 --- a/sims/styles/calendar.css +++ b/sims/styles/calendar.css @@ -1,21 +1,5 @@ /* Calendar widget styling */ -/* Date time button */ -#date-time-button { - background: transparent; - border: none; - padding: 0; - margin: 0; - box-shadow: none; -} - -#date-time { - color: var(--foreground); - background-color: var(--module-bg); - padding: 4px 8px; - border-radius: 12px; -} - /* Calendar event items */ .event-item { border-radius: 8px; diff --git a/sims/styles/colors.css b/sims/styles/colors.css index 1c14ada..6df1851 100644 --- a/sims/styles/colors.css +++ b/sims/styles/colors.css @@ -17,13 +17,24 @@ --violet: #AD60FF; --red: #FC3F2C; - --window-bg: alpha(var(--background), 0.9); + /* Semantic tokens. Surfaces/text are derived from --foreground so they + work on both dark and light palettes (stylix redefines the base + colors at runtime and these follow). */ + --accent: var(--blue); + --surface: alpha(var(--foreground), 0.06); + --surface-hover: alpha(var(--foreground), 0.11); + --surface-active: alpha(var(--foreground), 0.16); + --hairline: alpha(var(--foreground), 0.08); + --text-muted: alpha(var(--foreground), 0.62); + --text-faint: alpha(var(--foreground), 0.38); + + --window-bg: alpha(var(--background), 0.94); --module-bg: alpha(var(--mid-bg), 0.8); --border-color: var(--light-bg); - --ws-active: var(--blue); - --ws-visible: var(--violet); - --ws-inactive: var(--light-grey); - --ws-empty: var(--dark-grey); - --ws-hover: var(--turquoise); + --ws-active: var(--accent); + --ws-visible: alpha(var(--accent), 0.5); + --ws-inactive: alpha(var(--foreground), 0.55); + --ws-empty: alpha(var(--foreground), 0.18); + --ws-hover: alpha(var(--foreground), 0.85); --ws-urgent: var(--red); } diff --git a/sims/styles/main.css b/sims/styles/main.css index 854c0e5..8919810 100644 --- a/sims/styles/main.css +++ b/sims/styles/main.css @@ -11,10 +11,16 @@ @import url("./media.css"); -/* unset so we can style everything from the ground up. */ +/* unset so we can style everything from the ground up. `all: unset` + makes font-size/font-family inherit, so the base font is set once on the + toplevels and any widget rule (e.g. icon sizes) can still override it. */ * { all: unset; color: var(--foreground); +} + +window, +tooltip { font-size: 16px; font-family: "Jost*", sans-serif; } diff --git a/sims/styles/menu.css b/sims/styles/menu.css index 0063ae6..2b94fd0 100644 --- a/sims/styles/menu.css +++ b/sims/styles/menu.css @@ -1,38 +1,30 @@ -#date-time, -menu>menuitem>label, -#date-time>label, -/* system tray */ -#system-tray { - padding: 2px 4px; - background-color: var(--module-bg); -} - -/* menu and menu items (written for the system tray) */ +/* Context menus (system tray) */ menu { - border: solid 2px; - border-radius: 10px; - border-color: var(--border-color); + padding: 4px; + border: solid 1px var(--hairline); + border-radius: 12px; background-color: var(--window-bg); } -menu>menuitem { - border-radius: 0px; - background-color: var(--module-bg); - padding: 6px; - margin-left: 2px; - margin-right: 2px; +menu > menuitem { + padding: 6px 10px; + border-radius: 8px; } -menu>menuitem:first-child { - margin-top: 1px; - border-radius: 8px 8px 0px 0px; +menu > menuitem:hover { + background-color: alpha(var(--accent), 0.18); } -menu>menuitem:last-child { - margin-bottom: 1px; - border-radius: 0px 0px 8px 8px; +menu > menuitem:hover > label { + color: var(--accent); } -menu>menuitem:hover { - background-color: var(--pink); +menu > menuitem:disabled > label { + color: var(--text-faint); +} + +menu > separator { + min-height: 1px; + margin: 4px 6px; + background-color: var(--hairline); } diff --git a/sims/styles/notmuch.css b/sims/styles/notmuch.css index 2f70ae8..e116e72 100644 --- a/sims/styles/notmuch.css +++ b/sims/styles/notmuch.css @@ -1,34 +1,42 @@ -/* Notmuch email widget styling */ +/* Notmuch unread badge. Base chip look lives in bar.css. + Calm by default; tinted when there is unread mail, solid red only when + the email debt timer is in alarm. */ -#notmuch-widget { - background-color: var(--module-bg); - padding: 4px 8px; - border-radius: 12px; - transition: background-color 0.2s ease; +#notmuch-icon { + color: var(--text-muted); } -#notmuch-widget:hover { - background-color: var(--light-bg); +#unread-count { + color: var(--foreground); + font-weight: bold; + font-feature-settings: "tnum"; + min-width: 16px; } #notmuch-widget.has-unread { - background-color: var(--blue); + background-color: alpha(var(--accent), 0.18); } #notmuch-widget.has-unread:hover { - background-color: var(--turquoise); + background-color: alpha(var(--accent), 0.28); } -#notmuch-widget.no-unread { - background-color: var(--module-bg); +#notmuch-widget.has-unread #notmuch-icon, +#notmuch-widget.has-unread #unread-count { + color: var(--accent); } #notmuch-widget.debt-warn { - background-color: var(--orange); + background-color: alpha(var(--orange), 0.2); } #notmuch-widget.debt-warn:hover { - background-color: var(--gold); + background-color: alpha(var(--orange), 0.3); +} + +#notmuch-widget.debt-warn #notmuch-icon, +#notmuch-widget.debt-warn #unread-count { + color: var(--orange); } #notmuch-widget.debt-alarm { @@ -36,21 +44,10 @@ } #notmuch-widget.debt-alarm:hover { - background-color: var(--pink); + background-color: shade(var(--red), 1.1); } -#unread-count { - color: var(--foreground); - font-size: 14px; - font-weight: bold; - min-width: 16px; -} - -#notmuch-widget.has-unread #notmuch-icon, -#notmuch-widget.has-unread #unread-count, -#notmuch-widget.debt-warn #notmuch-icon, -#notmuch-widget.debt-warn #unread-count, #notmuch-widget.debt-alarm #notmuch-icon, #notmuch-widget.debt-alarm #unread-count { color: var(--background); -} \ No newline at end of file +} diff --git a/sims/styles/org.css b/sims/styles/org.css index e29388b..7b64765 100644 --- a/sims/styles/org.css +++ b/sims/styles/org.css @@ -1,48 +1,43 @@ -/* Org-agenda bar widget + dropdown */ +/* Org-agenda bar widget + dropdown. Base chip look lives in bar.css. */ -#org-widget { - background-color: var(--module-bg); - padding: 4px 8px; - border-radius: 12px; - transition: background-color 0.2s ease; +#org-icon { + color: var(--text-muted); } -#org-widget:hover { - background-color: var(--light-bg); +#org-count { + font-weight: bold; + font-feature-settings: "tnum"; + min-width: 16px; } #org-widget.empty { - background-color: var(--module-bg); opacity: 0.6; } #org-widget.has-next { - background-color: var(--blue); + background-color: alpha(var(--accent), 0.18); } #org-widget.has-next:hover { - background-color: var(--turquoise); -} - -#org-widget.has-in-progress { - background-color: var(--violet); -} - -#org-widget.has-in-progress.has-next { - background-color: var(--turquoise); -} - -#org-count { - font-size: 14px; - font-weight: bold; - min-width: 16px; + background-color: alpha(var(--accent), 0.28); } #org-widget.has-next #org-icon, -#org-widget.has-next #org-count, +#org-widget.has-next #org-count { + color: var(--accent); +} + +#org-widget.has-in-progress { + background-color: alpha(var(--violet), 0.2); +} + +#org-widget.has-in-progress:hover { + background-color: alpha(var(--violet), 0.3); +} + #org-widget.has-in-progress #org-icon, #org-widget.has-in-progress #org-count { - color: var(--background); + color: var(--violet); } /* Dropdown */ diff --git a/sims/styles/workspaces.css b/sims/styles/workspaces.css index 4db4c36..fa834a5 100644 --- a/sims/styles/workspaces.css +++ b/sims/styles/workspaces.css @@ -1,50 +1,54 @@ +/* Workspace rail: small dots, the focused one stretches into an accent pill. + The chip is 28px tall; 10px vertical padding leaves 8px dots. */ #workspaces { - padding: 6px; - min-width: 0px; - background-color: var(--module-bg); + min-height: 8px; + padding: 10px 12px; + border-radius: 14px; + background-color: var(--surface); } -#workspaces>button { - padding: 8px; - transition: padding 0.05s steps(8), background-color 0.15s ease; +#workspaces > button { + min-width: 8px; + min-height: 8px; + border-radius: 99px; background-color: var(--ws-inactive); - border-radius: 100px; + transition: min-width 200ms cubic-bezier(0.4, 0, 0.2, 1), + background-color 150ms ease; } -#workspaces>button>label { +#workspaces > button > label { font-size: 0px; } -#workspaces>button:hover { - background-color: var(--ws-hover); -} - -#workspaces>button.empty { +#workspaces > button.empty { background-color: var(--ws-empty); } -#workspaces>button.visible { +#workspaces > button.visible { background-color: var(--ws-visible); } -#workspaces>button.active { - padding: 8px 32px; +#workspaces > button:hover { + background-color: var(--ws-hover); +} + +#workspaces > button.active { + min-width: 24px; background-color: var(--ws-active); } -#workspaces>button.urgent { +#workspaces > button.urgent { background-color: var(--ws-urgent); - color: var(--foreground); - font-weight: bold; animation: urgent-blink 1s infinite; } -#workspaces>button.foreign { +/* Workspace shown on a different monitor than this bar */ +#workspaces > button.foreign { opacity: 0.45; } @keyframes urgent-blink { 0% { opacity: 1.0; } - 50% { opacity: 0.5; } + 50% { opacity: 0.4; } 100% { opacity: 1.0; } }