feat: Nomarchy ground-up rewrite on NixOS 26.05
Full replacement of the previous iteration, rebuilt around three ideas:
- Pure evaluation: theme-state.json lives inside the flake and is read
via the nomarchy.stateFile option — no --impure, ever.
- All-Home-Manager theming: `nomarchy-theme-sync apply` writes the JSON
and runs `home-manager switch`; every theme change is one atomic,
rollbackable generation. Wallpaper (swww) is the sole runtime piece.
- Flat, downstream-first layout: modules/{nixos,home} with one
options.nix each, exported as nixosModules/homeModules + overlay +
flake template; system (nixos-rebuild) and desktop (home-manager
switch) rebuild paths are fully split.
Ships 21 themes imported from the previous iteration (palettes,
wallpapers, btop themes, six whole-swap Waybar identities), Stylix for
the GTK/Qt/cursor long tail, a live ISO target with offline theme
switching, and docs/TESTING.md with the QEMU verification workflow.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
79
modules/home/stylix.nix
Normal file
79
modules/home/stylix.nix
Normal file
@@ -0,0 +1,79 @@
|
||||
# Stylix — themes the long tail of applications (GTK, Qt, cursors,
|
||||
# fonts) from the same theme-state.json that drives the live engine.
|
||||
#
|
||||
# Division of labour: the hot-reload trio (Hyprland, Waybar, Ghostty)
|
||||
# is owned by the Nomarchy engine and updates instantly; everything
|
||||
# Stylix touches updates on the next home-manager switch. That is why
|
||||
# autoEnable is off and the trio's Stylix targets stay disabled.
|
||||
#
|
||||
# Note: the stylix home module itself is imported by homeModules.nomarchy
|
||||
# in flake.nix (it needs the stylix flake input).
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
cfg = config.nomarchy;
|
||||
t = cfg.theme;
|
||||
c = t.colors;
|
||||
hex = lib.removePrefix "#";
|
||||
|
||||
# Map the Nomarchy palette onto base16 roles.
|
||||
base16 = {
|
||||
base00 = hex c.base; # default background
|
||||
base01 = hex c.mantle; # darker background (status bars)
|
||||
base02 = hex c.surface; # selection background
|
||||
base03 = hex c.muted; # comments
|
||||
base04 = hex c.subtext; # dark foreground
|
||||
base05 = hex c.text; # default foreground
|
||||
base06 = hex c.text; # light foreground
|
||||
base07 = hex c.text; # lightest foreground
|
||||
base08 = hex c.bad; # red
|
||||
base09 = hex c.warn; # orange
|
||||
base0A = hex c.warn; # yellow
|
||||
base0B = hex c.good; # green
|
||||
base0C = hex (builtins.elemAt t.ansi 6); # cyan
|
||||
base0D = hex c.accent; # blue
|
||||
base0E = hex c.accentAlt;# magenta
|
||||
base0F = hex c.bad; # brown/deprecated
|
||||
};
|
||||
in
|
||||
{
|
||||
config = lib.mkIf cfg.stylix.enable {
|
||||
stylix = {
|
||||
enable = true;
|
||||
autoEnable = false; # explicit targets only — the engine owns the rest
|
||||
polarity = if t.mode == "light" then "light" else "dark";
|
||||
base16Scheme = base16;
|
||||
|
||||
targets = {
|
||||
gtk.enable = true;
|
||||
qt.enable = true;
|
||||
};
|
||||
|
||||
cursor = {
|
||||
name = lib.mkDefault "Bibata-Modern-Classic";
|
||||
package = lib.mkDefault pkgs.bibata-cursors;
|
||||
size = lib.mkDefault 24;
|
||||
};
|
||||
|
||||
fonts = {
|
||||
monospace = {
|
||||
name = t.fonts.mono;
|
||||
package = lib.mkDefault pkgs.nerd-fonts.jetbrains-mono;
|
||||
};
|
||||
sansSerif = {
|
||||
name = t.fonts.ui;
|
||||
package = lib.mkDefault pkgs.inter;
|
||||
};
|
||||
serif = {
|
||||
name = t.fonts.ui;
|
||||
package = lib.mkDefault pkgs.inter;
|
||||
};
|
||||
emoji = {
|
||||
name = "Noto Color Emoji";
|
||||
package = lib.mkDefault pkgs.noto-fonts-color-emoji;
|
||||
};
|
||||
sizes.terminal = t.fonts.size;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user