{ config, pkgs, lib, inputs, ... }: { imports = [ inputs.stylix.nixosModules.stylix ]; config = lib.mkIf (lib.elem config.networking.hostName [ "FredOS-Gaming" "FredOS-Macbook" ]) { stylix = { enable = true; # builtins.path hashes only the image content, not the whole flake tree, # so palette.json is only rebuilt when the wallpaper itself changes. image = builtins.path { name = "wallpaper.png"; path = inputs.self + "/walls/wallpaper.png"; }; polarity = "dark"; # Let stylix theme every target it supports. Per-target opt-outs go # under home-manager.users.fred.stylix.targets..enable = false. autoEnable = true; cursor = { package = pkgs.bibata-cursors; name = "Bibata-Modern-Ice"; size = 24; }; fonts = { monospace = { package = pkgs.nerd-fonts.fira-mono; name = "FiraMono Nerd Font"; }; sansSerif = { package = pkgs.inter; name = "Inter"; }; serif = { package = pkgs.inter; name = "Inter"; }; }; }; home-manager.users.fred = { config, lib, pkgs, ... }: let c = config.lib.stylix.colors; # Pure-Nix hex parsing for color distance calculation. hexDigit = ch: { "0"=0;"1"=1;"2"=2;"3"=3;"4"=4;"5"=5;"6"=6;"7"=7; "8"=8;"9"=9;"a"=10;"b"=11;"c"=12;"d"=13;"e"=14;"f"=15; }.${ch}; hexByte = s: hexDigit (builtins.substring 0 1 s) * 16 + hexDigit (builtins.substring 1 1 s); hexToRgb = hex: let h = lib.toLower hex; in { r = hexByte (builtins.substring 0 2 h); g = hexByte (builtins.substring 2 2 h); b = hexByte (builtins.substring 4 2 h); }; # papirus-folders named palette → representative hex values. pfPalette = { adwaita="3584e4"; black="000000"; bluegrey="607d8b"; breeze="1d99f3"; brown="795548"; cyan="00bcd4"; darkcyan="00838f"; deeporange="ff5722"; green="4caf50"; grey="9e9e9e"; indigo="3f51b5"; magenta="e91e63"; nordic="5e81ac"; orange="ff9800"; palebrown="a1887f"; palegreen="8bc34a"; pink="f06292"; red="f44336"; teal="009688"; violet="9c27b0"; white="ffffff"; yellow="ffeb3b"; }; # Closest papirus-folders color to stylix's accent (base0D), chosen at # eval time via squared RGB distance — no runtime script needed. closestPfColor = let sq = x: x * x; dist = a: b: sq (a.r - b.r) + sq (a.g - b.g) + sq (a.b - b.b); accent = hexToRgb c.base0D; ranked = map (n: { name = n; d = dist accent (hexToRgb pfPalette.${n}); }) (builtins.attrNames pfPalette); in (builtins.foldl' (best: x: if x.d < best.d then x else best) (builtins.head ranked) (builtins.tail ranked)).name; # Papirus-Dark with folders recolored to the closest matching color. # Built as a derivation so it lands in the nix store — no activation scripts. papirusDark = pkgs.runCommand "papirus-dark-${closestPfColor}" { nativeBuildInputs = [ pkgs.papirus-folders ]; } '' # Work in a fully writable temp tree so papirus-folders can find and # modify the theme without fighting the nix sandbox path structure. tmpdata=$(mktemp -d) mkdir -p $tmpdata/icons cp -r ${pkgs.papirus-icon-theme}/share/icons/Papirus-Dark $tmpdata/icons/ chmod -R u+w $tmpdata/icons/Papirus-Dark export HOME=$(mktemp -d) export XDG_DATA_HOME=$tmpdata papirus-folders -C ${closestPfColor} -t Papirus-Dark mkdir -p $out/share/icons cp -r $tmpdata/icons/Papirus-Dark $out/share/icons/ ''; # Map matugen's Material You placeholders to the closest base16 slot # in stylix's palette. The mapping is approximate (Material You has # more semantic colours than base16), but covers the placeholders # used in our Zen userChrome and Vesktop quickCss templates. stylixize = builtins.replaceStrings [ "{{colors.primary.default.hex}}" "{{colors.primary_container.default.hex}}" "{{colors.secondary_container.default.hex}}" "{{colors.tertiary_container.default.hex}}" "{{colors.surface.default.hex}}" "{{colors.surface_container.default.hex}}" "{{colors.surface_container_low.default.hex}}" "{{colors.surface_container_high.default.hex}}" "{{colors.on_surface.default.hex}}" "{{colors.on_surface_variant.default.hex}}" "{{colors.outline.default.hex}}" "{{colors.outline_variant.default.hex}}" ] [ "#${c.base0D}" # primary accent "#${c.base02}" # primary container "#${c.base0C}" # secondary container (cyan) "#${c.base0E}" # tertiary container (purple) "#${c.base00}" # surface (main bg) "#${c.base01}" # surface container "#${c.base00}" # surface container low "#${c.base02}" # surface container high "#${c.base05}" # on surface (fg) "#${c.base04}" # on surface variant (muted fg) "#${c.base03}" # outline "#${c.base02}" # outline variant ]; in { # Zen and Vesktop have no native stylix targets, so we keep the # existing matugen CSS templates and substitute placeholders with # stylix base16 colours at Nix-eval time. home.file.".zen/fraudek5.Default Profile/chrome/userChrome.css".text = stylixize (builtins.readFile "${inputs.self}/templates/zen-userChrome.css"); home.file.".config/vesktop/settings/quickCss.css".text = stylixize (builtins.readFile "${inputs.self}/templates/vesktop-quickCss.css"); gtk.iconTheme = { package = papirusDark; name = "Papirus-Dark"; }; }; }; }