Themes
Theme System Architecture
A modular, isolated, and compositor-agnostic theming engine designed to “decorate” rather than “define” system functionality.
🏗️ Two-Tiered Architecture
The core philosophy of this theme system is strict isolation combined with modern defaults. We move away from a “blank slate” approach toward a system that is beautiful by default but remains fully customizable.
Tier 1: Global Defaults (The Base)
When modules.theme.active is set to null, the system employs a “Global Default” tier.
- Palette: Standardized on Catppuccin Mocha for its high quality and broad community support.
- Goal: Ensure the system feels premium and visually coherent out-of-the-box.
- Implementation: Apps like Foot and WezTerm hardcode these defaults in their base Nix modules.
Tier 2: Active Theme (The Decoration)
When an active theme is selected (e.g., Alucard, Autumnal), it acts as a decorator.
- Mechanism: The theme module populates
modules.theme.colorsandmodules.theme.fonts. - Propagation: Applications “react” to these changes via
mkIf (config.modules.theme.active != null)blocks.
🎨 Integration Levels
1. System Level (Hard-Linked)
Components that define the global “look and feel”:
- GTK & QT (Kvantum): Centralized in
modules/theme/default.nix. - WMs (Hyprland/Niri): Use hooks and native settings to apply the color palette to borders, gaps, and shadows.
- Fonts: A unified
fontssubmodule provides aliases (mono,sans,terminal) that all apps must consume.
2. App Level (Reactive)
Applications that support native theming or internal configuration:
- Terminal Emulators (Foot, WezTerm): They use a “Default + Override” pattern. They default to Catppuccin but dynamically generate their config based on the active theme’s hex values.
- Shell (Zsh): Prompts are modularized and selectable via
modules.theme.apps.zsh.prompt. Supported options includestarship(modern default),matrix(retro green), andp10k(Powerlevel10k integration). - Tmux: Support for dynamic theme switching via
modules.theme.apps.tmux.theme. Catppuccin settings are modularized undermodules.shell.tmux.catppuccin, including support for status bar transparency. - Rofi: The theme selection is centralized in
modules.theme.apps.rofi.theme(e.g.,gemini,autumnal,matrix).
🛠️ Themes Upgrade Plan (Roadmap)
To improve flexibility and scale, the system is moving toward these goals:
- Standardized Color Submodule: Move all theme colors into a strictly typed Nix submodule to catch errors at evaluation time (e.g., missing
highlightorbordercolors). - Catppuccin-First Strategy: Leverage the vast Catppuccin ecosystem. If an app has an official Catppuccin theme, we prefer using it as the default/fallback before falling back to generic hex injection.
- Modularized
apps.nix: As more apps are added,apps.nixwill be split into functional categories (e.g.,apps/browsers.nix,apps/terminals.nix,apps/shells.nix) to keep the logic manageable. - Live Reloading: Enhance
hey hook reloadto ensure that changing the active theme in a host config results in a seamless transition without restarting sessions.
🖋️ Adding a New Theme
- Create
modules/themes/<name>/default.nix. - Define
mkIf (cfg.active == "<name>"). - Populate
modules.theme.colors(following the ANSI + Types spec) andmodules.theme.fonts. - Register the folder in
modules/themes/default.nix.