From ba952b4b57a5ec71db4fcdea814ce5d2d1b73a9e Mon Sep 17 00:00:00 2001 From: Ivan Malison Date: Mon, 9 Feb 2026 16:41:33 -0800 Subject: [PATCH] taffybar CSS: extract per-widget colors to nth-child rotation Replace individual .outer-pad.audio, .outer-pad.network, etc. color rules with a 5-color palette in end-widget-colors.css that cycles via :nth-child(5n+N). Add workspace pill reset to prevent the rotation from bleeding into workspace widgets. Move per-widget color variables from theme.css into end-widget-colors.css (keep tray colors in theme since the SNI tray is a center widget outside the rotation). Co-Authored-By: Claude Opus 4.6 --- .../config/taffybar/end-widget-colors.css | 106 ++++++++++++++++++ dotfiles/config/taffybar/taffybar.css | 102 ++++------------- dotfiles/config/taffybar/theme.css | 44 +------- 3 files changed, 129 insertions(+), 123 deletions(-) create mode 100644 dotfiles/config/taffybar/end-widget-colors.css diff --git a/dotfiles/config/taffybar/end-widget-colors.css b/dotfiles/config/taffybar/end-widget-colors.css new file mode 100644 index 00000000..88d42520 --- /dev/null +++ b/dotfiles/config/taffybar/end-widget-colors.css @@ -0,0 +1,106 @@ +/* End-widget color rotation. + * + * Defines a 5-color palette and cycles through it using :nth-child(). + * End widgets are children of their own container box in taffybar's layout, + * so nth-child counts only among siblings in that box. + * + * NOTE: These rules also match workspace .outer-pad elements. + * taffybar.css resets workspace pills via `.workspaces .outer-pad` which + * has equal specificity but comes later in the cascade, so it wins. + * + * To change the palette, edit the @define-color values below. + * To add more colors to the rotation, add end-color-6-* etc. and a + * corresponding :nth-child(Nn+6) rule block (updating N in all selectors). + */ + +/* --- Rotation palette (5 colors) --- */ + +/* 1 — indigo */ +@define-color end-color-1-bg rgba(50, 60, 160, 0.92); +@define-color end-color-1-fg #d5d8f8; +@define-color end-color-1-border rgba(90, 100, 210, 0.60); + +/* 2 — purple */ +@define-color end-color-2-bg rgba(110, 45, 160, 0.92); +@define-color end-color-2-fg #e8d5f8; +@define-color end-color-2-border rgba(155, 85, 210, 0.60); + +/* 3 — emerald */ +@define-color end-color-3-bg rgba(25, 130, 75, 0.92); +@define-color end-color-3-fg #c8f5e0; +@define-color end-color-3-border rgba(55, 190, 115, 0.60); + +/* 4 — teal */ +@define-color end-color-4-bg rgba(20, 120, 140, 0.92); +@define-color end-color-4-fg #d0f2f8; +@define-color end-color-4-border rgba(50, 175, 200, 0.60); + +/* 5 — rose */ +@define-color end-color-5-bg rgba(160, 40, 70, 0.92); +@define-color end-color-5-fg #f8d5e0; +@define-color end-color-5-border rgba(210, 80, 115, 0.60); + +/* --- Color rotation rules --- */ + +/* Slot 1: indigo (child 1, 6, 11, ...) */ +.outer-pad:nth-child(5n+1) { + background-color: @end-color-1-bg; + border-color: @end-color-1-border; + box-shadow: 0 1px 0 rgba(255, 255, 255, 0.06), 0 10px 24px rgba(0, 0, 0, 0.30); +} +.outer-pad:nth-child(5n+1) :not(menu):not(menuitem):not(popover):not(window), +.outer-pad:nth-child(5n+1) :not(menu):not(menuitem):not(popover):not(window) * { + color: @end-color-1-fg; +} + +/* Slot 2: purple (child 2, 7, 12, ...) */ +.outer-pad:nth-child(5n+2) { + background-color: @end-color-2-bg; + border-color: @end-color-2-border; + box-shadow: 0 1px 0 rgba(255, 255, 255, 0.06), 0 10px 24px rgba(0, 0, 0, 0.30); +} +.outer-pad:nth-child(5n+2) :not(menu):not(menuitem):not(popover):not(window), +.outer-pad:nth-child(5n+2) :not(menu):not(menuitem):not(popover):not(window) * { + color: @end-color-2-fg; +} + +/* Slot 3: emerald (child 3, 8, 13, ...) */ +.outer-pad:nth-child(5n+3) { + background-color: @end-color-3-bg; + border-color: @end-color-3-border; + box-shadow: 0 1px 0 rgba(255, 255, 255, 0.06), 0 10px 24px rgba(0, 0, 0, 0.30); +} +.outer-pad:nth-child(5n+3) :not(menu):not(menuitem):not(popover):not(window), +.outer-pad:nth-child(5n+3) :not(menu):not(menuitem):not(popover):not(window) * { + color: @end-color-3-fg; +} + +/* Slot 4: teal (child 4, 9, 14, ...) */ +.outer-pad:nth-child(5n+4) { + background-color: @end-color-4-bg; + border-color: @end-color-4-border; + box-shadow: 0 1px 0 rgba(255, 255, 255, 0.06), 0 10px 24px rgba(0, 0, 0, 0.30); +} +.outer-pad:nth-child(5n+4) :not(menu):not(menuitem):not(popover):not(window), +.outer-pad:nth-child(5n+4) :not(menu):not(menuitem):not(popover):not(window) * { + color: @end-color-4-fg; +} + +/* Slot 5: rose (child 5, 10, 15, ...) */ +.outer-pad:nth-child(5n+5) { + background-color: @end-color-5-bg; + border-color: @end-color-5-border; + box-shadow: 0 1px 0 rgba(255, 255, 255, 0.06), 0 10px 24px rgba(0, 0, 0, 0.30); +} +.outer-pad:nth-child(5n+5) :not(menu):not(menuitem):not(popover):not(window), +.outer-pad:nth-child(5n+5) :not(menu):not(menuitem):not(popover):not(window) * { + color: @end-color-5-fg; +} + +/* --- SNI tray (center widget, not part of the rotation) --- */ + +.outer-pad.sni-tray { + background-color: @widget-tray-bg; + border-color: @widget-tray-border; + box-shadow: 0 1px 0 rgba(255, 255, 255, 0.06), 0 10px 24px rgba(0, 0, 0, 0.30); +} diff --git a/dotfiles/config/taffybar/taffybar.css b/dotfiles/config/taffybar/taffybar.css index a4e80f23..e2e98e2c 100644 --- a/dotfiles/config/taffybar/taffybar.css +++ b/dotfiles/config/taffybar/taffybar.css @@ -5,6 +5,7 @@ * by GTK's CSS parser. */ @import url("theme.css"); +@import url("end-widget-colors.css"); /* Base typography + foreground color for the bar itself. * @@ -84,95 +85,32 @@ background-color: transparent; } -/* Per-widget colored squircle overrides. - decorateWithClassAndBox "name" (in taffybar.hs) adds the widget class to - the same element that has .outer-pad, so `.outer-pad.audio` etc. target - each widget's pill. Colors come from @widget-*-bg/fg/border in theme.css. */ -.outer-pad.audio { - background-color: @widget-audio-bg; - border-color: @widget-audio-border; - box-shadow: 0 1px 0 rgba(255, 255, 255, 0.06), 0 10px 24px rgba(0, 0, 0, 0.30); -} -.outer-pad.audio :not(menu):not(menuitem):not(popover):not(window), -.outer-pad.audio :not(menu):not(menuitem):not(popover):not(window) * { - color: @widget-audio-fg; -} +/* Per-widget color overrides now live in end-widget-colors.css, + which rotates through a 5-color palette via :nth-child(). */ -.outer-pad.network { - background-color: @widget-network-bg; - border-color: @widget-network-border; - box-shadow: 0 1px 0 rgba(255, 255, 255, 0.06), 0 10px 24px rgba(0, 0, 0, 0.30); -} -.outer-pad.network :not(menu):not(menuitem):not(popover):not(window), -.outer-pad.network :not(menu):not(menuitem):not(popover):not(window) * { - color: @widget-network-fg; -} - -.outer-pad.mpris { - background-color: @widget-mpris-bg; - border-color: @widget-mpris-border; - box-shadow: 0 1px 0 rgba(255, 255, 255, 0.06), 0 10px 24px rgba(0, 0, 0, 0.30); -} -.outer-pad.mpris :not(menu):not(menuitem):not(popover):not(window), -.outer-pad.mpris :not(menu):not(menuitem):not(popover):not(window) * { - color: @widget-mpris-fg; -} .outer-pad.mpris .icon { font-family: "Iosevka Nerd Font"; } -.outer-pad.clock { - background-color: @widget-clock-bg; - border-color: @widget-clock-border; - box-shadow: 0 1px 0 rgba(255, 255, 255, 0.06), 0 10px 24px rgba(0, 0, 0, 0.30); -} -.outer-pad.clock :not(menu):not(menuitem):not(popover):not(window), -.outer-pad.clock :not(menu):not(menuitem):not(popover):not(window) * { - color: @widget-clock-fg; -} - -.outer-pad.disk-usage { - background-color: @widget-disk-bg; - border-color: @widget-disk-border; - box-shadow: 0 1px 0 rgba(255, 255, 255, 0.06), 0 10px 24px rgba(0, 0, 0, 0.30); -} -.outer-pad.disk-usage :not(menu):not(menuitem):not(popover):not(window), -.outer-pad.disk-usage :not(menu):not(menuitem):not(popover):not(window) * { - color: @widget-disk-fg; -} - -.outer-pad.sni-tray { - background-color: @widget-tray-bg; - border-color: @widget-tray-border; - box-shadow: 0 1px 0 rgba(255, 255, 255, 0.06), 0 10px 24px rgba(0, 0, 0, 0.30); -} -.outer-pad.sni-tray :not(menu):not(menuitem):not(popover):not(window), -.outer-pad.sni-tray :not(menu):not(menuitem):not(popover):not(window) * { - color: @widget-tray-fg; -} - -.outer-pad.battery { - background-color: @widget-battery-bg; - border-color: @widget-battery-border; - box-shadow: 0 1px 0 rgba(255, 255, 255, 0.06), 0 10px 24px rgba(0, 0, 0, 0.30); -} -.outer-pad.battery :not(menu):not(menuitem):not(popover):not(window), -.outer-pad.battery :not(menu):not(menuitem):not(popover):not(window) * { - color: @widget-battery-fg; -} - -.outer-pad.backlight { - background-color: @widget-backlight-bg; - border-color: @widget-backlight-border; - box-shadow: 0 1px 0 rgba(255, 255, 255, 0.06), 0 10px 24px rgba(0, 0, 0, 0.30); -} -.outer-pad.backlight :not(menu):not(menuitem):not(popover):not(window), -.outer-pad.backlight :not(menu):not(menuitem):not(popover):not(window) * { - color: @widget-backlight-fg; -} - /* Workspaces styling */ +/* Reset workspace .outer-pad pills to default styling so the nth-child color + rotation from end-widget-colors.css doesn't bleed into workspace pills. + This has specificity 0,2,0 (same as the nth-child rules) but comes later + in the cascade, so it wins. */ +.workspaces .outer-pad { + background-color: @pill-background; + box-shadow: + inset 0 1px 0 @pill-highlight, + inset 0 0 0 1px @pill-border, + 0 10px 24px @pill-shadow; +} +.workspaces .outer-pad :not(menu):not(menuitem):not(popover):not(window), +.workspaces .outer-pad :not(menu):not(menuitem):not(popover):not(window) * { + color: @font-color; +} + + /* Asymmetric padding: 10px left leaves room for the overlaid workspace number label; 3px right keeps the pill tight against the trailing icon edge. */ .workspaces .inner-pad { diff --git a/dotfiles/config/taffybar/theme.css b/dotfiles/config/taffybar/theme.css index b5ca3cdf..82091f20 100644 --- a/dotfiles/config/taffybar/theme.css +++ b/dotfiles/config/taffybar/theme.css @@ -21,52 +21,14 @@ @define-color pill-highlight rgba(255, 255, 255, 0.10); @define-color pill-shadow rgba(0, 0, 0, 0.28); -/* Per-widget backgrounds — each widget gets a distinct tinted squircle so they - are visually distinguishable at a glance. Each group defines: - *-bg : pill background color (semi-transparent, dark-tinted) - *-fg : text/icon color (light, tinted to complement the background) - *-border : subtle border stroke color */ +/* Per-widget end-widget colors now live in end-widget-colors.css + (5-color rotation palette applied via :nth-child). */ -/* PulseAudio volume widget — purple */ -@define-color widget-audio-bg rgba(110, 45, 160, 0.92); -@define-color widget-audio-fg #e8d5f8; -@define-color widget-audio-border rgba(155, 85, 210, 0.60); - -/* NetworkManager wifi/ethernet widget — teal */ -@define-color widget-network-bg rgba(20, 120, 140, 0.92); -@define-color widget-network-fg #d0f2f8; -@define-color widget-network-border rgba(50, 175, 200, 0.60); - -/* MPRIS2 now-playing widget — rose/crimson */ -@define-color widget-mpris-bg rgba(160, 40, 70, 0.92); -@define-color widget-mpris-fg #f8d5e0; -@define-color widget-mpris-border rgba(210, 80, 115, 0.60); - -/* Clock widget — indigo/royal blue */ -@define-color widget-clock-bg rgba(50, 60, 160, 0.92); -@define-color widget-clock-fg #d5d8f8; -@define-color widget-clock-border rgba(90, 100, 210, 0.60); - -/* Disk-usage widget — emerald green */ -@define-color widget-disk-bg rgba(25, 130, 75, 0.92); -@define-color widget-disk-fg #c8f5e0; -@define-color widget-disk-border rgba(55, 190, 115, 0.60); - -/* StatusNotifierItem system tray — neutral dark slate */ +/* StatusNotifierItem system tray — neutral dark slate (center widget, not rotated) */ @define-color widget-tray-bg rgba(65, 70, 100, 0.92); @define-color widget-tray-fg #d8dae8; @define-color widget-tray-border rgba(110, 115, 160, 0.60); -/* Battery (icon and text) — amber/gold */ -@define-color widget-battery-bg rgba(160, 115, 20, 0.92); -@define-color widget-battery-fg #f8ecc5; -@define-color widget-battery-border rgba(210, 165, 50, 0.60); - -/* Backlight/brightness widget — warm golden */ -@define-color widget-backlight-bg rgba(170, 120, 15, 0.92); -@define-color widget-backlight-fg #f8efc5; -@define-color widget-backlight-border rgba(220, 170, 45, 0.60); - /* Text */ @define-color font-color #e7e4ee; @define-color font-muted #b8b1c6;