From 91e3ccb85b2642c9e6dbd6654f5cc34b0300c65f Mon Sep 17 00:00:00 2001 From: Emma Thorpe Date: Tue, 9 Jun 2026 19:00:36 +0100 Subject: [PATCH] feat(sway): unify the desktop on Catppuccin Mocha Replace the mismatched theming (gruvbox i3status-rust, unthemed foot, default Sway borders) with a single Catppuccin Mocha palette so the desktop matches the Vim colorscheme. A `ctp` let-binding holds the raw hex once; consumers add "#" as needed. Themed: foot (16-colour + selection/cursor), i3status-rust ("plain" base + overrides, idle blocks on mantle, loud bg only for warning/critical), Sway window borders and the bar/workspace buttons, swaylock (full ring/inside/text set) and dunst (base/text bg, blue/peach frames). Lives in the shared home/sway.nix, so every Sway host is themed consistently. Vim already uses catppuccin_mocha, so the editor is unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) --- lyrathorpe/home/sway.nix | 188 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 183 insertions(+), 5 deletions(-) diff --git a/lyrathorpe/home/sway.nix b/lyrathorpe/home/sway.nix index fa7e9bb..2a86e58 100644 --- a/lyrathorpe/home/sway.nix +++ b/lyrathorpe/home/sway.nix @@ -14,6 +14,33 @@ portable ? true, ... }: +let + # Catppuccin Mocha. Raw 6-digit hex (no leading "#"); prefix "#" where a + # consumer needs it -- Sway/i3status/dunst want "#", foot/swaylock do not. + ctp = { + base = "1e1e2e"; + mantle = "181825"; + crust = "11111b"; + surface0 = "313244"; + surface1 = "45475a"; + surface2 = "585b70"; + overlay0 = "6c7086"; + subtext0 = "a6adc8"; + subtext1 = "bac2de"; + text = "cdd6f4"; + rosewater = "f5e0dc"; + red = "f38ba8"; + maroon = "eba0ac"; + peach = "fab387"; + yellow = "f9e2af"; + green = "a6e3a1"; + teal = "94e2d5"; + sapphire = "74c7ec"; + blue = "89b4fa"; + mauve = "cba6f7"; + pink = "f5c2e7"; + }; +in { wayland.windowManager.sway = { enable = true; @@ -34,6 +61,38 @@ xkb_variant = "dvorak"; }; + # Window borders -- Catppuccin Mocha (blue accent on the focused window). + colors = { + focused = { + border = "#${ctp.blue}"; + background = "#${ctp.base}"; + text = "#${ctp.text}"; + indicator = "#${ctp.blue}"; + childBorder = "#${ctp.blue}"; + }; + focusedInactive = { + border = "#${ctp.surface0}"; + background = "#${ctp.base}"; + text = "#${ctp.subtext0}"; + indicator = "#${ctp.surface0}"; + childBorder = "#${ctp.surface0}"; + }; + unfocused = { + border = "#${ctp.surface0}"; + background = "#${ctp.base}"; + text = "#${ctp.subtext0}"; + indicator = "#${ctp.surface0}"; + childBorder = "#${ctp.surface0}"; + }; + urgent = { + border = "#${ctp.red}"; + background = "#${ctp.base}"; + text = "#${ctp.text}"; + indicator = "#${ctp.red}"; + childBorder = "#${ctp.red}"; + }; + }; + window.commands = [ { criteria.app_id = "launcher"; @@ -52,6 +111,33 @@ ]; size = 11.0; }; + # Bar background + workspace buttons -- Catppuccin Mocha. The mantle + # background matches i3status-rust's idle_bg below for a uniform strip. + colors = { + background = "#${ctp.mantle}"; + statusline = "#${ctp.text}"; + separator = "#${ctp.surface0}"; + focusedWorkspace = { + border = "#${ctp.blue}"; + background = "#${ctp.blue}"; + text = "#${ctp.base}"; + }; + activeWorkspace = { + border = "#${ctp.surface0}"; + background = "#${ctp.surface0}"; + text = "#${ctp.text}"; + }; + inactiveWorkspace = { + border = "#${ctp.mantle}"; + background = "#${ctp.mantle}"; + text = "#${ctp.subtext0}"; + }; + urgentWorkspace = { + border = "#${ctp.red}"; + background = "#${ctp.red}"; + text = "#${ctp.base}"; + }; + }; } ]; @@ -79,13 +165,70 @@ }; }; - programs.swaylock = { + # Terminal: Catppuccin Mocha. foot reads ~/.config/foot/foot.ini; the Sway + # `terminal` above still launches the same binary, now themed. + programs.foot = { enable = true; settings = { - color = "1e1e2e"; + colors = { + background = ctp.base; + foreground = ctp.text; + regular0 = ctp.surface1; + regular1 = ctp.red; + regular2 = ctp.green; + regular3 = ctp.yellow; + regular4 = ctp.blue; + regular5 = ctp.pink; + regular6 = ctp.teal; + regular7 = ctp.subtext1; + bright0 = ctp.surface2; + bright1 = ctp.red; + bright2 = ctp.green; + bright3 = ctp.yellow; + bright4 = ctp.blue; + bright5 = ctp.pink; + bright6 = ctp.teal; + bright7 = ctp.subtext0; + "selection-foreground" = ctp.base; + "selection-background" = ctp.rosewater; + }; + cursor.color = "${ctp.base} ${ctp.rosewater}"; + }; + }; + + programs.swaylock = { + enable = true; + # Catppuccin Mocha (swaylock colours are hex without "#"). + settings = { + color = ctp.base; indicator-radius = 100; indicator-thickness = 7; show-failed-attempts = true; + font = "Noto Sans"; + + inside-color = ctp.base; + inside-clear-color = ctp.base; + inside-ver-color = ctp.base; + inside-wrong-color = ctp.base; + + ring-color = ctp.surface1; + ring-clear-color = ctp.yellow; + ring-ver-color = ctp.blue; + ring-wrong-color = ctp.red; + + key-hl-color = ctp.blue; + bs-hl-color = ctp.red; + + line-color = ctp.base; + line-clear-color = ctp.base; + line-ver-color = ctp.base; + line-wrong-color = ctp.base; + separator-color = "00000000"; + + text-color = ctp.text; + text-clear-color = ctp.text; + text-ver-color = ctp.text; + text-wrong-color = ctp.text; }; }; @@ -111,16 +254,30 @@ services.dunst = { enable = true; + # Catppuccin Mocha notifications (dunst colours need a leading "#"). settings = { global = { font = "Noto Sans 11"; - frame_color = "#89b4fa"; + frame_color = "#${ctp.blue}"; + frame_width = 2; separator_color = "frame"; offset = "10x10"; corner_radius = 5; }; + urgency_low = { + background = "#${ctp.base}"; + foreground = "#${ctp.text}"; + frame_color = "#${ctp.surface1}"; + }; + urgency_normal = { + background = "#${ctp.base}"; + foreground = "#${ctp.text}"; + frame_color = "#${ctp.blue}"; + }; urgency_critical = { - frame_color = "#fab387"; + background = "#${ctp.base}"; + foreground = "#${ctp.text}"; + frame_color = "#${ctp.peach}"; timeout = 0; }; }; @@ -129,8 +286,29 @@ programs.i3status-rust = { enable = true; bars.default = { - theme = "gruvbox-dark"; + # Catppuccin Mocha: a flat "plain" base recoloured via overrides. Idle + # blocks sit on mantle (matching the Sway bar background) with light text; + # only warning/critical states get a loud tinted background. The `theme` + # bar option is shallow-merged away by `settings.theme`, so set the base + # theme and its overrides together here. icons = "awesome6"; + settings.theme = { + theme = "plain"; + overrides = { + idle_bg = "#${ctp.mantle}"; + idle_fg = "#${ctp.text}"; + info_bg = "#${ctp.mantle}"; + info_fg = "#${ctp.blue}"; + good_bg = "#${ctp.mantle}"; + good_fg = "#${ctp.green}"; + warning_bg = "#${ctp.peach}"; + warning_fg = "#${ctp.base}"; + critical_bg = "#${ctp.red}"; + critical_fg = "#${ctp.base}"; + separator_bg = "#${ctp.mantle}"; + separator_fg = "#${ctp.surface1}"; + }; + }; blocks = [ { block = "disk_space";