From 90a9390f37769a99c4e23061e9e72d6dbf9454cd Mon Sep 17 00:00:00 2001 From: Mathias Date: Mon, 21 Sep 2026 22:39:09 +0200 Subject: [PATCH] consistent styling --- Makefile | 1 + README.md | 1 + basic/.config/themes/current | 1 + basic/.config/themes/scripts/new-theme.sh | 26 +++ basic/.config/themes/scripts/switch-theme.sh | 63 +++++++ basic/.config/themes/scripts/sync-theme.sh | 83 +++++++++ .../themes/themes/catppuccin-mocha/hypr.conf | 5 + .../themes/themes/catppuccin-mocha/kitty.conf | 88 ++++++++++ .../themes/themes/catppuccin-mocha/rofi.rasi | 33 ++++ .../themes/themes/catppuccin-mocha/theme.css | 53 ++++++ .../themes/catppuccin-mocha/theme.env.sh | 42 +++++ .../themes/themes/catppuccin-mocha/theme.fish | 25 +++ .../themes/themes/catppuccin-mocha/theme.lua | 87 ++++++++++ basic/.config/themes/themes/registry.conf | 10 ++ basic/.stow-ignore | 4 + basic/scripts/fetch-ports.sh | 32 ++++ hypr/.config/hypr/hyprland.lua | 29 +++- hypr/.config/hypr/hyprlock.conf | 16 +- hypr/.config/hypr/themes/download.sh | 6 - hypr/.config/hypr/themes/mocha.lua | 0 hypr/.config/kitty/kitty.conf | 3 +- hypr/.config/kitty/themes/download.sh | 6 - hypr/.config/kitty/themes/mocha.conf | 85 +--------- hypr/.config/rofi/themes/hyprltm-net.rasi | 157 ++++++++++++++++++ hypr/.config/rofi/themes/ltmnight.rasi | 67 ++++++++ hypr/.config/waybar/mocha.css | 1 + hypr/.config/waybar/style.css | 121 +++++++------- hypr/.config/waypaper/style.css | 20 ++- hypr/.config/wofi/mocha.css | 1 + hypr/.config/wofi/style.css | 69 ++++++++ term/.bashrc | 5 + term/.config/fish/config.fish | 5 + term/.config/nvim/lua/plugins/catppuccin.lua | 7 +- term/.config/starship.toml | 88 +--------- term/.config/tmux/tmux.conf | 6 +- term/.config/yazi/theme.toml | 5 + test/lint.sh | 16 ++ 37 files changed, 1004 insertions(+), 263 deletions(-) create mode 120000 basic/.config/themes/current create mode 100755 basic/.config/themes/scripts/new-theme.sh create mode 100755 basic/.config/themes/scripts/switch-theme.sh create mode 100755 basic/.config/themes/scripts/sync-theme.sh rename hypr/.config/hypr/themes/mocha.conf => basic/.config/themes/themes/catppuccin-mocha/hypr.conf (80%) create mode 100644 basic/.config/themes/themes/catppuccin-mocha/kitty.conf create mode 100644 basic/.config/themes/themes/catppuccin-mocha/rofi.rasi create mode 100644 basic/.config/themes/themes/catppuccin-mocha/theme.css create mode 100644 basic/.config/themes/themes/catppuccin-mocha/theme.env.sh create mode 100644 basic/.config/themes/themes/catppuccin-mocha/theme.fish create mode 100644 basic/.config/themes/themes/catppuccin-mocha/theme.lua create mode 100644 basic/.config/themes/themes/registry.conf create mode 100644 basic/.stow-ignore create mode 100755 basic/scripts/fetch-ports.sh delete mode 100755 hypr/.config/hypr/themes/download.sh delete mode 100644 hypr/.config/hypr/themes/mocha.lua delete mode 100755 hypr/.config/kitty/themes/download.sh mode change 100644 => 120000 hypr/.config/kitty/themes/mocha.conf create mode 100644 hypr/.config/rofi/themes/hyprltm-net.rasi create mode 100644 hypr/.config/rofi/themes/ltmnight.rasi create mode 120000 hypr/.config/waybar/mocha.css create mode 120000 hypr/.config/wofi/mocha.css create mode 100644 hypr/.config/wofi/style.css diff --git a/Makefile b/Makefile index 9b5b8ea..a8b71b0 100644 --- a/Makefile +++ b/Makefile @@ -7,6 +7,7 @@ # untereinander unabhaengig. basic: bash basic/setup.sh + stow --ignore='.stow-ignore' --ignore='scripts' --ignore='setup.sh' --ignore='packages.txt' basic term: basic bash term/scripts/setup.sh diff --git a/README.md b/README.md index 0b7c1a4..4d19471 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ Personal configuration files for an Arch Linux workstation (Hyprland + Neovim + | Directory | Contents | |-----------|----------| +| `basic/` | Base system packages + the **central theme** (`basic/.config/themes` → `~/.config/themes`: Catppuccin Mocha palette, `current` symlink, `switch-theme.sh`/`sync-theme.sh`). All other packages reference it instead of copying colors. | | `term/` | Fish + kitty + starship + nvim + tmux + yazi + fastfetch + opencode terminal environment | | `hypr/` | Hyprland compositor config, kitty theme, waypaper/hyprpaper wallpapers | | `kreation/`| VST plugin (`MT-PowerDrumKit.vst3`) | diff --git a/basic/.config/themes/current b/basic/.config/themes/current new file mode 120000 index 0000000..9b2b05b --- /dev/null +++ b/basic/.config/themes/current @@ -0,0 +1 @@ +themes/catppuccin-mocha \ No newline at end of file diff --git a/basic/.config/themes/scripts/new-theme.sh b/basic/.config/themes/scripts/new-theme.sh new file mode 100755 index 0000000..5441a05 --- /dev/null +++ b/basic/.config/themes/scripts/new-theme.sh @@ -0,0 +1,26 @@ +#!/bin/bash +# Scaffold a new theme directory (basic/.config/themes/scripts/new-theme.sh). +# +# Usage: new-theme.sh e.g. new-theme.sh rose-pine-moon +# +# Copies themes/catppuccin-mocha as a template. Afterwards: +# 1. Replace every palette value in the new directory. +# 2. Add one row to themes/registry.conf. +# 3. Run scripts/switch-theme.sh to try it. + +set -euo pipefail + +REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../.." && pwd)" +THEMES_DIR="$REPO_ROOT/basic/.config/themes/themes" + +[[ $# -eq 1 ]] || { echo "usage: $(basename "$0") " >&2; exit 1; } +theme_id="$1" +if [[ ! "$theme_id" =~ ^[a-z0-9][a-z0-9-]*$ ]]; then + echo "error: invalid theme-id '$theme_id'" >&2 + exit 1 +fi +[[ -e "$THEMES_DIR/$theme_id" ]] && { echo "error: $theme_id already exists" >&2; exit 1; } + +cp -r "$THEMES_DIR/catppuccin-mocha" "$THEMES_DIR/$theme_id" +echo "scaffolded $THEMES_DIR/$theme_id" +echo "next: replace the palette values, add a registry.conf row, run switch-theme.sh $theme_id" diff --git a/basic/.config/themes/scripts/switch-theme.sh b/basic/.config/themes/scripts/switch-theme.sh new file mode 100755 index 0000000..fbe41e8 --- /dev/null +++ b/basic/.config/themes/scripts/switch-theme.sh @@ -0,0 +1,63 @@ +#!/bin/bash +# Central theme switcher (basic/.config/themes/scripts/switch-theme.sh). +# +# Usage: switch-theme.sh e.g. switch-theme.sh catppuccin-mocha +# +# Retargets the tracked `current` symlink to themes/ and reloads +# every consumer that can be reloaded. Because `current` lives in the repo, +# the switch is a reviewable git change; re-stowing is not required since +# all consumers resolve through ~/.config/themes/current at runtime. +# +# A future non-Catppuccin theme only needs its own themes// +# directory plus a row in themes/registry.conf — this script stays untouched. + +set -euo pipefail + +usage() { + echo "usage: $(basename "$0") " >&2 + echo "available:" >&2 + ls -1 "$(repo_root)/basic/.config/themes/themes" 2>/dev/null | grep -v '^registry.conf$' | sed 's/^/ /' >&2 || true +} + +repo_root() { + local src="$0" + if command -v readlink >/dev/null 2>&1; then + src="$(readlink -f "$0")" + fi + cd "$(dirname "$src")/../../../.." && pwd +} + +main() { + [[ $# -eq 1 ]] || { usage; exit 1; } + local theme_id="$1" + if [[ ! "$theme_id" =~ ^[a-z0-9][a-z0-9-]*$ ]]; then + echo "error: invalid theme-id '$theme_id'" >&2 + exit 1 + fi + + local root + root="$(repo_root)" + local dest="$root/basic/.config/themes/themes/$theme_id" + local link="$root/basic/.config/themes/current" + + [[ -d "$dest" ]] || { echo "error: unknown theme '$theme_id' (no $dest)" >&2; usage; exit 1; } + + ln -sfn "themes/$theme_id" "$link" + echo "theme switched: current -> themes/$theme_id" + + # Best-effort live reloads; every step is guarded so the switch + # succeeds even on machines without a running compositor. + if command -v hyprctl >/dev/null 2>&1; then + hyprctl reload >/dev/null 2>&1 || true + fi + if command -v tmux >/dev/null 2>&1 && [[ -n "${TMUX:-}" ]]; then + tmux source-file "$HOME/.config/tmux/tmux.conf" >/dev/null 2>&1 || true + fi + if pgrep -x waybar >/dev/null 2>&1; then + pkill -x waybar >/dev/null 2>&1 || true + (waybar >/dev/null 2>&1 &) || true + fi + echo "note: restart Neovim (or :colorscheme \$THEME_NVIM_COLORSCHEME) and open a new shell to pick up theme.env.sh." +} + +main "$@" diff --git a/basic/.config/themes/scripts/sync-theme.sh b/basic/.config/themes/scripts/sync-theme.sh new file mode 100755 index 0000000..0e84cc6 --- /dev/null +++ b/basic/.config/themes/scripts/sync-theme.sh @@ -0,0 +1,83 @@ +#!/bin/bash +# Central theme drift guard (basic/.config/themes/scripts/sync-theme.sh). +# +# Fails if hardcoded theme hex values appear anywhere in the repo outside: +# - basic/.config/themes (the single source of truth) +# - term/.config/tmux/plugins/ (vendored upstream, stow-ignored) +# - term/.config/yazi/theme.toml (declared mirror: yazi has no include) +# - term/.config/starship.toml (declared mirror: starship has no include) +# - hypr/.config/rofi/themes/ltmnight.rasi (declared mirror: rasi has no +# alpha() function, so the two translucency values are #RRGGBBAA hex; +# everything else maps onto the central theme via @import) +# - test/ + docs (may quote values in prose) +# +# Run with: bash basic/.config/themes/scripts/sync-theme.sh +# test/lint.sh invokes it as part of `make test-lint`. + +set -uo pipefail + +REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../.." && pwd)" +cd "$REPO_ROOT" || exit 1 + +# Sentinel hex values of the active palette (case-insensitive). +SENTINELS='74c7ec|1e1e2e|cdd6f4|45475a|b4befe|f38ba8|a6e3a1|f9e2af|181825|11111b|89b4fa|f5e0dc' + +matches="$(grep -rniE --include='*.conf' --include='*.css' --include='*.rasi' \ + --include='*.lua' --include='*.toml' --include='*.fish' --include='*.sh' \ + --exclude-dir='.git' --exclude-dir='plugins' --exclude-dir='test' \ + -E "$SENTINELS" . 2>/dev/null | grep -vE '^./basic/.config/themes' \ + | grep -vE 'term/.config/(yazi/theme.toml|starship.toml)' \ + | grep -vE 'hypr/.config/rofi/themes/ltmnight.rasi' || true)" + +if [[ -n "$matches" ]]; then + echo "FAIL: hardcoded theme colors outside basic/.config/themes (and declared mirrors):" + printf '%s\n' "$matches" | sed 's/^/ /' + echo "Move the values into basic/.config/themes and reference them instead." + exit 1 +fi + +echo "ok: no hardcoded theme colors outside the central theme" + +# --------------------------------------------------------------------------- +# Role/palette consistency: every role in theme.css must equal its palette +# twin (roles are literal hex because some parsers drop @-references). +# --------------------------------------------------------------------------- +python3 - <<'EOF' +import re, sys + +css_path = "basic/.config/themes/themes/catppuccin-mocha/theme.css" +defines = dict(re.findall(r"@define-color\s+([a-z0-9_]+)\s+(#[0-9a-fA-F]+)", open(css_path).read())) + +# role -> palette twin (bg_translucent intentionally excluded: crust + alpha). +pairs = { + "bg": "base", "bg_dim": "mantle", "bg_deep": "crust", + "fg": "text", "fg_dim": "subtext0", "fg_muted": "overlay1", + "surface": "surface0", "border": "surface1", + "accent": "sapphire", "accent2": "lavender", + "ok": "green", "warn": "yellow", "urgent": "red", +} + +missing = [k for k in list(pairs) + list(pairs.values()) if k not in defines] +if missing: + print(f"FAIL: theme.css missing defines: {sorted(missing)}") + sys.exit(1) + +bad = [r for r, p in pairs.items() if defines[r].lower() != defines[p].lower()] +if bad: + print(f"FAIL: roles out of sync with palette in {css_path}: {bad}") + sys.exit(1) + +trans = defines.get("bg_translucent_raw", "") +m = re.fullmatch(r"rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*([0-9.]+)\s*\)", trans) +if not m: + # defines[] regex only captures #hex; re-read raw value (may be rgba()). + raw = re.search(r"@define-color\s+bg_translucent\s+([^;]+);", open(css_path).read()) + trans = raw.group(1).strip() if raw else "" + m = re.fullmatch(r"rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*([0-9.]+)\s*\)", trans) +crust_rgb = tuple(int(defines["crust"][i:i+2], 16) for i in (1, 3, 5)) +if not m or tuple(map(int, m.groups()[:3])) != crust_rgb or not (0 < float(m.group(4)) < 1): + print(f"FAIL: bg_translucent must be rgba(crust, alpha<1) in {css_path}") + sys.exit(1) + +print("ok: theme.css roles match palette") +EOF diff --git a/hypr/.config/hypr/themes/mocha.conf b/basic/.config/themes/themes/catppuccin-mocha/hypr.conf similarity index 80% rename from hypr/.config/hypr/themes/mocha.conf rename to basic/.config/themes/themes/catppuccin-mocha/hypr.conf index 8ccb56a..900fce9 100644 --- a/hypr/.config/hypr/themes/mocha.conf +++ b/basic/.config/themes/themes/catppuccin-mocha/hypr.conf @@ -1,3 +1,8 @@ +# Central theme: catppuccin-mocha (Catppuccin Mocha), hyprland $vars. +# Part of basic/.config/themes. Managed file: refresh via +# basic/scripts/fetch-ports.sh +# (upstream: catppuccin/hyprland generated mocha.conf). +# Hyprland consumers load it via: source = ~/.config/themes/current/hypr.conf $rosewater = rgb(f5e0dc) $rosewaterAlpha = f5e0dc diff --git a/basic/.config/themes/themes/catppuccin-mocha/kitty.conf b/basic/.config/themes/themes/catppuccin-mocha/kitty.conf new file mode 100644 index 0000000..4d37c4e --- /dev/null +++ b/basic/.config/themes/themes/catppuccin-mocha/kitty.conf @@ -0,0 +1,88 @@ +# Central theme: catppuccin-mocha (Catppuccin Mocha), kitty colors. +# Part of basic/.config/themes. Managed file: refresh via +# basic/scripts/fetch-ports.sh +# (upstream: catppuccin/kitty themes/mocha.conf). +# vim:ft=kitty + +## name: Catppuccin Kitty Mocha +## author: Catppuccin Org +## license: MIT +## upstream: https://github.com/catppuccin/kitty/blob/main/themes/mocha.conf +## blurb: Soothing pastel theme for the high-spirited! + + + +# The basic colors +foreground #cdd6f4 +background #1e1e2e +selection_foreground #1e1e2e +selection_background #f5e0dc + +# Cursor colors +cursor #f5e0dc +cursor_text_color #1e1e2e + +# Scrollbar colors +scrollbar_handle_color #9399b2 +scrollbar_track_color #45475a + +# URL color when hovering with mouse +url_color #f5e0dc + +# Kitty window border colors +active_border_color #b4befe +inactive_border_color #6c7086 +bell_border_color #f9e2af + +# OS Window titlebar colors +wayland_titlebar_color system +macos_titlebar_color system + +# Tab bar colors +active_tab_foreground #11111b +active_tab_background #cba6f7 +inactive_tab_foreground #cdd6f4 +inactive_tab_background #181825 +tab_bar_background #11111b + +# Colors for marks (marked text in the terminal) +mark1_foreground #1e1e2e +mark1_background #b4befe +mark2_foreground #1e1e2e +mark2_background #cba6f7 +mark3_foreground #1e1e2e +mark3_background #74c7ec + +# The 16 terminal colors + +# black +color0 #45475a +color8 #585b70 + +# red +color1 #f38ba8 +color9 #f38ba8 + +# green +color2 #a6e3a1 +color10 #a6e3a1 + +# yellow +color3 #f9e2af +color11 #f9e2af + +# blue +color4 #89b4fa +color12 #89b4fa + +# magenta +color5 #f5c2e7 +color13 #f5c2e7 + +# cyan +color6 #94e2d5 +color14 #94e2d5 + +# white +color7 #bac2de +color15 #a6adc8 diff --git a/basic/.config/themes/themes/catppuccin-mocha/rofi.rasi b/basic/.config/themes/themes/catppuccin-mocha/rofi.rasi new file mode 100644 index 0000000..dd65e9d --- /dev/null +++ b/basic/.config/themes/themes/catppuccin-mocha/rofi.rasi @@ -0,0 +1,33 @@ +/* Central theme: catppuccin-mocha (Catppuccin Mocha), rofi palette. + * Part of basic/.config/themes. Managed file: refresh via + * basic/scripts/fetch-ports.sh + * (upstream: catppuccin/rofi themes/catppuccin-mocha.rasi). */ +* { + rosewater: #f5e0dc; + flamingo: #f2cdcd; + pink: #f5c2e7; + mauve: #cba6f7; + red: #f38ba8; + maroon: #eba0ac; + peach: #fab387; + yellow: #f9e2af; + green: #a6e3a1; + teal: #94e2d5; + sky: #89dceb; + sapphire: #74c7ec; + blue: #89b4fa; + lavender: #b4befe; + text: #cdd6f4; + subtext1: #bac2de; + subtext0: #a6adc8; + overlay2: #9399b2; + overlay1: #7f849c; + overlay0: #6c7086; + surface2: #585b70; + surface1: #45475a; + surface0: #313244; + base: #1e1e2e; + mantle: #181825; + crust: #11111b; +} + diff --git a/basic/.config/themes/themes/catppuccin-mocha/theme.css b/basic/.config/themes/themes/catppuccin-mocha/theme.css new file mode 100644 index 0000000..aa354f5 --- /dev/null +++ b/basic/.config/themes/themes/catppuccin-mocha/theme.css @@ -0,0 +1,53 @@ +/* Central theme: catppuccin-mocha (Catppuccin Mocha). + * Part of basic/.config/themes. Managed file: refresh via + * basic/scripts/fetch-ports.sh (upstream: catppuccin/waybar themes/mocha.css), + * then re-apply the role aliases below. Consumers must use this file via + * ~/.config/themes/current/theme.css, never a private copy. + * Role aliases (stable interface, theme-agnostic) follow the palette. */ +@define-color rosewater #f5e0dc; +@define-color flamingo #f2cdcd; +@define-color pink #f5c2e7; +@define-color mauve #cba6f7; +@define-color red #f38ba8; +@define-color maroon #eba0ac; +@define-color peach #fab387; +@define-color yellow #f9e2af; +@define-color green #a6e3a1; +@define-color teal #94e2d5; +@define-color sky #89dceb; +@define-color sapphire #74c7ec; +@define-color blue #89b4fa; +@define-color lavender #b4befe; +@define-color text #cdd6f4; +@define-color subtext1 #bac2de; +@define-color subtext0 #a6adc8; +@define-color overlay2 #9399b2; +@define-color overlay1 #7f849c; +@define-color overlay0 #6c7086; +@define-color surface2 #585b70; +@define-color surface1 #45475a; +@define-color surface0 #313244; +@define-color base #1e1e2e; +@define-color mantle #181825; +@define-color crust #11111b; + +/* ---- Stable role interface (theme-agnostic; consumers use THESE) ---- + * NOTE: values are literal hex, NOT @references to the palette above. + * Some parsers (wofi/waybar Gtk.CssProvider paths) silently drop + * @define-color lines that reference another @color, which made every + * background transparent. Keep each role in sync with its palette twin + * (mapping below); scripts/sync-theme.sh verifies this mechanically. */ +@define-color bg #1e1e2e; /* = @base */ +@define-color bg_dim #181825; /* = @mantle */ +@define-color bg_deep #11111b; /* = @crust */ +@define-color bg_translucent rgba(17, 17, 27, 0.85); /* crust at 85% (translucent window bg) */ +@define-color fg #cdd6f4; /* = @text */ +@define-color fg_dim #a6adc8; /* = @subtext0 */ +@define-color fg_muted #7f849c; /* = @overlay1 */ +@define-color surface #313244; /* = @surface0 */ +@define-color border #45475a; /* = @surface1 */ +@define-color accent #74c7ec; /* = @sapphire */ +@define-color accent2 #b4befe; /* = @lavender */ +@define-color ok #a6e3a1; /* = @green */ +@define-color warn #f9e2af; /* = @yellow */ +@define-color urgent #f38ba8; /* = @red */ diff --git a/basic/.config/themes/themes/catppuccin-mocha/theme.env.sh b/basic/.config/themes/themes/catppuccin-mocha/theme.env.sh new file mode 100644 index 0000000..27251f8 --- /dev/null +++ b/basic/.config/themes/themes/catppuccin-mocha/theme.env.sh @@ -0,0 +1,42 @@ +# Central theme interface: catppuccin-mocha (Catppuccin Mocha). +# Part of basic/.config/themes. Managed file: edit the palette here. +# Sourced by POSIX shells (~/.bashrc) and by Hyprland-launched apps. +# Generic THEME_* vars are the stable, theme-agnostic interface; the +# CATPPUCCIN_* / palette vars below exist because lazy.nvim, TPM and +# starship need the literal upstream names. A future non-Catppuccin theme +# only adds a new directory exporting the same THEME_* names. + +export THEME_NAME="catppuccin" +export THEME_FLAVOR="mocha" +export THEME_ID="catppuccin-mocha" + +# Generic roles (stable interface). +export THEME_BG="#1e1e2e" +export THEME_BG_DIM="#181825" +export THEME_FG="#cdd6f4" +export THEME_FG_DIM="#a6adc8" +export THEME_SURFACE="#313244" +export THEME_BORDER="#45475a" +export THEME_ACCENT="#74c7ec" +export THEME_ACCENT2="#b4befe" +export THEME_OK="#a6e3a1" +export THEME_WARN="#f9e2af" +export THEME_URGENT="#f38ba8" + +# Plugin / colorscheme mapping (see ../registry.conf). +export THEME_NVIM_COLORSCHEME="catppuccin" +export THEME_TMUX_PLUGIN="catppuccin/tmux" +export THEME_GTK="Adwaita:dark" + +# Upstream literal names (compat for lazy.nvim / TPM / starship). +export CATPPUCCIN_FLAVOR="mocha" +export CATPPUCCIN_BASE="#1e1e2e" +export CATPPUCCIN_MANTLE="#181825" +export CATPPUCCIN_CRUST="#11111b" +export CATPPUCCIN_TEXT="#cdd6f4" +export CATPPUCCIN_SAPPHIRE="#74c7ec" +export CATPPUCCIN_LAVENDER="#b4befe" +export CATPPUCCIN_SURFACE1="#45475a" +export CATPPUCCIN_RED="#f38ba8" +export CATPPUCCIN_GREEN="#a6e3a1" +export CATPPUCCIN_YELLOW="#f9e2af" diff --git a/basic/.config/themes/themes/catppuccin-mocha/theme.fish b/basic/.config/themes/themes/catppuccin-mocha/theme.fish new file mode 100644 index 0000000..c9f64ab --- /dev/null +++ b/basic/.config/themes/themes/catppuccin-mocha/theme.fish @@ -0,0 +1,25 @@ +# Central theme interface: catppuccin-mocha (Catppuccin Mocha). +# Fish companion of theme.env.sh. Sourced from fish/config.fish. +# Managed file: edit the palette here, not in consumers. + +set -gx THEME_NAME "catppuccin" +set -gx THEME_FLAVOR "mocha" +set -gx THEME_ID "catppuccin-mocha" + +set -gx THEME_BG "#1e1e2e" +set -gx THEME_BG_DIM "#181825" +set -gx THEME_FG "#cdd6f4" +set -gx THEME_FG_DIM "#a6adc8" +set -gx THEME_SURFACE "#313244" +set -gx THEME_BORDER "#45475a" +set -gx THEME_ACCENT "#74c7ec" +set -gx THEME_ACCENT2 "#b4befe" +set -gx THEME_OK "#a6e3a1" +set -gx THEME_WARN "#f9e2af" +set -gx THEME_URGENT "#f38ba8" + +set -gx THEME_NVIM_COLORSCHEME "catppuccin" +set -gx THEME_TMUX_PLUGIN "catppuccin/tmux" +set -gx THEME_GTK "Adwaita:dark" + +set -gx CATPPUCCIN_FLAVOR "mocha" diff --git a/basic/.config/themes/themes/catppuccin-mocha/theme.lua b/basic/.config/themes/themes/catppuccin-mocha/theme.lua new file mode 100644 index 0000000..408b3ab --- /dev/null +++ b/basic/.config/themes/themes/catppuccin-mocha/theme.lua @@ -0,0 +1,87 @@ +-- Central theme interface: catppuccin-mocha (Catppuccin Mocha). +-- Part of basic/.config/themes. Managed file: edit the palette here. +-- Consumers (hyprland.lua, hyprlock helpers) load this via +-- dofile(os.getenv("HOME") .. "/.config/themes/current/theme.lua") +-- and must use the generic roles (bg/fg/accent/...) so a future +-- non-Catppuccin theme only adds a new directory. Full palette is +-- passed through for components that need specific colors. +-- Hyprland color syntax: "rgb(hex)" / "rgba(hexaa)". + +local T = { + name = "catppuccin", + flavor = "mocha", + + hex = { + rosewater = "f5e0dc", + flamingo = "f2cdcd", + pink = "f5c2e7", + mauve = "cba6f7", + red = "f38ba8", + maroon = "eba0ac", + peach = "fab387", + yellow = "f9e2af", + green = "a6e3a1", + teal = "94e2d5", + sky = "89dceb", + sapphire = "74c7ec", + blue = "89b4fa", + lavender = "b4befe", + text = "cdd6f4", + subtext1 = "bac2de", + subtext0 = "a6adc8", + overlay2 = "9399b2", + overlay1 = "7f849c", + overlay0 = "6c7086", + surface2 = "585b70", + surface1 = "45475a", + surface0 = "313244", + base = "1e1e2e", + mantle = "181825", + crust = "11111b", + }, + + -- Generic roles (stable interface, theme-agnostic). + bg = "rgba(1e1e2eee)", + bg_dim = "rgb(181825)", + fg = "rgb(cdd6f4)", + fg_dim = "rgb(a6adc8)", + surface = "rgb(313244)", + border_active = "rgba(74c7ecee)", + border_inactive = "rgba(45475aee)", + shadow = "rgba(74c7ecee)", + accent = "rgb(74c7ec)", + accent2 = "rgb(b4befe)", + ok = "rgb(a6e3a1)", + warn = "rgb(f9e2af)", + urgent = "rgb(f38ba8)", + + -- Full palette passthrough (hyprland syntax). + rosewater = "rgb(f5e0dc)", + flamingo = "rgb(f2cdcd)", + pink = "rgb(f5c2e7)", + mauve = "rgb(cba6f7)", + red = "rgb(f38ba8)", + maroon = "rgb(eba0ac)", + peach = "rgb(fab387)", + yellow = "rgb(f9e2af)", + green = "rgb(a6e3a1)", + teal = "rgb(94e2d5)", + sky = "rgb(89dceb)", + sapphire = "rgb(74c7ec)", + blue = "rgb(89b4fa)", + lavender = "rgb(b4befe)", + text = "rgb(cdd6f4)", + subtext1 = "rgb(bac2de)", + subtext0 = "rgb(a6adc8)", + overlay2 = "rgb(9399b2)", + overlay1 = "rgb(7f849c)", + overlay0 = "rgb(6c7086)", + surface2 = "rgb(585b70)", + surface1 = "rgb(45475a)", + surface0 = "rgb(313244)", + base = "rgb(1e1e2e)", + mantle = "rgb(181825)", + crust = "rgb(11111b)", +} + +return T diff --git a/basic/.config/themes/themes/registry.conf b/basic/.config/themes/themes/registry.conf new file mode 100644 index 0000000..67d7535 --- /dev/null +++ b/basic/.config/themes/themes/registry.conf @@ -0,0 +1,10 @@ +# Central theme registry (basic/.config/themes/themes/registry.conf). +# +# One row per installed theme. Columns (pipe-separated): +# theme-id | nvim colorscheme | tmux plugin | gtk theme | notes +# +# Consumers must branch on THEME_ID / THEME_NVIM_COLORSCHEME / +# THEME_TMUX_PLUGIN only — never on hardcoded theme names elsewhere. +# Adding a future non-Catppuccin theme means: scaffold the directory with +# scripts/new-theme.sh, fill in its palette, add one row here. +catppuccin-mocha|catppuccin|catppuccin/tmux|Adwaita:dark|default; Catppuccin Mocha everywhere diff --git a/basic/.stow-ignore b/basic/.stow-ignore new file mode 100644 index 0000000..94fffe5 --- /dev/null +++ b/basic/.stow-ignore @@ -0,0 +1,4 @@ +setup.sh +packages.txt +scripts +.stow-ignore diff --git a/basic/scripts/fetch-ports.sh b/basic/scripts/fetch-ports.sh new file mode 100755 index 0000000..f4012e9 --- /dev/null +++ b/basic/scripts/fetch-ports.sh @@ -0,0 +1,32 @@ +#!/bin/bash +# Refresh vendored upstream port files (basic/scripts/fetch-ports.sh). +# +# This script is intentionally NOT stowed (basic/.stow-ignore) and NOT run +# by the test harness: it contacts the network. Run it manually when you +# want to pull newer upstream Catppuccin ports into the central theme: +# +# bash basic/scripts/fetch-ports.sh +# +# The central palette (theme.lua / theme.css roles / hypr.conf) remains the +# source of truth; after fetching, re-apply the provenance headers and the +# role-alias block at the end of theme.css if upstream overwrote them. + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +DEST="$SCRIPT_DIR/../.config/themes/themes/catppuccin-mocha" + +# Pinned upstream revisions (bump deliberately, then run this script). +KITTY_PIN="main" +WAYBAR_PIN="main" +ROFI_PIN="main" + +curl -fsSL "https://raw.githubusercontent.com/catppuccin/kitty/${KITTY_PIN}/themes/mocha.conf" \ + -o "$DEST/kitty.conf" +curl -fsSL "https://raw.githubusercontent.com/catppuccin/waybar/${WAYBAR_PIN}/themes/mocha.css" \ + -o "$DEST/theme.css" +curl -fsSL "https://raw.githubusercontent.com/catppuccin/rofi/${ROFI_PIN}/themes/catppuccin-mocha.rasi" \ + -o "$DEST/rofi.rasi" + +echo "ports refreshed into $DEST" +echo "reminder: re-apply file headers + theme.css role aliases, then run scripts/sync-theme.sh" diff --git a/hypr/.config/hypr/hyprland.lua b/hypr/.config/hypr/hyprland.lua index 0b8d0ce..fe197a7 100644 --- a/hypr/.config/hypr/hyprland.lua +++ b/hypr/.config/hypr/hyprland.lua @@ -1,6 +1,11 @@ -local var_color_active_border = "rgba(74c7ecee)" -local var_color_inactive_border = "rgba(45475aee)" -local var_color_decoration_shadow = "rgba(74c7ecee)" +-- Central theme (basic/.config/themes): single source of truth for colors. +-- Consumers must use `theme.*` roles, never hardcoded hex, so a future +-- non-Catppuccin theme only adds a new directory. (HyprMod's +-- hyprland-gui.conf may additionally override borders at runtime.) +local theme = dofile(os.getenv("HOME") .. "/.config/themes/current/theme.lua") +local var_color_active_border = theme.border_active +local var_color_inactive_border = theme.border_inactive +local var_color_decoration_shadow = theme.shadow local var_mainMod = "SUPER" local var_terminal = "kitty" local var_fileManager = "dolphin" @@ -53,7 +58,7 @@ hl.env("XDG_SESSION_DESKTOP", "Hyprland") hl.env("XDG_SESSION_TYPE", "wayland") hl.env("XDG_MENU_PREFIX", "plasma-") hl.env("GTK_USE_PORTAL", "1") -hl.env("GTK_THEME", "Adwaita:dark") +hl.env("GTK_THEME", os.getenv("THEME_GTK") or "Adwaita:dark") hl.env("QT_WAYLAND_DISABLE_WINDOWDECORATION", "1") hl.env("QT_QPA_PLATFORMTHEME", "kde") @@ -65,7 +70,7 @@ hl.env("QT_QPA_PLATFORMTHEME", "kde") -- ## COLOR SCHEMES ### -- #################### -require("themes.mocha") +-- (Colors come from the central theme via `theme` above; no per-file copies.) -- #################### -- ## LOOK AND FEEL ### @@ -699,6 +704,20 @@ hl.layer_rule({ }, blur_popups = true, }) +-- Central theme: blur behind the wofi popups (SUPER+SPACE drun, SUPER+K +-- keybind help), whose window itself is translucent (@bg_translucent). +hl.layer_rule({ + match = { + namespace = "wofi", + }, + blur = true, +}) +hl.layer_rule({ + match = { + namespace = "wofi", + }, + blur_popups = true, +}) hl.window_rule({ name = "no-rounding-fullscreen", match = { diff --git a/hypr/.config/hypr/hyprlock.conf b/hypr/.config/hypr/hyprlock.conf index 94b887e..43e598b 100755 --- a/hypr/.config/hypr/hyprlock.conf +++ b/hypr/.config/hypr/hyprlock.conf @@ -9,6 +9,11 @@ # you can get started by copying this config to ~/.config/hypr/hyprlock.conf # +# Central theme: palette variables ($sapphire, $text, ...) come from +# basic/.config/themes via ~/.config/themes/current/hypr.conf. +# Edit colors there, never hardcoded values here. +source = ~/.config/themes/current/hypr.conf + $font = Monospace general { @@ -45,11 +50,11 @@ input-field { outline_thickness = 3 inner_color = rgba(0, 0, 0, 0.0) # no fill - outer_color = rgba(33ccffee) rgba(00ff99ee) 45deg - check_color = rgba(00ff99ee) rgba(ff6633ee) 120deg - fail_color = rgba(ff6633ee) rgba(ff0066ee) 40deg + outer_color = $sapphire $lavender 45deg + check_color = $sapphire $peach 120deg + fail_color = $maroon $red 40deg - font_color = rgb(143, 143, 143) + font_color = $subtext0 fade_on_empty = false rounding = 15 @@ -74,6 +79,7 @@ input-field { label { monitor = text = $TIME # ref. https://wiki.hyprland.org/Hypr-Ecosystem/hyprlock/#variable-substitution + color = $text font_size = 90 font_family = $font @@ -86,6 +92,7 @@ label { label { monitor = text = cmd[update:60000] date +"%A, %d %B %Y" # update every 60 seconds + color = $subtext0 font_size = 25 font_family = $font @@ -97,6 +104,7 @@ label { label { monitor = text = $LAYOUT[en,ru] + color = $subtext0 font_size = 24 onclick = hyprctl switchxkblayout all next diff --git a/hypr/.config/hypr/themes/download.sh b/hypr/.config/hypr/themes/download.sh deleted file mode 100755 index 4ff149d..0000000 --- a/hypr/.config/hypr/themes/download.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash - -out_dir="$HOME/dotfiles/themes/.config/catppuccin/mocha.conf" -url="https://raw.githubusercontent.com/catppuccin/hyprland/main/themes/mocha.conf" - -curl -o "$out_dir" "$url" diff --git a/hypr/.config/hypr/themes/mocha.lua b/hypr/.config/hypr/themes/mocha.lua deleted file mode 100644 index e69de29..0000000 diff --git a/hypr/.config/kitty/kitty.conf b/hypr/.config/kitty/kitty.conf index 4e5651d..61ad021 100644 --- a/hypr/.config/kitty/kitty.conf +++ b/hypr/.config/kitty/kitty.conf @@ -3,7 +3,8 @@ map ctrl+shift+c copy_to_clipboard map ctrl+shift+v paste_from_clipboard copy_on_select yes -# Coloer theme +# Color theme: central theme (basic/.config/themes). themes/mocha.conf is a +# symlink into the central palette — edit colors there, never here. include themes/mocha.conf # Font diff --git a/hypr/.config/kitty/themes/download.sh b/hypr/.config/kitty/themes/download.sh deleted file mode 100755 index 6257636..0000000 --- a/hypr/.config/kitty/themes/download.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash - -out_dir="$HOME/dotfiles/themes/.config/themes/kitty/catppuccin/mocha.conf" -url="https://raw.githubusercontent.com/catppuccin/kitty/main/themes/mocha.conf" - -curl -o "$out_dir" "$url" diff --git a/hypr/.config/kitty/themes/mocha.conf b/hypr/.config/kitty/themes/mocha.conf deleted file mode 100644 index 6eb38be..0000000 --- a/hypr/.config/kitty/themes/mocha.conf +++ /dev/null @@ -1,84 +0,0 @@ -# vim:ft=kitty - -## name: Catppuccin Kitty Mocha -## author: Catppuccin Org -## license: MIT -## upstream: https://github.com/catppuccin/kitty/blob/main/themes/mocha.conf -## blurb: Soothing pastel theme for the high-spirited! - - - -# The basic colors -foreground #cdd6f4 -background #1e1e2e -selection_foreground #1e1e2e -selection_background #f5e0dc - -# Cursor colors -cursor #f5e0dc -cursor_text_color #1e1e2e - -# Scrollbar colors -scrollbar_handle_color #9399b2 -scrollbar_track_color #45475a - -# URL color when hovering with mouse -url_color #f5e0dc - -# Kitty window border colors -active_border_color #b4befe -inactive_border_color #6c7086 -bell_border_color #f9e2af - -# OS Window titlebar colors -wayland_titlebar_color system -macos_titlebar_color system - -# Tab bar colors -active_tab_foreground #11111b -active_tab_background #cba6f7 -inactive_tab_foreground #cdd6f4 -inactive_tab_background #181825 -tab_bar_background #11111b - -# Colors for marks (marked text in the terminal) -mark1_foreground #1e1e2e -mark1_background #b4befe -mark2_foreground #1e1e2e -mark2_background #cba6f7 -mark3_foreground #1e1e2e -mark3_background #74c7ec - -# The 16 terminal colors - -# black -color0 #45475a -color8 #585b70 - -# red -color1 #f38ba8 -color9 #f38ba8 - -# green -color2 #a6e3a1 -color10 #a6e3a1 - -# yellow -color3 #f9e2af -color11 #f9e2af - -# blue -color4 #89b4fa -color12 #89b4fa - -# magenta -color5 #f5c2e7 -color13 #f5c2e7 - -# cyan -color6 #94e2d5 -color14 #94e2d5 - -# white -color7 #bac2de -color15 #a6adc8 diff --git a/hypr/.config/kitty/themes/mocha.conf b/hypr/.config/kitty/themes/mocha.conf new file mode 120000 index 0000000..83ea2cc --- /dev/null +++ b/hypr/.config/kitty/themes/mocha.conf @@ -0,0 +1 @@ +../../../../basic/.config/themes/themes/catppuccin-mocha/kitty.conf \ No newline at end of file diff --git a/hypr/.config/rofi/themes/hyprltm-net.rasi b/hypr/.config/rofi/themes/hyprltm-net.rasi new file mode 100644 index 0000000..274802a --- /dev/null +++ b/hypr/.config/rofi/themes/hyprltm-net.rasi @@ -0,0 +1,157 @@ +// Managed by dotfiles: hypr/.config/rofi/themes/hyprltm-net.rasi +// (stowed to ~/.config/rofi/themes/hyprltm-net.rasi). +// Third-party layout from hyprltm-net 0.5.0 (Djalel Oukid), kept structurally +// identical: all colors resolve through @theme "ltmnight" (ltmnight.rasi), +// which maps onto the central theme (basic/.config/themes). +// Do not add hex colors here — the palette lives in ltmnight.rasi. +// __ __ __ ________ ___ _ __ __ +// / / / /_ ______ _____/ / /_ __/ |/ / / | / /___/ /_ +// / /_/ / / / / __ \/ ___/ / / / / /|_/ /_____ / |/ / _ / __/ +// / __ / /_/ / /_/ / / / /___ / / / / / /_____ / /| / __/ /_ +// /_/ /_/\__, / .___/_/ /_____//_/ /_/ /_/ /_/ |_/\___/\__/ +// /____/_/ + +// Copyright © 2025-2026 Djalel Oukid (sniper1720) + +@theme "ltmnight" + +window { + background-color: @background; + border: 2px; + border-color: @primary-fixed; + padding: 0; + border-radius: 10px; + width: 50%; + location: 0; + x-offset: 0; + y-offset: 0; + transparency: "real"; +} + +mainbox { + enabled: true; + spacing: 0em; + padding: 10px; + orientation: vertical; + children: [ inputbar, message, listview ]; + background-color: transparent; +} + +inputbar { + enabled: true; + spacing: 0.5em; + padding: 8px 15px; + margin: 0 0 10px 0; + background-color: @selection; + border: 0px 0px 2px 0px; + border-color: @primary-fixed; + border-radius: 8px; +} + +prompt { + enabled: true; + expand: false; + text-color: @prompt; + padding: 0px 5px; + background-color: transparent; + str: ""; +} + +entry { + enabled: true; + background-color: transparent; + text-color: @on-primary-fixed; + caret-color: @ltmnight8; + placeholder: ""; + placeholder-color: @placeholder; + expand: true; +} + +listview { + background-color: transparent; + border: 0; + padding: 5px; + cycle: true; + layout: vertical; + spacing: 2px; + scrollbar: false; + columns: 1; + dynamic: true; + fixed-height:false; +} + +element { + enabled: true; + padding: 5px 10px; + margin: 2px 0; + background-color: transparent; + text-color: @foreground; + border: 0; + border-radius: 5px; + orientation: horizontal; + children: [ element-text ]; + vertical-align: 0.5; +} + +element-icon { + background-color: transparent; + size: 0px; + margin: 0px; + enabled: false; +} + +element-text { + background-color: transparent; + text-color: inherit; + highlight-color: @ltmnight6; + expand: true; + vertical-align: 0.5; + format: "{text}"; +} + +element selected { + background-color: @selection; + text-color: @on-selection; + border-radius: 5px; +} + +element urgent { + background-color: @error; + text-color: @on-error; +} + +element active { + background-color: @primary; + text-color: @on-primary; +} + +scrollbar { + handle-color: @ltmnight8; + background-color: @primary-fixed; + width: 4px; + padding: 0; + border-radius: 0px; +} + +case-indicator { + enabled: false; +} + +message { + enabled: true; + margin: 10px 0px 10px 0px; + padding: 10px; + border: 1px; + border-radius: 8px; + border-color: @message-border; + background-color: @message-background; + children: [ textbox ]; +} + + textbox { + background-color: @message-background; + text-color: @message-text; + vertical-align: 0.5; + horizontal-align: 0.0; + highlight: none; + } \ No newline at end of file diff --git a/hypr/.config/rofi/themes/ltmnight.rasi b/hypr/.config/rofi/themes/ltmnight.rasi new file mode 100644 index 0000000..fb15a23 --- /dev/null +++ b/hypr/.config/rofi/themes/ltmnight.rasi @@ -0,0 +1,67 @@ +// ltmnight Palette for Rofi — now mapped onto the CENTRAL theme +// (basic/.config/themes → ~/.config/themes/current/rofi.rasi, Catppuccin Mocha). +// Tracked in dotfiles: hypr/.config/rofi/themes/ltmnight.rasi +// (stowed to ~/.config/rofi/themes/ltmnight.rasi). +// +// Only the palette values changed to Mocha; every variable NAME below is +// unchanged, so hyprltm-net.rasi (@theme "ltmnight") and hyprltm-net's +// core.sh -theme-str overrides (@on-primary-fixed, @error-message, ...) +// keep working untouched. The two translucency values use #RRGGBBAA hex +// because rasi has no alpha() function — keep them in sync with @base / +// @surface0 from the central theme if you ever switch flavors. + +@import "/home/mathias/.config/themes/current/rofi.rasi" + +* { + ltmnight0: @base; /* Background */ + ltmnight1: @surface0; /* Current Line / Secondary Background */ + ltmnight2: @text; /* Foreground Text */ + ltmnight3: @overlay1; /* Comment / Faded Foreground */ + ltmnight4: @red; /* Red / Errors */ + ltmnight5: @peach; /* Orange / Warnings */ + ltmnight6: @yellow; /* Yellow / Warnings */ + ltmnight7: @green; /* Green / Success */ + ltmnight8: @sapphire; /* Cyan / Info */ + ltmnight9: @mauve; /* Purple / Accents */ + ltmnight10: @pink; /* Pink / Accents */ + ltmnight11: @overlay0; /* Gray / Placeholders */ + + + + // Rofi Color Mappings to ltmnight Palette + background: #1e1e2ee6; /* @base at 90% */ + foreground: @ltmnight2; + + primary: @ltmnight9; + accent: @ltmnight10; + on-primary: @ltmnight2; + + primary-fixed: @ltmnight1; + on-primary-fixed: @ltmnight2; + + selection: #31324480; /* @surface0 at 50% */ + on-selection: @ltmnight2; + + error: @ltmnight4; + on-error: @ltmnight2; + + surface: #1e1e2ee6; /* @base at 90% */ + on-surface: @ltmnight2; + + outline: @ltmnight3; + shadow: rgba(0, 0, 0, 0.5); + + highlight: @ltmnight6; + + prompt: @ltmnight11; + placeholder: @ltmnight11; + + message-background: transparent; + message-border: @ltmnight8; + message-text: @ltmnight8; + + error-message: @ltmnight4; + warning-message: @ltmnight5; + success-message: @ltmnight7; + info-message: @ltmnight8; +} diff --git a/hypr/.config/waybar/mocha.css b/hypr/.config/waybar/mocha.css new file mode 120000 index 0000000..c1eb9f6 --- /dev/null +++ b/hypr/.config/waybar/mocha.css @@ -0,0 +1 @@ +../../../basic/.config/themes/themes/catppuccin-mocha/theme.css \ No newline at end of file diff --git a/hypr/.config/waybar/style.css b/hypr/.config/waybar/style.css index 25bf1dc..9073688 100755 --- a/hypr/.config/waybar/style.css +++ b/hypr/.config/waybar/style.css @@ -1,29 +1,19 @@ -/* ------------------------------------------------- - Calm Glass (Hyprland / Waybar) — GTK CSS safe --------------------------------------------------- */ +/* Central theme: roles + palette imported from basic/.config/themes + * (mocha.css is a symlink into the current theme's theme.css). + * This file must use @role/@palette names only — never hardcoded colors — + * so a future theme only swaps the central files. */ +@import url("mocha.css"); * { font-family: "JetBrainsMono Nerd Font", FontAwesome, sans-serif; font-size: 13px; } -/* ---------- GTK Color Definitions ---------- */ -@define-color fg rgba(235, 238, 242, 0.92); -@define-color fg-dim rgba(235, 238, 242, 0.72); -@define-color fg-muted rgba(235, 238, 242, 0.55); - -@define-color glass rgba(18, 22, 30, 0.55); -@define-color glass_2 rgba(18, 22, 30, 0.32); -@define-color glass_3 rgba(18, 22, 30, 0.22); - -@define-color stroke rgba(255, 255, 255, 0.12); -@define-color stroke_2 rgba(255, 255, 255, 0.07); - /* ---------- Waybar Container ---------- */ window#waybar { - background-color: @glass; + background-color: @bg_dim; color: @fg; - border-bottom: 1px solid @stroke; + border-bottom: 1px solid @border; box-shadow: 0 10px 30px rgba(0,0,0,0.30); transition-property: background-color, opacity; @@ -43,35 +33,35 @@ button { button:hover { background: inherit; - box-shadow: inset 0 -2px rgba(255,255,255,0.18); + box-shadow: inset 0 -2px @accent; } #workspaces button { padding: 0 8px; margin: 4px 3px; - background-color: rgba(255,255,255,0.04); - color: @fg-dim; - border: 1px solid rgba(255,255,255,0.06); + background-color: @surface; + color: @fg_dim; + border: 1px solid @border; border-radius: 10px; } #workspaces button:hover { - background: rgba(255,255,255,0.07); + background: @border; color: @fg; } #workspaces button.focused, #workspaces button.active { - background-color: rgba(255,255,255,0.10); - color: @fg; - border: 1px solid rgba(255,255,255,0.12); - box-shadow: inset 0 -2px rgba(255,255,255,0.18); + background-color: @accent; + color: @bg_deep; + border: 1px solid @accent; + box-shadow: inset 0 -2px @accent2; } #workspaces button.urgent { - background-color: rgba(190,110,120,0.35); - border-color: rgba(190,110,120,0.50); - color: @fg; + background-color: @urgent; + border-color: @urgent; + color: @bg_deep; } #window, @@ -99,6 +89,7 @@ button:hover { #pulseaudio, #wireplumber, #custom-media, +#custom-gpu, #tray, #mode, #idle_inhibitor, @@ -111,8 +102,8 @@ button:hover { #privacy-item { padding: 0 10px; color: @fg; - background-color: @glass_2; - border: 1px solid @stroke_2; + background-color: @surface; + border: 1px solid @border; border-radius: 10px; margin: 4px 4px; } @@ -121,31 +112,32 @@ button:hover { #wireplumber:hover, #network:hover, #clock:hover { - background-color: @glass_3; + background-color: @border; } #clock { - border-color: rgba(140, 170, 190, 0.25); + border-color: @accent; } /* Battery */ #battery.charging, #battery.plugged { - background-color: rgba(120,170,140,0.22); - border-color: rgba(120,170,140,0.34); + background-color: @ok; + border-color: @ok; + color: @bg_deep; } @keyframes blink { to { - background-color: rgba(190,110,120,0.18); - border-color: rgba(190,110,120,0.50); + background-color: @urgent; + border-color: @urgent; } } #battery.critical:not(.charging) { - background-color: rgba(190,110,120,0.35); - border-color: rgba(190,110,120,0.55); - color: @fg; + background-color: @urgent; + border-color: @urgent; + color: @bg_deep; animation-name: blink; animation-duration: 0.6s; animation-timing-function: steps(10); @@ -155,31 +147,33 @@ button:hover { /* Network */ #network.disconnected { - background-color: rgba(190,110,120,0.30); - border-color: rgba(190,110,120,0.45); + background-color: @urgent; + border-color: @urgent; + color: @bg_deep; } /* Audio */ #pulseaudio:hover { - background-color: rgba(190,160,110,0.20); - border-color: rgba(190,160,110,0.28); + background-color: @border; } #pulseaudio.muted { - background-color: rgba(140,170,190,0.18); - border-color: rgba(140,170,190,0.26); - color: @fg-dim; + background-color: @surface; + border-color: @border; + color: @fg_muted; } #wireplumber.muted { - background-color: rgba(190,110,120,0.28); - border-color: rgba(190,110,120,0.40); + background-color: @urgent; + border-color: @urgent; + color: @bg_deep; } /* Temperature */ #temperature.critical { - background-color: rgba(190,110,120,0.30); - border-color: rgba(190,110,120,0.45); + background-color: @urgent; + border-color: @urgent; + color: @bg_deep; } /* Tray */ @@ -189,20 +183,20 @@ button:hover { #tray > .needs-attention { -gtk-icon-effect: highlight; - background-color: rgba(190,110,120,0.30); + background-color: @urgent; border-radius: 10px; } /* Idle inhibitor */ #idle_inhibitor.activated { - background-color: rgba(255,255,255,0.10); - border-color: rgba(255,255,255,0.14); - color: @fg; + background-color: @accent; + border-color: @accent; + color: @bg_deep; } /* Scratchpad */ #scratchpad { - background: rgba(255,255,255,0.05); + background: @surface; } #scratchpad.empty { @@ -223,14 +217,17 @@ button:hover { } #privacy-item.screenshare { - background-color: rgba(190,160,110,0.30); - border-color: rgba(190,160,110,0.40); + background-color: @warn; + border-color: @warn; + color: @bg_deep; } #privacy-item.audio-in { - background-color: rgba(120,170,140,0.25); - border-color: rgba(120,170,140,0.36); + background-color: @ok; + border-color: @ok; + color: @bg_deep; } #privacy-item.audio-out { - background-color: rgba(140,170,190,0.25); - border-color: rgba(140,170,190,0.36); + background-color: @accent; + border-color: @accent; + color: @bg_deep; } diff --git a/hypr/.config/waypaper/style.css b/hypr/.config/waypaper/style.css index b4fe025..a882671 100644 --- a/hypr/.config/waypaper/style.css +++ b/hypr/.config/waypaper/style.css @@ -1,17 +1,21 @@ -/* Waypaper custom stylesheet (stowed to ~/.config/waypaper/style.css). - * Makes the currently selected wallpaper unmissable: - * thick Catppuccin-mocha sapphire border (#74c7ec, same as Hyprland - * active border) + tinted fill + outer glow. +/* Central theme: roles imported from basic/.config/themes. + * NOTE: waypaper loads this file via Gtk.CssProvider.load_from_data, so a + * relative @import would resolve against the process working directory and + * NOT against this file's location. The import MUST stay an absolute path. + * This file must use @role names only — never hardcoded colors. + * Makes the currently selected wallpaper unmissable: thick accent border + * (same role as the Hyprland active border) + tinted fill + outer glow. * Selector `.highlighted-button` is the official waypaper hook * (see waypaper docs: "Custom styles and colors"). */ +@import url("/home/mathias/.config/themes/current/theme.css"); .highlighted-button { background-image: none; box-shadow: none; - background-color: rgba(116, 199, 236, 0.25); - border: 3px solid #74c7ec; + background-color: alpha(@accent, 0.25); + border: 3px solid @accent; border-radius: 8px; - box-shadow: 0 0 0 2px rgba(116, 199, 236, 0.6), 0 0 14px rgba(116, 199, 236, 0.9); + box-shadow: 0 0 0 2px alpha(@accent, 0.6), 0 0 14px alpha(@accent, 0.9); } .highlighted-button > image, @@ -20,5 +24,5 @@ } button:hover { - border-color: #74c7ec; + border-color: @accent; } diff --git a/hypr/.config/wofi/mocha.css b/hypr/.config/wofi/mocha.css new file mode 120000 index 0000000..c1eb9f6 --- /dev/null +++ b/hypr/.config/wofi/mocha.css @@ -0,0 +1 @@ +../../../basic/.config/themes/themes/catppuccin-mocha/theme.css \ No newline at end of file diff --git a/hypr/.config/wofi/style.css b/hypr/.config/wofi/style.css new file mode 100644 index 0000000..fe9a469 --- /dev/null +++ b/hypr/.config/wofi/style.css @@ -0,0 +1,69 @@ +/* Central theme: roles + palette imported from basic/.config/themes + * (mocha.css is a symlink into the current theme's theme.css, so this + * resolves identically in the repo and once stowed — unlike a + * ../themes/... relative hop, which differs between the two). + * This file styles every wofi popup: SUPER+SPACE app launcher (drun) and + * SUPER+K keybind help (dmenu). Use @role/@palette names only. */ +@import url("mocha.css"); + +window { + margin: 0px; + background-color: @bg_translucent; + border: 2px solid @accent; + border-radius: 12px; +} + +#input { + margin: 8px; + padding: 6px 10px; + background-color: @surface; + color: @fg; + border: 1px solid @border; + border-radius: 8px; +} + +#input:focus { + border-color: @accent; +} + +#inner-box { + margin: 8px; + background-color: transparent; +} + +#outer-box { + margin: 0px; + padding: 4px; + background-color: transparent; +} + +#scroll { + margin: 0px; + background-color: transparent; +} + +#entry { + padding: 6px 10px; + margin: 2px 0px; + background-color: transparent; + color: @fg; + border-radius: 8px; +} + +#entry:selected { + background-color: @accent; +} + +#entry:selected #text { + color: @bg_deep; +} + +#text { + margin: 2px 6px; + color: @fg; +} + +#img { + margin-right: 8px; + background-color: transparent; +} diff --git a/term/.bashrc b/term/.bashrc index 8860f4c..d365c5e 100644 --- a/term/.bashrc +++ b/term/.bashrc @@ -37,3 +37,8 @@ fi export DATAFLEX_BACKEND_REPO="/c/_Master/202602 DataFleX/repos/flexibility_platform_backend/" export PATH="$HOME/.local/bin:$PATH" + +# Central theme (basic/.config/themes): single source of truth for colors. +if [ -f "$HOME/.config/themes/current/theme.env.sh" ]; then + . "$HOME/.config/themes/current/theme.env.sh" +fi diff --git a/term/.config/fish/config.fish b/term/.config/fish/config.fish index 29fb8aa..98b9bb6 100644 --- a/term/.config/fish/config.fish +++ b/term/.config/fish/config.fish @@ -1,3 +1,8 @@ +# Central theme (basic/.config/themes): single source of truth for colors. +if test -f ~/.config/themes/current/theme.fish + source ~/.config/themes/current/theme.fish +end + # Enable OpenCode web search via Exa AI set -gx OPENCODE_ENABLE_EXA 1 diff --git a/term/.config/nvim/lua/plugins/catppuccin.lua b/term/.config/nvim/lua/plugins/catppuccin.lua index 3032542..83aa8d4 100644 --- a/term/.config/nvim/lua/plugins/catppuccin.lua +++ b/term/.config/nvim/lua/plugins/catppuccin.lua @@ -4,7 +4,10 @@ return { lazy = false, priority = 1000, config = function() - require("catppuccin").setup({ flavor = "mocha" }) - vim.cmd.colorscheme("catppuccin") + -- Central theme (basic/.config/themes): flavor/colorscheme come from + -- $CATPPUCCIN_FLAVOR / $THEME_NVIM_COLORSCHEME so a future theme only + -- changes the central files (see themes/registry.conf). + require("catppuccin").setup({ flavor = os.getenv("CATPPUCCIN_FLAVOR") or "mocha" }) + vim.cmd.colorscheme(os.getenv("THEME_NVIM_COLORSCHEME") or "catppuccin") end, } diff --git a/term/.config/starship.toml b/term/.config/starship.toml index 9c6ccdb..84fbbb0 100644 --- a/term/.config/starship.toml +++ b/term/.config/starship.toml @@ -169,6 +169,11 @@ show_notifications = true min_time_to_notify = 45000 min_time = 0 +# Central theme note: starship has no `include` mechanism, so this palette is +# a declared mirror of basic/.config/themes/themes/catppuccin-mocha (see +# theme.env.sh / theme.css for the source of truth). Only the active +# palette is kept here; switch flavors by replacing this block from the +# central theme (scripts/switch-theme.sh reminds you). Do not hand-edit hex. [palettes.catppuccin_mocha] rosewater = "#f5e0dc" flamingo = "#f2cdcd" @@ -197,86 +202,3 @@ base = "#1e1e2e" mantle = "#181825" crust = "#11111b" -[palettes.catppuccin_frappe] -rosewater = "#f2d5cf" -flamingo = "#eebebe" -pink = "#f4b8e4" -mauve = "#ca9ee6" -red = "#e78284" -maroon = "#ea999c" -peach = "#ef9f76" -yellow = "#e5c890" -green = "#a6d189" -teal = "#81c8be" -sky = "#99d1db" -sapphire = "#85c1dc" -blue = "#8caaee" -lavender = "#babbf1" -text = "#c6d0f5" -subtext1 = "#b5bfe2" -subtext0 = "#a5adce" -overlay2 = "#949cbb" -overlay1 = "#838ba7" -overlay0 = "#737994" -surface2 = "#626880" -surface1 = "#51576d" -surface0 = "#414559" -base = "#303446" -mantle = "#292c3c" -crust = "#232634" - -[palettes.catppuccin_latte] -rosewater = "#dc8a78" -flamingo = "#dd7878" -pink = "#ea76cb" -mauve = "#8839ef" -red = "#d20f39" -maroon = "#e64553" -peach = "#fe640b" -yellow = "#df8e1d" -green = "#40a02b" -teal = "#179299" -sky = "#04a5e5" -sapphire = "#209fb5" -blue = "#1e66f5" -lavender = "#7287fd" -text = "#4c4f69" -subtext1 = "#5c5f77" -subtext0 = "#6c6f85" -overlay2 = "#7c7f93" -overlay1 = "#8c8fa1" -overlay0 = "#9ca0b0" -surface2 = "#acb0be" -surface1 = "#bcc0cc" -surface0 = "#ccd0da" -base = "#eff1f5" -mantle = "#e6e9ef" -crust = "#dce0e8" - -[palettes.catppuccin_macchiato] -rosewater = "#f4dbd6" -flamingo = "#f0c6c6" -pink = "#f5bde6" -mauve = "#c6a0f6" -red = "#ed8796" -maroon = "#ee99a0" -peach = "#f5a97f" -yellow = "#eed49f" -green = "#a6da95" -teal = "#8bd5ca" -sky = "#91d7e3" -sapphire = "#7dc4e4" -blue = "#8aadf4" -lavender = "#b7bdf8" -text = "#cad3f5" -subtext1 = "#b8c0e0" -subtext0 = "#a5adcb" -overlay2 = "#939ab7" -overlay1 = "#8087a2" -overlay0 = "#6e738d" -surface2 = "#5b6078" -surface1 = "#494d64" -surface0 = "#363a4f" -base = "#24273a" -mantle = "#1e2030" -crust = "#181926" diff --git a/term/.config/tmux/tmux.conf b/term/.config/tmux/tmux.conf index 3fac407..f4f03c7 100644 --- a/term/.config/tmux/tmux.conf +++ b/term/.config/tmux/tmux.conf @@ -60,9 +60,11 @@ set -g @continuum-save-interval '5' set -g @continuum-restore 'on' # set -g @resurrect-capture-pane-contents 'on' -# Catppuccin theme +# Central theme (basic/.config/themes): flavor comes from $CATPPUCCIN_FLAVOR +# (theme.env.sh / theme.fish), defaulting to mocha. The plugin itself is +# owned by TPM (see registry.conf for the theme -> plugin mapping). set -g @plugin 'catppuccin/tmux' -set -g @catppuccin_flavor "mocha" +run-shell 'tmux set -g @catppuccin_flavor "${CATPPUCCIN_FLAVOR:-mocha}"' set -g @catppuccin_window_status_style "rounded" set -g @catppuccin_window_text "#W" diff --git a/term/.config/yazi/theme.toml b/term/.config/yazi/theme.toml index 8161dbd..fccbc4b 100644 --- a/term/.config/yazi/theme.toml +++ b/term/.config/yazi/theme.toml @@ -1,3 +1,8 @@ +# Central theme note: yazi has no `include` mechanism, so this file is a +# declared mirror of basic/.config/themes/themes/catppuccin-mocha (Catppuccin +# Mocha). Do not hand-tweak hex values here; port them from the central theme. +# (Also note: syntect_theme below points at ~/.config/yazi/, which is not +# stowed on a fresh setup until `stow term` runs.) [app] overall = { bg = "#1e1e2e" } diff --git a/test/lint.sh b/test/lint.sh index 555cbd8..9eb8ddc 100755 --- a/test/lint.sh +++ b/test/lint.sh @@ -157,6 +157,22 @@ while IFS= read -r pkg; do fi done < <(grep -P '^\t' Makefile | grep -E '\bstow\b' | awk '{print $NF}' | sort -u) +# --------------------------------------------------------------------------- +# 7. Central theme drift guard: no hardcoded theme colors outside +# basic/.config/themes (plus declared mirrors). See +# basic/.config/themes/scripts/sync-theme.sh. +# --------------------------------------------------------------------------- +echo "== Checking central theme has no hardcoded copies ==" +if [[ -f "basic/.config/themes/scripts/sync-theme.sh" ]]; then + if bash basic/.config/themes/scripts/sync-theme.sh; then + say_pass "central theme drift guard" + else + say_fail "central theme drift guard" + fi +else + say_fail "basic/.config/themes/scripts/sync-theme.sh missing" +fi + # --------------------------------------------------------------------------- # Summary # ---------------------------------------------------------------------------