diff --git a/new/configuration.nix b/new/configuration.nix
new file mode 100644
index 0000000..4b4bbe0
--- /dev/null
+++ b/new/configuration.nix
@@ -0,0 +1,7 @@
+{...}: {
+ imports = [
+ # ./hardware-configuration.nix
+ ./user
+ ./system
+ ];
+}
diff --git a/new/data/gruvbox-dark.nix b/new/data/gruvbox-dark.nix
new file mode 100644
index 0000000..a5bd438
--- /dev/null
+++ b/new/data/gruvbox-dark.nix
@@ -0,0 +1,26 @@
+{...}: {
+ background = "#282828";
+ foreground = "#ebdbb2";
+
+ normal = {
+ black = "#282828";
+ red = "#cc241d";
+ green = "#98971a";
+ yellow = "#d79921";
+ blue = "#458588";
+ magenta = "#b16286";
+ cyan = "#689d6a";
+ white = "#a89984";
+ };
+
+ bright = {
+ black = "#928374";
+ red = "#fb4934";
+ green = "#b8bb26";
+ yellow = "#fabd2f";
+ blue = "#83a598";
+ magenta = "#d3869b";
+ cyan = "#8ec07c";
+ white = "#ebdbb2";
+ };
+}
diff --git a/new/data/gruvbox-light.nix b/new/data/gruvbox-light.nix
new file mode 100644
index 0000000..9058095
--- /dev/null
+++ b/new/data/gruvbox-light.nix
@@ -0,0 +1,26 @@
+{...}: {
+ background = "#fbf1c7";
+ foreground = "#3c3836";
+
+ normal = {
+ black = "#fbf1c7";
+ red = "#cc241d";
+ green = "#98971a";
+ yellow = "#d79921";
+ blue = "#458588";
+ magenta = "#b16286";
+ cyan = "#689d6a";
+ white = "#7c6f64";
+ };
+
+ bright = {
+ black = "#928374";
+ red = "#9d0006";
+ green = "#79740e";
+ yellow = "#b57614";
+ blue = "#076678";
+ magenta = "#8f3f71";
+ cyan = "#427b58";
+ white = "#3c3836";
+ };
+}
diff --git a/new/data/theme.nix b/new/data/theme.nix
new file mode 100644
index 0000000..2fc5a08
--- /dev/null
+++ b/new/data/theme.nix
@@ -0,0 +1,21 @@
+{config, ...}:
+let
+ theme = if config.darkMode then import ./gruvbox-dark.nix {}
+ else import ./gruvbox-light.nix {};
+in
+{
+ inherit (theme) background foreground normal bright;
+
+ extra = {
+ red = "#bd574e";
+ orange = "#eb8242";
+ yellow = "#ede06b";
+ green = "#9bb67c";
+ teal = "#87a7b3";
+ purple = "#ad6989";
+ brown = "#ad8b73";
+ darkbrown = "#85603f";
+ darkerbrown = "#5e454b";
+ cream = "#fefcf3";
+ };
+}
diff --git a/new/data/user.nix b/new/data/user.nix
new file mode 100644
index 0000000..659b642
--- /dev/null
+++ b/new/data/user.nix
@@ -0,0 +1,4 @@
+{...}: {
+ email = "janis@nirgendwo.xyz";
+ username = "alice";
+}
diff --git a/new/data/zsh-aliases.nix b/new/data/zsh-aliases.nix
new file mode 100644
index 0000000..a21009c
--- /dev/null
+++ b/new/data/zsh-aliases.nix
@@ -0,0 +1,13 @@
+{...}: {
+ ll = "ls -l";
+ la = "ls -la";
+ git-tree = "git log --graph --oneline --all";
+ c = "clear";
+ cl = "clear; ls --color=auto";
+ q = "exit";
+ ssh = "TERM=xterm-256color ssh";
+ emacs = "emacs -nw"; # Use emacs in terminal mode.
+
+ # dotfiles
+ dotfiles = "git --git-dir=$HOME/.dotfiles/ --work-tree=$HOME";
+}
diff --git a/new/flake.nix b/new/flake.nix
new file mode 100644
index 0000000..6a008f8
--- /dev/null
+++ b/new/flake.nix
@@ -0,0 +1,59 @@
+{
+ inputs = {
+ nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05";
+ home-manager = {
+ url = "github:nix-community/home-manager";
+ inputs.nixpkgs.follows = "nixpkgs";
+ };
+ disko = {
+ url = "github:nix-community/disko";
+ inputs.nixpkgs.follows = "nixpkgs";
+ };
+ nur.url = "github:nix-community/nur";
+ };
+
+ outputs = inputs @ { self, disko, nixpkgs, home-manager, ... }:
+ let
+ system = "x86_64-linux";
+ in rec {
+ mkSystem = {host, ...}: nixpkgs.lib.nixosSystem {
+ inherit system;
+
+ modules = [
+ ./configuration.nix
+ host
+ home-manager.nixosModules.home-manager
+ disko.nixosModules.disko
+ {
+ home-manager.useGlobalPkgs = true; # Use global packages in home-manager
+ home-manager.useUserPackages = true; # Use user packages in home-manager
+
+ home-manager.extraSpecialArgs = {
+ inherit inputs;
+ };
+ }
+ ];
+
+ specialArgs = {
+ inherit inputs home-manager;
+ };
+
+ pkgs = import nixpkgs {
+ inherit system;
+ config.allowUnfree = true; # Allow unfree packages globally
+ overlays = [
+ inputs.nur.overlays.default
+ ];
+ };
+ };
+
+ nixosConfigurations = {
+ vm = mkSystem {
+ host = ./hosts/vm.nix;
+ };
+ laptop = mkSystem {
+ host = ./hosts/laptop;
+ };
+ };
+ };
+}
diff --git a/new/home/alacritty.nix b/new/home/alacritty.nix
new file mode 100644
index 0000000..c2b1beb
--- /dev/null
+++ b/new/home/alacritty.nix
@@ -0,0 +1,35 @@
+{config, ...}:
+let
+ theme = import ../data/theme.nix {inherit config; };
+
+in {
+ programs.alacritty = {
+ enable = true;
+ settings = {
+ font.normal.family = "monospace";
+ window = {
+ dynamic_title = true;
+ title = "Alacritty";
+ };
+
+ # gruvbox dark theme
+ colors = {
+ primary = {
+ inherit (theme) background foreground;
+ };
+
+ inherit (theme) normal bright;
+ };
+
+ keyboard = {
+ bindings = [
+ {
+ key = "Return";
+ mods = "Shift|Control";
+ action = "SpawnNewInstance";
+ }
+ ];
+ };
+ };
+ };
+}
diff --git a/new/home/default.nix b/new/home/default.nix
new file mode 100644
index 0000000..6106265
--- /dev/null
+++ b/new/home/default.nix
@@ -0,0 +1,37 @@
+{pkgs, ...}:
+let
+ user = import ../data/user.nix {};
+in {
+ imports = [
+ ./alacritty.nix
+ ./firefox.nix
+ ./sway.nix
+ ./waybar.nix
+ ./zsh.nix
+ ./rofi.nix
+ ];
+
+ fonts.fontconfig.enable = true;
+ home = {
+ stateVersion = "25.05";
+ homeDirectory = "/home/${user.username}";
+ username = user.username;
+
+ sessionVariables = {
+ EDITOR = "nvim";
+ VISUAL = "nvim";
+ };
+
+ packages = with pkgs; [
+ # Add your global packages here
+ neovim
+ git
+ wget
+ curl
+ htop
+ tree
+ htop
+ pavucontrol
+ ];
+ };
+}
diff --git a/new/home/firefox.nix b/new/home/firefox.nix
new file mode 100644
index 0000000..fe70c0e
--- /dev/null
+++ b/new/home/firefox.nix
@@ -0,0 +1,127 @@
+{pkgs, ...}: let
+ user = import ../data/user.nix {};
+in{
+ programs.firefox = {
+ enable = true;
+
+ policies = {
+ CaptivePortal = false;
+ DisablePocket = true;
+ DisableTelemetry = true;
+ DisableFirefoxStudies = true;
+ FirefoxHome = {
+ Pocket = false;
+ Snippets = false;
+ };
+ };
+
+ profiles = {
+ default = {
+ isDefault = true;
+
+ search = {
+ default = "ddg";
+ force = true;
+ privateDefault = "ddg";
+ };
+
+ settings = {
+ # disable warning when editing about:config
+ "browser.aboutConfig.showWarning" = false;
+ # webgpu
+ "dom.webgpu.enabled" = true;
+ "gfx.webrender.all" = true;
+ "signon.rememberSignons" = false;
+ # mozilla syncserver
+ "identity.sync.tokenserver.uri" = "https://nirgendswo.com:8001/1.0/sync/1.5";
+ "services.sync.username" = user.email;
+ "browser.startup.page" = 3; # resume previous session
+ "browser.startup.homepage" = "about:home";
+ "browser.toolbars.bookmarks.visibility" = "never";
+
+ # hardening
+ "browser.newtabpage.enabled" = false;
+ "browser.newtabpage.activity-stream.feeds.telemetry" = false;
+ "browser.newtabpage.activity-stream.telemetry" = false;
+ "browser.newtabpage.activity-stream.feeds.snippets" = false;
+ "browser.newtabpage.activity-stream.feeds.section.topstories" = false;
+ "browser.newtabpage.activity-stream.showSponsoredTopSites" = false;
+ "browser.newtabpage.activity-stream.showSponsored" = false;
+ "browser.newtabpage.activity-stream.feeds.discoverystreamfeed" = false;
+ "browser.newtabpage.activity-stream.default.sites" = "";
+ "browser.newtab.preload" = false;
+ "geo.provider.network.url" = "https://location.services.mozilla.com/v1/geolocate?key=%MOZILLA_API_KEY%";
+ "geo.provider.ms-windows-location" = false;
+ "geo.provider.use_corelocation" = false;
+ "geo.provider.use_gpsd" = false;
+ "geo.provider.use_geoclue" = false;
+ "browser.region.network.url" = "";
+ "browser.region.update.enabled" = false;
+ "intl.accept_languages" = "en-US,en-GB,en";
+ "javascript.use_us_language_locale" = true;
+ "app.update.auto" = false;
+
+ "extensions.discover.enabled" = false;
+ "extensions.htmlaboutaddons.recommendations.enabled" = false;
+ "extenisons.getAddons.showPane" = false;
+
+ "datareporting.healthreport.uploadEnabled" = false;
+ "datareporting.policy.dataSubmissionEnabled" = false;
+ "toolkit.telemetry.enabled" = false;
+ "toolkit.telemetry.unified" = false;
+ "toolkit.telemetry.server" = "data:,";
+ "toolkit.telemetry.archive.enabled" = false;
+ "toolkit.telemetry.newProfilePing.enabled" = false;
+ "toolkit.telemetry.shutdownPingSender.enabled" = false;
+ "toolkit.telemetry.updatePing.enabled" = false;
+ "toolkit.telemetry.bhrPing.enabled" = false;
+ "toolkit.telemetry.firstShutdownPing.enabled" = false;
+ "toolkit.telemetry.coverage.opt-out" = true;
+ "toolkit.coverage.opt-out" = true;
+ "beacon.enabled" = false;
+
+ "app.shield.optoutstudies.enabled" = false;
+
+ "captivedetect.canonicalURL" = "";
+ "network.captive-portal-service.enabled" = false;
+ "network.connectivity-service.enabled" = false;
+
+ "browser.safebrowsing.malware.enabled" = false;
+ "browser.safebrowsing.phishing.enabled" = false;
+ "browser.safebrowsing.blockedURIs.enabled" = false;
+ "browser.safebrowsing.provider.google4.gethashURL" = "";
+ "browser.safebrowsing.provider.google4.updateURL" = "";
+ "browser.safebrowsing.provider.google4.dataSharingURL" = "";
+ "browser.safebrowsing.provider.google.gethashURL" = "";
+ "browser.safebrowsing.provider.google.updateURL" = "";
+
+ "browser.safebrowsing.downloads.enabled" = false;
+ "browser.safebrowsing.downloads.remote.enabled" = false;
+ "browser.safebrowsing.downloads.remote.url" = "";
+ "browser.safebrowsing.allowOverride" = false;
+
+ "network.prefetch-next" = false;
+ "network.dns.disablePrefetch" = true;
+ "network.predictor.enabled" = false;
+
+ "browser.fixup.alternate.enabled" = false;
+ "browser.urlbar.trimURLs" = false;
+
+ "browser.contentblocking.category" = "strict";
+ "privacy.partition.serviceWorkers" = true;
+ "privacy.partition.always_partition_third_party_non_cookie_storage" = true;
+ "privacy.partition.always_partition_third_party_non_cookie_storage.exempt_sessionstorage" = true;
+ "privacy.resistFingerprinting" = true;
+ "privacy.resistFingerprinting.block_mozAddonManager" = true;
+
+ "app.normandy.enabled" = false;
+ "app.normandy.api_url" = "";
+ };
+
+ extensions.packages = with pkgs.nur.repos.rycee.firefox-addons; [
+ ublock-origin bitwarden rust-search-extension betterttv
+ ];
+ };
+ };
+ };
+}
diff --git a/new/home/libinput.nix b/new/home/libinput.nix
new file mode 100644
index 0000000..7285fd0
--- /dev/null
+++ b/new/home/libinput.nix
@@ -0,0 +1,19 @@
+{pkgs, config, ...}: {
+ home.packages = with pkgs; [
+ libinput
+ libinput-gestures
+ ];
+
+ # Ensure libinput-gestures service is enabled
+ wayland.windowManager.sway.systemd.extraCommands = [
+ "systemctl --user enable libinput-gestures.service"
+ "systemctl --user start libinput-gestures.service"
+ ];
+
+ xdg.configFile."libinput-gestures.conf".text = ''
+ gesture swipe left 4 swaymsg workspace next
+ gesture swipe right 4 swaymsg workspace next
+ gesture swipe down 4 swaylock-wrapper
+ gesture pinch in 4 rofi -combi-modi window,drun,run,ssh,combi -show combi -show-icons
+'';
+}
diff --git a/new/home/rofi.nix b/new/home/rofi.nix
new file mode 100644
index 0000000..f54e60b
--- /dev/null
+++ b/new/home/rofi.nix
@@ -0,0 +1,239 @@
+{pkgs, config, ...}: let
+ theme = import ../data/theme.nix { inherit config; };
+in {
+ xdg.dataFile."rofi/themes/launcher.rasi".text = ''
+/**
+ *
+ * Author : Aditya Shakya (adi1090x)
+ * Github : @adi1090x
+ *
+ * Rofi Theme File
+ * Rofi Version: 1.7.3
+ **/
+
+/*****----- Configuration -----*****/
+configuration {
+ modi: "drun,run,filebrowser,window";
+ show-icons: false;
+ display-drun: "";
+ display-run: "";
+ display-filebrowser: "";
+ display-window: "";
+ drun-display-format: "{name}";
+ window-format: "{w} · {c} · {t}";
+}
+
+/*****----- Global Properties -----*****/
+* {
+ font: "JetBrains Mono Nerd Font 10";
+ background: #101010;
+ background-alt: #252525;
+ foreground: #FFFFFF;
+ selected: #505050;
+ active: #909090;
+ urgent: #707070;
+}
+
+/*****----- Main Window -----*****/
+window {
+ /* properties for window widget */
+ transparency: "real";
+ location: center;
+ anchor: center;
+ fullscreen: false;
+ width: 400px;
+ x-offset: 0px;
+ y-offset: 0px;
+
+ /* properties for all widgets */
+ enabled: true;
+ border-radius: 20px;
+ cursor: "default";
+ background-color: @background;
+}
+
+/*****----- Main Box -----*****/
+mainbox {
+ enabled: true;
+ spacing: 0px;
+ background-color: transparent;
+ orientation: vertical;
+ children: [ "inputbar", "listbox" ];
+}
+
+listbox {
+ spacing: 20px;
+ padding: 20px;
+ background-color: transparent;
+ orientation: vertical;
+ children: [ "message", "listview", "mode-switcher" ];
+}
+
+/*****----- Inputbar -----*****/
+inputbar {
+ enabled: true;
+ spacing: 10px;
+ padding: 100px 40px;
+ background-color: transparent;
+ background-image: url("~/.config/rofi/images/g.png", width);
+ text-color: @foreground;
+ orientation: horizontal;
+ children: [ "textbox-prompt-colon", "entry" ];
+}
+textbox-prompt-colon {
+ enabled: true;
+ expand: false;
+ str: "";
+ padding: 12px 15px;
+ border-radius: 100%;
+ background-color: @background-alt;
+ text-color: inherit;
+}
+entry {
+ enabled: true;
+ expand: true;
+ padding: 12px 16px;
+ border-radius: 100%;
+ background-color: @background-alt;
+ text-color: inherit;
+ cursor: text;
+ placeholder: "Search";
+ placeholder-color: inherit;
+}
+
+/*****----- Mode Switcher -----*****/
+mode-switcher{
+ enabled: true;
+ spacing: 10px;
+ background-color: transparent;
+ text-color: @foreground;
+}
+button {
+ padding: 12px;
+ border-radius: 100%;
+ background-color: @background-alt;
+ text-color: inherit;
+ cursor: pointer;
+}
+button selected {
+ background-color: @selected;
+ text-color: @foreground;
+}
+
+/*****----- Listview -----*****/
+listview {
+ enabled: true;
+ columns: 1;
+ lines: 5;
+ cycle: true;
+ dynamic: true;
+ scrollbar: false;
+ layout: vertical;
+ reverse: false;
+ fixed-height: true;
+ fixed-columns: true;
+
+ spacing: 10px;
+ background-color: transparent;
+ text-color: @foreground;
+ cursor: "default";
+}
+
+/*****----- Elements -----*****/
+element {
+ enabled: true;
+ spacing: 10px;
+ padding: 12px;
+ border-radius: 100%;
+ background-color: transparent;
+ text-color: @foreground;
+ cursor: pointer;
+}
+element normal.normal {
+ background-color: inherit;
+ text-color: inherit;
+}
+element normal.urgent {
+ background-color: @urgent;
+ text-color: @foreground;
+}
+element normal.active {
+ background-color: @active;
+ text-color: @foreground;
+}
+element selected.normal {
+ background-color: @selected;
+ text-color: @foreground;
+}
+element selected.urgent {
+ background-color: @urgent;
+ text-color: @foreground;
+}
+element selected.active {
+ background-color: @urgent;
+ text-color: @foreground;
+}
+element-icon {
+ background-color: transparent;
+ text-color: inherit;
+ size: 32px;
+ cursor: inherit;
+}
+element-text {
+ background-color: transparent;
+ text-color: inherit;
+ cursor: inherit;
+ vertical-align: 0.5;
+ horizontal-align: 0.0;
+}
+
+/*****----- Message -----*****/
+message {
+ background-color: transparent;
+}
+textbox {
+ padding: 12px;
+ border-radius: 100%;
+ background-color: @background-alt;
+ text-color: @foreground;
+ vertical-align: 0.5;
+ horizontal-align: 0.0;
+}
+error-message {
+ padding: 15px;
+ border-radius: 0px;
+ background-color: @background;
+ text-color: @foreground;
+}
+'';
+
+ xdg.configFile."rofi/launcher.rasi".text = ''
+configuration {
+ modi: "drun,run,ssh,filebrowser,window";
+ terminal: "${pkgs.alacritty}/bin/alacritty";
+ show-icons: true;
+ display-drun: "";
+ display-run: "";
+ display-ssh: "";
+
+ drun-display-format: "{name}";
+ run-display-format: "{name}";
+ ssh-display-format: "{name}";
+ combi-display-format: "{mode} {name}";
+
+ combi-modi: "window,drun,run,filebrowser";
+
+ kb-mode-previous: "Control+h";
+ kb-mode-next: "Control+l";
+ kb-mode-complete: "";
+ kb-remove-char-back: "BackSpace,Shift+BackSpace";
+}
+'';
+ programs.rofi = {
+ enable = true;
+ package = pkgs.rofi-wayland;
+ terminal = "{pkgs.alacritty}/bin/alacritty";
+
+ theme = "launcher.rasi";
+ };
+}
diff --git a/new/home/sway.nix b/new/home/sway.nix
new file mode 100644
index 0000000..46145ea
--- /dev/null
+++ b/new/home/sway.nix
@@ -0,0 +1,150 @@
+{pkgs, lib, config, ...}:
+let
+ mod = "Mod4";
+ left = "h";
+ right = "l";
+ up = "k";
+ down = "j";
+
+ launcher = "${pkgs.rofi}/bin/rofi -config ${config.xdg.configHome}/rofi/launcher.rasi -theme ${config.xdg.dataHome}/rofi/themes/launcher.rasi -show drun -show-icons";
+
+in {
+ home.packages = with pkgs; [
+ brightnessctl
+ wmctrl
+ wireplumber
+ alacritty
+ waybar
+ sway
+ rofi-wayland
+ ];
+ wayland = {
+ windowManager = {
+ sway = {
+ enable = true;
+ systemd = {
+ enable = true;
+ };
+
+ config = {
+ modifier = "${mod}";
+
+ gaps = {
+ inner = 8;
+ };
+
+ bars = [{
+ command = "${pkgs.waybar}/bin/waybar";
+ }];
+
+ window = {
+ border = 3;
+ titlebar = false;
+ };
+
+ input = {
+ "type:pointer" = {
+ pointer_accel = "-1";
+ };
+
+ "type:keyboard" = {
+ xkb_layout = "gb,dk";
+ xkb_options =
+ "caps:escape,grp:menu_toggle,grp:rctrl_toggle";
+ repeat_delay = "250";
+ repeat_rate = "25";
+ };
+
+ "type:touchpad" = {
+ natural_scroll = "enabled";
+ tap = "enabled";
+ tap_button_map = "lrm";
+ pointer_accel = "0";
+ };
+ };
+
+ keybindings = with pkgs; {
+ "Print" = "exec screenshot";
+ "${mod}+Print" = "exec screenshot --area";
+ "${mod}+Shift+Print" = "exec screenshot --current-window";
+
+ "XF86AudioRaiseVolume" = "exec ${wireplumber}/bin/wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+";
+ "XF86AudioLowerVolume" = "exec ${wireplumber}/bin/wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-";
+ "XF86AudioMute" = "exec ${wireplumber}/bin/wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle";
+ "XF86AudioMicMute" = "exec ${wireplumber}/bin/wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle";
+
+ "XF86AudioPlay" = "mpc toggle";
+ "XF86AudioNext" = "mpc next";
+ "XF86AudioPrev" = "mpc prev";
+
+ "XF86MonBrightnessUp" = "exec ${brightnessctl}/bin/brightnessctl set +10%";
+ "XF86MonBrightnessDown" = "exec ${brightnessctl}/bin/brightnessctl set 10%-";
+
+ "${mod}+Shift+Return" = "exec ${alacritty}/bin/alacritty";
+ "${mod}+q" = "kill";
+ "${mod}+p" = "exec ${launcher}";
+ "${mod}+Shift+e" = "exec ${pkgs.emacs}/bin/emacsclient -c -a ''";
+ "${mod}+Shift+b" = "exec ${pkgs.firefox}/bin/firefox";
+ "${mod}+Shift+c" = "reload";
+ "${mod}+Shift+q" = "exec ${pkgs.sway}/bin/swaymsg exit";
+
+ "${mod}+${left}" = "focus left";
+ "${mod}+${right}" = "focus right";
+ "${mod}+${up}" = "focus up";
+ "${mod}+${down}" = "focus down";
+
+ "${mod}+Shift+${left}" = "move left";
+ "${mod}+Shift+${right}" = "move right";
+ "${mod}+Shift+${up}" = "move up";
+ "${mod}+Shift+${down}" = "move down";
+
+ "${mod}+Ctrl+${left}" = "move workspace to output left";
+ "${mod}+Ctrl+${right}" = "move workspace to output right";
+
+ "${mod}+b" = "splith";
+ "${mod}+v" = "splitv";
+
+ "${mod}+s" = "layout stacking";
+ "${mod}+w" = "layout tabbed";
+ "${mod}+e" = "layout toggle split";
+
+ "${mod}+Shift+space" = "layout toggle floating";
+ "${mod}+space" = "focus mode_toggle";
+ "${mod}+Shift+f" = "fullscreen";
+
+ } // lib.attrsets.mergeAttrsList (map
+ (n: let workspace = toString n; in {
+ "${mod}+${workspace}" = "workspace ${workspace}";
+ "${mod}+Shift+${workspace}" = "move container to workspace ${workspace}";
+ })
+ [1 2 3 4 5 6 7 8 9 0]
+ );
+
+ colors = {
+ focused = {
+ background = "#A7C080";
+ text = "#272E33";
+ indicator = "#A7C080";
+ border = "#A7C080";
+ childBorder = "#A7C080";
+ };
+ unfocused = {
+ background = "#9DA9A0";
+ text = "#272E33";
+ indicator = "#9DA9A0";
+ border = "#9DA9A0";
+ childBorder = "#9DA9A0";
+ };
+ urgent = {
+ background = "#E67E80";
+ text = "#272E33";
+ indicator = "#E67E80";
+ border = "#E67E80";
+ childBorder = "#E67E80";
+ };
+ };
+ };
+ };
+ };
+ };
+}
diff --git a/new/home/waybar.nix b/new/home/waybar.nix
new file mode 100644
index 0000000..1055409
--- /dev/null
+++ b/new/home/waybar.nix
@@ -0,0 +1,234 @@
+{lib, config, ...}:
+let
+ theme = import ../data/theme.nix {inherit config; };
+ utils = import ../utils.nix {inherit lib; };
+in let
+ self = rec {
+ # ModuleDesc has the shape {name, config?, background?, color?, style?}
+ module-descs = [
+ {
+ name = "custom/left-most";
+ background = theme.background;
+ }
+ {
+ name = "pulseaudio";
+ config = {
+ format = "{volume}% {icon} {format_source}";
+ format-bluetooth = "{volume}% {icon} {format_source}";
+ format-muted = "{format_source}";
+ format-source = "{volume}% ";
+ format-source-muted = "";
+ format-icons = {
+ headphones = "";
+ default = ["" "" ""];
+ };
+ on-click = "pavucontrol";
+ };
+ background = theme.normal.yellow;
+ }
+ {
+ name = "network";
+ config = {
+ format-wifi = "{essid} {signalStrength}% {icon}";
+ format-ethernet = "{ipaddr} ";
+ format-disconnected = "Disconnected ";
+ tooltip-format = ''Interface: {ifname}
+IP: {ipaddr}
+Speed: {bandwidthUpBytes} / {bandwidthDownBytes}
+Signal: {signalStrength}%
+SSID: {essid} {frequency}'';
+ on-click = "iwgtk";
+ format-icons = ["" "" "" "" ""];
+ };
+ background = theme.normal.green;
+ }
+ {
+ name = "custom/vpn";
+ config = {
+ format = "{}";
+ excape = true;
+ interval = 30;
+ exec = "nordvpn-rofi.sh --status-json";
+ return-type = "json";
+ on-click = "rofi -show vpn -modes 'vpn:nordvpn-rofi.sh'";
+ };
+ style = {
+ connected.color = theme.normal.black;
+ disconnected.color = theme.normal.yellow;
+ };
+ background = theme.extra.teal;}
+ ]
+ ++ (if (config.has_battery) then [{
+ name = "battery";
+ config = {
+ states = {
+ critical = 15;
+ warning = 25;
+ good = 80;
+ full = 90;
+ };
+ interval = 30;
+ format = "{capacity}% {icon}";
+ format-charging = "{capacity}% ";
+ format-plugged = "{capacity}% ";
+ format-icons = ["" "" "" "" ""];
+ };
+ background = theme.extra.aqua;
+ }] else [])
+ ++ [
+ {
+ name = "cpu";
+ config = {
+ format = "{}% ";
+ };
+ background = theme.extra.brown;
+ }
+ {
+ name = "memory";
+ config = {
+ format = "{}% ";
+ };
+ background = theme.extra.darkbrown;
+ }
+ {
+ name = "temperature";
+ config = {
+ critical-threshold = 80;
+ hwmon-path = "/sys/class/hwmon/hwmon5/temp1_input";
+ format = "{temperatureC}°C {icon}";
+ format-icons = ["" "" ""];
+ };
+ background = theme.extra.darkerbrown;
+ }
+ {
+ name = "clock";
+ config = {
+ format = "{:%H:%M} ";
+ tooltip-format = "{calendar}";
+ calendar = {
+ mode = "month";
+ weeks-pos = "left";
+ on-scroll = 1;
+ format = {
+ months = "{}";
+ days = "{}";
+ weekdays = "{}";
+ today = "{}";
+ };
+ on-scroll-up = "shift_up";
+ on-scroll-down = "shift_down";
+ };
+ };
+ background = theme.normal.black;
+ }
+ {name = "tray"; config = { spacing = 10; }; background = theme.background;}
+ ];
+
+ # default style for modules
+ default-style = "padding-left: 8pt; padding-right: 8pt;";
+
+ # ModuleDesc -> Module
+ mkModule = desc: let
+ background = desc.background or theme.background;
+ color = desc.color or theme.foreground;
+ config = desc.config or {};
+ # style = module.style or "";
+ style = default-style;
+ style-name = builtins.replaceStrings ["/"] ["-"] desc.name;
+ in {
+ inherit (desc) name;
+ setting = {
+ } // config;
+
+ style = "#${style-name} {" + default-style + ''background: ${background};color: ${color};'' + "}\n";
+ };
+
+ mkSpacer = idx: left: right: {
+ name = "custom/arrow${toString idx}";
+ setting = {
+ format = "";
+ tooltip = false;
+ };
+ style = "#custom-arrow${toString idx} {font-size: 14pt;background: ${left.background};color: ${right.background};}\n";
+ };
+
+ # modules interlaced with spacers
+ # [ModuleDesc] -> [Module]
+ mkSpacedModules = descs: with builtins;
+ let
+ len = length descs;
+ in lib.lists.flatten
+ (lib.lists.imap0
+ (n: descs: let
+ left = elemAt descs 0;
+ right = elemAt descs 1;
+ in if n == len then [
+ (mkModule left)
+ (mkSpacer n left right)
+ (mkModule right)
+ ] else [
+ (mkModule left)
+ (mkSpacer n left right)
+ ])
+ (utils.windows 2 descs)
+ );
+
+ # Module -> {"name" = setting}
+ mkModuleConfig = {name, setting, ...}: lib.attrsets.optionalAttrs (!utils.isEmptySet setting) {
+ "${name}" = setting;
+ };
+
+ # builds bar configuration with left, center, and right modules
+ # right modules get spacers in between them.
+ # {left: [ModuleDesc], center: [ModuleDesc], right: [ModuleDesc], config: {}} -> {config, style}
+ mkBar = {left, center, right, config, ...}:
+ let
+ # Create modules from the descriptions
+ right' = mkSpacedModules right;
+ left' = map (module: mkModule module) left;
+ center' = map (module: mkModule module) center;
+ in let
+ # Create lists of module names for the config
+ modules-left = map (module: module.name) left';
+ modules-center = map (module: module.name) center';
+ modules-right = map (module: module.name) right';
+ # Combine all modules into a single list
+ modules = lib.lists.flatten [left' center' right'];
+ in {
+ config = lib.attrsets.mergeAttrsList (lib.lists.flatten [
+ {
+ inherit modules-left modules-center modules-right;
+ }
+ config
+ (map mkModuleConfig modules)
+ ]);
+ style = lib.strings.concatStringsSep "\n" (map (module: module.style) modules);
+ };
+ };
+
+ bar = self.mkBar {
+ left = [ {name = "sway/workspaces";} {name = "sway/mode";} ];
+ center = [ {name = "sway/window";} ];
+ right = self.module-descs;
+ config = {
+ height = 25;
+ spacing = 0;
+ position = "top";
+ };
+ };
+in {
+ imports = [ ../options.nix ];
+ programs.waybar = {
+ enable = true;
+
+ settings = {
+ mainBar = bar.config;
+ };
+
+ style = ''
+* {border: none; border-radius: 0; min-height: 0; margin: 0; padding: 0; box-shadow: none; text-shadow: none;}
+#waybar { background: rgba(40, 40, 40, 0.3); color: #ffffff; font-family: "sans-serif"; font-size: 12pt; font-weight: 500; }
+''
+ + bar.style;
+ };
+}
diff --git a/new/home/zsh.nix b/new/home/zsh.nix
new file mode 100644
index 0000000..2a9cc9f
--- /dev/null
+++ b/new/home/zsh.nix
@@ -0,0 +1,39 @@
+{pkgs, ...}:
+let
+ aliases = import ../data/zsh-aliases.nix {};
+in {
+ home.packages = with pkgs; [ pure-prompt ];
+ programs.zsh = {
+ enable = true;
+ enableCompletion = true;
+ shellAliases = aliases;
+
+ history = {
+ size = 10000000;
+ save = 10000000;
+ findNoDups = true;
+ saveNoDups = true;
+ ignoreDups = true;
+ share = true;
+ extended = true;
+ append = true;
+ path = "$HOME/.zsh_history";
+ };
+
+ initExtra = ''
+prompt pure
+zstyle :prompt:pure:path color cyan
+zstyle :prompt:pure:prompt:error color red
+zstyle :prompt:pure:prompt:success color green
+bindkey -v
+autoload -Uz edit-command-line
+zle -N edit-command-line
+bindkey '^X^E' edit-command-line
+'';
+ };
+
+ programs.fzf = {
+ enable = true;
+ enableZshIntegration = true;
+ };
+}
diff --git a/new/hosts/laptop/default.nix b/new/hosts/laptop/default.nix
new file mode 100644
index 0000000..59e58c0
--- /dev/null
+++ b/new/hosts/laptop/default.nix
@@ -0,0 +1,6 @@
+{modulesPath, ...}: {
+ imports = [
+ ./disks.nix
+ (modulesPath + "/installer/scan/not-detected.nix")
+ ];
+}
diff --git a/new/hosts/laptop/disks.nix b/new/hosts/laptop/disks.nix
new file mode 100644
index 0000000..840923c
--- /dev/null
+++ b/new/hosts/laptop/disks.nix
@@ -0,0 +1,78 @@
+{
+ disko.devices = {
+ disk = {
+ root = {
+ type = "disk";
+ device = "/dev/nvme0n1";
+ content = {
+ type = "gpt";
+ partitions = {
+ ESP = {
+ label = "boot";
+ name = "ESP";
+ type = "EF00";
+ size = "512M";
+ content = {
+ type = "filesystem";
+ format = "vfat";
+ mountpoint = "/boot";
+ mountOptions = [ "umask=0077" ];
+ };
+ };
+
+ luks = {
+ size = "100%";
+ label = "luks";
+ content = {
+ type = "luks";
+ name = "cryptroot";
+ extraOpenArgs = [
+ "--allow-discards"
+ "--perf-no_read_workqueue"
+ "--perf-no_write_workqueue"
+ ];
+ # https://0pointer.net/blog/unlocking-luks2-volumes-with-tpm2-fido2-pkcs11-security-hardware-on-systemd-248.html
+ settings = {crypttabExtraOpts = ["tpm2-device=auto" "token-timeout=10"];};
+ content = {
+ type = "btrfs";
+ extraArgs = ["-L" "nixos" "-f"];
+ subvolumes = {
+ "@root" = {
+ mountpoint = "/";
+ mountOptions = ["subvol=@root" "compress=zstd" "noatime"];
+ };
+ "@home" = {
+ mountpoint = "/home";
+ mountOptions = ["subvol=@home" "compress=zstd" "noatime"];
+ };
+ "@nix" = {
+ mountpoint = "/nix";
+ mountOptions = ["subvol=@nix" "compress=zstd" "noatime"];
+ };
+ "@persist" = {
+ mountpoint = "/persist";
+ mountOptions = ["subvol=@persist" "compress=zstd" "noatime"];
+ };
+ "@log" = {
+ mountpoint = "/var/log";
+ mountOptions = ["subvol=@log" "compress=zstd" "noatime"];
+ };
+ "@snapshots" = {
+ };
+ "@swap" = {
+ mountpoint = "/swap";
+ swap.swapfile.size = "32G";
+ };
+ };
+ };
+ };
+ };
+ };
+ };
+ };
+ };
+ };
+
+ fileSystems."/persist".neededForBoot = true;
+ fileSystems."/var/log".neededForBoot = true;
+}
diff --git a/new/hosts/vm.nix b/new/hosts/vm.nix
new file mode 100644
index 0000000..1a2c661
--- /dev/null
+++ b/new/hosts/vm.nix
@@ -0,0 +1,29 @@
+{config, lib, modulesPath, ...}: {
+ imports = [
+ ../options.nix
+ (modulesPath + "/profiles/qemu-guest.nix")
+ ];
+
+ vmGuest = true;
+
+ boot = {
+ kernelModules = [ "kvm-intel" ];
+ initrd.availableKernelModules = [ "virtio_pci" "ahci" "xhci_pci" "sr_mod" "virtio_blk" ];
+ };
+
+ networking.useDHCP = lib.mkDefault true;
+ nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
+
+ fileSystems."/" =
+ { device = "/dev/disk/by-uuid/723e4a6a-97b9-49ff-999f-806b12ea26b6";
+ fsType = "ext4";
+ };
+
+ fileSystems."/boot" =
+ { device = "/dev/disk/by-uuid/15E6-98FA";
+ fsType = "vfat";
+ options = [ "fmask=0077" "dmask=0077" ];
+ };
+
+ swapDevices = [ ];
+}
diff --git a/new/options.nix b/new/options.nix
new file mode 100644
index 0000000..c47bfc3
--- /dev/null
+++ b/new/options.nix
@@ -0,0 +1,21 @@
+{lib, ...}: {
+ options = {
+ has_battery = lib.mkOption {
+ type = lib.types.bool;
+ default = false;
+ description = "Whether the system has a battery.";
+ };
+
+ vmGuest = lib.mkOption {
+ type = lib.types.bool;
+ default = false;
+ description = "Enable VM guest services.";
+ };
+
+ darkMode = lib.mkOption {
+ type = lib.types.bool;
+ default = false;
+ description = "Enable dark mode for the system.";
+ };
+ };
+}
diff --git a/new/system/default.nix b/new/system/default.nix
new file mode 100644
index 0000000..a2c8206
--- /dev/null
+++ b/new/system/default.nix
@@ -0,0 +1,114 @@
+{pkgs, config, ...}: {
+ imports = [
+ ../options.nix
+ ];
+
+ environment.systemPackages = with pkgs; [
+ # Basic utilities
+ zsh
+ wget
+ curl
+ git
+ vim
+
+ htop
+
+ linux-firmware
+ linuxHeaders
+ ];
+
+ nix.settings.experimental-features = [
+ "nix-command"
+ "flakes"
+ ];
+
+ system.stateVersion = "25.05";
+
+ boot = {
+ loader.systemd-boot.enable = true;
+ loader.efi.canTouchEfiVariables = true;
+
+ # kernelModules = [];
+ kernelPackages = pkgs.linuxPackages_zen;
+ };
+
+ hardware = {
+ enableAllFirmware = true;
+ amdgpu.initrd.enable = true;
+ graphics = {
+ enable = true;
+ enable32Bit = true;
+ };
+ };
+
+ security = {
+ polkit.enable = true;
+ rtkit.enable = true;
+ };
+
+ fonts = {
+ enableDefaultPackages = true;
+ packages = with pkgs; [
+ noto-fonts
+ noto-fonts-cjk-sans
+ noto-fonts-emoji
+ liberation_ttf
+ roboto
+ roboto-mono
+ twitter-color-emoji
+ nerd-fonts.fira-code
+ nerd-fonts.fira-mono
+ unicode-emoji
+ fira-sans
+ font-awesome
+ fira-mono
+ fira-code
+ material-icons
+ source-sans
+ source-code-pro
+ pkgs.nur.repos.redpz.sf-mono
+ ];
+ fontconfig = {
+ defaultFonts = {
+ monospace = ["SF Mono" "Fira Mono" "Noto Mono"];
+ serif = ["Liberation Serif" "Noto Serif"];
+ sansSerif = ["Liberation Sans" "Noto Sans" "Roboto"];
+ emoji = ["Twitter Color Emoji" "Noto Emoji"];
+ };
+ };
+ };
+
+ networking = {
+ networkmanager.enable = true;
+ nameservers = ["1.1.1.1" "9.9.9.9"];
+ };
+ time.timeZone = "Europe/Amsterdam";
+ i18n.defaultLocale = "en_GB.UTF-8";
+
+ console = {
+ font = "Lat2-Terminus16";
+ keyMap = "uk";
+ };
+
+ services = {
+ qemuGuest.enable = config.vmGuest;
+ spice-vdagentd.enable = config.vmGuest;
+
+ pipewire = {
+ enable = true;
+ pulse.enable = true;
+ alsa.enable = true;
+ alsa.support32Bit = true;
+ };
+
+ openssh = {
+ enable = true;
+ settings = {
+ PasswordAuthentication = true; # Enable password authentication.
+ PermitRootLogin = "yes"; # Allow root login (not recommended for production).
+ };
+ };
+
+ libinput.enable = true;
+ };
+}
diff --git a/new/user/default.nix b/new/user/default.nix
new file mode 100644
index 0000000..57d68f7
--- /dev/null
+++ b/new/user/default.nix
@@ -0,0 +1,31 @@
+{pkgs, ...}:
+let
+ user = import ../data/user.nix {};
+in {
+ users.users.${user.username} = {
+ shell = pkgs.zsh;
+ group = "users";
+ home = "/home/${user.username}";
+ createHome = true;
+ isNormalUser = true;
+ extraGroups = [ "wheel" "input" ];
+ };
+
+ programs.zsh.enable = true;
+
+ services = {
+ greetd = {
+ enable = true;
+ settings = {
+ default_session = {
+ command = "${pkgs.greetd.tuigreet}/bin/tuigreet --time --cmd sway";
+ user = "greeter";
+ };
+ };
+ };
+ };
+
+ home-manager.users.${user.username} = { ... }: {
+ imports = [ ../home ];
+ };
+}
diff --git a/new/utils.nix b/new/utils.nix
new file mode 100644
index 0000000..cd69dfc
--- /dev/null
+++ b/new/utils.nix
@@ -0,0 +1,20 @@
+{lib, ...}: rec {
+ min = a: b: if a < b then a else b;
+ max = a: b: if a > b then a else b;
+ # build list of `len` lists of `n` elements of `xs`
+ windows = with builtins; n: xs: let
+ len = length xs;
+ n' = min n len;
+ # when len = n, there is still one window
+ num-windows = max 0 (len - n' + 1);
+ in
+ genList
+ # for i in 0..len
+ (i: genList
+ # for j in 0..n -> xs[i + j]
+ (j: elemAt xs (i + j))
+ n')
+ num-windows;
+
+ isEmptySet = set: with builtins; length (attrNames set) == 0;
+}