2026-05-11 13:32:18 +01:00
|
|
|
{ config, pkgs, lib, inputs, ... }:
|
|
|
|
|
{
|
|
|
|
|
imports = [ inputs.stylix.nixosModules.stylix ];
|
|
|
|
|
|
|
|
|
|
config = lib.mkIf (lib.elem config.networking.hostName [ "FredOS-Gaming" "FredOS-Macbook" ]) {
|
|
|
|
|
stylix = {
|
|
|
|
|
enable = true;
|
2026-05-14 14:58:13 +01:00
|
|
|
# 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";
|
|
|
|
|
};
|
2026-05-11 13:32:18 +01:00
|
|
|
polarity = "dark";
|
|
|
|
|
|
2026-05-11 19:44:07 +01:00
|
|
|
# Let stylix theme every target it supports. Per-target opt-outs go
|
|
|
|
|
# under home-manager.users.fred.stylix.targets.<x>.enable = false.
|
|
|
|
|
autoEnable = true;
|
2026-05-11 13:32:18 +01:00
|
|
|
|
|
|
|
|
cursor = {
|
2026-05-12 11:48:28 +01:00
|
|
|
package = pkgs.bibata-cursors;
|
|
|
|
|
name = "Bibata-Modern-Ice";
|
2026-05-11 13:32:18 +01:00
|
|
|
size = 24;
|
|
|
|
|
};
|
|
|
|
|
|
2026-05-11 13:44:50 +01:00
|
|
|
fonts = {
|
|
|
|
|
monospace = {
|
|
|
|
|
package = pkgs.nerd-fonts.fira-mono;
|
|
|
|
|
name = "FiraMono Nerd Font";
|
|
|
|
|
};
|
|
|
|
|
sansSerif = {
|
|
|
|
|
package = pkgs.inter;
|
|
|
|
|
name = "Inter";
|
|
|
|
|
};
|
|
|
|
|
serif = {
|
|
|
|
|
package = pkgs.inter;
|
|
|
|
|
name = "Inter";
|
|
|
|
|
};
|
2026-05-11 13:32:18 +01:00
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
2026-05-11 20:08:36 +01:00
|
|
|
home-manager.users.fred = { config, lib, pkgs, ... }: let
|
|
|
|
|
c = config.lib.stylix.colors;
|
2026-05-15 22:11:57 +01:00
|
|
|
|
|
|
|
|
# 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 ];
|
|
|
|
|
} ''
|
|
|
|
|
mkdir -p $out/share/icons
|
|
|
|
|
cp -r ${pkgs.papirus-icon-theme}/share/icons/Papirus-Dark $out/share/icons/
|
|
|
|
|
chmod -R u+w $out/share/icons/Papirus-Dark
|
2026-05-15 22:20:56 +01:00
|
|
|
|
|
|
|
|
export HOME=$(mktemp -d)
|
|
|
|
|
mkdir -p $HOME/.local/share/icons
|
|
|
|
|
ln -s $out/share/icons/Papirus-Dark $HOME/.local/share/icons/Papirus-Dark
|
|
|
|
|
|
|
|
|
|
papirus-folders -C ${closestPfColor} -t Papirus-Dark
|
2026-05-15 22:11:57 +01:00
|
|
|
'';
|
|
|
|
|
|
2026-05-11 20:08:36 +01:00
|
|
|
# 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");
|
|
|
|
|
|
2026-05-15 22:11:57 +01:00
|
|
|
gtk.iconTheme = {
|
|
|
|
|
package = papirusDark;
|
|
|
|
|
name = "Papirus-Dark";
|
|
|
|
|
};
|
2026-05-11 13:32:18 +01:00
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
}
|