about summary refs log tree commit diff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/acme.nix (renamed from modules/nixos/acme.nix)0
-rw-r--r--modules/alacritty.nix (renamed from modules/common/alacritty.nix)0
-rw-r--r--modules/alertmanager.nix (renamed from modules/nixos/alertmanager.nix)0
-rw-r--r--modules/android.nix (renamed from modules/nixos/android.nix)0
-rw-r--r--modules/aria2.nix (renamed from modules/common/aria2.nix)0
-rw-r--r--modules/bat.nix (renamed from modules/common/bat.nix)0
-rw-r--r--modules/beets.nix (renamed from modules/nixos/beets.nix)0
-rw-r--r--modules/bluetooth.nix (renamed from modules/nixos/bluetooth.nix)0
-rw-r--r--modules/chromium.nix (renamed from modules/nixos/chromium.nix)0
-rw-r--r--modules/clickhouse.nix (renamed from modules/nixos/clickhouse.nix)0
-rw-r--r--modules/common/ark.nix (renamed from modules/nixos/common/ark.nix)2
-rw-r--r--modules/common/common/default.nix14
-rw-r--r--modules/common/common/documentation.nix28
-rw-r--r--modules/common/common/locale.nix6
-rw-r--r--modules/common/common/networking.nix4
-rw-r--r--modules/common/common/nix.nix125
-rw-r--r--modules/common/common/stylix.nix61
-rw-r--r--modules/common/common/users.nix15
-rw-r--r--modules/common/console.nix (renamed from modules/nixos/common/console.nix)0
-rw-r--r--modules/common/default.nix29
-rw-r--r--modules/common/documentation.nix (renamed from modules/nixos/common/documentation.nix)11
-rw-r--r--modules/common/git.nix173
-rw-r--r--modules/common/gnupg.nix72
-rw-r--r--modules/common/home-manager.nix (renamed from modules/common/common/home-manager.nix)11
-rw-r--r--modules/common/kernel.nix (renamed from modules/nixos/common/kernel.nix)0
-rw-r--r--modules/common/locale.nix (renamed from modules/nixos/common/locale.nix)5
-rw-r--r--modules/common/networking.nix (renamed from modules/nixos/common/networking.nix)1
-rw-r--r--modules/common/nix.nix150
-rw-r--r--modules/common/openssh.nix72
-rw-r--r--modules/common/profiles/dev/containers.nix57
-rw-r--r--modules/common/profiles/headful.nix57
-rw-r--r--modules/common/profiles/headless.nix25
-rw-r--r--modules/common/secrets.nix (renamed from modules/common/common/secrets.nix)1
-rw-r--r--modules/common/security.nix (renamed from modules/nixos/common/security.nix)0
-rw-r--r--modules/common/services.nix (renamed from modules/nixos/common/services.nix)0
-rw-r--r--modules/common/shell/default.nix (renamed from modules/common/common/shell/default.nix)2
-rw-r--r--modules/common/shell/functions.bash (renamed from modules/common/common/shell/functions.bash)0
-rw-r--r--modules/common/stylix.nix105
-rw-r--r--modules/common/systemd.nix (renamed from modules/nixos/common/systemd.nix)0
-rw-r--r--modules/common/tmp.nix (renamed from modules/nixos/common/tmp.nix)0
-rw-r--r--modules/common/users.nix (renamed from modules/nixos/common/users.nix)18
-rw-r--r--modules/common/vim/default.nix47
-rw-r--r--modules/common/xdg.nix (renamed from modules/common/common/xdg.nix)39
-rw-r--r--modules/curl.nix (renamed from modules/common/curl.nix)0
-rw-r--r--modules/darwin/common/default.nix13
-rw-r--r--modules/darwin/common/home-manager.nix4
-rw-r--r--modules/darwin/common/locale.nix8
-rw-r--r--modules/darwin/common/networking.nix11
-rw-r--r--modules/darwin/common/nix.nix17
-rw-r--r--modules/darwin/common/secrets.nix4
-rw-r--r--modules/darwin/common/shell.nix4
-rw-r--r--modules/darwin/common/stylix.nix12
-rw-r--r--modules/darwin/common/users.nix12
-rw-r--r--modules/darwin/common/xdg.nix24
-rw-r--r--modules/darwin/default.nix9
-rw-r--r--modules/darwin/gnupg.nix13
-rw-r--r--modules/darwin/homebrew.nix29
-rw-r--r--modules/darwin/profiles/default.nix94
-rw-r--r--modules/darwin/profiles/headful.nix33
-rw-r--r--modules/darwin/vim/default.nix38
-rw-r--r--modules/default.nix1
-rw-r--r--modules/direnv.nix (renamed from modules/common/direnv.nix)0
-rw-r--r--modules/docker.nix (renamed from modules/nixos/docker.nix)0
-rw-r--r--modules/dwm.nix (renamed from modules/nixos/dwm.nix)0
-rw-r--r--modules/editorconfig.nix (renamed from modules/common/editorconfig.nix)0
-rw-r--r--modules/emacs.nix (renamed from modules/nixos/emacs.nix)0
-rw-r--r--modules/emacs/default.nix (renamed from modules/common/emacs/default.nix)204
-rw-r--r--modules/emacs/doom/config.el (renamed from modules/common/emacs/doom/config.el)5
-rw-r--r--modules/emacs/doom/init.el (renamed from modules/common/emacs/doom/init.el)0
-rw-r--r--modules/emacs/doom/packages.el (renamed from modules/common/emacs/doom/packages.el)0
-rw-r--r--modules/endlessh-go.nix (renamed from modules/nixos/endlessh-go.nix)0
-rw-r--r--modules/endlessh.nix (renamed from modules/nixos/endlessh.nix)0
-rw-r--r--modules/eza.nix (renamed from modules/common/eza.nix)0
-rw-r--r--modules/fail2ban.nix (renamed from modules/nixos/fail2ban.nix)0
-rw-r--r--modules/firefox/addons.json (renamed from modules/nixos/firefox/addons.json)4
-rw-r--r--modules/firefox/addons.nix315
-rw-r--r--modules/firefox/default.nix (renamed from modules/nixos/firefox/default.nix)1
-rw-r--r--modules/firefox/userChrome.css (renamed from modules/nixos/firefox/userChrome.css)0
-rw-r--r--modules/firefox/userContent.css (renamed from modules/nixos/firefox/userContent.css)0
-rw-r--r--modules/foot.nix (renamed from modules/nixos/foot.nix)0
-rw-r--r--modules/games/default.nix (renamed from modules/nixos/games/default.nix)9
-rw-r--r--modules/games/gamemode.nix (renamed from modules/nixos/games/gamemode.nix)0
-rw-r--r--modules/games/lutris.nix (renamed from modules/nixos/games/lutris.nix)0
-rw-r--r--modules/games/mangohud.nix (renamed from modules/nixos/games/mangohud.nix)0
-rw-r--r--modules/games/minecraft.nix (renamed from modules/nixos/games/minecraft.nix)0
-rw-r--r--modules/games/steam-run.nix (renamed from modules/nixos/games/steam-run.nix)0
-rw-r--r--modules/games/steam.nix (renamed from modules/nixos/games/steam.nix)0
-rw-r--r--modules/git/default.nix300
-rw-r--r--modules/git/favicon.ico (renamed from modules/nixos/git/favicon.ico)bin15406 -> 15406 bytes
-rw-r--r--modules/git/logo.gif (renamed from modules/nixos/git/logo.gif)bin138553 -> 138553 bytes
-rw-r--r--modules/gnupg.nix106
-rw-r--r--modules/gotify.nix (renamed from modules/nixos/gotify.nix)0
-rw-r--r--modules/grafana.nix (renamed from modules/nixos/grafana.nix)0
-rw-r--r--modules/htop.nix (renamed from modules/common/htop.nix)0
-rw-r--r--modules/hydra.nix (renamed from modules/nixos/hydra.nix)0
-rw-r--r--modules/incus.nix (renamed from modules/nixos/incus.nix)0
-rw-r--r--modules/ipfs.nix (renamed from modules/nixos/ipfs.nix)0
-rw-r--r--modules/jackett.nix (renamed from modules/nixos/jackett.nix)0
-rw-r--r--modules/k3s.nix (renamed from modules/nixos/k3s.nix)0
-rw-r--r--modules/kde.nix (renamed from modules/nixos/kde.nix)0
-rw-r--r--modules/libvirtd.nix (renamed from modules/nixos/libvirtd.nix)0
-rw-r--r--modules/lidarr.nix (renamed from modules/nixos/lidarr.nix)0
-rw-r--r--modules/loki.nix (renamed from modules/nixos/loki.nix)0
-rw-r--r--modules/matrix/default.nix1
-rw-r--r--modules/matrix/dendrite.nix (renamed from modules/nixos/matrix/dendrite.nix)3
-rw-r--r--modules/matrix/element.nix (renamed from modules/nixos/matrix/element.nix)2
-rw-r--r--modules/monitoring/dashboards/endlessh.json (renamed from modules/nixos/monitoring/dashboards/endlessh.json)0
-rw-r--r--modules/monitoring/dashboards/nginx.json (renamed from modules/nixos/monitoring/dashboards/nginx.json)0
-rw-r--r--modules/monitoring/dashboards/node.json (renamed from modules/nixos/monitoring/dashboards/node.json)0
-rw-r--r--modules/monitoring/dashboards/ntfy.json (renamed from modules/nixos/monitoring/dashboards/ntfy.json)0
-rw-r--r--modules/monitoring/dashboards/postgresql.json (renamed from modules/nixos/monitoring/dashboards/postgresql.json)0
-rw-r--r--modules/monitoring/dashboards/redis.json (renamed from modules/nixos/monitoring/dashboards/redis.json)0
-rw-r--r--modules/monitoring/dashboards/unbound.json (renamed from modules/nixos/monitoring/dashboards/unbound.json)0
-rw-r--r--modules/monitoring/default.nix (renamed from modules/nixos/monitoring/default.nix)0
-rw-r--r--modules/monitoring/rules/nginx.yaml (renamed from modules/nixos/monitoring/rules/nginx.yaml)0
-rw-r--r--modules/monitoring/rules/node.yaml (renamed from modules/nixos/monitoring/rules/node.yaml)0
-rw-r--r--modules/monitoring/rules/postgres.yaml (renamed from modules/nixos/monitoring/rules/postgres.yaml)0
-rw-r--r--modules/monitoring/rules/redis.yaml (renamed from modules/nixos/monitoring/rules/redis.yaml)0
-rw-r--r--modules/mpd.nix (renamed from modules/nixos/mpd.nix)0
-rw-r--r--modules/mpv.nix (renamed from modules/common/mpv.nix)84
-rw-r--r--modules/murmur.nix (renamed from modules/nixos/murmur.nix)0
-rw-r--r--modules/nextcloud.nix (renamed from modules/nixos/nextcloud.nix)0
-rw-r--r--modules/nginx.nix (renamed from modules/nixos/nginx.nix)0
-rw-r--r--modules/nixos/common/default.nix21
-rw-r--r--modules/nixos/common/home-manager.nix4
-rw-r--r--modules/nixos/common/nix.nix35
-rw-r--r--modules/nixos/common/secrets.nix4
-rw-r--r--modules/nixos/common/shell.nix1
-rw-r--r--modules/nixos/common/stylix.nix46
-rw-r--r--modules/nixos/common/xdg.nix41
-rw-r--r--modules/nixos/default.nix75
-rw-r--r--modules/nixos/firefox/addons.nix1143
-rw-r--r--modules/nixos/git/default.nix136
-rw-r--r--modules/nixos/gnupg.nix41
-rw-r--r--modules/nixos/matrix/default.nix6
-rw-r--r--modules/nixos/mpv.nix92
-rw-r--r--modules/nixos/openssh.nix51
-rw-r--r--modules/nixos/profiles/default.nix37
-rw-r--r--modules/nixos/profiles/dev/containers.nix32
-rw-r--r--modules/nixos/profiles/dev/default.nix30
-rw-r--r--modules/nixos/zathura.nix13
-rw-r--r--modules/nmap.nix (renamed from modules/common/nmap.nix)0
-rw-r--r--modules/node-exporter.nix (renamed from modules/nixos/node-exporter.nix)0
-rw-r--r--modules/nsd.nix (renamed from modules/nixos/nsd.nix)0
-rw-r--r--modules/ntfy.nix (renamed from modules/nixos/ntfy.nix)0
-rw-r--r--modules/nullmailer.nix (renamed from modules/nixos/nullmailer.nix)0
-rw-r--r--modules/openssh.nix119
-rw-r--r--modules/password-store.nix (renamed from modules/common/password-store.nix)0
-rw-r--r--modules/plausible.nix (renamed from modules/nixos/plausible.nix)0
-rw-r--r--modules/podman.nix (renamed from modules/nixos/podman.nix)0
-rw-r--r--modules/postgresql.nix (renamed from modules/nixos/postgresql.nix)0
-rw-r--r--modules/profiles/default.nix (renamed from modules/common/profiles/default.nix)22
-rw-r--r--modules/profiles/dev/containers.nix71
-rw-r--r--modules/profiles/dev/default.nix (renamed from modules/common/profiles/dev/default.nix)22
-rw-r--r--modules/profiles/dev/gdbinit (renamed from modules/common/profiles/dev/gdbinit)0
-rw-r--r--modules/profiles/dev/ghci.conf (renamed from modules/common/profiles/dev/ghci.conf)0
-rw-r--r--modules/profiles/dev/pystartup.py (renamed from modules/common/profiles/dev/pystartup.py)0
-rw-r--r--modules/profiles/dev/sql.nix (renamed from modules/common/profiles/dev/sql.nix)0
-rw-r--r--modules/profiles/email.nix (renamed from modules/common/profiles/email.nix)4
-rw-r--r--modules/profiles/headful.nix (renamed from modules/nixos/profiles/headful.nix)67
-rw-r--r--modules/profiles/headless.nix (renamed from modules/nixos/profiles/headless.nix)15
-rw-r--r--modules/prometheus.nix (renamed from modules/nixos/prometheus.nix)0
-rw-r--r--modules/promtail.nix (renamed from modules/nixos/promtail.nix)0
-rw-r--r--modules/psd.nix (renamed from modules/nixos/psd.nix)0
-rw-r--r--modules/qutebrowser.nix (renamed from modules/common/qutebrowser.nix)0
-rw-r--r--modules/radarr.nix (renamed from modules/nixos/radarr.nix)0
-rw-r--r--modules/radicale.nix (renamed from modules/nixos/radicale.nix)0
-rw-r--r--modules/redis.nix (renamed from modules/nixos/redis.nix)0
-rw-r--r--modules/rss-bridge.nix (renamed from modules/nixos/rss-bridge.nix)10
-rw-r--r--modules/rtorrent.nix (renamed from modules/nixos/rtorrent.nix)0
-rw-r--r--modules/searx.nix (renamed from modules/nixos/searx.nix)0
-rw-r--r--modules/shadowsocks.nix (renamed from modules/nixos/shadowsocks.nix)0
-rw-r--r--modules/soju.nix (renamed from modules/nixos/soju.nix)0
-rw-r--r--modules/solaar.nix (renamed from modules/nixos/solaar.nix)0
-rw-r--r--modules/sonarr.nix (renamed from modules/nixos/sonarr.nix)0
-rw-r--r--modules/sound.nix (renamed from modules/nixos/sound.nix)0
-rw-r--r--modules/subversion.nix (renamed from modules/common/subversion.nix)0
-rw-r--r--modules/syncthing.nix (renamed from modules/nixos/syncthing.nix)0
-rw-r--r--modules/throttled.nix (renamed from modules/nixos/throttled.nix)0
-rw-r--r--modules/thunderbird.nix (renamed from modules/nixos/thunderbird.nix)0
-rw-r--r--modules/tmux.nix (renamed from modules/common/tmux.nix)0
-rw-r--r--modules/unbound.nix (renamed from modules/nixos/unbound.nix)0
-rw-r--r--modules/vaultwarden.nix (renamed from modules/nixos/vaultwarden.nix)0
-rw-r--r--modules/victoriametrics.nix (renamed from modules/nixos/victoriametrics.nix)4
-rw-r--r--modules/vim/default.nix (renamed from modules/nixos/vim/default.nix)34
-rw-r--r--modules/vim/rc.vim (renamed from modules/common/vim/rc.vim)0
-rw-r--r--modules/vscode.nix (renamed from modules/common/vscode.nix)0
-rw-r--r--modules/wayland.nix (renamed from modules/nixos/wayland.nix)0
-rw-r--r--modules/wget.nix (renamed from modules/common/wget.nix)0
-rw-r--r--modules/wireguard.nix (renamed from modules/nixos/wireguard.nix)0
-rw-r--r--modules/x11.nix (renamed from modules/nixos/x11.nix)0
-rw-r--r--modules/xmonad.nix (renamed from modules/nixos/xmonad.nix)0
-rw-r--r--modules/zathura.nix (renamed from modules/common/zathura.nix)5
193 files changed, 1581 insertions, 3090 deletions
diff --git a/modules/nixos/acme.nix b/modules/acme.nix
index 6a75818..6a75818 100644
--- a/modules/nixos/acme.nix
+++ b/modules/acme.nix
diff --git a/modules/common/alacritty.nix b/modules/alacritty.nix
index 704ce79..704ce79 100644
--- a/modules/common/alacritty.nix
+++ b/modules/alacritty.nix
diff --git a/modules/nixos/alertmanager.nix b/modules/alertmanager.nix
index a3457bc..a3457bc 100644
--- a/modules/nixos/alertmanager.nix
+++ b/modules/alertmanager.nix
diff --git a/modules/nixos/android.nix b/modules/android.nix
index 363bd6c..363bd6c 100644
--- a/modules/nixos/android.nix
+++ b/modules/android.nix
diff --git a/modules/common/aria2.nix b/modules/aria2.nix
index cdf1c4f..cdf1c4f 100644
--- a/modules/common/aria2.nix
+++ b/modules/aria2.nix
diff --git a/modules/common/bat.nix b/modules/bat.nix
index a95d67d..a95d67d 100644
--- a/modules/common/bat.nix
+++ b/modules/bat.nix
diff --git a/modules/nixos/beets.nix b/modules/beets.nix
index 732f400..732f400 100644
--- a/modules/nixos/beets.nix
+++ b/modules/beets.nix
diff --git a/modules/nixos/bluetooth.nix b/modules/bluetooth.nix
index 117aff7..117aff7 100644
--- a/modules/nixos/bluetooth.nix
+++ b/modules/bluetooth.nix
diff --git a/modules/nixos/chromium.nix b/modules/chromium.nix
index c7842d5..c7842d5 100644
--- a/modules/nixos/chromium.nix
+++ b/modules/chromium.nix
diff --git a/modules/nixos/clickhouse.nix b/modules/clickhouse.nix
index 12dc7fa..12dc7fa 100644
--- a/modules/nixos/clickhouse.nix
+++ b/modules/clickhouse.nix
diff --git a/modules/nixos/common/ark.nix b/modules/common/ark.nix
index 6c7148f..84ff6db 100644
--- a/modules/nixos/common/ark.nix
+++ b/modules/common/ark.nix
@@ -10,12 +10,12 @@ let
 in
 {
   imports = [
+    inputs.impermanence.nixosModules.impermanence
     (mkAliasOptionModule [ "ark" ] [
       "nixfiles"
       "modules"
       "ark"
     ])
-    inputs.impermanence.nixosModules.impermanence
   ];
 
   options.nixfiles.modules.ark =
diff --git a/modules/common/common/default.nix b/modules/common/common/default.nix
deleted file mode 100644
index 62e4a95..0000000
--- a/modules/common/common/default.nix
+++ /dev/null
@@ -1,14 +0,0 @@
-_: {
-  imports = [
-    ./documentation.nix
-    ./home-manager.nix
-    ./locale.nix
-    ./networking.nix
-    ./nix.nix
-    ./secrets.nix
-    ./shell
-    ./stylix.nix
-    ./users.nix
-    ./xdg.nix
-  ];
-}
diff --git a/modules/common/common/documentation.nix b/modules/common/common/documentation.nix
deleted file mode 100644
index 2202e11..0000000
--- a/modules/common/common/documentation.nix
+++ /dev/null
@@ -1,28 +0,0 @@
-{
-  config,
-  lib,
-  this,
-  ...
-}:
-with lib;
-{
-  config = mkMerge [
-    (mkIf this.isHeadful {
-      hm.manual = {
-        html.enable = false;
-        json.enable = false;
-        manpages.enable = true;
-      };
-
-      documentation = {
-        enable = true;
-        doc.enable = false;
-        info.enable = false;
-      };
-    })
-    (mkIf this.isHeadless {
-      hm.manual.manpages.enable = false;
-      documentation.enable = false;
-    })
-  ];
-}
diff --git a/modules/common/common/locale.nix b/modules/common/common/locale.nix
deleted file mode 100644
index bcb577a..0000000
--- a/modules/common/common/locale.nix
+++ /dev/null
@@ -1,6 +0,0 @@
-_: {
-  hm.home.language = {
-    collate = "C";
-    messages = "C";
-  };
-}
diff --git a/modules/common/common/networking.nix b/modules/common/common/networking.nix
deleted file mode 100644
index 2e19162..0000000
--- a/modules/common/common/networking.nix
+++ /dev/null
@@ -1,4 +0,0 @@
-{ pkgs, ... }:
-{
-  environment.systemPackages = with pkgs; [ myip ];
-}
diff --git a/modules/common/common/nix.nix b/modules/common/common/nix.nix
deleted file mode 100644
index fdb0125..0000000
--- a/modules/common/common/nix.nix
+++ /dev/null
@@ -1,125 +0,0 @@
-{
-  config,
-  inputs,
-  lib,
-  localUsername ? lib.my.username,
-  pkgs,
-  this,
-  ...
-}:
-with lib;
-{
-  _module.args =
-    let
-      importNixpkgs =
-        nixpkgs:
-        import nixpkgs {
-          inherit (config.nixpkgs) config;
-          inherit (this) system;
-        };
-    in
-    rec {
-      pkgsLocal = importNixpkgs "${config.my.home}/src/nixpkgs"; # Impure!
-      pkgsMaster = importNixpkgs inputs.nixpkgs-master;
-      pkgsStable = importNixpkgs inputs.nixpkgs-stable;
-      pkgsRev =
-        rev: hash:
-        importNixpkgs (
-          pkgs.fetchFromGitHub {
-            owner = "NixOS";
-            repo = "nixpkgs";
-            inherit rev hash;
-          }
-        );
-      pkgsPr = pr: pkgsRev "refs/pull/${toString pr}/head";
-    };
-
-  nixpkgs.overlays = with inputs; [
-    self.overlays.default
-    (_: _: { })
-  ];
-
-  nix =
-    let
-      notSelfInputs = filterAttrs (n: _: n != "self") inputs;
-    in
-    {
-      settings = {
-        # https://nixos.org/manual/nix/unstable/contributing/experimental-features.html#currently-available-experimental-features
-        # https://github.com/NixOS/nix/blob/master/src/libutil/experimental-features.cc
-        experimental-features = concatStringsSep " " [
-          "flakes"
-          "nix-command"
-          "recursive-nix"
-          "repl-flake"
-        ];
-
-        keep-derivations = if this.isHeadful then "true" else "false";
-        keep-outputs = if this.isHeadful then "true" else "false";
-
-        flake-registry = "${inputs.flake-registry}/flake-registry.json";
-
-        warn-dirty = false;
-
-        keep-going = true;
-
-        substituters = [
-          "https://azahi.cachix.org"
-          "https://nix-community.cachix.org"
-        ];
-        trusted-public-keys = [
-          "azahi.cachix.org-1:2bayb+iWYMAVw3ZdEpVg+NPOHCXncw7WMQ0ElX1GO3s="
-          "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
-        ];
-
-        trusted-users = [
-          "root"
-          localUsername
-        ];
-      };
-
-      nixPath = mapAttrsToList (n: v: "${n}=${v}") notSelfInputs ++ [
-        "nixfiles=${config.my.home}/src/nixfiles"
-      ];
-
-      registry = mapAttrs (_: flake: { inherit flake; }) notSelfInputs // {
-        nixfiles.flake = inputs.self;
-      };
-    };
-
-  environment = {
-    systemPackages =
-      with pkgs;
-      optionals this.isHeadful [
-        nix-top
-        nix-tree
-        nixfiles
-      ];
-    variables.NIXFILES = "${config.my.home}/src/nixfiles";
-  };
-
-  hm = {
-    # Used primarily in conjunction with the "nixfiles" script.
-    home.file.".nix-defexpr/default.nix".text =
-      let
-        hostname = strings.escapeNixIdentifier this.hostname;
-      in
-      optionalString this.isHeadful ''
-        let
-          self = builtins.getFlake "nixfiles";
-          configurations = self.nixosConfigurations;
-          local = configurations.${hostname};
-        in rec {
-          inherit self;
-          inherit (self) inputs lib;
-          inherit (lib) my;
-          this = my.configurations.${hostname};
-          inherit (local) config;
-          inherit (local.config.system.build) toplevel vm vmWithBootLoader manual;
-          pretty = expr: lib.trace (lib.generators.toPretty {} expr) {};
-        } // configurations // local._module.args
-      '';
-
-    programs.bash.shellAliases.nix = "nix --verbose --print-build-logs";
-  };
-}
diff --git a/modules/common/common/stylix.nix b/modules/common/common/stylix.nix
deleted file mode 100644
index f1b8f81..0000000
--- a/modules/common/common/stylix.nix
+++ /dev/null
@@ -1,61 +0,0 @@
-{ lib, pkgs, ... }:
-with lib;
-{
-  imports = [
-    (mkAliasOptionModule [ "colors" ] [
-      "lib"
-      "stylix"
-      "colors"
-    ])
-  ];
-
-  options.nixfiles.modules.common.stylix.fonts.extraPackages = mkOption {
-    description = "Font packages.";
-    default = with pkgs; [
-      font-awesome
-      noto-fonts
-      noto-fonts-emoji
-      sarasa-gothic
-      source-han-mono
-      source-han-sans
-      source-han-serif
-      twitter-color-emoji
-    ];
-    readOnly = true;
-  };
-
-  # Styling and color binding can be sourced from here[1].
-  #
-  # [1]: https://github.com/tinted-theming/base24/blob/master/styling.md
-  config.stylix = {
-    image = pkgs.fetchurl {
-      url = "https://upload.wikimedia.org/wikipedia/commons/a/a5/Bonaparte_ante_la_Esfinge%2C_por_Jean-Léon_Gérôme.jpg";
-      sha256 = "sha256-qWv52oT8cF9K4ZoeawmR3jgoGB2ARfjbKKc12IljUcM=";
-    };
-
-    base16Scheme = "${pkgs.base16-schemes}/share/themes/tomorrow.yaml";
-
-    fonts = {
-      monospace = {
-        package = pkgs.iosevka;
-        name = "Iosevka";
-      };
-
-      serif = {
-        package = pkgs.iosevka-bin.override { variant = "Etoile"; };
-        name = "Iosevka Etoile";
-      };
-
-      sansSerif = {
-        package = pkgs.iosevka-bin.override { variant = "Aile"; };
-        name = "Iosevka Aile";
-      };
-
-      sizes = {
-        desktop = 10;
-        applications = 10;
-        terminal = 12;
-      };
-    };
-  };
-}
diff --git a/modules/common/common/users.nix b/modules/common/common/users.nix
deleted file mode 100644
index dc1b32e..0000000
--- a/modules/common/common/users.nix
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-  lib,
-  localUsername ? lib.my.username,
-  ...
-}:
-with lib;
-{
-  imports = [
-    (mkAliasOptionModule [ "my" ] [
-      "users"
-      "users"
-      localUsername
-    ])
-  ];
-}
diff --git a/modules/nixos/common/console.nix b/modules/common/console.nix
index 330310c..330310c 100644
--- a/modules/nixos/common/console.nix
+++ b/modules/common/console.nix
diff --git a/modules/common/default.nix b/modules/common/default.nix
index 92f719d..ef9fb18 100644
--- a/modules/common/default.nix
+++ b/modules/common/default.nix
@@ -1,28 +1 @@
-_: {
-  imports = [
-    ./alacritty.nix
-    ./aria2.nix
-    ./bat.nix
-    ./common
-    ./curl.nix
-    ./direnv.nix
-    ./editorconfig.nix
-    ./emacs
-    ./eza.nix
-    ./git.nix
-    ./gnupg.nix
-    ./htop.nix
-    ./mpv.nix
-    ./nmap.nix
-    ./openssh.nix
-    ./password-store.nix
-    ./profiles
-    ./qutebrowser.nix
-    ./subversion.nix
-    ./tmux.nix
-    ./vim
-    ./vscode.nix
-    ./wget.nix
-    ./zathura.nix
-  ];
-}
+{ lib, ... }: with lib; { imports = attrValues (modulesIn ./.); }
diff --git a/modules/nixos/common/documentation.nix b/modules/common/documentation.nix
index f7d1585..20856cb 100644
--- a/modules/nixos/common/documentation.nix
+++ b/modules/common/documentation.nix
@@ -7,9 +7,18 @@
 }:
 with lib;
 {
-  config = mkIf this.isHeadful {
+  config = {
+    hm.manual = {
+      manpages.enable = this.isHeadful;
+      html.enable = false;
+      json.enable = false;
+    };
+
     documentation = {
+      enable = this.isHeadful;
       dev.enable = true;
+      doc.enable = false;
+      info.enable = false;
       nixos.enable = true;
 
       man.man-db.manualPages =
diff --git a/modules/common/git.nix b/modules/common/git.nix
deleted file mode 100644
index fbe190e..0000000
--- a/modules/common/git.nix
+++ /dev/null
@@ -1,173 +0,0 @@
-{
-  config,
-  inputs,
-  lib,
-  localUsername ? lib.my.username,
-  pkgs,
-  ...
-}:
-with lib;
-let
-  cfg = config.nixfiles.modules.git;
-in
-{
-  options.nixfiles.modules.git.client.enable = mkEnableOption "Git client";
-
-  config = mkIf cfg.client.enable {
-    secrets = {
-      glab-cli-config = {
-        file = "${inputs.self}/secrets/glab-cli-config";
-        path = "${config.dirs.config}/glab-cli/config.yml";
-        owner = localUsername;
-      };
-      gh-hosts = {
-        file = "${inputs.self}/secrets/gh-hosts";
-        path = "${config.dirs.config}/gh/hosts.yml";
-        owner = localUsername;
-      };
-      hut = {
-        file = "${inputs.self}/secrets/hut";
-        path = "${config.dirs.config}/hut/config";
-        owner = localUsername;
-      };
-    };
-
-    nixfiles.modules.common.shell.aliases = {
-      gl = "glab";
-      ht = "hut";
-    };
-
-    hm = {
-      home.packages = with pkgs; [
-        git-extras
-        glab
-        hut
-      ];
-
-      programs = {
-        git = {
-          enable = true;
-
-          package = pkgs.git.override {
-            doInstallCheck = false;
-            pythonSupport = false;
-            sendEmailSupport = true;
-            withLibsecret = false;
-            withSsh = true;
-          };
-
-          userName = my.fullname;
-          userEmail = my.email;
-          signing = {
-            inherit (my.pgp) key;
-            signByDefault = true;
-          };
-
-          extraConfig =
-            {
-              color.ui = true;
-              core.whitespace = "trailing-space";
-              init.defaultBranch = "master";
-              status.submoduleSummary = true;
-              commit.verbose = true;
-              push.autoSetupRemote = true;
-              pull.rebase = true;
-              rebase = {
-                autoStash = true;
-                autoSquash = true;
-              };
-              rerere.enabled = true;
-              branch.sort = "-committerdate";
-              diff = {
-                mnemonicPrefix = true;
-                renames = "copies";
-                submodule = "log";
-              };
-              submodule.recurse = true;
-              sendemail = rec {
-                smtpServer = my.domain.shire;
-                smtpUser = "${my.username}@${smtpServer}";
-                smtpEncryption = "ssl";
-                smtpServerPort = 465;
-                annotate = true;
-                confirm = "always";
-              };
-              column.ui = "auto";
-              github.user = my.username;
-              gitlab.user = my.username;
-            }
-            // mapAttrs' (name: value: nameValuePair ''url "git@${value}:"'' { insteadOf = "${name}:"; }) {
-              "bitbucket" = "bitbucket.com";
-              "codeberg" = "codeberg.org";
-              "github" = "github.com";
-              "gitlab" = "gitlab.com";
-              "sourcehut" = "git.sr.ht";
-            }
-            //
-              mapAttrs' (name: values: nameValuePair ''url "https://${values}/"'' { insteadOf = "${name}:"; })
-                {
-                  "alpine" = "gitlab.alpinelinux.org";
-                  "debian" = "salsa.debian.org";
-                  "freedesktop" = "gitlab.freedesktop.org";
-                  "gnome" = "gitlab.gnome.org";
-                  "haskell" = "gitlab.haskell.org";
-                  "homotopic" = "gitlab.homotopic.tech";
-                  "horizon" = "gitlab.horizon-haskell.net";
-                  "kde" = "invent.kde.org";
-                  "nixca" = "gitlab.nixca.dev";
-                  "notabug" = "notabug.org";
-                  "opencode" = "opencode.net";
-                  "torproject" = "gitlab.torproject.org";
-                  "videolan" = "code.videolan.org";
-                };
-
-          aliases =
-            let
-              git = getExe config.hm.programs.git.package;
-              curl = getExe pkgs.curl;
-            in
-            {
-              amend = "commit --amend";
-              cat = "cat-file -p";
-              fast = "clone --depth=1";
-              fixup = "commit --fixup";
-              fuck = "!${git} reset --hard && ${git} clean --force -dx";
-              get = "pull --all --recurse-submodules --autostash";
-              gud = ''commit -m "git gud"'';
-              refresh = "clean --force -dx";
-              tree = "log --graph --date=relative --pretty=tformat:'%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%an %ad)%Creset'";
-              uncommit = "reset --soft HEAD~1";
-              untrack = "rm --cache --";
-              wtc = "!${curl} -sq whatthecommit.com/index.txt | ${git} commit -F -";
-            };
-
-          # All helper tools/editor generated files should go here. This must be
-          # kept void of any project-specific or residual files.
-          ignores = [
-            "*~"
-            ".DS_Store"
-            ".cache/clangd/"
-            ".ccls-cache/"
-            ".gdb_history"
-            ".netrwhist"
-            ".projectile"
-            "[._]*.s[a-v][a-z]"
-            "[._]*.sw[a-p]"
-            "[._]s[a-rt-v][a-z]"
-            "[._]ss[a-gi-z]"
-            "[._]sw[a-p]"
-            "\#*\#"
-            "compile_commands*.json"
-            "cscope.*"
-            "vgcore.*"
-          ];
-        };
-
-        gh = {
-          enable = true;
-          settings.git_protocol = "ssh";
-        };
-      };
-    };
-  };
-}
diff --git a/modules/common/gnupg.nix b/modules/common/gnupg.nix
deleted file mode 100644
index b32d94c..0000000
--- a/modules/common/gnupg.nix
+++ /dev/null
@@ -1,72 +0,0 @@
-{ config, lib, ... }:
-with lib;
-let
-  cfg = config.nixfiles.modules.gnupg;
-in
-{
-  options.nixfiles.modules.gnupg.enable = mkEnableOption "GnuPG";
-
-  config = mkIf cfg.enable {
-    hm.programs.gpg = {
-      enable = true;
-
-      settings =
-        {
-          display-charset = "utf-8";
-          enable-progress-filter = true;
-          fixed-list-mode = true;
-          keyid-format = "0xlong";
-          no-comments = true;
-          no-emit-version = true;
-          no-greeting = true;
-          with-fingerprint = true;
-          throw-keyids = false;
-
-          use-agent = true;
-
-          armor = true;
-
-          no-random-seed-file = true;
-
-          list-options = "show-uid-validity";
-          verify-options = "show-uid-validity";
-        }
-        // (
-          let
-            cipherAlgos = [
-              "AES256"
-              "AES192"
-              "AES"
-            ];
-            digestAlgos = [
-              "SHA512"
-              "SHA384"
-              "SHA256"
-              "SHA224"
-            ];
-            compressionAlgos = [
-              "ZLIB"
-              "BZIP2"
-              "ZIP"
-              "Uncompressed"
-            ];
-
-            cs = concatStringsSep " ";
-          in
-          {
-            default-preference-list = cs (cipherAlgos ++ digestAlgos ++ compressionAlgos);
-
-            personal-cipher-preferences = cs cipherAlgos;
-            personal-digest-preferences = cs digestAlgos;
-            personal-compress-preferences = cs compressionAlgos;
-
-            s2k-cipher-algo = head cipherAlgos;
-            s2k-digest-algo = head digestAlgos;
-
-            digest-algo = head digestAlgos;
-            cert-digest-algo = head digestAlgos;
-          }
-        );
-    };
-  };
-}
diff --git a/modules/common/common/home-manager.nix b/modules/common/home-manager.nix
index 3c9fa0e..9c4cbeb 100644
--- a/modules/common/common/home-manager.nix
+++ b/modules/common/home-manager.nix
@@ -1,24 +1,25 @@
 {
+  config,
   inputs,
   lib,
-  localUsername ? lib.my.username,
   ...
 }:
 with lib;
 {
   imports = [
+    inputs.home-manager.nixosModule
     (mkAliasOptionModule [ "hm" ] [
       "home-manager"
       "users"
-      localUsername
+      my.username
     ])
   ];
 
   hm = {
     news.display = "silent";
-    # NOTE Inheriting directly from `system.stateVersion` does not work with
-    # nix-darwin for some reason.
-    home.stateVersion = with builtins; head (split "\n" (readFile "${inputs.nixpkgs}/.version"));
+    home = {
+      inherit (config.system) stateVersion;
+    };
   };
 
   home-manager = {
diff --git a/modules/nixos/common/kernel.nix b/modules/common/kernel.nix
index 5c45b5d..5c45b5d 100644
--- a/modules/nixos/common/kernel.nix
+++ b/modules/common/kernel.nix
diff --git a/modules/nixos/common/locale.nix b/modules/common/locale.nix
index 8b91a5a..7e8eefb 100644
--- a/modules/nixos/common/locale.nix
+++ b/modules/common/locale.nix
@@ -6,6 +6,11 @@
 }:
 with lib;
 {
+  hm.home.language = {
+    collate = "C";
+    messages = "C";
+  };
+
   i18n = {
     defaultLocale = mkDefault "en_GB.UTF-8";
     supportedLocales = [
diff --git a/modules/nixos/common/networking.nix b/modules/common/networking.nix
index ecadf6e..727def4 100644
--- a/modules/nixos/common/networking.nix
+++ b/modules/common/networking.nix
@@ -123,6 +123,7 @@ in
 
       systemPackages = with pkgs; [
         ethtool
+        myip
         nethogs
       ];
     };
diff --git a/modules/common/nix.nix b/modules/common/nix.nix
new file mode 100644
index 0000000..db46336
--- /dev/null
+++ b/modules/common/nix.nix
@@ -0,0 +1,150 @@
+{
+  config,
+  inputs,
+  lib,
+  pkgs,
+  this,
+  ...
+}:
+with lib;
+let
+  cfg = config.nixfiles.modules.common.nix;
+in
+{
+  options.nixfiles.modules.common.nix.allowedUnfreePackages = mkOption {
+    description = "A list of allowed unfree packages.";
+    type = with types; listOf str;
+    default = [ ];
+  };
+
+  config = {
+    _module.args =
+      let
+        importNixpkgs =
+          nixpkgs:
+          import nixpkgs {
+            inherit (config.nixpkgs) config;
+            inherit (this) system;
+          };
+      in
+      rec {
+        pkgsLocal = importNixpkgs "${config.my.home}/src/nixpkgs"; # Impure!
+        pkgsMaster = importNixpkgs inputs.nixpkgs-master;
+        pkgsStable = importNixpkgs inputs.nixpkgs-stable;
+        pkgsRev =
+          rev: hash:
+          importNixpkgs (
+            pkgs.fetchFromGitHub {
+              owner = "NixOS";
+              repo = "nixpkgs";
+              inherit rev hash;
+            }
+          );
+        pkgsPr = pr: pkgsRev "refs/pull/${toString pr}/head";
+      };
+
+    hm = {
+      # Used primarily in conjunction with the "nixfiles" script.
+      home.file.".nix-defexpr/default.nix".text =
+        let
+          hostname = strings.escapeNixIdentifier this.hostname;
+        in
+        optionalString this.isHeadful ''
+          let
+            self = builtins.getFlake "nixfiles";
+            configurations = self.nixosConfigurations;
+            local = configurations.${hostname};
+          in rec {
+            inherit self;
+            inherit (self) inputs lib;
+            inherit (lib) my;
+            this = my.configurations.${hostname};
+            inherit (local) config;
+            inherit (local.config.system.build) toplevel vm vmWithBootLoader manual;
+            pretty = expr: lib.trace (lib.generators.toPretty {} expr) {};
+          } // configurations // local._module.args
+        '';
+
+      programs.bash.shellAliases.nix = "nix --verbose --print-build-logs";
+    };
+
+    nix =
+      let
+        notSelfInputs = filterAttrs (n: _: n != "self") inputs;
+      in
+      {
+        daemonCPUSchedPolicy = "idle";
+        daemonIOSchedClass = "idle";
+        daemonIOSchedPriority = 7;
+
+        settings = {
+          # https://nixos.org/manual/nix/unstable/contributing/experimental-features.html#currently-available-experimental-features
+          # https://github.com/NixOS/nix/blob/master/src/libutil/experimental-features.cc
+          experimental-features = concatStringsSep " " [
+            "flakes"
+            "nix-command"
+            "recursive-nix"
+            "repl-flake"
+          ];
+
+          keep-derivations = if this.isHeadful then "true" else "false";
+          keep-outputs = if this.isHeadful then "true" else "false";
+
+          flake-registry = "${inputs.flake-registry}/flake-registry.json";
+
+          warn-dirty = false;
+
+          keep-going = true;
+
+          substituters = [
+            "https://azahi.cachix.org"
+            "https://nix-community.cachix.org"
+          ];
+          trusted-public-keys = [
+            "azahi.cachix.org-1:2bayb+iWYMAVw3ZdEpVg+NPOHCXncw7WMQ0ElX1GO3s="
+            "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
+          ];
+
+          trusted-users = [
+            "root"
+            my.username
+          ];
+        };
+
+        nixPath = mapAttrsToList (n: v: "${n}=${v}") notSelfInputs ++ [
+          "nixfiles=${config.my.home}/src/nixfiles"
+        ];
+
+        registry = mapAttrs (_: flake: { inherit flake; }) notSelfInputs // {
+          nixfiles.flake = inputs.self;
+        };
+      };
+
+    nixpkgs = {
+      config.allowUnfreePredicate = p: elem (getName p) cfg.allowedUnfreePackages;
+
+      overlays = with inputs; [
+        self.overlays.default
+        (_: _: { })
+      ];
+    };
+
+    environment = {
+      localBinInPath = true;
+      defaultPackages = mkForce [ ];
+      systemPackages =
+        with pkgs;
+        optionals this.isHeadful [
+          nix-top
+          nix-tree
+          nixfiles
+        ];
+      sessionVariables = {
+        NIXFILES = "${config.my.home}/src/nixfiles";
+        NIX_SHELL_PRESERVE_PROMPT = "1";
+      };
+    };
+
+    system.stateVersion = with builtins; head (split "\n" (readFile "${inputs.nixpkgs}/.version"));
+  };
+}
diff --git a/modules/common/openssh.nix b/modules/common/openssh.nix
deleted file mode 100644
index f60a1ef..0000000
--- a/modules/common/openssh.nix
+++ /dev/null
@@ -1,72 +0,0 @@
-{
-  config,
-  lib,
-  pkgs,
-  ...
-}:
-with lib;
-let
-  cfg = config.nixfiles.modules.openssh;
-in
-{
-  options.nixfiles.modules.openssh.client.enable = mkEnableOption "OpenSSH client";
-
-  config = mkIf cfg.client.enable {
-    hm = {
-      home.packages = with pkgs; [
-        mosh
-        sshfs
-        sshpass
-      ];
-
-      programs.ssh = {
-        enable = true;
-
-        hashKnownHosts = true;
-
-        controlMaster = "auto";
-        controlPersist = "24H";
-
-        serverAliveCountMax = 30;
-        serverAliveInterval = 60;
-
-        matchBlocks =
-          let
-            mkBlock =
-              name:
-              {
-                hostname ? name,
-                port ? 22022, # NOTE This is not the default OpenSSH port.
-                user ? my.username,
-                identityFile ? "${config.my.home}/.ssh/${my.username}_${my.ssh.type}",
-                extraAttrs ? { },
-              }:
-              nameValuePair name (
-                {
-                  inherit
-                    hostname
-                    port
-                    user
-                    identityFile
-                    ;
-                }
-                // extraAttrs
-              );
-
-            internalServers = mapAttrs' mkBlock (
-              mapAttrs (name: _: { hostname = "${name}.${my.domain.shire}"; }) (
-                filterAttrs (_: attr: hasAttr "wireguard" attr && attr.isHeadless) my.configurations
-              )
-            );
-          in
-          internalServers
-          // (mapAttrs' mkBlock {
-            gitolite = {
-              user = "git";
-              hostname = "git.${my.domain.shire}";
-            };
-          });
-      };
-    };
-  };
-}
diff --git a/modules/common/profiles/dev/containers.nix b/modules/common/profiles/dev/containers.nix
deleted file mode 100644
index 8f3bfc6..0000000
--- a/modules/common/profiles/dev/containers.nix
+++ /dev/null
@@ -1,57 +0,0 @@
-{
-  config,
-  lib,
-  pkgs,
-  ...
-}:
-with lib;
-let
-  cfg = config.nixfiles.modules.profiles.dev.containers;
-in
-{
-  options.nixfiles.modules.profiles.dev.containers.enable =
-    mkEnableOption "Tools for working with containers and container orchestration"
-    // {
-      default = config.nixfiles.modules.profiles.dev.enable;
-    };
-
-  config = mkIf cfg.enable {
-    nixfiles.modules.common.shell.aliases = {
-      h = "helm";
-      k = "kubectl";
-      kns = "kubens";
-      ktx = "kubectx";
-    };
-
-    hm.home = {
-      sessionVariables = {
-        MINIKUBE_IN_STYLE = "false";
-        WERF_DEV = "true";
-        WERF_INSECURE_REGISTRY = "true";
-        WERF_LOG_DEBUG = "true";
-        WERF_LOG_PRETTY = "false";
-        WERF_LOG_VERBOSE = "true";
-        WERF_SYNCHRONIZATION = ":local";
-        WERF_TELEMETRY = "false";
-      };
-
-      packages = with pkgs; [
-        k9s
-        kubectl
-        kubectl-doctor
-        kubectl-images
-        kubectl-tree
-        kubectx
-        kubelogin-oidc
-        kubent
-        kubernetes-helm
-        kubespy
-        minikube
-        skopeo
-        stern
-        telepresence2
-        werf
-      ];
-    };
-  };
-}
diff --git a/modules/common/profiles/headful.nix b/modules/common/profiles/headful.nix
deleted file mode 100644
index cd29225..0000000
--- a/modules/common/profiles/headful.nix
+++ /dev/null
@@ -1,57 +0,0 @@
-{
-  config,
-  lib,
-  pkgs,
-  this,
-  ...
-}:
-with lib;
-let
-  cfg = config.nixfiles.modules.profiles.headful;
-in
-{
-  options.nixfiles.modules.profiles.headful.enable = mkEnableOption "headful profile" // {
-    default = this.isHeadful;
-  };
-
-  config = mkIf cfg.enable {
-    nixfiles.modules = {
-      profiles.dev.enable = true;
-
-      alacritty.enable = true;
-      aria2.enable = true;
-      emacs.enable = true;
-      mpv.enable = true;
-      openssh.client.enable = true;
-      password-store.enable = true;
-      vscode.enable = true;
-      zathura.enable = true;
-    };
-
-    hm = {
-      home = {
-        file.".digrc".text = ''
-          +answer
-          +multiline
-          +recurse
-        '';
-
-        packages = with pkgs; [
-          fd
-          ripgrep
-          sd
-          tldr
-        ];
-      };
-    };
-
-    environment.systemPackages = with pkgs; [
-      arping
-      dnsutils
-      inetutils
-      ldns
-      socat
-      tcpdump
-    ];
-  };
-}
diff --git a/modules/common/profiles/headless.nix b/modules/common/profiles/headless.nix
deleted file mode 100644
index 1f8096c..0000000
--- a/modules/common/profiles/headless.nix
+++ /dev/null
@@ -1,25 +0,0 @@
-{
-  config,
-  lib,
-  pkgs,
-  this,
-  ...
-}:
-with lib;
-let
-  cfg = config.nixfiles.modules.profiles.headless;
-in
-{
-  options.nixfiles.modules.profiles.headless.enable = mkEnableOption "headless profile" // {
-    default = this.isHeadless;
-  };
-
-  config = mkIf cfg.enable {
-    hm.home.file = {
-      ".hushlogin".text = "";
-      ".bash_history".source = config.hm.lib.file.mkOutOfStoreSymlink "/dev/null";
-    };
-
-    environment.systemPackages = with pkgs; [ alacritty.terminfo ];
-  };
-}
diff --git a/modules/common/common/secrets.nix b/modules/common/secrets.nix
index 3c05c09..03a2eeb 100644
--- a/modules/common/common/secrets.nix
+++ b/modules/common/secrets.nix
@@ -9,6 +9,7 @@
 with lib;
 {
   imports = [
+    inputs.agenix.nixosModules.default
     (mkAliasOptionModule [ "secrets" ] [
       "age"
       "secrets"
diff --git a/modules/nixos/common/security.nix b/modules/common/security.nix
index c635cdc..c635cdc 100644
--- a/modules/nixos/common/security.nix
+++ b/modules/common/security.nix
diff --git a/modules/nixos/common/services.nix b/modules/common/services.nix
index 12e4bf7..12e4bf7 100644
--- a/modules/nixos/common/services.nix
+++ b/modules/common/services.nix
diff --git a/modules/common/common/shell/default.nix b/modules/common/shell/default.nix
index 883bfae..437ce57 100644
--- a/modules/common/common/shell/default.nix
+++ b/modules/common/shell/default.nix
@@ -191,6 +191,8 @@ in
       home.packages = with pkgs; [ grc ];
     };
 
+    programs.command-not-found.enable = false;
+
     environment = {
       etc."grc.conf".source = "${pkgs.grc}/etc/grc.conf";
 
diff --git a/modules/common/common/shell/functions.bash b/modules/common/shell/functions.bash
index f354adb..f354adb 100644
--- a/modules/common/common/shell/functions.bash
+++ b/modules/common/shell/functions.bash
diff --git a/modules/common/stylix.nix b/modules/common/stylix.nix
new file mode 100644
index 0000000..953685e
--- /dev/null
+++ b/modules/common/stylix.nix
@@ -0,0 +1,105 @@
+{
+  config,
+  inputs,
+  lib,
+  pkgs,
+  ...
+}:
+with lib;
+{
+  imports = [
+    inputs.stylix.nixosModules.stylix
+    (mkAliasOptionModule [ "colors" ] [
+      "lib"
+      "stylix"
+      "colors"
+    ])
+  ];
+
+  options.nixfiles.modules.common.stylix.fonts.extraPackages = mkOption {
+    description = "Font packages.";
+    default = with pkgs; [
+      font-awesome
+      noto-fonts
+      noto-fonts-emoji
+      sarasa-gothic
+      source-han-mono
+      source-han-sans
+      source-han-serif
+      twitter-color-emoji
+    ];
+    readOnly = true;
+  };
+
+  # Styling and color binding can be sourced from here[1].
+  #
+  # [1]: https://github.com/tinted-theming/base24/blob/master/styling.md
+  config = {
+    stylix = {
+      image = pkgs.fetchurl {
+        url = "https://upload.wikimedia.org/wikipedia/commons/a/a5/Bonaparte_ante_la_Esfinge%2C_por_Jean-Léon_Gérôme.jpg";
+        sha256 = "sha256-qWv52oT8cF9K4ZoeawmR3jgoGB2ARfjbKKc12IljUcM=";
+      };
+
+      base16Scheme = "${pkgs.base16-schemes}/share/themes/tomorrow.yaml";
+
+      fonts = {
+        monospace = {
+          package = pkgs.iosevka;
+          name = "Iosevka";
+        };
+
+        serif = {
+          package = pkgs.iosevka-bin.override { variant = "Etoile"; };
+          name = "Iosevka Etoile";
+        };
+
+        sansSerif = {
+          package = pkgs.iosevka-bin.override { variant = "Aile"; };
+          name = "Iosevka Aile";
+        };
+
+        sizes = {
+          desktop = 10;
+          applications = 10;
+          terminal = 12;
+        };
+      };
+
+      cursor = {
+        name = "phinger-cursors-light";
+        package = pkgs.phinger-cursors;
+        size = 32;
+      };
+    };
+
+    fonts = {
+      packages = mkAfter config.nixfiles.modules.common.stylix.fonts.extraPackages;
+
+      fontconfig.defaultFonts = with config.stylix.fonts; {
+        serif = mkForce [
+          serif.name
+          "Sarasa Gothic"
+          "Source Han Serif"
+          "Noto Serif"
+        ];
+        sansSerif = mkForce [
+          sansSerif.name
+          "Sarasa Gothic"
+          "Source Han Sans"
+          "Noto Sans"
+        ];
+        monospace = mkForce [
+          monospace.name
+          "Sarasa Mono"
+          "Source Han Mono"
+          "Noto Sans Mono"
+        ];
+        emoji = mkForce [
+          "Twitter Color Emoji"
+          "Noto Color Emoji"
+        ];
+      };
+    };
+  };
+}
diff --git a/modules/nixos/common/systemd.nix b/modules/common/systemd.nix
index b393d9f..b393d9f 100644
--- a/modules/nixos/common/systemd.nix
+++ b/modules/common/systemd.nix
diff --git a/modules/nixos/common/tmp.nix b/modules/common/tmp.nix
index d56e2b6..d56e2b6 100644
--- a/modules/nixos/common/tmp.nix
+++ b/modules/common/tmp.nix
diff --git a/modules/nixos/common/users.nix b/modules/common/users.nix
index a92a38e..ba1a89b 100644
--- a/modules/nixos/common/users.nix
+++ b/modules/common/users.nix
@@ -1,13 +1,17 @@
-{
-  lib,
-  localUsername ? lib.my.username,
-  ...
-}:
+{ lib, ... }:
 with lib;
 let
-  home = "/home/${localUsername}";
+  home = "/home/${my.username}";
 in
 {
+  imports = [
+    (mkAliasOptionModule [ "my" ] [
+      "users"
+      "users"
+      my.username
+    ])
+  ];
+
   ark.directories = [ home ];
 
   users = {
@@ -16,7 +20,7 @@ in
     users = {
       root.hashedPassword = "@HASHED_PASSWORD@";
 
-      ${localUsername} = {
+      ${my.username} = {
         isNormalUser = true;
         uid = 1000;
         description = my.fullname;
diff --git a/modules/common/vim/default.nix b/modules/common/vim/default.nix
deleted file mode 100644
index 93729bc..0000000
--- a/modules/common/vim/default.nix
+++ /dev/null
@@ -1,47 +0,0 @@
-{
-  config,
-  lib,
-  pkgs,
-  ...
-}:
-with lib;
-let
-  cfg = config.nixfiles.modules.vim;
-in
-{
-  options.nixfiles.modules.vim = {
-    enable = mkEnableOption "Vim";
-
-    rc = mkOption {
-      type = types.str;
-      default = readFile ./rc.vim;
-      description = "Configuration file.";
-    };
-
-    plugins = mkOption {
-      type = with types; listOf package;
-      default = with pkgs.vimPlugins; [
-        editorconfig-vim
-        vim-eunuch
-        vim-nix
-        vim-sensible
-        vim-sleuth
-        vim-surround
-        vim-unimpaired
-      ];
-      description = "Plugins.";
-    };
-  };
-
-  config = mkIf cfg.enable {
-    hm.stylix.targets.vim.enable = false;
-
-    environment = with config.programs.vim; {
-      systemPackages = [ package ];
-      variables = rec {
-        EDITOR = mkOverride 15 (getExe' package "vim");
-        VISUAL = EDITOR;
-      };
-    };
-  };
-}
diff --git a/modules/common/common/xdg.nix b/modules/common/xdg.nix
index 4463c15..c581369 100644
--- a/modules/common/common/xdg.nix
+++ b/modules/common/xdg.nix
@@ -1,5 +1,13 @@
-{ config, lib, ... }:
+{
+  config,
+  lib,
+  this,
+  ...
+}:
 with lib;
+let
+  cfg = config.nixfiles.modules.common.xdg;
+in
 {
   imports =
     let
@@ -68,5 +76,34 @@ with lib;
           videos = tmp;
         };
     };
+    defaultApplications = mkOption {
+      description = "Default applications.";
+      type = with types; attrsOf (listOf str);
+      default = { };
+    };
+  };
+
+  config = {
+    xdg.portal = mkIf this.isHeadful { enable = true; };
+
+    hm.xdg = mkMerge [
+      (with cfg; {
+        enable = true;
+
+        inherit cacheHome;
+        inherit configHome;
+        inherit dataHome;
+        inherit stateHome;
+        inherit userDirs;
+      })
+      (mkIf this.isHeadful {
+        mimeApps = {
+          enable = true;
+          defaultApplications = mkMerge (
+            mapAttrsToList (n: v: genAttrs v (_: [ "${n}.desktop" ])) cfg.defaultApplications
+          );
+        };
+      })
+    ];
   };
 }
diff --git a/modules/common/curl.nix b/modules/curl.nix
index 6895262..6895262 100644
--- a/modules/common/curl.nix
+++ b/modules/curl.nix
diff --git a/modules/darwin/common/default.nix b/modules/darwin/common/default.nix
deleted file mode 100644
index 04f7b29..0000000
--- a/modules/darwin/common/default.nix
+++ /dev/null
@@ -1,13 +0,0 @@
-_: {
-  imports = [
-    ./home-manager.nix
-    ./locale.nix
-    ./networking.nix
-    ./nix.nix
-    ./secrets.nix
-    ./shell.nix
-    ./stylix.nix
-    ./users.nix
-    ./xdg.nix
-  ];
-}
diff --git a/modules/darwin/common/home-manager.nix b/modules/darwin/common/home-manager.nix
deleted file mode 100644
index 487c64b..0000000
--- a/modules/darwin/common/home-manager.nix
+++ /dev/null
@@ -1,4 +0,0 @@
-{ inputs, ... }:
-{
-  imports = [ inputs.home-manager.darwinModule ];
-}
diff --git a/modules/darwin/common/locale.nix b/modules/darwin/common/locale.nix
deleted file mode 100644
index 19770a3..0000000
--- a/modules/darwin/common/locale.nix
+++ /dev/null
@@ -1,8 +0,0 @@
-{ lib, ... }:
-with lib;
-{
-  environment.variables.LANG = "en_GB.UTF-8";
-
-  # TODO https://daiderd.com/nix-darwin/manual/index.html#opt-system.keyboard.enableKeyMapping
-  system.keyboard = { };
-}
diff --git a/modules/darwin/common/networking.nix b/modules/darwin/common/networking.nix
deleted file mode 100644
index eae7c2f..0000000
--- a/modules/darwin/common/networking.nix
+++ /dev/null
@@ -1,11 +0,0 @@
-{
-  localHostname ? this.hostname,
-  this,
-  ...
-}:
-{
-  networking = {
-    computerName = localHostname;
-    hostName = localHostname;
-  };
-}
diff --git a/modules/darwin/common/nix.nix b/modules/darwin/common/nix.nix
deleted file mode 100644
index 63b0d90..0000000
--- a/modules/darwin/common/nix.nix
+++ /dev/null
@@ -1,17 +0,0 @@
-{ lib, this, ... }:
-with lib;
-{
-  nix = {
-    daemonIOLowPriority = false;
-    daemonProcessType = "Standard";
-
-    settings.extra-platforms = optionalString (this.system == "aarch64-darwin") ''
-      x86_64-darwin aarch64-darwin
-    '';
-  };
-
-  services.nix-daemon.enable = true;
-
-  # https://github.com/LnL7/nix-darwin/blob/master/CHANGELOG
-  system.stateVersion = 4;
-}
diff --git a/modules/darwin/common/secrets.nix b/modules/darwin/common/secrets.nix
deleted file mode 100644
index 681c5c2..0000000
--- a/modules/darwin/common/secrets.nix
+++ /dev/null
@@ -1,4 +0,0 @@
-{ inputs, ... }:
-{
-  imports = [ inputs.agenix.darwinModules.default ];
-}
diff --git a/modules/darwin/common/shell.nix b/modules/darwin/common/shell.nix
deleted file mode 100644
index 2139f2f..0000000
--- a/modules/darwin/common/shell.nix
+++ /dev/null
@@ -1,4 +0,0 @@
-{ pkgs, ... }:
-{
-  environment.shells = with pkgs; [ bashInteractive ];
-}
diff --git a/modules/darwin/common/stylix.nix b/modules/darwin/common/stylix.nix
deleted file mode 100644
index 8712172..0000000
--- a/modules/darwin/common/stylix.nix
+++ /dev/null
@@ -1,12 +0,0 @@
-{
-  config,
-  inputs,
-  lib,
-  ...
-}:
-with lib;
-{
-  imports = [ inputs.stylix.darwinModules.stylix ];
-
-  fonts.fonts = mkAfter config.nixfiles.modules.common.stylix.fonts.extraPackages;
-}
diff --git a/modules/darwin/common/users.nix b/modules/darwin/common/users.nix
deleted file mode 100644
index 9043f51..0000000
--- a/modules/darwin/common/users.nix
+++ /dev/null
@@ -1,12 +0,0 @@
-{
-  lib,
-  localUsername ? lib.my.username,
-  ...
-}:
-with lib;
-{
-  # The only MacOS machine I'm currently using has a pre-configured domain user
-  # account that I have to login as. I may accidentally break something if I
-  # change options here so this section is left practically untouched.
-  users.users.${localUsername}.home = "/Users/${localUsername}";
-}
diff --git a/modules/darwin/common/xdg.nix b/modules/darwin/common/xdg.nix
deleted file mode 100644
index 526dc0b..0000000
--- a/modules/darwin/common/xdg.nix
+++ /dev/null
@@ -1,24 +0,0 @@
-{ config, lib, ... }:
-with lib;
-let
-  cfg = config.nixfiles.modules.common.xdg;
-in
-{
-  hm.home.sessionVariables =
-    with cfg;
-    {
-      XDG_CACHE_HOME = cacheHome;
-      XDG_CONFIG_HOME = configHome;
-      XDG_DATA_HOME = dataHome;
-      XDG_STATE_HOME = stateHome;
-    }
-    // (with userDirs; {
-      XDG_DOCUMENTS_DIR = documents;
-      XDG_DOWNLOAD_DIR = download;
-      XDG_MUSIC_DIR = music;
-      XDG_PICTURES_DIR = pictures;
-      XDG_PUBLICSHARE_DIR = publicShare;
-      XDG_TEMPLATES_DIR = templates;
-      XDG_VIDEOS_DIR = videos;
-    });
-}
diff --git a/modules/darwin/default.nix b/modules/darwin/default.nix
deleted file mode 100644
index ba7a2a7..0000000
--- a/modules/darwin/default.nix
+++ /dev/null
@@ -1,9 +0,0 @@
-_: {
-  imports = [
-    ./common
-    ./gnupg.nix
-    ./homebrew.nix
-    ./profiles
-    ./vim
-  ];
-}
diff --git a/modules/darwin/gnupg.nix b/modules/darwin/gnupg.nix
deleted file mode 100644
index d8b1cf1..0000000
--- a/modules/darwin/gnupg.nix
+++ /dev/null
@@ -1,13 +0,0 @@
-{ config, lib, ... }:
-with lib;
-let
-  cfg = config.nixfiles.modules.gnupg;
-in
-{
-  config = mkIf cfg.enable {
-    programs.gnupg.agent = {
-      enable = true;
-      enableSSHSupport = true;
-    };
-  };
-}
diff --git a/modules/darwin/homebrew.nix b/modules/darwin/homebrew.nix
deleted file mode 100644
index 41a2c6c..0000000
--- a/modules/darwin/homebrew.nix
+++ /dev/null
@@ -1,29 +0,0 @@
-{ config, lib, ... }:
-with lib;
-let
-  cfg = config.nixfiles.modules.homebrew;
-in
-{
-  options.nixfiles.modules.homebrew.enable = mkEnableOption "Homebrew";
-
-  config = mkIf cfg.enable {
-    hm.programs.bash.initExtra = mkAfter ''
-      if [ -x "/opt/homebrew/bin/brew" ]; then
-        export PATH="$PATH:/opt/homebrew/bin"
-      fi
-    '';
-
-    # This option requires an installed Homebrew[1].
-    #
-    # [1]: https://daiderd.com/nix-darwin/manual/index.html#opt-homebrew.enable
-    # [1]: https://brew.sh
-    homebrew = {
-      enable = true;
-      onActivation = {
-        autoUpdate = true;
-        upgrade = true;
-        cleanup = "zap";
-      };
-    };
-  };
-}
diff --git a/modules/darwin/profiles/default.nix b/modules/darwin/profiles/default.nix
deleted file mode 100644
index 9a3353f..0000000
--- a/modules/darwin/profiles/default.nix
+++ /dev/null
@@ -1,94 +0,0 @@
-{
-  config,
-  lib,
-  pkgs,
-  ...
-}:
-with lib;
-let
-  cfg = config.nixfiles.modules.profiles.default;
-in
-{
-  imports = [ ./headful.nix ];
-
-  config = mkIf cfg.enable {
-    hm.home.packages = with pkgs; [ m-cli ];
-
-    system = {
-      defaults = {
-        CustomUserPreferences = { };
-
-        ActivityMonitor = { };
-
-        NSGlobalDomain = {
-          AppleEnableMouseSwipeNavigateWithScrolls = true;
-          AppleEnableSwipeNavigateWithScrolls = true;
-
-          AppleInterfaceStyle = null;
-
-          AppleShowAllExtensions = true;
-          AppleShowAllFiles = true;
-
-          InitialKeyRepeat = 15;
-          KeyRepeat = 2;
-
-          NSAutomaticCapitalizationEnabled = false;
-          NSAutomaticDashSubstitutionEnabled = false;
-          NSAutomaticPeriodSubstitutionEnabled = false;
-          NSAutomaticQuoteSubstitutionEnabled = false;
-          NSAutomaticSpellingCorrectionEnabled = false;
-
-          # Make function keys to work as they should.
-          "com.apple.keyboard.fnState" = true;
-
-          # Disable the absolutely retarded "natural" scrolling.
-          "com.apple.swipescrolldirection" = false;
-        };
-
-        dock = {
-          orientation = "bottom";
-          tilesize = 18;
-
-          # Don't change these options because this will disallow rearranging
-          # shortcuts.
-          show-recents = true;
-          static-only = false;
-
-          # Disable hot corners.
-          wvous-bl-corner = 1;
-          wvous-br-corner = 1;
-          wvous-tl-corner = 1;
-          wvous-tr-corner = 1;
-        };
-
-        finder = {
-          AppleShowAllExtensions = true;
-          AppleShowAllFiles = true;
-
-          CreateDesktop = true;
-
-          FXDefaultSearchScope = "SCcf";
-          FXEnableExtensionChangeWarning = false;
-          FXPreferredViewStyle = "clmv";
-
-          ShowStatusBar = false;
-          ShowPathbar = true;
-          _FXShowPosixPathInTitle = true;
-        };
-
-        trackpad = {
-          Clicking = true;
-          Dragging = false;
-        };
-      };
-
-      keyboard = {
-        enableKeyMapping = true;
-        nonUS.remapTilde = true;
-        remapCapsLockToControl = false;
-        remapCapsLockToEscape = true;
-        swapLeftCommandAndLeftAlt = false;
-      };
-    };
-  };
-}
diff --git a/modules/darwin/profiles/headful.nix b/modules/darwin/profiles/headful.nix
deleted file mode 100644
index 023386b..0000000
--- a/modules/darwin/profiles/headful.nix
+++ /dev/null
@@ -1,33 +0,0 @@
-{
-  config,
-  lib,
-  pkgs,
-  ...
-}:
-with lib;
-let
-  cfg = config.nixfiles.modules.profiles.headful;
-in
-{
-  config = mkIf cfg.enable {
-    nixfiles.modules.homebrew.enable = true;
-
-    # I'm addicted to GNU...
-    hm.home.packages = with pkgs; [
-      coreutils
-      findutils
-      getopt
-      gnugrep
-      gnused
-      gnutar
-      gzip
-      which
-    ];
-
-    homebrew.casks = [
-      { name = "firefox"; }
-      { name = "iterm2"; }
-      { name = "telegram-desktop"; }
-    ];
-  };
-}
diff --git a/modules/darwin/vim/default.nix b/modules/darwin/vim/default.nix
deleted file mode 100644
index 4c3f7e1..0000000
--- a/modules/darwin/vim/default.nix
+++ /dev/null
@@ -1,38 +0,0 @@
-{
-  config,
-  lib,
-  pkgs,
-  ...
-}:
-with lib;
-let
-  cfg = config.nixfiles.modules.vim;
-in
-{
-  config = mkIf cfg.enable {
-    programs.vim.package =
-      (pkgs.macvim.overrideAttrs (
-        _: _: {
-          # Too much of a hassle to selectively override this. Let's just
-          # explicitly override everything.
-          configureFlags = [
-            "--disable-luainterp"
-            "--disable-python3interp"
-            "--disable-sparkle"
-            "--enable-gui=macvim"
-            "--with-compiledby=Nix"
-            "--with-features=huge"
-            "--with-tlib=ncurses"
-            "--without-local-dir"
-          ];
-        }
-      )).configure
-        (
-          with cfg;
-          {
-            customRC = rc;
-            packages.myVimPackage.start = plugins;
-          }
-        );
-  };
-}
diff --git a/modules/default.nix b/modules/default.nix
new file mode 100644
index 0000000..ef9fb18
--- /dev/null
+++ b/modules/default.nix
@@ -0,0 +1 @@
+{ lib, ... }: with lib; { imports = attrValues (modulesIn ./.); }
diff --git a/modules/common/direnv.nix b/modules/direnv.nix
index ececad8..ececad8 100644
--- a/modules/common/direnv.nix
+++ b/modules/direnv.nix
diff --git a/modules/nixos/docker.nix b/modules/docker.nix
index 62dc095..62dc095 100644
--- a/modules/nixos/docker.nix
+++ b/modules/docker.nix
diff --git a/modules/nixos/dwm.nix b/modules/dwm.nix
index 912be0c..912be0c 100644
--- a/modules/nixos/dwm.nix
+++ b/modules/dwm.nix
diff --git a/modules/common/editorconfig.nix b/modules/editorconfig.nix
index 5dfe845..5dfe845 100644
--- a/modules/common/editorconfig.nix
+++ b/modules/editorconfig.nix
diff --git a/modules/nixos/emacs.nix b/modules/emacs.nix
index 8a59c9b..8a59c9b 100644
--- a/modules/nixos/emacs.nix
+++ b/modules/emacs.nix
diff --git a/modules/common/emacs/default.nix b/modules/emacs/default.nix
index 4c43fd5..2230ee0 100644
--- a/modules/common/emacs/default.nix
+++ b/modules/emacs/default.nix
@@ -2,9 +2,7 @@
   config,
   inputs,
   lib,
-  localUsername ? lib.my.username,
   pkgs,
-  this,
   ...
 }:
 with lib;
@@ -17,10 +15,20 @@ in
   config = mkIf cfg.enable {
     secrets.authinfo = {
       file = "${inputs.self}/secrets/authinfo";
-      owner = localUsername;
+      owner = my.username;
     };
 
     nixfiles.modules = {
+      common.xdg.defaultApplications.emacsclient = [
+        "application/atom+xml"
+        "application/json"
+        "application/rss+xml"
+        "application/schema+json"
+        "application/xhtml+xml"
+        "application/xml"
+        "text/csv"
+        "text/plain"
+      ];
       git.client.enable = true;
       gnupg.enable = true;
       password-store.enable = true;
@@ -69,108 +77,92 @@ in
               text = concatLines [
                 (
                   let
-                    extraBins =
-                      with pkgs;
-                      [
-                        (aspellWithDicts (
-                          p: with p; [
-                            en
-                            ru
-                          ]
-                        )) # :checkers (spell +aspell)
-                        asmfmt # :editor format
-                        cargo # :lang rust
-                        clang-tools # :lang (cc +lsp) :editor format
-                        cmake-format # :lang cc :editor format
-                        cmigemo # :lang japanese
-                        config.hm.programs.emacs.package # !doom
-                        config.nix.package # !doom
-                        delve # :lang go :tools debugger
-                        dockerfile-language-server-nodejs # :tools (docker +lsp)
-                        dockfmt # :tools docker :editor format
-                        editorconfig-core-c # :tools editorconfig
-                        fd # doom!
-                        gcc # :lang cc
-                        ghc # :lang haskell
-                        gnuplot # :lang (org +gnuplot)
-                        gnutar # :tools tree-sitter
-                        gnutls # doom! :app irc
-                        go # :lang go
-                        godef # :lang go
-                        gomodifytags # :lang go
-                        gopls # :lang (go +lsp)
-                        gore # :lang go
-                        gotests # :lang go
-                        gotools # :lang go
-                        graphviz # :lang (org +roam2) :lang plantuml
-                        gzip # :tools tree-sitter
-                        haskellPackages.cabal-fmt # :lang haskell :editor format
-                        haskellPackages.cabal-install # :lang haskell
-                        haskellPackages.haskell-language-server # :lang (haskell +lsp)
-                        haskellPackages.hoogle # :lang haskell
-                        haskellPackages.ormolu # :lang haskell :editor format
-                        html-tidy # :lang web :editor format
-                        jdk # :lang java :lang plantuml :checkers grammar
-                        languagetool # :checkers grammar
-                        libxml2 # :lang data :editor format
-                        markdownlint-cli # :lang markdown
-                        nil # :lang (nix +lsp)
-                        nixfmt # :lang nix :editor format
-                        nls # :lang (nickel +lsp)
-                        nodePackages.bash-language-server # :lang (sh +lsp)
-                        nodePackages.eslint # :lang (json +lsp)
-                        nodePackages.js-beautify # :lang web
-                        nodePackages.prettier # :editor format
-                        nodePackages.stylelint # :lang web
-                        nodePackages.vscode-css-languageserver-bin # lang (web +lsp)
-                        nodePackages.vscode-html-languageserver-bin # lang (web +lsp)
-                        nodePackages.vscode-json-languageserver-bin # lang (json +lsp)
-                        nodejs # :tools debugger
-                        pandoc # :lang org markdown latex
-                        pinentry-emacs # doom!
-                        pipenv # :lang python
-                        poetry # :lang python
-                        pre-commit # :tools magit
-                        python3 # :lang python
-                        python3Packages.black # :lang python :editor format
-                        python3Packages.isort # :lang python :editor format
-                        python3Packages.nose # :lang python
-                        python3Packages.pyflakes # :lang python :editor format
-                        python3Packages.pytest # :lang python
-                        python3Packages.python-lsp-server # :lang python :editor format
-                        ripgrep # doom!
-                        rust-analyzer # :lang (rust +lsp)
-                        rustc # :lang rust
-                        rustfmt # :lang rust
-                        shellcheck # :lang sh
-                        shfmt # :lang sh :editor format
-                        sops
-                        sqlite # :lang (org +roam2) :tools lookup
-                        terraform-ls # :tools (terraform +lsp)
-                        texlab # lang (tex +lsp)
-                        texlive.combined.scheme-full # :lang org tex
-                        unzip # :tools debugger
-                        wordnet # :tools (lookup +dictionary +offline)
-                        yaml-language-server # :lang (yaml +lsp)
-                        zig # :lang zig :editor format
-                        zls # :lang (zig +lsp)
-                        zstd # :emacs undo
-                      ]
-                      ++ (
-                        # GDB doesn't support[1] Apple Silicon.
-                        #
-                        # [1]: https://inbox.sourceware.org/gdb/6b48224b-9e2e-518d-793b-df4fc5514884@arm.com/
-                        if (this.system != "aarch64-darwin") then
-                          [ gdb ] # :tools debugger
-                        else
-                          [ lldb ] # :tools debugger
-                      );
-
-                    parinferRustLibrary =
-                      if (hasSuffix "linux" this.system) then
-                        "${pkgs.parinfer-rust}/lib/libparinfer_rust.so"
-                      else
-                        "${pkgs.parinfer-rust}/lib/libparinfer_rust.dylib";
+                    extraBins = with pkgs; [
+                      (aspellWithDicts (
+                        p: with p; [
+                          en
+                          ru
+                        ]
+                      )) # :checkers (spell +aspell)
+                      asmfmt # :editor format
+                      cargo # :lang rust
+                      clang-tools # :lang (cc +lsp) :editor format
+                      cmake-format # :lang cc :editor format
+                      cmigemo # :lang japanese
+                      config.hm.programs.emacs.package # !doom
+                      config.nix.package # !doom
+                      delve # :lang go :tools debugger
+                      dockerfile-language-server-nodejs # :tools (docker +lsp)
+                      dockfmt # :tools docker :editor format
+                      editorconfig-core-c # :tools editorconfig
+                      fd # doom!
+                      gcc # :lang cc
+                      ghc # :lang haskell
+                      gnuplot # :lang (org +gnuplot)
+                      gnutar # :tools tree-sitter
+                      gnutls # doom! :app irc
+                      go # :lang go
+                      godef # :lang go
+                      gomodifytags # :lang go
+                      gopls # :lang (go +lsp)
+                      gore # :lang go
+                      gotests # :lang go
+                      gotools # :lang go
+                      graphviz # :lang (org +roam2) :lang plantuml
+                      gzip # :tools tree-sitter
+                      haskellPackages.cabal-fmt # :lang haskell :editor format
+                      haskellPackages.cabal-install # :lang haskell
+                      haskellPackages.haskell-language-server # :lang (haskell +lsp)
+                      haskellPackages.hoogle # :lang haskell
+                      haskellPackages.ormolu # :lang haskell :editor format
+                      html-tidy # :lang web :editor format
+                      jdk # :lang java :lang plantuml :checkers grammar
+                      languagetool # :checkers grammar
+                      libxml2 # :lang data :editor format
+                      markdownlint-cli # :lang markdown
+                      nil # :lang (nix +lsp)
+                      nixfmt # :lang nix :editor format
+                      nls # :lang (nickel +lsp)
+                      nodePackages.bash-language-server # :lang (sh +lsp)
+                      nodePackages.eslint # :lang (json +lsp)
+                      nodePackages.js-beautify # :lang web
+                      nodePackages.prettier # :editor format
+                      nodePackages.stylelint # :lang web
+                      nodePackages.vscode-css-languageserver-bin # lang (web +lsp)
+                      nodePackages.vscode-html-languageserver-bin # lang (web +lsp)
+                      nodePackages.vscode-json-languageserver-bin # lang (json +lsp)
+                      nodejs # :tools debugger
+                      pandoc # :lang org markdown latex
+                      pinentry-emacs # doom!
+                      pipenv # :lang python
+                      poetry # :lang python
+                      pre-commit # :tools magit
+                      python3 # :lang python
+                      python3Packages.black # :lang python :editor format
+                      python3Packages.isort # :lang python :editor format
+                      python3Packages.nose # :lang python
+                      python3Packages.pyflakes # :lang python :editor format
+                      python3Packages.pytest # :lang python
+                      python3Packages.python-lsp-server # :lang python :editor format
+                      ripgrep # doom!
+                      rust-analyzer # :lang (rust +lsp)
+                      rustc # :lang rust
+                      rustfmt # :lang rust
+                      shellcheck # :lang sh
+                      shfmt # :lang sh :editor format
+                      sops
+                      sqlite # :lang (org +roam2) :tools lookup
+                      terraform-ls # :tools (terraform +lsp)
+                      texlab # lang (tex +lsp)
+                      texlive.combined.scheme-full # :lang org tex
+                      unzip # :tools debugger
+                      wordnet # :tools (lookup +dictionary +offline)
+                      yaml-language-server # :lang (yaml +lsp)
+                      zig # :lang zig :editor format
+                      zls # :lang (zig +lsp)
+                      zstd # :emacs undo
+                      gdb # :tools debugger
+                    ];
                   in
                   ''
                     ;; Integrate packages which are required by various modules
@@ -194,7 +186,7 @@ in
 
                     ;; :editor parinfer
                     (setq parinfer-rust-auto-download nil
-                          parinfer-rust-library "${parinferRustLibrary}")
+                          parinfer-rust-library "${pkgs.parinfer-rust}/lib/libparinfer_rust.so")
 
                     ;; :lang (org +roam2) :email mu4e
                     (setq emacsql-sqlite-executable "${getExe pkgs.emacsql-sqlite}")
diff --git a/modules/common/emacs/doom/config.el b/modules/emacs/doom/config.el
index c893e7f..79c0156 100644
--- a/modules/common/emacs/doom/config.el
+++ b/modules/emacs/doom/config.el
@@ -9,9 +9,8 @@
   scroll-margin 10
   hscroll-margin 10)
 
-(when (featurep :system 'linux)
-  (setq browse-url-generic-program (executable-find "firefox")
-        browse-url-browser-function 'browse-url-generic))
+(setq browse-url-generic-program (executable-find "firefox")
+      browse-url-browser-function 'browse-url-generic)
 
 ;;
 ;;; Doom-specific
diff --git a/modules/common/emacs/doom/init.el b/modules/emacs/doom/init.el
index 571993b..571993b 100644
--- a/modules/common/emacs/doom/init.el
+++ b/modules/emacs/doom/init.el
diff --git a/modules/common/emacs/doom/packages.el b/modules/emacs/doom/packages.el
index 2ed0e4c..2ed0e4c 100644
--- a/modules/common/emacs/doom/packages.el
+++ b/modules/emacs/doom/packages.el
diff --git a/modules/nixos/endlessh-go.nix b/modules/endlessh-go.nix
index efaaa8f..efaaa8f 100644
--- a/modules/nixos/endlessh-go.nix
+++ b/modules/endlessh-go.nix
diff --git a/modules/nixos/endlessh.nix b/modules/endlessh.nix
index f1bf0bc..f1bf0bc 100644
--- a/modules/nixos/endlessh.nix
+++ b/modules/endlessh.nix
diff --git a/modules/common/eza.nix b/modules/eza.nix
index 96b7d4c..96b7d4c 100644
--- a/modules/common/eza.nix
+++ b/modules/eza.nix
diff --git a/modules/nixos/fail2ban.nix b/modules/fail2ban.nix
index a0cc2b4..a0cc2b4 100644
--- a/modules/nixos/fail2ban.nix
+++ b/modules/fail2ban.nix
diff --git a/modules/nixos/firefox/addons.json b/modules/firefox/addons.json
index eb26194..c1ea3fa 100644
--- a/modules/nixos/firefox/addons.json
+++ b/modules/firefox/addons.json
@@ -4,10 +4,6 @@
     "slug": "bitwarden-password-manager"
   },
   {
-    "pname": "bypass-paywalls",
-    "slug": "bypass-paywalls-clean-d"
-  },
-  {
     "slug": "consent-o-matic"
   },
   {
diff --git a/modules/firefox/addons.nix b/modules/firefox/addons.nix
new file mode 100644
index 0000000..54e67ee
--- /dev/null
+++ b/modules/firefox/addons.nix
@@ -0,0 +1,315 @@
+{ buildFirefoxXpiAddon, lib }:
+{
+  "bitwarden" = buildFirefoxXpiAddon {
+    pname = "bitwarden";
+    version = "2024.4.1";
+    addonId = "{446900e4-71c2-419f-a6a7-df9c091e268b}";
+    url = "https://addons.mozilla.org/firefox/downloads/file/4263752/bitwarden_password_manager-2024.4.1.xpi";
+    sha256 = "1ba1e66cb9a4ee3bf80a81fc31348b04162385455d2b02f9902473e3931d9693";
+    meta = with lib; {
+      homepage = "https://bitwarden.com";
+      description = "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.";
+      license = licenses.gpl3;
+      mozPermissions = [
+        "<all_urls>"
+        "*://*/*"
+        "tabs"
+        "contextMenus"
+        "storage"
+        "unlimitedStorage"
+        "clipboardRead"
+        "clipboardWrite"
+        "idle"
+        "webRequest"
+        "webRequestBlocking"
+        "file:///*"
+        "https://*/*"
+        "https://lastpass.com/export.php"
+      ];
+      platforms = platforms.all;
+    };
+  };
+  "consent-o-matic" = buildFirefoxXpiAddon {
+    pname = "consent-o-matic";
+    version = "1.0.13";
+    addonId = "gdpr@cavi.au.dk";
+    url = "https://addons.mozilla.org/firefox/downloads/file/4246350/consent_o_matic-1.0.13.xpi";
+    sha256 = "ee577eaedebd9fef65f77218b86c59972818442c9af551d551a7015a4a246e9a";
+    meta = with lib; {
+      homepage = "https://consentomatic.au.dk/";
+      description = "Automatic handling of GDPR consent forms";
+      license = licenses.mit;
+      mozPermissions = [
+        "activeTab"
+        "tabs"
+        "storage"
+        "<all_urls>"
+      ];
+      platforms = platforms.all;
+    };
+  };
+  "darkreader" = buildFirefoxXpiAddon {
+    pname = "darkreader";
+    version = "4.9.83";
+    addonId = "addon@darkreader.org";
+    url = "https://addons.mozilla.org/firefox/downloads/file/4262984/darkreader-4.9.83.xpi";
+    sha256 = "a43cca2449de202d17040b0d91b2fb3ed4dd58ac81ec5d3fde4c9940d326c822";
+    meta = with lib; {
+      homepage = "https://darkreader.org/";
+      description = "Dark mode for every website. Take care of your eyes, use dark theme for night and daily browsing.";
+      license = licenses.mit;
+      mozPermissions = [
+        "alarms"
+        "contextMenus"
+        "storage"
+        "tabs"
+        "theme"
+        "<all_urls>"
+      ];
+      platforms = platforms.all;
+    };
+  };
+  "furiganaize" = buildFirefoxXpiAddon {
+    pname = "furiganaize";
+    version = "0.7.2";
+    addonId = "{a2503cd4-4083-4c2f-bef2-37767a569867}";
+    url = "https://addons.mozilla.org/firefox/downloads/file/4032306/furiganaize-0.7.2.xpi";
+    sha256 = "7545bc418f2afbc576b0e762f2b2fa0545d5d94f3f80737e5356d087a5951c0b";
+    meta = with lib; {
+      homepage = "https://github.com/kuanyui/Furiganaize";
+      description = "Auto insert furigana (振り仮名) on Japanese kanji.";
+      license = licenses.mit;
+      mozPermissions = [
+        "http://*/*"
+        "https://*/*"
+        "file://*/*"
+        "<all_urls>"
+        "activeTab"
+        "tabs"
+        "storage"
+      ];
+      platforms = platforms.all;
+    };
+  };
+  "ipfs-companion" = buildFirefoxXpiAddon {
+    pname = "ipfs-companion";
+    version = "3.1.0";
+    addonId = "ipfs-firefox-addon@lidel.org";
+    url = "https://addons.mozilla.org/firefox/downloads/file/4172699/ipfs_companion-3.1.0.xpi";
+    sha256 = "784f6d1e0497d86f1e42cfe7de8548b5cc28fabe80e50771d90f59ddf1b9d3c1";
+    meta = with lib; {
+      homepage = "https://github.com/ipfs/ipfs-companion";
+      description = "Harness the power of IPFS in your browser";
+      license = licenses.cc0;
+      mozPermissions = [
+        "idle"
+        "tabs"
+        "notifications"
+        "proxy"
+        "storage"
+        "unlimitedStorage"
+        "contextMenus"
+        "clipboardWrite"
+        "webNavigation"
+        "webRequest"
+        "webRequestBlocking"
+      ];
+      platforms = platforms.all;
+    };
+  };
+  "languagetool" = buildFirefoxXpiAddon {
+    pname = "languagetool";
+    version = "8.6.0";
+    addonId = "languagetool-webextension@languagetool.org";
+    url = "https://addons.mozilla.org/firefox/downloads/file/4249956/languagetool-8.6.0.xpi";
+    sha256 = "d9db9aac9fdd53eb39179c153161762cd9e9eb1f6d7da8e8b8a32238b4847094";
+    meta = with lib; {
+      homepage = "https://languagetool.org";
+      description = "With this extension you can check text with the free style and grammar checker LanguageTool. It finds many errors that a simple spell checker cannot detect, like mixing up there/their, a/an, or repeating a word.";
+      mozPermissions = [
+        "activeTab"
+        "storage"
+        "contextMenus"
+        "alarms"
+        "http://*/*"
+        "https://*/*"
+        "file:///*"
+        "*://docs.google.com/document/*"
+        "*://languagetool.org/*"
+      ];
+      platforms = platforms.all;
+    };
+  };
+  "no-pdf-download" = buildFirefoxXpiAddon {
+    pname = "no-pdf-download";
+    version = "1.0.6";
+    addonId = "{b9b25e4a-bdf4-4270-868c-3f619eaf437d}";
+    url = "https://addons.mozilla.org/firefox/downloads/file/3020560/no_pdf_download-1.0.6.xpi";
+    sha256 = "fa27b6729178a23ccf2eee07cd7650d841fc6040f2e5adfb919931b671ed79e6";
+    meta = with lib; {
+      homepage = "https://github.com/MorbZ/no-pdf-download";
+      description = "Opens all PDF files directly in the browser.";
+      license = licenses.mit;
+      mozPermissions = [
+        "webRequest"
+        "webRequestBlocking"
+        "<all_urls>"
+      ];
+      platforms = platforms.all;
+    };
+  };
+  "redirector" = buildFirefoxXpiAddon {
+    pname = "redirector";
+    version = "3.5.3";
+    addonId = "redirector@einaregilsson.com";
+    url = "https://addons.mozilla.org/firefox/downloads/file/3535009/redirector-3.5.3.xpi";
+    sha256 = "eddbd3d5944e748d0bd6ecb6d9e9cf0e0c02dced6f42db21aab64190e71c0f71";
+    meta = with lib; {
+      homepage = "http://einaregilsson.com/redirector/";
+      description = "Automatically redirects to user-defined urls on certain pages";
+      license = licenses.mit;
+      mozPermissions = [
+        "webRequest"
+        "webRequestBlocking"
+        "webNavigation"
+        "storage"
+        "tabs"
+        "http://*/*"
+        "https://*/*"
+        "notifications"
+      ];
+      platforms = platforms.all;
+    };
+  };
+  "rikaichamp" = buildFirefoxXpiAddon {
+    pname = "rikaichamp";
+    version = "1.18.0";
+    addonId = "{59812185-ea92-4cca-8ab7-cfcacee81281}";
+    url = "https://addons.mozilla.org/firefox/downloads/file/4241410/10ten_ja_reader-1.18.0.xpi";
+    sha256 = "5433bcfec5a327bf1fa198b3f0645a9cdcdc44232465ad940fa8a5858b6996f8";
+    meta = with lib; {
+      homepage = "https://github.com/birchill/10ten-ja-reader/";
+      description = "Quickly translate Japanese by hovering over words. Formerly released as Rikaichamp.";
+      license = licenses.gpl3;
+      mozPermissions = [
+        "alarms"
+        "clipboardWrite"
+        "contextMenus"
+        "storage"
+        "unlimitedStorage"
+        "http://*/*"
+        "https://*/*"
+        "file:///*"
+        "https://docs.google.com/*"
+      ];
+      platforms = platforms.all;
+    };
+  };
+  "skip-redirect" = buildFirefoxXpiAddon {
+    pname = "skip-redirect";
+    version = "2.3.6";
+    addonId = "skipredirect@sblask";
+    url = "https://addons.mozilla.org/firefox/downloads/file/3920533/skip_redirect-2.3.6.xpi";
+    sha256 = "dbe8950245c1f475c5c1c6daab89c79b83ba4680621c91e80f15be7b09b618ae";
+    meta = with lib; {
+      description = "Some web pages use intermediary pages before redirecting to a final page. This add-on tries to extract the final url from the intermediary url and goes there straight away if successful.";
+      license = licenses.mit;
+      mozPermissions = [
+        "<all_urls>"
+        "clipboardWrite"
+        "contextMenus"
+        "notifications"
+        "storage"
+        "webRequest"
+        "webRequestBlocking"
+      ];
+      platforms = platforms.all;
+    };
+  };
+  "ublock-origin" = buildFirefoxXpiAddon {
+    pname = "ublock-origin";
+    version = "1.57.2";
+    addonId = "uBlock0@raymondhill.net";
+    url = "https://addons.mozilla.org/firefox/downloads/file/4261710/ublock_origin-1.57.2.xpi";
+    sha256 = "9928e79a52cecf7cfa231fdb0699c7d7a427660d94eb10d711ed5a2f10d2eb89";
+    meta = with lib; {
+      homepage = "https://github.com/gorhill/uBlock#ublock-origin";
+      description = "Finally, an efficient wide-spectrum content blocker. Easy on CPU and memory.";
+      license = licenses.gpl3;
+      mozPermissions = [
+        "alarms"
+        "dns"
+        "menus"
+        "privacy"
+        "storage"
+        "tabs"
+        "unlimitedStorage"
+        "webNavigation"
+        "webRequest"
+        "webRequestBlocking"
+        "<all_urls>"
+        "http://*/*"
+        "https://*/*"
+        "file://*/*"
+        "https://easylist.to/*"
+        "https://*.fanboy.co.nz/*"
+        "https://filterlists.com/*"
+        "https://forums.lanik.us/*"
+        "https://github.com/*"
+        "https://*.github.io/*"
+        "https://*.letsblock.it/*"
+        "https://github.com/uBlockOrigin/*"
+        "https://ublockorigin.github.io/*"
+        "https://*.reddit.com/r/uBlockOrigin/*"
+      ];
+      platforms = platforms.all;
+    };
+  };
+  "user-agent-switcher" = buildFirefoxXpiAddon {
+    pname = "user-agent-switcher";
+    version = "0.5.0";
+    addonId = "{a6c4a591-f1b2-4f03-b3ff-767e5bedf4e7}";
+    url = "https://addons.mozilla.org/firefox/downloads/file/4098688/user_agent_string_switcher-0.5.0.xpi";
+    sha256 = "9dc8da3c8c46d4f04d12fd789c63501fa6a2f502f859b286939a090db63eae33";
+    meta = with lib; {
+      homepage = "http://add0n.com/useragent-switcher.html";
+      description = "Spoof websites trying to gather information about your web navigation—like your browser type and operating system—to deliver distinct content you may not want.";
+      license = licenses.mpl20;
+      mozPermissions = [
+        "storage"
+        "<all_urls>"
+        "webNavigation"
+        "webRequest"
+        "webRequestBlocking"
+        "contextMenus"
+        "*://*/*"
+      ];
+      platforms = platforms.all;
+    };
+  };
+  "violentmonkey" = buildFirefoxXpiAddon {
+    pname = "violentmonkey";
+    version = "2.18.0";
+    addonId = "{aecec67f-0d10-4fa7-b7c7-609a2db280cf}";
+    url = "https://addons.mozilla.org/firefox/downloads/file/4220396/violentmonkey-2.18.0.xpi";
+    sha256 = "4abbeea842b82965379c6011dec6a435dfff0f69c20749118a8ba2f7d14cb0f1";
+    meta = with lib; {
+      homepage = "https://violentmonkey.github.io/";
+      description = "Userscript support for browsers, open source.";
+      license = licenses.mit;
+      mozPermissions = [
+        "tabs"
+        "<all_urls>"
+        "webRequest"
+        "webRequestBlocking"
+        "notifications"
+        "storage"
+        "unlimitedStorage"
+        "clipboardWrite"
+        "contextMenus"
+        "cookies"
+      ];
+      platforms = platforms.all;
+    };
+  };
+}
diff --git a/modules/nixos/firefox/default.nix b/modules/firefox/default.nix
index 881e9ad..ce2cecc 100644
--- a/modules/nixos/firefox/default.nix
+++ b/modules/firefox/default.nix
@@ -127,7 +127,6 @@ in
               in
               with addons;
               [
-                bypass-paywalls
                 consent-o-matic
                 darkreader
                 furiganaize
diff --git a/modules/nixos/firefox/userChrome.css b/modules/firefox/userChrome.css
index 80d1f7a..80d1f7a 100644
--- a/modules/nixos/firefox/userChrome.css
+++ b/modules/firefox/userChrome.css
diff --git a/modules/nixos/firefox/userContent.css b/modules/firefox/userContent.css
index cf7b659..cf7b659 100644
--- a/modules/nixos/firefox/userContent.css
+++ b/modules/firefox/userContent.css
diff --git a/modules/nixos/foot.nix b/modules/foot.nix
index 502e143..502e143 100644
--- a/modules/nixos/foot.nix
+++ b/modules/foot.nix
diff --git a/modules/nixos/games/default.nix b/modules/games/default.nix
index 585164e..dea9d3c 100644
--- a/modules/nixos/games/default.nix
+++ b/modules/games/default.nix
@@ -4,14 +4,7 @@ let
   cfg = config.nixfiles.modules.games;
 in
 {
-  imports = [
-    ./gamemode.nix
-    ./lutris.nix
-    ./mangohud.nix
-    ./minecraft.nix
-    ./steam-run.nix
-    ./steam.nix
-  ];
+  imports = attrValues (modulesIn ./.);
 
   options.nixfiles.modules.games.enable32BitSupport = mkEnableOption "support for games";
 
diff --git a/modules/nixos/games/gamemode.nix b/modules/games/gamemode.nix
index eb485f8..eb485f8 100644
--- a/modules/nixos/games/gamemode.nix
+++ b/modules/games/gamemode.nix
diff --git a/modules/nixos/games/lutris.nix b/modules/games/lutris.nix
index 62fe521..62fe521 100644
--- a/modules/nixos/games/lutris.nix
+++ b/modules/games/lutris.nix
diff --git a/modules/nixos/games/mangohud.nix b/modules/games/mangohud.nix
index 955f50c..955f50c 100644
--- a/modules/nixos/games/mangohud.nix
+++ b/modules/games/mangohud.nix
diff --git a/modules/nixos/games/minecraft.nix b/modules/games/minecraft.nix
index 6e163dc..6e163dc 100644
--- a/modules/nixos/games/minecraft.nix
+++ b/modules/games/minecraft.nix
diff --git a/modules/nixos/games/steam-run.nix b/modules/games/steam-run.nix
index cfee8ae..cfee8ae 100644
--- a/modules/nixos/games/steam-run.nix
+++ b/modules/games/steam-run.nix
diff --git a/modules/nixos/games/steam.nix b/modules/games/steam.nix
index 5883b0e..5883b0e 100644
--- a/modules/nixos/games/steam.nix
+++ b/modules/games/steam.nix
diff --git a/modules/git/default.nix b/modules/git/default.nix
new file mode 100644
index 0000000..a65c31e
--- /dev/null
+++ b/modules/git/default.nix
@@ -0,0 +1,300 @@
+{
+  config,
+  inputs,
+  lib,
+  libNginx,
+  libPlausible,
+  pkgs,
+  ...
+}:
+with lib;
+let
+  cfg = config.nixfiles.modules.git;
+in
+{
+  options.nixfiles.modules.git = {
+    client.enable = mkEnableOption "Git client";
+
+    server = {
+      enable = mkEnableOption "Git server";
+
+      domain = mkOption {
+        description = "Domain name sans protocol scheme.";
+        type = with types; nullOr str;
+        default = "git.${config.networking.domain}";
+      };
+
+      package = mkOption {
+        description = "Package.";
+        type = types.package;
+        default = pkgs.cgit;
+      };
+    };
+  };
+
+  config = mkMerge [
+    (mkIf cfg.client.enable {
+      secrets = {
+        glab-cli-config = {
+          file = "${inputs.self}/secrets/glab-cli-config";
+          path = "${config.dirs.config}/glab-cli/config.yml";
+          owner = my.username;
+        };
+        gh-hosts = {
+          file = "${inputs.self}/secrets/gh-hosts";
+          path = "${config.dirs.config}/gh/hosts.yml";
+          owner = my.username;
+        };
+        hut = {
+          file = "${inputs.self}/secrets/hut";
+          path = "${config.dirs.config}/hut/config";
+          owner = my.username;
+        };
+      };
+
+      nixfiles.modules.common.shell.aliases = {
+        gl = "glab";
+        ht = "hut";
+      };
+
+      hm = {
+        home.packages = with pkgs; [
+          git-extras
+          glab
+          hut
+        ];
+
+        programs = {
+          git = {
+            enable = true;
+
+            package = pkgs.git.override {
+              doInstallCheck = false;
+              pythonSupport = false;
+              sendEmailSupport = true;
+              withLibsecret = false;
+              withSsh = true;
+            };
+
+            userName = my.fullname;
+            userEmail = my.email;
+            signing = {
+              inherit (my.pgp) key;
+              signByDefault = true;
+            };
+
+            extraConfig =
+              {
+                color.ui = true;
+                core.whitespace = "trailing-space";
+                init.defaultBranch = "master";
+                status.submoduleSummary = true;
+                commit.verbose = true;
+                push.autoSetupRemote = true;
+                pull.rebase = true;
+                rebase = {
+                  autoStash = true;
+                  autoSquash = true;
+                };
+                rerere.enabled = true;
+                branch.sort = "-committerdate";
+                diff = {
+                  mnemonicPrefix = true;
+                  renames = "copies";
+                  submodule = "log";
+                };
+                submodule.recurse = true;
+                sendemail = rec {
+                  smtpServer = my.domain.shire;
+                  smtpUser = "${my.username}@${smtpServer}";
+                  smtpEncryption = "ssl";
+                  smtpServerPort = 465;
+                  annotate = true;
+                  confirm = "always";
+                };
+                column.ui = "auto";
+                github.user = my.username;
+                gitlab.user = my.username;
+              }
+              // mapAttrs' (name: value: nameValuePair ''url "git@${value}:"'' { insteadOf = "${name}:"; }) {
+                "bitbucket" = "bitbucket.com";
+                "codeberg" = "codeberg.org";
+                "github" = "github.com";
+                "gitlab" = "gitlab.com";
+                "sourcehut" = "git.sr.ht";
+              }
+              //
+                mapAttrs' (name: values: nameValuePair ''url "https://${values}/"'' { insteadOf = "${name}:"; })
+                  {
+                    "alpine" = "gitlab.alpinelinux.org";
+                    "debian" = "salsa.debian.org";
+                    "freedesktop" = "gitlab.freedesktop.org";
+                    "gnome" = "gitlab.gnome.org";
+                    "haskell" = "gitlab.haskell.org";
+                    "homotopic" = "gitlab.homotopic.tech";
+                    "horizon" = "gitlab.horizon-haskell.net";
+                    "kde" = "invent.kde.org";
+                    "nixca" = "gitlab.nixca.dev";
+                    "notabug" = "notabug.org";
+                    "opencode" = "opencode.net";
+                    "torproject" = "gitlab.torproject.org";
+                    "videolan" = "code.videolan.org";
+                  };
+
+            aliases =
+              let
+                git = getExe config.hm.programs.git.package;
+                curl = getExe pkgs.curl;
+              in
+              {
+                amend = "commit --amend";
+                cat = "cat-file -p";
+                fast = "clone --depth=1";
+                fixup = "commit --fixup";
+                fuck = "!${git} reset --hard && ${git} clean --force -dx";
+                get = "pull --all --recurse-submodules --autostash";
+                gud = ''commit -m "git gud"'';
+                refresh = "clean --force -dx";
+                tree = "log --graph --date=relative --pretty=tformat:'%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%an %ad)%Creset'";
+                uncommit = "reset --soft HEAD~1";
+                untrack = "rm --cache --";
+                wtc = "!${curl} -sq whatthecommit.com/index.txt | ${git} commit -F -";
+              };
+
+            # All helper tools/editor generated files should go here. This must be
+            # kept void of any project-specific or residual files.
+            ignores = [
+              "*~"
+              ".DS_Store"
+              ".cache/clangd/"
+              ".ccls-cache/"
+              ".gdb_history"
+              ".netrwhist"
+              ".projectile"
+              "[._]*.s[a-v][a-z]"
+              "[._]*.sw[a-p]"
+              "[._]s[a-rt-v][a-z]"
+              "[._]ss[a-gi-z]"
+              "[._]sw[a-p]"
+              "\#*\#"
+              "compile_commands*.json"
+              "cscope.*"
+              "vgcore.*"
+            ];
+          };
+
+          gh = {
+            enable = true;
+            settings.git_protocol = "ssh";
+          };
+        };
+      };
+    })
+    (mkIf cfg.server.enable {
+      ark.directories = [ config.services.gitolite.dataDir ];
+
+      nixfiles.modules.nginx = {
+        enable = true;
+        virtualHosts.${cfg.server.domain} = {
+          locations = {
+            "/".extraConfig =
+              let
+                cgitrc = pkgs.writeText "cgitrc" ''
+                  root-title=github sux (⩺_⩹)
+                  root-desc=https://github.com/azahi
+
+                  clone-url=https://${cfg.server.domain}/$CGIT_REPO_URL
+
+                  logo=/cgit-custom-logo.gif
+                  favicon=/cgit-custom-favicon.gif
+                  css=/cgit-custom-style.css
+
+                  about-filter=${cfg.server.package}/lib/cgit/filters/about-formatting.sh
+                  source-filter=${cfg.server.package}/lib/cgit/filters/syntax-highlighting.py
+                  commit-filter=${cfg.server.package}/lib/cgit/filters/commit-links.sh
+
+                  enable-git-config=1
+                  enable-gitweb-owner=1
+                  remove-suffix=1
+
+                  readme=:README
+                  readme=:README.md
+                  readme=:README.org
+                  readme=:README.txt
+                  readme=:readme
+                  readme=:readme.md
+                  readme=:readme.org
+                  readme=:readme.txt
+
+                  scan-path=${config.services.gitolite.dataDir}/repositories
+                '';
+              in
+              ''
+                include ${config.services.nginx.package}/conf/fastcgi_params;
+                fastcgi_split_path_info ^(/?)(.+)$;
+                fastcgi_pass unix:${config.services.fcgiwrap.socketAddress};
+                fastcgi_param SCRIPT_FILENAME ${cfg.server.package}/cgit/cgit.cgi;
+                fastcgi_param CGIT_CONFIG ${cgitrc};
+                fastcgi_param PATH_INFO $uri;
+                fastcgi_param QUERY_STRING $args;
+                fastcgi_param HTTP_HOST $server_name;
+
+                ${libNginx.config.appendHead [
+                  ''<meta name="go-import" content="$host$uri git https://$host$uri">''
+                  (libPlausible.htmlPlausibleScript { inherit (cfg.server) domain; })
+                ]}
+              '';
+            "~* ^.+(cgit.css|robots.txt)$".extraConfig = ''
+              root ${cfg.server.package}/cgit;
+            '';
+            "~* ^.+cgit-custom-logo.gif$".extraConfig = ''
+              alias ${./logo.gif};
+            '';
+            "~* ^.+cgit-custom-favicon.gif$".extraConfig = ''
+              alias ${./favicon.ico};
+            '';
+            "~* ^.+cgit-custom-style.css$".extraConfig =
+              let
+                css = pkgs.writeText "custom.css" ''
+                  @import url("cgit.css");
+
+                  div#cgit {
+                    font-family: monospace;
+                    -moz-tab-size: 4;
+                    tab-size: 4;
+                  }
+                '';
+              in
+              ''
+                alias ${css};
+              '';
+          };
+        };
+      };
+
+      services =
+        let
+          user = "git";
+          group = "git";
+        in
+        {
+          gitolite = {
+            enable = true;
+            inherit user group;
+            adminPubkey = my.ssh.key;
+            extraGitoliteRc = ''
+              # This allows hiding repositories via "cgit.ignore"[1].
+              #
+              # [1]: https://www.omarpolo.com/post/cgit-gitolite.html
+              $RC{GIT_CONFIG_KEYS} = '.*';
+            '';
+          };
+
+          fcgiwrap = {
+            enable = true;
+            inherit user group;
+          };
+        };
+    })
+  ];
+}
diff --git a/modules/nixos/git/favicon.ico b/modules/git/favicon.ico
index bb7cc39..bb7cc39 100644
--- a/modules/nixos/git/favicon.ico
+++ b/modules/git/favicon.ico
Binary files differdiff --git a/modules/nixos/git/logo.gif b/modules/git/logo.gif
index 05874f9..05874f9 100644
--- a/modules/nixos/git/logo.gif
+++ b/modules/git/logo.gif
Binary files differdiff --git a/modules/gnupg.nix b/modules/gnupg.nix
new file mode 100644
index 0000000..69a10e3
--- /dev/null
+++ b/modules/gnupg.nix
@@ -0,0 +1,106 @@
+{
+  config,
+  lib,
+  pkgs,
+  ...
+}:
+with lib;
+let
+  cfg = config.nixfiles.modules.gnupg;
+in
+{
+  options.nixfiles.modules.gnupg = {
+    enable = mkEnableOption "GnuPG";
+    pinentry = mkOption {
+      description = "Name of a pinentry implementation.";
+      type = types.package;
+      default = pkgs.pinentry-curses;
+    };
+  };
+
+  config = mkIf cfg.enable {
+    hm = {
+      programs.gpg = {
+        enable = true;
+
+        homedir = "${config.dirs.data}/gnupg";
+
+        settings =
+          {
+            display-charset = "utf-8";
+            enable-progress-filter = true;
+            fixed-list-mode = true;
+            keyid-format = "0xlong";
+            no-comments = true;
+            no-emit-version = true;
+            no-greeting = true;
+            with-fingerprint = true;
+            throw-keyids = false;
+
+            use-agent = true;
+
+            armor = true;
+
+            no-random-seed-file = true;
+
+            list-options = "show-uid-validity";
+            verify-options = "show-uid-validity";
+          }
+          // (
+            let
+              cipherAlgos = [
+                "AES256"
+                "AES192"
+                "AES"
+              ];
+              digestAlgos = [
+                "SHA512"
+                "SHA384"
+                "SHA256"
+                "SHA224"
+              ];
+              compressionAlgos = [
+                "ZLIB"
+                "BZIP2"
+                "ZIP"
+                "Uncompressed"
+              ];
+
+              cs = concatStringsSep " ";
+            in
+            {
+              default-preference-list = cs (cipherAlgos ++ digestAlgos ++ compressionAlgos);
+
+              personal-cipher-preferences = cs cipherAlgos;
+              personal-digest-preferences = cs digestAlgos;
+              personal-compress-preferences = cs compressionAlgos;
+
+              s2k-cipher-algo = head cipherAlgos;
+              s2k-digest-algo = head digestAlgos;
+
+              digest-algo = head digestAlgos;
+              cert-digest-algo = head digestAlgos;
+            }
+          );
+      };
+
+      services.gpg-agent = {
+        enable = true;
+
+        enableSshSupport = true;
+        enableScDaemon = false;
+
+        defaultCacheTtl = 999999;
+        defaultCacheTtlSsh = 999999;
+        maxCacheTtl = 999999;
+        maxCacheTtlSsh = 999999;
+
+        grabKeyboardAndMouse = true;
+
+        sshKeys = [ my.pgp.grip ];
+
+        pinentryPackage = cfg.pinentry;
+      };
+    };
+  };
+}
diff --git a/modules/nixos/gotify.nix b/modules/gotify.nix
index ad9b277..ad9b277 100644
--- a/modules/nixos/gotify.nix
+++ b/modules/gotify.nix
diff --git a/modules/nixos/grafana.nix b/modules/grafana.nix
index 233c9e5..233c9e5 100644
--- a/modules/nixos/grafana.nix
+++ b/modules/grafana.nix
diff --git a/modules/common/htop.nix b/modules/htop.nix
index 647abf7..647abf7 100644
--- a/modules/common/htop.nix
+++ b/modules/htop.nix
diff --git a/modules/nixos/hydra.nix b/modules/hydra.nix
index 85b89ab..85b89ab 100644
--- a/modules/nixos/hydra.nix
+++ b/modules/hydra.nix
diff --git a/modules/nixos/incus.nix b/modules/incus.nix
index 184aa03..184aa03 100644
--- a/modules/nixos/incus.nix
+++ b/modules/incus.nix
diff --git a/modules/nixos/ipfs.nix b/modules/ipfs.nix
index cd28372..cd28372 100644
--- a/modules/nixos/ipfs.nix
+++ b/modules/ipfs.nix
diff --git a/modules/nixos/jackett.nix b/modules/jackett.nix
index 492e77a..492e77a 100644
--- a/modules/nixos/jackett.nix
+++ b/modules/jackett.nix
diff --git a/modules/nixos/k3s.nix b/modules/k3s.nix
index 1ad99c3..1ad99c3 100644
--- a/modules/nixos/k3s.nix
+++ b/modules/k3s.nix
diff --git a/modules/nixos/kde.nix b/modules/kde.nix
index 4f44a5e..4f44a5e 100644
--- a/modules/nixos/kde.nix
+++ b/modules/kde.nix
diff --git a/modules/nixos/libvirtd.nix b/modules/libvirtd.nix
index 009fd24..009fd24 100644
--- a/modules/nixos/libvirtd.nix
+++ b/modules/libvirtd.nix
diff --git a/modules/nixos/lidarr.nix b/modules/lidarr.nix
index 84d363b..84d363b 100644
--- a/modules/nixos/lidarr.nix
+++ b/modules/lidarr.nix
diff --git a/modules/nixos/loki.nix b/modules/loki.nix
index c446848..c446848 100644
--- a/modules/nixos/loki.nix
+++ b/modules/loki.nix
diff --git a/modules/matrix/default.nix b/modules/matrix/default.nix
new file mode 100644
index 0000000..ef9fb18
--- /dev/null
+++ b/modules/matrix/default.nix
@@ -0,0 +1 @@
+{ lib, ... }: with lib; { imports = attrValues (modulesIn ./.); }
diff --git a/modules/nixos/matrix/dendrite.nix b/modules/matrix/dendrite.nix
index 5e8a7e4..dafef00 100644
--- a/modules/nixos/matrix/dendrite.nix
+++ b/modules/matrix/dendrite.nix
@@ -55,6 +55,7 @@ in
             "= /.well-known/matrix/server" = {
               extraConfig = ''
                 add_header Content-Type application/json;
+                add_header Access-Control-Allow-Origin *;
               '';
               return = "200 '${generators.toJSON { } { "m.server" = "${cfg.domain}:443"; }}'";
             };
@@ -178,7 +179,7 @@ in
                   logging = [
                     {
                       type = "std";
-                      level = "warn";
+                      level = "info";
                     }
                   ];
                 };
diff --git a/modules/nixos/matrix/element.nix b/modules/matrix/element.nix
index 92a2927..01b991e 100644
--- a/modules/nixos/matrix/element.nix
+++ b/modules/matrix/element.nix
@@ -50,7 +50,7 @@ in
           brand = homeserver;
           branding.authFooterLinks = [
             {
-              text = "Hosted on NixOS";
+              text = "NixOS";
               url = "https://nixos.org";
             }
           ];
diff --git a/modules/nixos/monitoring/dashboards/endlessh.json b/modules/monitoring/dashboards/endlessh.json
index 7af5595..7af5595 100644
--- a/modules/nixos/monitoring/dashboards/endlessh.json
+++ b/modules/monitoring/dashboards/endlessh.json
diff --git a/modules/nixos/monitoring/dashboards/nginx.json b/modules/monitoring/dashboards/nginx.json
index cb8f160..cb8f160 100644
--- a/modules/nixos/monitoring/dashboards/nginx.json
+++ b/modules/monitoring/dashboards/nginx.json
diff --git a/modules/nixos/monitoring/dashboards/node.json b/modules/monitoring/dashboards/node.json
index 452e6f9..452e6f9 100644
--- a/modules/nixos/monitoring/dashboards/node.json
+++ b/modules/monitoring/dashboards/node.json
diff --git a/modules/nixos/monitoring/dashboards/ntfy.json b/modules/monitoring/dashboards/ntfy.json
index dadeae7..dadeae7 100644
--- a/modules/nixos/monitoring/dashboards/ntfy.json
+++ b/modules/monitoring/dashboards/ntfy.json
diff --git a/modules/nixos/monitoring/dashboards/postgresql.json b/modules/monitoring/dashboards/postgresql.json
index 9d856e8..9d856e8 100644
--- a/modules/nixos/monitoring/dashboards/postgresql.json
+++ b/modules/monitoring/dashboards/postgresql.json
diff --git a/modules/nixos/monitoring/dashboards/redis.json b/modules/monitoring/dashboards/redis.json
index 014ad3e..014ad3e 100644
--- a/modules/nixos/monitoring/dashboards/redis.json
+++ b/modules/monitoring/dashboards/redis.json
diff --git a/modules/nixos/monitoring/dashboards/unbound.json b/modules/monitoring/dashboards/unbound.json
index b04e9c5..b04e9c5 100644
--- a/modules/nixos/monitoring/dashboards/unbound.json
+++ b/modules/monitoring/dashboards/unbound.json
diff --git a/modules/nixos/monitoring/default.nix b/modules/monitoring/default.nix
index 6e5b782..6e5b782 100644
--- a/modules/nixos/monitoring/default.nix
+++ b/modules/monitoring/default.nix
diff --git a/modules/nixos/monitoring/rules/nginx.yaml b/modules/monitoring/rules/nginx.yaml
index f00d372..f00d372 100644
--- a/modules/nixos/monitoring/rules/nginx.yaml
+++ b/modules/monitoring/rules/nginx.yaml
diff --git a/modules/nixos/monitoring/rules/node.yaml b/modules/monitoring/rules/node.yaml
index a9b6b79..a9b6b79 100644
--- a/modules/nixos/monitoring/rules/node.yaml
+++ b/modules/monitoring/rules/node.yaml
diff --git a/modules/nixos/monitoring/rules/postgres.yaml b/modules/monitoring/rules/postgres.yaml
index 6a98c92..6a98c92 100644
--- a/modules/nixos/monitoring/rules/postgres.yaml
+++ b/modules/monitoring/rules/postgres.yaml
diff --git a/modules/nixos/monitoring/rules/redis.yaml b/modules/monitoring/rules/redis.yaml
index b47c313..b47c313 100644
--- a/modules/nixos/monitoring/rules/redis.yaml
+++ b/modules/monitoring/rules/redis.yaml
diff --git a/modules/nixos/mpd.nix b/modules/mpd.nix
index 7c3c821..7c3c821 100644
--- a/modules/nixos/mpd.nix
+++ b/modules/mpd.nix
diff --git a/modules/common/mpv.nix b/modules/mpv.nix
index 9cd1e91..9b26b08 100644
--- a/modules/common/mpv.nix
+++ b/modules/mpv.nix
@@ -12,6 +12,90 @@ in
   options.nixfiles.modules.mpv.enable = mkEnableOption "mpv";
 
   config = mkIf cfg.enable {
+    nixfiles.modules.common = {
+      shell.aliases.cam = "mpv av://v4l2:/dev/video0";
+
+      xdg.defaultApplications.mpv =
+        let
+          audio = [
+            "audio/aac"
+            "audio/ac3"
+            "audio/basic"
+            "audio/flac"
+            "audio/midi"
+            "audio/mp4"
+            "audio/mpeg"
+            "audio/ogg"
+            "audio/opus"
+            "audio/vnd.dts"
+            "audio/vnd.dts.hd"
+            "audio/webm"
+            "audio/x-adpcm"
+            "audio/x-aifc"
+            "audio/x-aiff"
+            "audio/x-ape"
+            "audio/x-flac+ogg"
+            "audio/x-m4b"
+            "audio/x-m4r"
+            "audio/x-matroska"
+            "audio/x-mpegurl"
+            "audio/x-musepack"
+            "audio/x-opus+ogg"
+            "audio/x-speex"
+            "audio/x-speex+ogg"
+            "audio/x-vorbis+ogg"
+            "audio/x-wav"
+            "audio/x-wavpack"
+            "x-content/audio-cdda"
+            "x-content/audio-dvd"
+          ];
+          video = [
+            "video/3gpp"
+            "video/3gpp2"
+            "video/mkv"
+            "video/mp2t"
+            "video/mp4"
+            "video/mpeg"
+            "video/ogg"
+            "video/quicktime"
+            "video/vnd.mpegurl"
+            "video/vnd.radgamettools.bink"
+            "video/vnd.radgamettools.smacker"
+            "video/wavelet"
+            "video/webm"
+            "video/x-matroska"
+            "video/x-matroska-3d"
+            "video/x-mjpeg"
+            "video/x-msvideo"
+            "video/x-ogm+ogg"
+            "video/x-theora+ogg"
+            "x-content/video-bluray"
+            "x-content/video-dvd"
+            "x-content/video-hddvd"
+            "x-content/video-svcd"
+            "x-content/video-vcd"
+          ];
+          image = [
+            "image/avif"
+            "image/bmp"
+            "image/gif"
+            "image/jp2"
+            "image/jpeg"
+            "image/jpg"
+            "image/jpm"
+            "image/jpx"
+            "image/jxl"
+            "image/png"
+            "image/tiff"
+            "image/vnd.microsoft.icon"
+            "image/webp"
+            "image/webp"
+            "image/x-tga"
+          ];
+        in
+        audio ++ video ++ image;
+    };
+
     hm.programs.mpv = {
       enable = true;
 
diff --git a/modules/nixos/murmur.nix b/modules/murmur.nix
index 7621c9e..7621c9e 100644
--- a/modules/nixos/murmur.nix
+++ b/modules/murmur.nix
diff --git a/modules/nixos/nextcloud.nix b/modules/nextcloud.nix
index 4053c38..4053c38 100644
--- a/modules/nixos/nextcloud.nix
+++ b/modules/nextcloud.nix
diff --git a/modules/nixos/nginx.nix b/modules/nginx.nix
index ed34237..ed34237 100644
--- a/modules/nixos/nginx.nix
+++ b/modules/nginx.nix
diff --git a/modules/nixos/common/default.nix b/modules/nixos/common/default.nix
deleted file mode 100644
index 4c192c9..0000000
--- a/modules/nixos/common/default.nix
+++ /dev/null
@@ -1,21 +0,0 @@
-_: {
-  imports = [
-    ./ark.nix
-    ./console.nix
-    ./documentation.nix
-    ./home-manager.nix
-    ./kernel.nix
-    ./locale.nix
-    ./networking.nix
-    ./nix.nix
-    ./secrets.nix
-    ./security.nix
-    ./services.nix
-    ./shell.nix
-    ./stylix.nix
-    ./systemd.nix
-    ./tmp.nix
-    ./users.nix
-    ./xdg.nix
-  ];
-}
diff --git a/modules/nixos/common/home-manager.nix b/modules/nixos/common/home-manager.nix
deleted file mode 100644
index c553a65..0000000
--- a/modules/nixos/common/home-manager.nix
+++ /dev/null
@@ -1,4 +0,0 @@
-{ inputs, ... }:
-{
-  imports = [ inputs.home-manager.nixosModule ];
-}
diff --git a/modules/nixos/common/nix.nix b/modules/nixos/common/nix.nix
deleted file mode 100644
index 146575d..0000000
--- a/modules/nixos/common/nix.nix
+++ /dev/null
@@ -1,35 +0,0 @@
-{
-  config,
-  inputs,
-  lib,
-  ...
-}:
-with lib;
-let
-  cfg = config.nixfiles.modules.common.nix;
-in
-{
-  options.nixfiles.modules.common.nix.allowedUnfreePackages = mkOption {
-    description = "A list of allowed unfree packages.";
-    type = with types; listOf str;
-    default = [ ];
-  };
-
-  config = {
-    nix = {
-      daemonCPUSchedPolicy = "idle";
-      daemonIOSchedClass = "idle";
-      daemonIOSchedPriority = 7;
-    };
-
-    nixpkgs.config.allowUnfreePredicate = p: elem (getName p) cfg.allowedUnfreePackages;
-
-    system.stateVersion = with builtins; head (split "\n" (readFile "${inputs.nixpkgs}/.version"));
-
-    environment = {
-      sessionVariables.NIX_SHELL_PRESERVE_PROMPT = "1";
-      localBinInPath = true;
-      defaultPackages = [ ];
-    };
-  };
-}
diff --git a/modules/nixos/common/secrets.nix b/modules/nixos/common/secrets.nix
deleted file mode 100644
index 31787ac..0000000
--- a/modules/nixos/common/secrets.nix
+++ /dev/null
@@ -1,4 +0,0 @@
-{ inputs, ... }:
-{
-  imports = [ inputs.agenix.nixosModules.default ];
-}
diff --git a/modules/nixos/common/shell.nix b/modules/nixos/common/shell.nix
deleted file mode 100644
index a1a7f08..0000000
--- a/modules/nixos/common/shell.nix
+++ /dev/null
@@ -1 +0,0 @@
-_: { programs.command-not-found.enable = false; }
diff --git a/modules/nixos/common/stylix.nix b/modules/nixos/common/stylix.nix
deleted file mode 100644
index 58b4f29..0000000
--- a/modules/nixos/common/stylix.nix
+++ /dev/null
@@ -1,46 +0,0 @@
-{
-  config,
-  inputs,
-  lib,
-  pkgs,
-  ...
-}:
-with lib;
-{
-  imports = [ inputs.stylix.nixosModules.stylix ];
-
-  stylix.cursor = {
-    name = "phinger-cursors-light";
-    package = pkgs.phinger-cursors;
-    size = 32;
-  };
-
-  fonts = {
-    packages = mkAfter config.nixfiles.modules.common.stylix.fonts.extraPackages;
-
-    fontconfig.defaultFonts = with config.stylix.fonts; {
-      serif = mkForce [
-        serif.name
-        "Sarasa Gothic"
-        "Source Han Serif"
-        "Noto Serif"
-      ];
-      sansSerif = mkForce [
-        sansSerif.name
-        "Sarasa Gothic"
-        "Source Han Sans"
-        "Noto Sans"
-      ];
-      monospace = mkForce [
-        monospace.name
-        "Sarasa Mono"
-        "Source Han Mono"
-        "Noto Sans Mono"
-      ];
-      emoji = mkForce [
-        "Twitter Color Emoji"
-        "Noto Color Emoji"
-      ];
-    };
-  };
-}
diff --git a/modules/nixos/common/xdg.nix b/modules/nixos/common/xdg.nix
deleted file mode 100644
index 1fe167e..0000000
--- a/modules/nixos/common/xdg.nix
+++ /dev/null
@@ -1,41 +0,0 @@
-{
-  config,
-  lib,
-  this,
-  ...
-}:
-with lib;
-let
-  cfg = config.nixfiles.modules.common.xdg;
-in
-{
-  options.nixfiles.modules.common.xdg.defaultApplications = mkOption {
-    description = "Default applications.";
-    type = with types; attrsOf (listOf str);
-    default = { };
-  };
-
-  config = {
-    xdg.portal = mkIf this.isHeadful { enable = true; };
-
-    hm.xdg = mkMerge [
-      (with cfg; {
-        enable = true;
-
-        inherit cacheHome;
-        inherit configHome;
-        inherit dataHome;
-        inherit stateHome;
-        inherit userDirs;
-      })
-      (mkIf this.isHeadful {
-        mimeApps = {
-          enable = true;
-          defaultApplications = mkMerge (
-            mapAttrsToList (n: v: genAttrs v (_: [ "${n}.desktop" ])) cfg.defaultApplications
-          );
-        };
-      })
-    ];
-  };
-}
diff --git a/modules/nixos/default.nix b/modules/nixos/default.nix
deleted file mode 100644
index 1d5e905..0000000
--- a/modules/nixos/default.nix
+++ /dev/null
@@ -1,75 +0,0 @@
-_: {
-  imports = [
-    ./acme.nix
-    ./alertmanager.nix
-    ./android.nix
-    ./beets.nix
-    ./bluetooth.nix
-    ./chromium.nix
-    ./clickhouse.nix
-    ./common
-    ./docker.nix
-    ./dwm.nix
-    ./emacs.nix
-    ./endlessh-go.nix
-    ./endlessh.nix
-    ./fail2ban.nix
-    ./firefox
-    ./foot.nix
-    ./games
-    ./git
-    ./gnupg.nix
-    ./gotify.nix
-    ./grafana.nix
-    ./hydra.nix
-    ./incus.nix
-    ./ipfs.nix
-    ./jackett.nix
-    ./k3s.nix
-    ./kde.nix
-    ./libvirtd.nix
-    ./lidarr.nix
-    ./loki.nix
-    ./matrix
-    ./monitoring
-    ./mpd.nix
-    ./mpv.nix
-    ./murmur.nix
-    ./nextcloud.nix
-    ./nginx.nix
-    ./node-exporter.nix
-    ./nsd.nix
-    ./ntfy.nix
-    ./nullmailer.nix
-    ./openssh.nix
-    ./plausible.nix
-    ./podman.nix
-    ./postgresql.nix
-    ./profiles
-    ./prometheus.nix
-    ./promtail.nix
-    ./psd.nix
-    ./radarr.nix
-    ./radicale.nix
-    ./redis.nix
-    ./rss-bridge.nix
-    ./rtorrent.nix
-    ./searx.nix
-    ./shadowsocks.nix
-    ./soju.nix
-    ./solaar.nix
-    ./sonarr.nix
-    ./sound.nix
-    ./syncthing.nix
-    ./throttled.nix
-    ./thunderbird.nix
-    ./unbound.nix
-    ./vaultwarden.nix
-    ./vim
-    ./wayland.nix
-    ./wireguard.nix
-    ./x11.nix
-    ./xmonad.nix
-    ./zathura.nix
-  ];
-}
diff --git a/modules/nixos/firefox/addons.nix b/modules/nixos/firefox/addons.nix
deleted file mode 100644
index 28235d4..0000000
--- a/modules/nixos/firefox/addons.nix
+++ /dev/null
@@ -1,1143 +0,0 @@
-{ buildFirefoxXpiAddon, lib }:
-{
-  "bitwarden" = buildFirefoxXpiAddon {
-    pname = "bitwarden";
-    version = "2024.2.1";
-    addonId = "{446900e4-71c2-419f-a6a7-df9c091e268b}";
-    url = "https://addons.mozilla.org/firefox/downloads/file/4246600/bitwarden_password_manager-2024.2.1.xpi";
-    sha256 = "f2db399e5a0915e4fd7e4906c32c72eac4a2b7bb4b4acacd892fff18e73085d4";
-    meta = with lib; {
-      homepage = "https://bitwarden.com";
-      description = "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.";
-      license = licenses.gpl3;
-      mozPermissions = [
-        "<all_urls>"
-        "tabs"
-        "contextMenus"
-        "storage"
-        "unlimitedStorage"
-        "clipboardRead"
-        "clipboardWrite"
-        "idle"
-        "http://*/*"
-        "https://*/*"
-        "webRequest"
-        "webRequestBlocking"
-        "file:///*"
-        "https://lastpass.com/export.php"
-      ];
-      platforms = platforms.all;
-    };
-  };
-  "bypass-paywalls" = buildFirefoxXpiAddon {
-    pname = "bypass-paywalls";
-    version = "3.6.0.0";
-    addonId = "magnolia_limited_permissions_d@12.34";
-    url = "https://addons.mozilla.org/firefox/downloads/file/4251818/bypass_paywalls_clean_d-3.6.0.0.xpi";
-    sha256 = "30a57df51a241838dca9360a12801ea82f2deaf76a6b63f1279235e2f5f3c939";
-    meta = with lib; {
-      homepage = "https://gitlab.com/magnolia1234/bypass-paywalls-firefox-clean";
-      description = "Bypass Paywalls";
-      license = licenses.mit;
-      mozPermissions = [
-        "cookies"
-        "storage"
-        "activeTab"
-        "webRequest"
-        "webRequestBlocking"
-        "*://*.360dx.com/*"
-        "*://*.60millions-mag.com/*"
-        "*://*.aargauerzeitung.ch/*"
-        "*://*.abc.es/*"
-        "*://*.abendblatt.de/*"
-        "*://*.abqjournal.com/*"
-        "*://*.abril.com.br/*"
-        "*://*.ad.nl/*"
-        "*://*.adage.com/*"
-        "*://*.adelaidenow.com.au/*"
-        "*://*.adweek.com/*"
-        "*://*.aerokurier.de/*"
-        "*://*.aerztezeitung.de/*"
-        "*://*.afr.com/*"
-        "*://*.ajc.com/*"
-        "*://*.al.com/*"
-        "*://*.allgemeine-zeitung.de/*"
-        "*://*.alternatives-economiques.fr/*"
-        "*://*.ambito.com/*"
-        "*://*.americanaffairsjournal.org/*"
-        "*://*.americanbanker.com/*"
-        "*://*.americastestkitchen.com/*"
-        "*://*.apollo-magazine.com/*"
-        "*://*.ara.cat/*"
-        "*://*.arabalears.cat/*"
-        "*://*.architecturaldigest.com/*"
-        "*://*.arcinfo.ch/*"
-        "*://*.artforum.com/*"
-        "*://*.artnet.com/*"
-        "*://*.artsenkrant.com/*"
-        "*://*.atavist.com/*"
-        "*://*.atlantico.fr/*"
-        "*://*.augsburger-allgemeine.de/*"
-        "*://*.auto-motor-und-sport.de/*"
-        "*://*.autocar.co.uk/*"
-        "*://*.automobilwoche.de/*"
-        "*://*.autonews.com/*"
-        "*://*.autoplus.fr/*"
-        "*://*.autosport.com/*"
-        "*://*.axios.com/*"
-        "*://*.azcentral.com/*"
-        "*://*.backpacker.com/*"
-        "*://*.balkaninsight.com/*"
-        "*://*.baltimoresun.com/*"
-        "*://*.barandbench.com/*"
-        "*://*.barrons.com/*"
-        "*://*.bd.nl/*"
-        "*://*.beleggersbelangen.nl/*"
-        "*://*.belfasttelegraph.co.uk/*"
-        "*://*.bendigoadvertiser.com.au/*"
-        "*://*.beobachter.ch/*"
-        "*://*.berliner-zeitung.de/*"
-        "*://*.berlingske.dk/*"
-        "*://*.betamtb.com/*"
-        "*://*.betternutrition.com/*"
-        "*://*.betterprogramming.pub/*"
-        "*://*.bicycling.com/*"
-        "*://*.bild.de/*"
-        "*://*.billboard.com/*"
-        "*://*.bizjournals.com/*"
-        "*://*.bloomberg.com/*"
-        "*://*.bloombergadria.com/*"
-        "*://*.bnd.com/*"
-        "*://*.bndestem.nl/*"
-        "*://*.boersen-zeitung.de/*"
-        "*://*.bonappetit.com/*"
-        "*://*.bordermail.com.au/*"
-        "*://*.bostonglobe.com/*"
-        "*://*.bostonherald.com/*"
-        "*://*.bqprime.com/*"
-        "*://*.braunschweiger-zeitung.de/*"
-        "*://*.brisbanetimes.com.au/*"
-        "*://*.britannica.com/*"
-        "*://*.buffalonews.com/*"
-        "*://*.business-standard.com/*"
-        "*://*.businessam.be/*"
-        "*://*.businessinsider.com.pl/*"
-        "*://*.businessinsider.com/*"
-        "*://*.businessinsider.nl/*"
-        "*://*.businessoffashion.com/*"
-        "*://*.businesspost.ie/*"
-        "*://*.cairnspost.com.au/*"
-        "*://*.calgaryherald.com/*"
-        "*://*.cambiocolombia.com/*"
-        "*://*.canarias7.es/*"
-        "*://*.canberratimes.com.au/*"
-        "*://*.capitalgazette.com/*"
-        "*://*.cartacapital.com.br/*"
-        "*://*.causeur.fr/*"
-        "*://*.cen.acs.org/*"
-        "*://*.centralwesterndaily.com.au/*"
-        "*://*.centrepresseaveyron.fr/*"
-        "*://*.challenges.fr/*"
-        "*://*.charentelibre.fr/*"
-        "*://*.charliehebdo.fr/*"
-        "*://*.charlotteobserver.com/*"
-        "*://*.chicagobusiness.com/*"
-        "*://*.chicagotribune.com/*"
-        "*://*.chronicle.com/*"
-        "*://*.cicero.de/*"
-        "*://*.cieletespace.fr/*"
-        "*://*.cincinnati.com/*"
-        "*://*.citywire.com/*"
-        "*://*.clarin.com/*"
-        "*://*.cleaneatingmag.com/*"
-        "*://*.cleveland.com/*"
-        "*://*.clicrbs.com.br/*"
-        "*://*.climbing.com/*"
-        "*://*.cmjornal.pt/*"
-        "*://*.cnbc.com/*"
-        "*://*.cntraveler.com/*"
-        "*://*.columbian.com/*"
-        "*://*.commentary.org/*"
-        "*://*.commercialappeal.com/*"
-        "*://*.computerweekly.com/*"
-        "*://*.connaissancedesarts.com/*"
-        "*://*.correiodopovo.com.br/*"
-        "*://*.corriere.it/*"
-        "*://*.corriereadriatico.it/*"
-        "*://*.corrieredellosport.it/*"
-        "*://*.cosmopolitan.com/*"
-        "*://*.cosmopolitan.fr/*"
-        "*://*.countryliving.com/*"
-        "*://*.courant.com/*"
-        "*://*.courier-journal.com/*"
-        "*://*.couriermail.com.au/*"
-        "*://*.courrierinternational.com/*"
-        "*://*.crainscleveland.com/*"
-        "*://*.crainsdetroit.com/*"
-        "*://*.crainsnewyork.com/*"
-        "*://*.crikey.com.au/*"
-        "*://*.cronista.com/*"
-        "*://*.crusoe.com.br/*"
-        "*://*.csmonitor.com/*"
-        "*://*.ctpost.com/*"
-        "*://*.curbed.com/*"
-        "*://*.cw.com.tw/*"
-        "*://*.dagsavisen.no/*"
-        "*://*.dailyadvertiser.com.au/*"
-        "*://*.dailyliberal.com.au/*"
-        "*://*.dailymail.co.uk/*"
-        "*://*.dailypress.com/*"
-        "*://*.dailytelegraph.com.au/*"
-        "*://*.dailywire.com/*"
-        "*://*.dallasnews.com/*"
-        "*://*.defector.com/*"
-        "*://*.delish.com/*"
-        "*://*.democratandchronicle.com/*"
-        "*://*.demorgen.be/*"
-        "*://*.denverpost.com/*"
-        "*://*.deraktionaer.de/*"
-        "*://*.desmoinesregister.com/*"
-        "*://*.destentor.nl/*"
-        "*://*.detroitnews.com/*"
-        "*://*.df.cl/*"
-        "*://*.dhnet.be/*"
-        "*://*.di.se/*"
-        "*://*.diariocorreo.pe/*"
-        "*://*.diariodemallorca.es/*"
-        "*://*.diariosur.es/*"
-        "*://*.diariovasco.com/*"
-        "*://*.diepresse.com/*"
-        "*://*.digiday.com/*"
-        "*://*.discovermagazine.com/*"
-        "*://*.dispatch.com/*"
-        "*://*.doorbraak.be/*"
-        "*://*.dvhn.nl/*"
-        "*://*.dwell.com/*"
-        "*://*.eastbaytimes.com/*"
-        "*://*.eastwest.eu/*"
-        "*://*.echo-online.de/*"
-        "*://*.economictimes.com/*"
-        "*://*.economist.com/*"
-        "*://*.ed.nl/*"
-        "*://*.editorialedomani.it/*"
-        "*://*.elcomercio.es/*"
-        "*://*.elcomercio.pe/*"
-        "*://*.elconfidencial.com/*"
-        "*://*.elcorreo.com/*"
-        "*://*.eldia.es/*"
-        "*://*.eldiario.es/*"
-        "*://*.eldiariomontanes.es/*"
-        "*://*.elespanol.com/*"
-        "*://*.elespectador.com/*"
-        "*://*.elle.com/*"
-        "*://*.elle.fr/*"
-        "*://*.elledecor.com/*"
-        "*://*.elmercurio.com/*"
-        "*://*.elmundo.es/*"
-        "*://*.elnortedecastilla.es/*"
-        "*://*.elnuevoherald.com/*"
-        "*://*.elobservador.com.uy/*"
-        "*://*.elpais.com.uy/*"
-        "*://*.elpais.com/*"
-        "*://*.elperiodico.com/*"
-        "*://*.eltiempo.com/*"
-        "*://*.eltribuno.com/*"
-        "*://*.em.com.br/*"
-        "*://*.enotes.com/*"
-        "*://*.epe.es/*"
-        "*://*.epicurious.com/*"
-        "*://*.epoch.org.il/*"
-        "*://*.espn.com/*"
-        "*://*.esprit.presse.fr/*"
-        "*://*.esquire.com/*"
-        "*://*.estadao.com.br/*"
-        "*://*.etc.se/*"
-        "*://*.euobserver.com/*"
-        "*://*.european-rubber-journal.com/*"
-        "*://*.europower.no/*"
-        "*://*.exame.com/*"
-        "*://*.examiner.com.au/*"
-        "*://*.expansion.com/*"
-        "*://*.expressnews.com/*"
-        "*://*.expresso.pt/*"
-        "*://*.farodevigo.es/*"
-        "*://*.fastcompany.com/*"
-        "*://*.faz.net/*"
-        "*://*.fd.nl/*"
-        "*://*.femmesdaujourdhui.be/*"
-        "*://*.fieldandstream.com/*"
-        "*://*.financialexpress.com/*"
-        "*://*.financialpost.com/*"
-        "*://*.firstthings.com/*"
-        "*://*.fiskeribladet.no/*"
-        "*://*.flair.be/*"
-        "*://*.flair.nl/*"
-        "*://*.flugrevue.de/*"
-        "*://*.fnlondon.com/*"
-        "*://*.forbes.com.au/*"
-        "*://*.forbes.com/*"
-        "*://*.foreignaffairs.com/*"
-        "*://*.foreignpolicy.com/*"
-        "*://*.fortune.com/*"
-        "*://*.foxnews.com/*"
-        "*://*.freep.com/*"
-        "*://*.freiepresse.de/*"
-        "*://*.freitag.de/*"
-        "*://*.fresnobee.com/*"
-        "*://*.ft.com/*"
-        "*://*.ftm.eu/*"
-        "*://*.ftm.nl/*"
-        "*://*.gazetadopovo.com.br/*"
-        "*://*.gazzetta.it/*"
-        "*://*.gbnews.com/*"
-        "*://*.geelongadvertiser.com.au/*"
-        "*://*.gelderlander.nl/*"
-        "*://*.genomeweb.com/*"
-        "*://*.gestion.pe/*"
-        "*://*.glassdoor.com/*"
-        "*://*.globes.co.il/*"
-        "*://*.globo.com/*"
-        "*://*.glossy.co/*"
-        "*://*.goldcoastbulletin.com.au/*"
-        "*://*.goodhousekeeping.com/*"
-        "*://*.gq.com/*"
-        "*://*.granta.com/*"
-        "*://*.groene.nl/*"
-        "*://*.grubstreet.com/*"
-        "*://*.haaretz.co.il/*"
-        "*://*.haaretz.com/*"
-        "*://*.handelszeitung.ch/*"
-        "*://*.harpers.org/*"
-        "*://*.harpersbazaar.com/*"
-        "*://*.haz.de/*"
-        "*://*.hbr.org/*"
-        "*://*.hbvl.be/*"
-        "*://*.heraldsun.com.au/*"
-        "*://*.hilltimes.com/*"
-        "*://*.hindustantimes.com/*"
-        "*://*.hindutamil.in/*"
-        "*://*.historyextra.com/*"
-        "*://*.hln.be/*"
-        "*://*.housebeautiful.com/*"
-        "*://*.houstonchronicle.com/*"
-        "*://*.hoy.es/*"
-        "*://*.huffingtonpost.it/*"
-        "*://*.humanite.fr/*"
-        "*://*.humo.be/*"
-        "*://*.ideal.es/*"
-        "*://*.ilfattoquotidiano.it/*"
-        "*://*.ilfoglio.it/*"
-        "*://*.ilgazzettino.it/*"
-        "*://*.ilgiorno.it/*"
-        "*://*.illawarramercury.com.au/*"
-        "*://*.ilmanifesto.it/*"
-        "*://*.ilmattino.it/*"
-        "*://*.ilmessaggero.it/*"
-        "*://*.ilrestodelcarlino.it/*"
-        "*://*.ilsecoloxix.it/*"
-        "*://*.ilsole24ore.com/*"
-        "*://*.iltelegrafolivorno.it/*"
-        "*://*.iltirreno.it/*"
-        "*://*.inc.com/*"
-        "*://*.inc42.com/*"
-        "*://*.independent.co.uk/*"
-        "*://*.independent.ie/*"
-        "*://*.indianexpress.com/*"
-        "*://*.indiatimes.com/*"
-        "*://*.indiatoday.in/*"
-        "*://*.indystar.com/*"
-        "*://*.inews.co.uk/*"
-        "*://*.informacion.es/*"
-        "*://*.infzm.com/*"
-        "*://*.inkl.com/*"
-        "*://*.inquirer.com/*"
-        "*://*.insidehighered.com/*"
-        "*://*.intelligentinvestor.com.au/*"
-        "*://*.interestingengineering.com/*"
-        "*://*.internazionale.it/*"
-        "*://*.intrafish.com/*"
-        "*://*.intrafish.no/*"
-        "*://*.investorschronicle.co.uk/*"
-        "*://*.investsmart.com.au/*"
-        "*://*.ipolitics.ca/*"
-        "*://*.irishexaminer.com/*"
-        "*://*.irishtimes.com/*"
-        "*://*.italian.tech/*"
-        "*://*.italiaoggi.it/*"
-        "*://*.jacksonville.com/*"
-        "*://*.jacobin.de/*"
-        "*://*.janes.com/*"
-        "*://*.japantimes.co.jp/*"
-        "*://*.jazziz.com/*"
-        "*://*.jazzwise.com/*"
-        "*://*.jgnt.co/*"
-        "*://*.journaldemillau.fr/*"
-        "*://*.journaldemontreal.com/*"
-        "*://*.journaldequebec.com/*"
-        "*://*.journaldunet.com/*"
-        "*://*.journalnow.com/*"
-        "*://*.journalstar.com/*"
-        "*://*.jpost.com/*"
-        "*://*.jsonline.com/*"
-        "*://*.kansas.com/*"
-        "*://*.kansascity.com/*"
-        "*://*.kentucky.com/*"
-        "*://*.kn-online.de/*"
-        "*://*.knack.be/*"
-        "*://*.knoxnews.com/*"
-        "*://*.krautreporter.de/*"
-        "*://*.ksta.de/*"
-        "*://*.kurier.at/*"
-        "*://*.kw.be/*"
-        "*://*.la-croix.com/*"
-        "*://*.labusinessjournal.com/*"
-        "*://*.lacote.ch/*"
-        "*://*.ladepeche.fr/*"
-        "*://*.ladiaria.com.uy/*"
-        "*://*.lalibre.be/*"
-        "*://*.lamontagne.fr/*"
-        "*://*.lanacion.com.ar/*"
-        "*://*.lanazione.it/*"
-        "*://*.lanouvellerepublique.fr/*"
-        "*://*.lanuovasardegna.it/*"
-        "*://*.laprovincia.es/*"
-        "*://*.larepubliquedespyrenees.fr/*"
-        "*://*.larioja.com/*"
-        "*://*.lasegunda.com/*"
-        "*://*.lasprovincias.es/*"
-        "*://*.lastampa.it/*"
-        "*://*.latercera.com/*"
-        "*://*.latimes.com/*"
-        "*://*.latribune.fr/*"
-        "*://*.lavanguardia.com/*"
-        "*://*.lavenir.net/*"
-        "*://*.laverdad.es/*"
-        "*://*.lavoz.com.ar/*"
-        "*://*.lavozdigital.es/*"
-        "*://*.law.com/*"
-        "*://*.lc.nl/*"
-        "*://*.lecho.be/*"
-        "*://*.lecourrierdesstrateges.fr/*"
-        "*://*.ledevoir.com/*"
-        "*://*.legrandcontinent.eu/*"
-        "*://*.lehighvalleylive.com/*"
-        "*://*.lejdd.fr/*"
-        "*://*.lemagit.fr/*"
-        "*://*.lemoniteur.fr/*"
-        "*://*.lenouveleconomiste.fr/*"
-        "*://*.lenouvelliste.ch/*"
-        "*://*.leparisien.fr/*"
-        "*://*.lepoint.fr/*"
-        "*://*.lescienze.it/*"
-        "*://*.lesechos.fr/*"
-        "*://*.lesinrocks.com/*"
-        "*://*.lesoleil.com/*"
-        "*://*.letelegramme.fr/*"
-        "*://*.levante-emv.com/*"
-        "*://*.levif.be/*"
-        "*://*.lexpress.fr/*"
-        "*://*.libelle.be/*"
-        "*://*.libelle.nl/*"
-        "*://*.limburger.nl/*"
-        "*://*.lindependant.fr/*"
-        "*://*.linforme.com/*"
-        "*://*.literaryreview.co.uk/*"
-        "*://*.livelaw.in/*"
-        "*://*.livemint.com/*"
-        "*://*.ln-online.de/*"
-        "*://*.lne.es/*"
-        "*://*.loebclassics.com/*"
-        "*://*.loeildelaphotographie.com/*"
-        "*://*.lopinion.fr/*"
-        "*://*.losandes.com.ar/*"
-        "*://*.lrb.co.uk/*"
-        "*://*.luzernerzeitung.ch/*"
-        "*://*.lvz.de/*"
-        "*://*.macrobusiness.com.au/*"
-        "*://*.madison.com/*"
-        "*://*.mainichi.jp/*"
-        "*://*.mallorcazeitung.es/*"
-        "*://*.mannheimer-morgen.de/*"
-        "*://*.marca.com/*"
-        "*://*.margriet.nl/*"
-        "*://*.marianne.net/*"
-        "*://*.marketwatch.com/*"
-        "*://*.masslive.com/*"
-        "*://*.maz-online.de/*"
-        "*://*.mcall.com/*"
-        "*://*.mcclatchydc.com/*"
-        "*://*.medium.com/*"
-        "*://*.medscape.com/*"
-        "*://*.menshealth.com/*"
-        "*://*.mercurynews.com/*"
-        "*://*.mexiconewsdaily.com/*"
-        "*://*.miamiherald.com/*"
-        "*://*.mid-day.com/*"
-        "*://*.midilibre.fr/*"
-        "*://*.mlive.com/*"
-        "*://*.moda.it/*"
-        "*://*.modernhealthcare.com/*"
-        "*://*.modernretail.co/*"
-        "*://*.monacomatin.mc/*"
-        "*://*.monocle.com/*"
-        "*://*.morgenpost.de/*"
-        "*://*.motorradonline.de/*"
-        "*://*.mundodeportivo.com/*"
-        "*://*.mv-voice.com/*"
-        "*://*.mz.de/*"
-        "*://*.nationalgeographic.com/*"
-        "*://*.nationalpost.com/*"
-        "*://*.nationalreview.com/*"
-        "*://*.nautil.us/*"
-        "*://*.neuepresse.de/*"
-        "*://*.newcastleherald.com.au/*"
-        "*://*.newleftreview.org/*"
-        "*://*.newrepublic.com/*"
-        "*://*.news-press.com/*"
-        "*://*.newscientist.com/*"
-        "*://*.newsday.com/*"
-        "*://*.newsobserver.com/*"
-        "*://*.newstatesman.com/*"
-        "*://*.newsweek.com/*"
-        "*://*.newsweek.pl/*"
-        "*://*.newyorker.com/*"
-        "*://*.nhregister.com/*"
-        "*://*.niagarafallsreview.ca/*"
-        "*://*.nicematin.com/*"
-        "*://*.nieuwsblad.be/*"
-        "*://*.nikkei.com/*"
-        "*://*.nj.com/*"
-        "*://*.nola.com/*"
-        "*://*.northerndailyleader.com.au/*"
-        "*://*.northjersey.com/*"
-        "*://*.nouvelobs.com/*"
-        "*://*.noz.de/*"
-        "*://*.nrc.nl/*"
-        "*://*.nrpyrenees.fr/*"
-        "*://*.nrz.de/*"
-        "*://*.ntnews.com.au/*"
-        "*://*.nw.de/*"
-        "*://*.nwitimes.com/*"
-        "*://*.nybooks.com/*"
-        "*://*.nydailynews.com/*"
-        "*://*.nymag.com/*"
-        "*://*.nypost.com/*"
-        "*://*.nysun.com/*"
-        "*://*.nyteknik.se/*"
-        "*://*.nytimes.com/*"
-        "*://*.nzherald.co.nz/*"
-        "*://*.nzz.ch/*"
-        "*://*.observador.pt/*"
-        "*://*.ocbj.com/*"
-        "*://*.ocregister.com/*"
-        "*://*.oklahoman.com/*"
-        "*://*.omaha.com/*"
-        "*://*.oprahdaily.com/*"
-        "*://*.oregonlive.com/*"
-        "*://*.orlandosentinel.com/*"
-        "*://*.ostsee-zeitung.de/*"
-        "*://*.otz.de/*"
-        "*://*.outdoorlife.com/*"
-        "*://*.outlookbusiness.com/*"
-        "*://*.outlookindia.com/*"
-        "*://*.outsideonline.com/*"
-        "*://*.oxygenmag.com/*"
-        "*://*.paloaltoonline.com/*"
-        "*://*.parismatch.com/*"
-        "*://*.parool.nl/*"
-        "*://*.penews.com/*"
-        "*://*.pennlive.com/*"
-        "*://*.petitbleu.fr/*"
-        "*://*.philanthropy.com/*"
-        "*://*.philomag.com/*"
-        "*://*.philomag.de/*"
-        "*://*.philosophynow.org/*"
-        "*://*.pilotonline.com/*"
-        "*://*.pionline.com/*"
-        "*://*.piqd.de/*"
-        "*://*.plasticsnews.com/*"
-        "*://*.politicaexterior.com/*"
-        "*://*.polityka.pl/*"
-        "*://*.popsci.com/*"
-        "*://*.popularmechanics.com/*"
-        "*://*.post-gazette.com/*"
-        "*://*.pourlascience.fr/*"
-        "*://*.pourleco.com/*"
-        "*://*.precisionmedicineonline.com/*"
-        "*://*.pressenterprise.com/*"
-        "*://*.prevention.com/*"
-        "*://*.profi.de/*"
-        "*://*.profil.at/*"
-        "*://*.project-syndicate.org/*"
-        "*://*.prospectmagazine.co.uk/*"
-        "*://*.public.fr/*"
-        "*://*.pzc.nl/*"
-        "*://*.quora.com/*"
-        "*://*.quotidiano.net/*"
-        "*://*.quotidianodipuglia.it/*"
-        "*://*.qz.com/*"
-        "*://*.rechargenews.com/*"
-        "*://*.record.pt/*"
-        "*://*.repubblica.it/*"
-        "*://*.reuters.com/*"
-        "*://*.revistaoeste.com/*"
-        "*://*.revueconflits.com/*"
-        "*://*.rhein-zeitung.de/*"
-        "*://*.richmond.com/*"
-        "*://*.rnd.de/*"
-        "*://*.roadandtrack.com/*"
-        "*://*.rollingstone.com/*"
-        "*://*.rp.pl/*"
-        "*://*.rubbernews.com/*"
-        "*://*.rugbypass.com/*"
-        "*://*.rugbyrama.fr/*"
-        "*://*.ruhrnachrichten.de/*"
-        "*://*.rundschau-online.de/*"
-        "*://*.runnersworld.com/*"
-        "*://*.sabado.pt/*"
-        "*://*.sacbee.com/*"
-        "*://*.saltwire.com/*"
-        "*://*.sandiegouniontribune.com/*"
-        "*://*.schwaebische.de/*"
-        "*://*.schwarzwaelder-bote.de/*"
-        "*://*.schweizermonat.ch/*"
-        "*://*.science-et-vie.com/*"
-        "*://*.science.org/*"
-        "*://*.sciencesetavenir.fr/*"
-        "*://*.scientificamerican.com/*"
-        "*://*.scmp.com/*"
-        "*://*.scotsman.com/*"
-        "*://*.sdbj.com/*"
-        "*://*.seattletimes.com/*"
-        "*://*.seekingalpha.com/*"
-        "*://*.sfchronicle.com/*"
-        "*://*.sfvbj.com/*"
-        "*://*.shz.de/*"
-        "*://*.si.com/*"
-        "*://*.silive.com/*"
-        "*://*.skimag.com/*"
-        "*://*.slate.com/*"
-        "*://*.slideshare.net/*"
-        "*://*.sloanreview.mit.edu/*"
-        "*://*.sltrib.com/*"
-        "*://*.smh.com.au/*"
-        "*://*.sn.at/*"
-        "*://*.sofrep.com/*"
-        "*://*.sourcingjournal.com/*"
-        "*://*.spectator.co.uk/*"
-        "*://*.spectator.com.au/*"
-        "*://*.spglobal.com/*"
-        "*://*.spiegel.de/*"
-        "*://*.sportico.com/*"
-        "*://*.springermedizin.de/*"
-        "*://*.standaard.be/*"
-        "*://*.standard.co.uk/*"
-        "*://*.standard.net.au/*"
-        "*://*.star-telegram.com/*"
-        "*://*.staradvertiser.com/*"
-        "*://*.startribune.com/*"
-        "*://*.statesman.com/*"
-        "*://*.statista.com/*"
-        "*://*.stcatharinesstandard.ca/*"
-        "*://*.stereogum.com/*"
-        "*://*.stltoday.com/*"
-        "*://*.stocknews.com/*"
-        "*://*.straitstimes.com/*"
-        "*://*.stratfor.com/*"
-        "*://*.studocu.com/*"
-        "*://*.study.com/*"
-        "*://*.stuttgarter-nachrichten.de/*"
-        "*://*.stuttgarter-zeitung.de/*"
-        "*://*.stylist.co.uk/*"
-        "*://*.sudouest.fr/*"
-        "*://*.sueddeutsche.de/*"
-        "*://*.suedkurier.de/*"
-        "*://*.sun-sentinel.com/*"
-        "*://*.suomensotilas.fi/*"
-        "*://*.sustainableplastics.com/*"
-        "*://*.svz.de/*"
-        "*://*.swarajyamag.com/*"
-        "*://*.syracuse.com/*"
-        "*://*.tagblatt.ch/*"
-        "*://*.tagesspiegel.de/*"
-        "*://*.tampabay.com/*"
-        "*://*.techinasia.com/*"
-        "*://*.technologyreview.com/*"
-        "*://*.techtarget.com/*"
-        "*://*.telegraaf.nl/*"
-        "*://*.telegraph.co.uk/*"
-        "*://*.telerama.fr/*"
-        "*://*.tennessean.com/*"
-        "*://*.tes.com/*"
-        "*://*.texasmonthly.com/*"
-        "*://*.the-american-interest.com/*"
-        "*://*.the-scientist.com/*"
-        "*://*.the-tls.co.uk/*"
-        "*://*.theadvocate.com.au/*"
-        "*://*.theadvocate.com/*"
-        "*://*.theage.com.au/*"
-        "*://*.theamericanconservative.com/*"
-        "*://*.theartnewspaper.com/*"
-        "*://*.theathletic.com/*"
-        "*://*.theatlantic.com/*"
-        "*://*.theaustralian.com.au/*"
-        "*://*.thebaffler.com/*"
-        "*://*.thebanker.com/*"
-        "*://*.thebookseller.com/*"
-        "*://*.thebulletin.org/*"
-        "*://*.thechronicle.com.au/*"
-        "*://*.thecourier.com.au/*"
-        "*://*.thecritic.co.uk/*"
-        "*://*.thecut.com/*"
-        "*://*.thedailybeast.com/*"
-        "*://*.thediplomat.com/*"
-        "*://*.theepochtimes.com/*"
-        "*://*.theglobeandmail.com/*"
-        "*://*.thehill.com/*"
-        "*://*.thehindu.com/*"
-        "*://*.thehindubusinessline.com/*"
-        "*://*.theimpression.com/*"
-        "*://*.theintercept.com/*"
-        "*://*.thejuggernaut.com/*"
-        "*://*.thelampmagazine.com/*"
-        "*://*.thelawyersdaily.ca/*"
-        "*://*.themarker.com/*"
-        "*://*.themarket.ch/*"
-        "*://*.themercury.com.au/*"
-        "*://*.thenation.com/*"
-        "*://*.thenewatlantis.com/*"
-        "*://*.theneweuropean.co.uk/*"
-        "*://*.thenewsminute.com/*"
-        "*://*.thepeterboroughexaminer.com/*"
-        "*://*.thepointmag.com/*"
-        "*://*.theprovince.com/*"
-        "*://*.thequint.com/*"
-        "*://*.therecord.com/*"
-        "*://*.thesaturdaypaper.com.au/*"
-        "*://*.thespec.com/*"
-        "*://*.thespectator.com/*"
-        "*://*.thestage.co.uk/*"
-        "*://*.thestar.com/*"
-        "*://*.thestate.com/*"
-        "*://*.thetimes.co.uk/*"
-        "*://*.theverge.com/*"
-        "*://*.theweek.com/*"
-        "*://*.thewest.com.au/*"
-        "*://*.thewrap.com/*"
-        "*://*.thueringer-allgemeine.de/*"
-        "*://*.tijd.be/*"
-        "*://*.timeshighereducation.com/*"
-        "*://*.timesofindia.com/*"
-        "*://*.timesunion.com/*"
-        "*://*.tirebusiness.com/*"
-        "*://*.tlz.de/*"
-        "*://*.topagrar.com/*"
-        "*://*.torontosun.com/*"
-        "*://*.towardsdatascience.com/*"
-        "*://*.townandcountrymag.com/*"
-        "*://*.townsvillebulletin.com.au/*"
-        "*://*.tradewindsnews.com/*"
-        "*://*.trailrunnermag.com/*"
-        "*://*.tri-cityherald.com/*"
-        "*://*.triathlete.com/*"
-        "*://*.trouw.nl/*"
-        "*://*.tt.com/*"
-        "*://*.tubantia.nl/*"
-        "*://*.tucson.com/*"
-        "*://*.tulsaworld.com/*"
-        "*://*.tuttosport.com/*"
-        "*://*.twincities.com/*"
-        "*://*.unherd.com/*"
-        "*://*.uol.com.br/*"
-        "*://*.upstreamonline.com/*"
-        "*://*.usatoday.com/*"
-        "*://*.usinenouvelle.com/*"
-        "*://*.utech-polyurethane.com/*"
-        "*://*.valeursactuelles.com/*"
-        "*://*.vancouversun.com/*"
-        "*://*.vanityfair.com/*"
-        "*://*.variety.com/*"
-        "*://*.varmatin.com/*"
-        "*://*.vegetariantimes.com/*"
-        "*://*.vikatan.com/*"
-        "*://*.vn.at/*"
-        "*://*.vn.nl/*"
-        "*://*.vogue.co.uk/*"
-        "*://*.vogue.com/*"
-        "*://*.voguebusiness.com/*"
-        "*://*.vol.at/*"
-        "*://*.volkskrant.nl/*"
-        "*://*.volksstimme.de/*"
-        "*://*.vulture.com/*"
-        "*://*.washingtonexaminer.com/*"
-        "*://*.washingtonpost.com/*"
-        "*://*.watoday.com.au/*"
-        "*://*.waz.de/*"
-        "*://*.weeklytimesnow.com.au/*"
-        "*://*.wellandtribune.ca/*"
-        "*://*.welt.de/*"
-        "*://*.weltkunst.de/*"
-        "*://*.weser-kurier.de/*"
-        "*://*.westernadvocate.com.au/*"
-        "*://*.wiesbadener-kurier.de/*"
-        "*://*.winnipegfreepress.com/*"
-        "*://*.wired.com/*"
-        "*://*.wiwo.de/*"
-        "*://*.wochenblatt.com/*"
-        "*://*.womenshealth.de/*"
-        "*://*.womenshealthmag.com/*"
-        "*://*.womensrunning.com/*"
-        "*://*.wonderzine.com/*"
-        "*://*.wp.de/*"
-        "*://*.wr.de/*"
-        "*://*.wsj.com/*"
-        "*://*.wwd.com/*"
-        "*://*.ynet.co.il/*"
-        "*://*.yogajournal.com/*"
-        "*://*.yorkshirepost.co.uk/*"
-        "*://*.zeit.de/*"
-        "*://*.zerohedge.com/*"
-        "*://*.amplitude.com/*"
-        "*://*.ampproject.org/*"
-        "*://*.axate.io/*"
-        "*://*.blueconic.net/*"
-        "*://*.cxense.com/*"
-        "*://*.ensighten.com/*"
-        "*://*.evolok.net/*"
-        "*://*.fewcents.co/*"
-        "*://*.ippen.space/*"
-        "*://*.loader-cdn.azureedge.net/*"
-        "*://*.matheranalytics.com/*"
-        "*://*.newsmemory.com/*"
-        "*://*.omeda.com/*"
-        "*://*.onecount.net/*"
-        "*://*.pelcro.com/*"
-        "*://*.piano.io/*"
-        "*://*.pico.tools/*"
-        "*://*.poool.fr/*"
-        "*://*.qiota.com/*"
-        "*://*.sophi.io/*"
-        "*://*.steadyhq.com/*"
-        "*://*.tinypass.com/*"
-        "*://*.weborama.fr/*"
-        "*://*.zephr.com/*"
-        "*://*.blink.net/*"
-        "*://*.bwbx.io/*"
-        "*://*.californiatimes.com/*"
-        "*://*.cedscdn.it/*"
-        "*://*.cedsdigital.it/*"
-        "*://*.cloudfront.net/*"
-        "*://*.corriereobjects.it/*"
-        "*://*.emol.cl/*"
-        "*://*.epochbase.com/*"
-        "*://*.epochbase.eu/*"
-        "*://*.flip-pay.com/*"
-        "*://*.gitlab.com/magnolia1234/*"
-        "*://*.go.com/*"
-        "*://*.hadrianpaywall.com/*"
-        "*://*.kinja-static.com/*"
-        "*://*.masthead.me/*"
-        "*://*.medscapestatic.com/*"
-        "*://*.ndcmediagroep.nl/*"
-        "*://*.nhst.tech/*"
-        "*://*.nyt.com/*"
-        "*://*.pasedigital.cl/*"
-        "*://*.wbmdstatic.com/*"
-        "*://*.wgchrrammzv.com/*"
-        "*://*.wyleex.com/*"
-        "*://archive.fo/*"
-        "*://archive.is/*"
-        "*://archive.li/*"
-        "*://archive.md/*"
-        "*://archive.ph/*"
-        "*://archive.vn/*"
-        "*://webcache.googleusercontent.com/*"
-        "*://*.gitlab.com/magnolia1234"
-      ];
-      platforms = platforms.all;
-    };
-  };
-  "consent-o-matic" = buildFirefoxXpiAddon {
-    pname = "consent-o-matic";
-    version = "1.0.13";
-    addonId = "gdpr@cavi.au.dk";
-    url = "https://addons.mozilla.org/firefox/downloads/file/4246350/consent_o_matic-1.0.13.xpi";
-    sha256 = "ee577eaedebd9fef65f77218b86c59972818442c9af551d551a7015a4a246e9a";
-    meta = with lib; {
-      homepage = "https://consentomatic.au.dk/";
-      description = "Automatic handling of GDPR consent forms";
-      license = licenses.mit;
-      mozPermissions = [
-        "activeTab"
-        "tabs"
-        "storage"
-        "<all_urls>"
-      ];
-      platforms = platforms.all;
-    };
-  };
-  "darkreader" = buildFirefoxXpiAddon {
-    pname = "darkreader";
-    version = "4.9.80";
-    addonId = "addon@darkreader.org";
-    url = "https://addons.mozilla.org/firefox/downloads/file/4249607/darkreader-4.9.80.xpi";
-    sha256 = "a93f1250b72cc27fe4a9b02be062c68fb079e45a1233d562852b48e1e9b99307";
-    meta = with lib; {
-      homepage = "https://darkreader.org/";
-      description = "Dark mode for every website. Take care of your eyes, use dark theme for night and daily browsing.";
-      license = licenses.mit;
-      mozPermissions = [
-        "alarms"
-        "contextMenus"
-        "storage"
-        "tabs"
-        "theme"
-        "<all_urls>"
-      ];
-      platforms = platforms.all;
-    };
-  };
-  "furiganaize" = buildFirefoxXpiAddon {
-    pname = "furiganaize";
-    version = "0.7.2";
-    addonId = "{a2503cd4-4083-4c2f-bef2-37767a569867}";
-    url = "https://addons.mozilla.org/firefox/downloads/file/4032306/furiganaize-0.7.2.xpi";
-    sha256 = "7545bc418f2afbc576b0e762f2b2fa0545d5d94f3f80737e5356d087a5951c0b";
-    meta = with lib; {
-      homepage = "https://github.com/kuanyui/Furiganaize";
-      description = "Auto insert furigana (振り仮名) on Japanese kanji.";
-      license = licenses.mit;
-      mozPermissions = [
-        "http://*/*"
-        "https://*/*"
-        "file://*/*"
-        "<all_urls>"
-        "activeTab"
-        "tabs"
-        "storage"
-      ];
-      platforms = platforms.all;
-    };
-  };
-  "ipfs-companion" = buildFirefoxXpiAddon {
-    pname = "ipfs-companion";
-    version = "3.1.0";
-    addonId = "ipfs-firefox-addon@lidel.org";
-    url = "https://addons.mozilla.org/firefox/downloads/file/4172699/ipfs_companion-3.1.0.xpi";
-    sha256 = "784f6d1e0497d86f1e42cfe7de8548b5cc28fabe80e50771d90f59ddf1b9d3c1";
-    meta = with lib; {
-      homepage = "https://github.com/ipfs/ipfs-companion";
-      description = "Harness the power of IPFS in your browser";
-      license = licenses.cc0;
-      mozPermissions = [
-        "idle"
-        "tabs"
-        "notifications"
-        "proxy"
-        "storage"
-        "unlimitedStorage"
-        "contextMenus"
-        "clipboardWrite"
-        "webNavigation"
-        "webRequest"
-        "webRequestBlocking"
-      ];
-      platforms = platforms.all;
-    };
-  };
-  "languagetool" = buildFirefoxXpiAddon {
-    pname = "languagetool";
-    version = "8.6.0";
-    addonId = "languagetool-webextension@languagetool.org";
-    url = "https://addons.mozilla.org/firefox/downloads/file/4249956/languagetool-8.6.0.xpi";
-    sha256 = "d9db9aac9fdd53eb39179c153161762cd9e9eb1f6d7da8e8b8a32238b4847094";
-    meta = with lib; {
-      homepage = "https://languagetool.org";
-      description = "With this extension you can check text with the free style and grammar checker LanguageTool. It finds many errors that a simple spell checker cannot detect, like mixing up there/their, a/an, or repeating a word.";
-      mozPermissions = [
-        "activeTab"
-        "storage"
-        "contextMenus"
-        "alarms"
-        "http://*/*"
-        "https://*/*"
-        "file:///*"
-        "*://docs.google.com/document/*"
-        "*://languagetool.org/*"
-      ];
-      platforms = platforms.all;
-    };
-  };
-  "no-pdf-download" = buildFirefoxXpiAddon {
-    pname = "no-pdf-download";
-    version = "1.0.6";
-    addonId = "{b9b25e4a-bdf4-4270-868c-3f619eaf437d}";
-    url = "https://addons.mozilla.org/firefox/downloads/file/3020560/no_pdf_download-1.0.6.xpi";
-    sha256 = "fa27b6729178a23ccf2eee07cd7650d841fc6040f2e5adfb919931b671ed79e6";
-    meta = with lib; {
-      homepage = "https://github.com/MorbZ/no-pdf-download";
-      description = "Opens all PDF files directly in the browser.";
-      license = licenses.mit;
-      mozPermissions = [
-        "webRequest"
-        "webRequestBlocking"
-        "<all_urls>"
-      ];
-      platforms = platforms.all;
-    };
-  };
-  "redirector" = buildFirefoxXpiAddon {
-    pname = "redirector";
-    version = "3.5.3";
-    addonId = "redirector@einaregilsson.com";
-    url = "https://addons.mozilla.org/firefox/downloads/file/3535009/redirector-3.5.3.xpi";
-    sha256 = "eddbd3d5944e748d0bd6ecb6d9e9cf0e0c02dced6f42db21aab64190e71c0f71";
-    meta = with lib; {
-      homepage = "http://einaregilsson.com/redirector/";
-      description = "Automatically redirects to user-defined urls on certain pages";
-      license = licenses.mit;
-      mozPermissions = [
-        "webRequest"
-        "webRequestBlocking"
-        "webNavigation"
-        "storage"
-        "tabs"
-        "http://*/*"
-        "https://*/*"
-        "notifications"
-      ];
-      platforms = platforms.all;
-    };
-  };
-  "rikaichamp" = buildFirefoxXpiAddon {
-    pname = "rikaichamp";
-    version = "1.18.0";
-    addonId = "{59812185-ea92-4cca-8ab7-cfcacee81281}";
-    url = "https://addons.mozilla.org/firefox/downloads/file/4241410/10ten_ja_reader-1.18.0.xpi";
-    sha256 = "5433bcfec5a327bf1fa198b3f0645a9cdcdc44232465ad940fa8a5858b6996f8";
-    meta = with lib; {
-      homepage = "https://github.com/birchill/10ten-ja-reader/";
-      description = "Quickly translate Japanese by hovering over words. Formerly released as Rikaichamp.";
-      license = licenses.gpl3;
-      mozPermissions = [
-        "alarms"
-        "clipboardWrite"
-        "contextMenus"
-        "storage"
-        "unlimitedStorage"
-        "http://*/*"
-        "https://*/*"
-        "file:///*"
-        "https://docs.google.com/*"
-      ];
-      platforms = platforms.all;
-    };
-  };
-  "skip-redirect" = buildFirefoxXpiAddon {
-    pname = "skip-redirect";
-    version = "2.3.6";
-    addonId = "skipredirect@sblask";
-    url = "https://addons.mozilla.org/firefox/downloads/file/3920533/skip_redirect-2.3.6.xpi";
-    sha256 = "dbe8950245c1f475c5c1c6daab89c79b83ba4680621c91e80f15be7b09b618ae";
-    meta = with lib; {
-      description = "Some web pages use intermediary pages before redirecting to a final page. This add-on tries to extract the final url from the intermediary url and goes there straight away if successful.";
-      license = licenses.mit;
-      mozPermissions = [
-        "<all_urls>"
-        "clipboardWrite"
-        "contextMenus"
-        "notifications"
-        "storage"
-        "webRequest"
-        "webRequestBlocking"
-      ];
-      platforms = platforms.all;
-    };
-  };
-  "ublock-origin" = buildFirefoxXpiAddon {
-    pname = "ublock-origin";
-    version = "1.56.0";
-    addonId = "uBlock0@raymondhill.net";
-    url = "https://addons.mozilla.org/firefox/downloads/file/4237670/ublock_origin-1.56.0.xpi";
-    sha256 = "f5fbeeac511ca4e10a74723413727fda8e6f9236c726d16eb54ade1fbe7be5be";
-    meta = with lib; {
-      homepage = "https://github.com/gorhill/uBlock#ublock-origin";
-      description = "Finally, an efficient wide-spectrum content blocker. Easy on CPU and memory.";
-      license = licenses.gpl3;
-      mozPermissions = [
-        "alarms"
-        "dns"
-        "menus"
-        "privacy"
-        "storage"
-        "tabs"
-        "unlimitedStorage"
-        "webNavigation"
-        "webRequest"
-        "webRequestBlocking"
-        "<all_urls>"
-        "http://*/*"
-        "https://*/*"
-        "file://*/*"
-        "https://easylist.to/*"
-        "https://*.fanboy.co.nz/*"
-        "https://filterlists.com/*"
-        "https://forums.lanik.us/*"
-        "https://github.com/*"
-        "https://*.github.io/*"
-        "https://*.letsblock.it/*"
-        "https://github.com/uBlockOrigin/*"
-        "https://ublockorigin.github.io/*"
-        "https://*.reddit.com/r/uBlockOrigin/*"
-      ];
-      platforms = platforms.all;
-    };
-  };
-  "user-agent-switcher" = buildFirefoxXpiAddon {
-    pname = "user-agent-switcher";
-    version = "0.5.0";
-    addonId = "{a6c4a591-f1b2-4f03-b3ff-767e5bedf4e7}";
-    url = "https://addons.mozilla.org/firefox/downloads/file/4098688/user_agent_string_switcher-0.5.0.xpi";
-    sha256 = "9dc8da3c8c46d4f04d12fd789c63501fa6a2f502f859b286939a090db63eae33";
-    meta = with lib; {
-      homepage = "http://add0n.com/useragent-switcher.html";
-      description = "Spoof websites trying to gather information about your web navigation—like your browser type and operating system—to deliver distinct content you may not want.";
-      license = licenses.mpl20;
-      mozPermissions = [
-        "storage"
-        "<all_urls>"
-        "webNavigation"
-        "webRequest"
-        "webRequestBlocking"
-        "contextMenus"
-        "*://*/*"
-      ];
-      platforms = platforms.all;
-    };
-  };
-  "violentmonkey" = buildFirefoxXpiAddon {
-    pname = "violentmonkey";
-    version = "2.18.0";
-    addonId = "{aecec67f-0d10-4fa7-b7c7-609a2db280cf}";
-    url = "https://addons.mozilla.org/firefox/downloads/file/4220396/violentmonkey-2.18.0.xpi";
-    sha256 = "4abbeea842b82965379c6011dec6a435dfff0f69c20749118a8ba2f7d14cb0f1";
-    meta = with lib; {
-      homepage = "https://violentmonkey.github.io/";
-      description = "Userscript support for browsers, open source.";
-      license = licenses.mit;
-      mozPermissions = [
-        "tabs"
-        "<all_urls>"
-        "webRequest"
-        "webRequestBlocking"
-        "notifications"
-        "storage"
-        "unlimitedStorage"
-        "clipboardWrite"
-        "contextMenus"
-        "cookies"
-      ];
-      platforms = platforms.all;
-    };
-  };
-}
diff --git a/modules/nixos/git/default.nix b/modules/nixos/git/default.nix
deleted file mode 100644
index 34ca200..0000000
--- a/modules/nixos/git/default.nix
+++ /dev/null
@@ -1,136 +0,0 @@
-{
-  config,
-  lib,
-  libNginx,
-  libPlausible,
-  pkgs,
-  ...
-}:
-with lib;
-let
-  cfg = config.nixfiles.modules.git;
-in
-{
-  options.nixfiles.modules.git.server = {
-    enable = mkEnableOption "Git server";
-
-    domain = mkOption {
-      description = "Domain name sans protocol scheme.";
-      type = with types; nullOr str;
-      default = "git.${config.networking.domain}";
-    };
-
-    package = mkOption {
-      description = "Package.";
-      type = types.package;
-      default = pkgs.cgit;
-    };
-  };
-
-  config = mkIf cfg.server.enable {
-    ark.directories = [ config.services.gitolite.dataDir ];
-
-    nixfiles.modules.nginx = {
-      enable = true;
-      virtualHosts.${cfg.server.domain} = {
-        locations = {
-          "/".extraConfig =
-            let
-              cgitrc = pkgs.writeText "cgitrc" ''
-                root-title=github sux (⩺_⩹)
-                root-desc=https://github.com/azahi
-
-                clone-url=https://${cfg.server.domain}/$CGIT_REPO_URL
-
-                logo=/cgit-custom-logo.gif
-                favicon=/cgit-custom-favicon.gif
-                css=/cgit-custom-style.css
-
-                about-filter=${cfg.server.package}/lib/cgit/filters/about-formatting.sh
-                source-filter=${cfg.server.package}/lib/cgit/filters/syntax-highlighting.py
-                commit-filter=${cfg.server.package}/lib/cgit/filters/commit-links.sh
-
-                enable-git-config=1
-                enable-gitweb-owner=1
-                remove-suffix=1
-
-                readme=:README
-                readme=:README.md
-                readme=:README.org
-                readme=:README.txt
-                readme=:readme
-                readme=:readme.md
-                readme=:readme.org
-                readme=:readme.txt
-
-                scan-path=${config.services.gitolite.dataDir}/repositories
-              '';
-            in
-            ''
-              include ${config.services.nginx.package}/conf/fastcgi_params;
-              fastcgi_split_path_info ^(/?)(.+)$;
-              fastcgi_pass unix:${config.services.fcgiwrap.socketAddress};
-              fastcgi_param SCRIPT_FILENAME ${cfg.server.package}/cgit/cgit.cgi;
-              fastcgi_param CGIT_CONFIG ${cgitrc};
-              fastcgi_param PATH_INFO $uri;
-              fastcgi_param QUERY_STRING $args;
-              fastcgi_param HTTP_HOST $server_name;
-
-              ${libNginx.config.appendHead [
-                ''<meta name="go-import" content="$host$uri git https://$host$uri">''
-                (libPlausible.htmlPlausibleScript { inherit (cfg.server) domain; })
-              ]}
-            '';
-          "~* ^.+(cgit.css|robots.txt)$".extraConfig = ''
-            root ${cfg.server.package}/cgit;
-          '';
-          "~* ^.+cgit-custom-logo.gif$".extraConfig = ''
-            alias ${./logo.gif};
-          '';
-          "~* ^.+cgit-custom-favicon.gif$".extraConfig = ''
-            alias ${./favicon.ico};
-          '';
-          "~* ^.+cgit-custom-style.css$".extraConfig =
-            let
-              css = pkgs.writeText "custom.css" ''
-                @import url("cgit.css");
-
-                div#cgit {
-                  font-family: monospace;
-                  -moz-tab-size: 4;
-                  tab-size: 4;
-                }
-              '';
-            in
-            ''
-              alias ${css};
-            '';
-        };
-      };
-    };
-
-    services =
-      let
-        user = "git";
-        group = "git";
-      in
-      {
-        gitolite = {
-          enable = true;
-          inherit user group;
-          adminPubkey = my.ssh.key;
-          extraGitoliteRc = ''
-            # This allows hiding repositories via "cgit.ignore"[1].
-            #
-            # [1]: https://www.omarpolo.com/post/cgit-gitolite.html
-            $RC{GIT_CONFIG_KEYS} = '.*';
-          '';
-        };
-
-        fcgiwrap = {
-          enable = true;
-          inherit user group;
-        };
-      };
-  };
-}
diff --git a/modules/nixos/gnupg.nix b/modules/nixos/gnupg.nix
deleted file mode 100644
index ad2c939..0000000
--- a/modules/nixos/gnupg.nix
+++ /dev/null
@@ -1,41 +0,0 @@
-{
-  config,
-  lib,
-  pkgs,
-  ...
-}:
-with lib;
-let
-  cfg = config.nixfiles.modules.gnupg;
-in
-{
-  options.nixfiles.modules.gnupg.pinentry = mkOption {
-    description = "Name of a pinentry implementation.";
-    type = types.package;
-    default = pkgs.pinentry-curses;
-  };
-
-  config = mkIf cfg.enable {
-    hm = {
-      programs.gpg.homedir = "${config.dirs.data}/gnupg";
-
-      services.gpg-agent = {
-        enable = true;
-
-        enableSshSupport = true;
-        enableScDaemon = false;
-
-        defaultCacheTtl = 999999;
-        defaultCacheTtlSsh = 999999;
-        maxCacheTtl = 999999;
-        maxCacheTtlSsh = 999999;
-
-        grabKeyboardAndMouse = true;
-
-        sshKeys = [ my.pgp.grip ];
-
-        pinentryPackage = cfg.pinentry;
-      };
-    };
-  };
-}
diff --git a/modules/nixos/matrix/default.nix b/modules/nixos/matrix/default.nix
deleted file mode 100644
index e7d5a02..0000000
--- a/modules/nixos/matrix/default.nix
+++ /dev/null
@@ -1,6 +0,0 @@
-_: {
-  imports = [
-    ./dendrite.nix
-    ./element.nix
-  ];
-}
diff --git a/modules/nixos/mpv.nix b/modules/nixos/mpv.nix
deleted file mode 100644
index 8042c1a..0000000
--- a/modules/nixos/mpv.nix
+++ /dev/null
@@ -1,92 +0,0 @@
-{ config, lib, ... }:
-with lib;
-let
-  cfg = config.nixfiles.modules.mpv;
-in
-{
-  config = mkIf cfg.enable {
-    nixfiles.modules.common = {
-      shell.aliases.cam = "mpv av://v4l2:/dev/video0";
-
-      xdg.defaultApplications.mpv =
-        let
-          audio = [
-            "audio/aac"
-            "audio/ac3"
-            "audio/basic"
-            "audio/flac"
-            "audio/midi"
-            "audio/mp4"
-            "audio/mpeg"
-            "audio/ogg"
-            "audio/opus"
-            "audio/vnd.dts"
-            "audio/vnd.dts.hd"
-            "audio/webm"
-            "audio/x-adpcm"
-            "audio/x-aifc"
-            "audio/x-aiff"
-            "audio/x-ape"
-            "audio/x-flac+ogg"
-            "audio/x-m4b"
-            "audio/x-m4r"
-            "audio/x-matroska"
-            "audio/x-mpegurl"
-            "audio/x-musepack"
-            "audio/x-opus+ogg"
-            "audio/x-speex"
-            "audio/x-speex+ogg"
-            "audio/x-vorbis+ogg"
-            "audio/x-wav"
-            "audio/x-wavpack"
-            "x-content/audio-cdda"
-            "x-content/audio-dvd"
-          ];
-          video = [
-            "video/3gpp"
-            "video/3gpp2"
-            "video/mkv"
-            "video/mp2t"
-            "video/mp4"
-            "video/mpeg"
-            "video/ogg"
-            "video/quicktime"
-            "video/vnd.mpegurl"
-            "video/vnd.radgamettools.bink"
-            "video/vnd.radgamettools.smacker"
-            "video/wavelet"
-            "video/webm"
-            "video/x-matroska"
-            "video/x-matroska-3d"
-            "video/x-mjpeg"
-            "video/x-msvideo"
-            "video/x-ogm+ogg"
-            "video/x-theora+ogg"
-            "x-content/video-bluray"
-            "x-content/video-dvd"
-            "x-content/video-hddvd"
-            "x-content/video-svcd"
-            "x-content/video-vcd"
-          ];
-          image = [
-            "image/avif"
-            "image/bmp"
-            "image/gif"
-            "image/jp2"
-            "image/jpeg"
-            "image/jpg"
-            "image/jpm"
-            "image/jpx"
-            "image/jxl"
-            "image/png"
-            "image/tiff"
-            "image/vnd.microsoft.icon"
-            "image/webp"
-            "image/webp"
-            "image/x-tga"
-          ];
-        in
-        audio ++ video ++ image;
-    };
-  };
-}
diff --git a/modules/nixos/openssh.nix b/modules/nixos/openssh.nix
deleted file mode 100644
index 9b82757..0000000
--- a/modules/nixos/openssh.nix
+++ /dev/null
@@ -1,51 +0,0 @@
-{ config, lib, ... }:
-with lib;
-let
-  cfg = config.nixfiles.modules.openssh;
-in
-{
-  options.nixfiles.modules.openssh.server = {
-    enable = mkEnableOption "OpenSSH server";
-
-    port = mkOption {
-      description = "OpenSSH server port.";
-      type = types.port;
-      default = 22022; # Port 22 should be occupied by a tarpit.
-    };
-  };
-
-  config = mkIf cfg.server.enable {
-    ark.files = [
-      "/etc/ssh/ssh_host_ed25519_key"
-      "/etc/ssh/ssh_host_ed25519_key.pub"
-      "/etc/ssh/ssh_host_rsa_key"
-      "/etc/ssh/ssh_host_rsa_key.pub"
-    ];
-
-    programs.mosh.enable = true;
-
-    services = {
-      openssh = {
-        enable = true;
-        ports = [ cfg.server.port ];
-        settings = {
-          ClientAliveCountMax = 3;
-          ClientAliveInterval = 60;
-          KbdInteractiveAuthentication = false;
-          LogLevel = if config.nixfiles.modules.fail2ban.enable then "VERBOSE" else "ERROR";
-          MaxAuthTries = 3;
-          PasswordAuthentication = false;
-          PermitRootLogin = mkForce "no";
-        };
-      };
-
-      fail2ban.jails.sshd = {
-        enabled = true;
-        settings = {
-          mode = "aggressive";
-          inherit (cfg.server) port;
-        };
-      };
-    };
-  };
-}
diff --git a/modules/nixos/profiles/default.nix b/modules/nixos/profiles/default.nix
deleted file mode 100644
index 93c46e3..0000000
--- a/modules/nixos/profiles/default.nix
+++ /dev/null
@@ -1,37 +0,0 @@
-{
-  config,
-  lib,
-  pkgs,
-  ...
-}:
-with lib;
-let
-  cfg = config.nixfiles.modules.profiles.default;
-in
-{
-  imports = [
-    ./dev
-    ./headful.nix
-    ./headless.nix
-  ];
-
-  config = mkIf cfg.enable {
-    ark.directories = [ "/var/log" ];
-
-    programs.less = {
-      enable = true;
-      envVariables.LESSHISTFILE = "-";
-    };
-
-    environment.systemPackages = with pkgs; [
-      cryptsetup
-      lshw
-      lsof
-      pciutils
-      psmisc
-      sysstat
-      usbutils
-      util-linux
-    ];
-  };
-}
diff --git a/modules/nixos/profiles/dev/containers.nix b/modules/nixos/profiles/dev/containers.nix
deleted file mode 100644
index d2a7d62..0000000
--- a/modules/nixos/profiles/dev/containers.nix
+++ /dev/null
@@ -1,32 +0,0 @@
-{
-  config,
-  lib,
-  pkgs,
-  ...
-}:
-with lib;
-let
-  cfg = config.nixfiles.modules.profiles.dev.containers;
-in
-{
-  config = mkIf cfg.enable {
-    nixfiles.modules = {
-      common.shell.aliases.b = "buildah";
-      podman.enable = true;
-    };
-
-    hm = {
-      home = {
-        sessionVariables.MINIKUBE_HOME = "${config.dirs.config}/minikube";
-
-        packages = with pkgs; [ buildah ];
-      };
-
-      xdg.dataFile."minikube/config/config.json".text = generators.toJSON { } {
-        config.Rootless = true;
-        driver = "podman";
-        container-runtime = "cri-o";
-      };
-    };
-  };
-}
diff --git a/modules/nixos/profiles/dev/default.nix b/modules/nixos/profiles/dev/default.nix
deleted file mode 100644
index d2411ea..0000000
--- a/modules/nixos/profiles/dev/default.nix
+++ /dev/null
@@ -1,30 +0,0 @@
-{
-  config,
-  lib,
-  pkgs,
-  ...
-}:
-with lib;
-let
-  cfg = config.nixfiles.modules.profiles.dev;
-in
-{
-  imports = [ ./containers.nix ];
-
-  config = mkIf cfg.enable {
-    hm.home.language = {
-      collate = "C";
-      messages = "C";
-    };
-
-    programs.wireshark = {
-      enable = true;
-      package = pkgs.wireshark;
-    };
-
-    my.extraGroups = [
-      "kvm"
-      "wireshark"
-    ];
-  };
-}
diff --git a/modules/nixos/zathura.nix b/modules/nixos/zathura.nix
deleted file mode 100644
index 95039a5..0000000
--- a/modules/nixos/zathura.nix
+++ /dev/null
@@ -1,13 +0,0 @@
-{ config, lib, ... }:
-with lib;
-let
-  cfg = config.nixfiles.modules.zathura;
-in
-{
-  config = mkIf cfg.enable {
-    nixfiles.modules.common.xdg.defaultApplications."org.pwmt.zathura" = [
-      "application/pdf"
-      "application/epub+zip"
-    ];
-  };
-}
diff --git a/modules/common/nmap.nix b/modules/nmap.nix
index 71b3d0b..71b3d0b 100644
--- a/modules/common/nmap.nix
+++ b/modules/nmap.nix
diff --git a/modules/nixos/node-exporter.nix b/modules/node-exporter.nix
index 8e76903..8e76903 100644
--- a/modules/nixos/node-exporter.nix
+++ b/modules/node-exporter.nix
diff --git a/modules/nixos/nsd.nix b/modules/nsd.nix
index f44a2a0..f44a2a0 100644
--- a/modules/nixos/nsd.nix
+++ b/modules/nsd.nix
diff --git a/modules/nixos/ntfy.nix b/modules/ntfy.nix
index 5739855..5739855 100644
--- a/modules/nixos/ntfy.nix
+++ b/modules/ntfy.nix
diff --git a/modules/nixos/nullmailer.nix b/modules/nullmailer.nix
index 9f7b4ac..9f7b4ac 100644
--- a/modules/nixos/nullmailer.nix
+++ b/modules/nullmailer.nix
diff --git a/modules/openssh.nix b/modules/openssh.nix
new file mode 100644
index 0000000..5504521
--- /dev/null
+++ b/modules/openssh.nix
@@ -0,0 +1,119 @@
+{
+  config,
+  lib,
+  pkgs,
+  ...
+}:
+with lib;
+let
+  cfg = config.nixfiles.modules.openssh;
+in
+{
+  options.nixfiles.modules.openssh = {
+    client.enable = mkEnableOption "OpenSSH client";
+    server = {
+      enable = mkEnableOption "OpenSSH server";
+
+      port = mkOption {
+        description = "OpenSSH server port.";
+        type = types.port;
+        default = 22022; # Port 22 should be occupied by a tarpit.
+      };
+    };
+  };
+
+  config = mkMerge [
+    (mkIf cfg.client.enable {
+      hm = {
+        home.packages = with pkgs; [
+          mosh
+          sshfs
+          sshpass
+        ];
+
+        programs.ssh = {
+          enable = true;
+
+          hashKnownHosts = true;
+
+          controlMaster = "auto";
+          controlPersist = "24H";
+
+          serverAliveCountMax = 30;
+          serverAliveInterval = 60;
+
+          matchBlocks =
+            let
+              mkBlock =
+                name:
+                {
+                  hostname ? name,
+                  port ? 22022, # NOTE This is not the default OpenSSH port.
+                  user ? my.username,
+                  identityFile ? "${config.my.home}/.ssh/${my.username}_${my.ssh.type}",
+                  extraAttrs ? { },
+                }:
+                nameValuePair name (
+                  {
+                    inherit
+                      hostname
+                      port
+                      user
+                      identityFile
+                      ;
+                  }
+                  // extraAttrs
+                );
+
+              internalServers = mapAttrs' mkBlock (
+                mapAttrs (name: _: { hostname = "${name}.${my.domain.shire}"; }) (
+                  filterAttrs (_: attr: hasAttr "wireguard" attr && attr.isHeadless) my.configurations
+                )
+              );
+            in
+            internalServers
+            // (mapAttrs' mkBlock {
+              gitolite = {
+                user = "git";
+                hostname = "git.${my.domain.shire}";
+              };
+            });
+        };
+      };
+    })
+    (mkIf cfg.server.enable {
+      ark.files = [
+        "/etc/ssh/ssh_host_ed25519_key"
+        "/etc/ssh/ssh_host_ed25519_key.pub"
+        "/etc/ssh/ssh_host_rsa_key"
+        "/etc/ssh/ssh_host_rsa_key.pub"
+      ];
+
+      programs.mosh.enable = true;
+
+      services = {
+        openssh = {
+          enable = true;
+          ports = [ cfg.server.port ];
+          settings = {
+            ClientAliveCountMax = 3;
+            ClientAliveInterval = 60;
+            KbdInteractiveAuthentication = false;
+            LogLevel = if config.nixfiles.modules.fail2ban.enable then "VERBOSE" else "ERROR";
+            MaxAuthTries = 3;
+            PasswordAuthentication = false;
+            PermitRootLogin = mkForce "no";
+          };
+        };
+
+        fail2ban.jails.sshd = {
+          enabled = true;
+          settings = {
+            mode = "aggressive";
+            inherit (cfg.server) port;
+          };
+        };
+      };
+    })
+  ];
+}
diff --git a/modules/common/password-store.nix b/modules/password-store.nix
index e5cd756..e5cd756 100644
--- a/modules/common/password-store.nix
+++ b/modules/password-store.nix
diff --git a/modules/nixos/plausible.nix b/modules/plausible.nix
index d63e3ab..d63e3ab 100644
--- a/modules/nixos/plausible.nix
+++ b/modules/plausible.nix
diff --git a/modules/nixos/podman.nix b/modules/podman.nix
index bb4fda5..bb4fda5 100644
--- a/modules/nixos/podman.nix
+++ b/modules/podman.nix
diff --git a/modules/nixos/postgresql.nix b/modules/postgresql.nix
index 5081340..5081340 100644
--- a/modules/nixos/postgresql.nix
+++ b/modules/postgresql.nix
diff --git a/modules/common/profiles/default.nix b/modules/profiles/default.nix
index 79ce39d..e3002b0 100644
--- a/modules/common/profiles/default.nix
+++ b/modules/profiles/default.nix
@@ -10,12 +10,7 @@ let
   cfg = config.nixfiles.modules.profiles.default;
 in
 {
-  imports = [
-    ./dev
-    ./email.nix
-    ./headful.nix
-    ./headless.nix
-  ];
+  imports = attrValues (modulesIn ./.);
 
   options.nixfiles.modules.profiles.default.enable =
     mkEnableOption "The most default profile of them all."
@@ -34,6 +29,8 @@ in
       }
     ];
 
+    ark.directories = [ "/var/log" ];
+
     nixfiles.modules = {
       bat.enable = true;
       eza.enable = true;
@@ -42,11 +39,24 @@ in
       vim.enable = true;
     };
 
+    programs.less = {
+      enable = true;
+      envVariables.LESSHISTFILE = "-";
+    };
+
     time.timeZone = "Europe/Moscow";
 
     environment.systemPackages = with pkgs; [
+      cryptsetup
       file
+      lshw
+      lsof
+      pciutils
+      psmisc
+      sysstat
       tree
+      usbutils
+      util-linux
     ];
   };
 }
diff --git a/modules/profiles/dev/containers.nix b/modules/profiles/dev/containers.nix
new file mode 100644
index 0000000..f75a26b
--- /dev/null
+++ b/modules/profiles/dev/containers.nix
@@ -0,0 +1,71 @@
+{
+  config,
+  lib,
+  pkgs,
+  ...
+}:
+with lib;
+let
+  cfg = config.nixfiles.modules.profiles.dev.containers;
+in
+{
+  options.nixfiles.modules.profiles.dev.containers.enable =
+    mkEnableOption "Tools for working with containers and container orchestration"
+    // {
+      default = config.nixfiles.modules.profiles.dev.enable;
+    };
+
+  config = mkIf cfg.enable {
+    nixfiles.modules = {
+      common.shell.aliases = {
+        h = "helm";
+        k = "kubectl";
+        kns = "kubens";
+        ktx = "kubectx";
+        b = "buildah";
+      };
+      podman.enable = true;
+    };
+
+    hm = {
+      home = {
+        sessionVariables = {
+          MINIKUBE_HOME = "${config.dirs.config}/minikube";
+          MINIKUBE_IN_STYLE = "false";
+          WERF_DEV = "true";
+          WERF_INSECURE_REGISTRY = "true";
+          WERF_LOG_DEBUG = "true";
+          WERF_LOG_PRETTY = "false";
+          WERF_LOG_VERBOSE = "true";
+          WERF_SYNCHRONIZATION = ":local";
+          WERF_TELEMETRY = "false";
+        };
+
+        packages = with pkgs; [
+          buildah
+          k9s
+          kubectl
+          kubectl-doctor
+          kubectl-images
+          kubectl-tree
+          kubectx
+          kubelogin-oidc
+          kubent
+          kubernetes-helm
+          kubespy
+          minikube
+          skopeo
+          stern
+          telepresence2
+          werf
+        ];
+      };
+
+      xdg.dataFile."minikube/config/config.json".text = generators.toJSON { } {
+        config.Rootless = true;
+        driver = "podman";
+        container-runtime = "cri-o";
+      };
+    };
+  };
+}
diff --git a/modules/common/profiles/dev/default.nix b/modules/profiles/dev/default.nix
index 6ac1fe6..eab447c 100644
--- a/modules/common/profiles/dev/default.nix
+++ b/modules/profiles/dev/default.nix
@@ -9,11 +9,7 @@ let
   cfg = config.nixfiles.modules.profiles.dev;
 in
 {
-  imports = [
-    ./containers.nix
-    ./hidden.nix
-    ./sql.nix
-  ];
+  imports = attrValues (modulesIn ./.);
 
   options.nixfiles.modules.profiles.dev.enable = mkEnableOption "Catch-all profile for stuff related to software development and etc.";
 
@@ -24,7 +20,6 @@ in
       direnv.enable = true;
       editorconfig.enable = true;
       git.client.enable = true;
-      gnupg.enable = true;
       nmap.enable = true;
       wget.enable = true;
     };
@@ -73,6 +68,11 @@ in
           sops
           yq
         ];
+
+        language = {
+          collate = "C";
+          messages = "C";
+        };
       };
 
       xdg.configFile = {
@@ -80,5 +80,15 @@ in
         "ghc/ghci.conf".source = ./ghci.conf;
       };
     };
+
+    programs.wireshark = {
+      enable = true;
+      package = pkgs.wireshark;
+    };
+
+    my.extraGroups = [
+      "kvm"
+      "wireshark"
+    ];
   };
 }
diff --git a/modules/common/profiles/dev/gdbinit b/modules/profiles/dev/gdbinit
index e266236..e266236 100644
--- a/modules/common/profiles/dev/gdbinit
+++ b/modules/profiles/dev/gdbinit
diff --git a/modules/common/profiles/dev/ghci.conf b/modules/profiles/dev/ghci.conf
index d672167..d672167 100644
--- a/modules/common/profiles/dev/ghci.conf
+++ b/modules/profiles/dev/ghci.conf
diff --git a/modules/common/profiles/dev/pystartup.py b/modules/profiles/dev/pystartup.py
index adde66c..adde66c 100644
--- a/modules/common/profiles/dev/pystartup.py
+++ b/modules/profiles/dev/pystartup.py
diff --git a/modules/common/profiles/dev/sql.nix b/modules/profiles/dev/sql.nix
index c2d4894..c2d4894 100644
--- a/modules/common/profiles/dev/sql.nix
+++ b/modules/profiles/dev/sql.nix
diff --git a/modules/common/profiles/email.nix b/modules/profiles/email.nix
index cf4169c..b2ef02f 100644
--- a/modules/common/profiles/email.nix
+++ b/modules/profiles/email.nix
@@ -15,6 +15,8 @@ in
   };
 
   config = mkIf cfg.enable {
+    nixfiles.modules.gnupg.enable = true;
+
     hm = {
       accounts.email = {
         maildirBasePath = "${config.my.home}/doc/mail";
@@ -34,7 +36,7 @@ in
                   msmtp.enable = true;
                   mu.enable = true;
                   thunderbird = {
-                    enable = hasSuffix "linux" this.system;
+                    enable = true;
                     settings = id: {
                       "mail.identity.id_${id}.compose_html" = false;
                       "mail.identity.id_${id}.reply_on_top" = 0;
diff --git a/modules/nixos/profiles/headful.nix b/modules/profiles/headful.nix
index 8206aa8..20363bc 100644
--- a/modules/nixos/profiles/headful.nix
+++ b/modules/profiles/headful.nix
@@ -2,6 +2,7 @@
   config,
   lib,
   pkgs,
+  this,
   ...
 }:
 with lib;
@@ -9,33 +10,57 @@ let
   cfg = config.nixfiles.modules.profiles.headful;
 in
 {
+  options.nixfiles.modules.profiles.headful.enable = mkEnableOption "headful profile" // {
+    default = this.isHeadful;
+  };
+
   config = mkIf cfg.enable {
     nixfiles.modules = {
+      profiles.dev.enable = true;
+
+      alacritty.enable = mkDefault true;
+      aria2.enable = true;
       chromium.enable = true;
+      dwm.enable = mkDefault false;
+      emacs.enable = true;
       firefox.enable = true;
+      foot.enable = mkDefault true;
+      kde.enable = mkDefault true;
+      mpv.enable = true;
+      nullmailer.enable = true;
+      openssh.client.enable = true;
+      password-store.enable = true;
       sound.enable = true;
       thunderbird.enable = true;
-
-      nullmailer.enable = true;
-
-      dwm.enable = mkDefault false;
-      kde.enable = mkDefault true;
-      xmonad.enable = mkDefault false;
-
+      vscode.enable = true;
       wayland.enable = mkDefault true;
       x11.enable = mkDefault true;
+      xmonad.enable = mkDefault false;
+      zathura.enable = true;
     };
 
     hm = {
-      home.packages = with pkgs; [
-        calibre
-        element-desktop
-        imv
-        libreoffice-fresh
-        mumble
-        telegram-desktop
-        tor-browser-bundle-bin
-      ];
+      home = {
+        file.".digrc".text = ''
+          +answer
+          +multiline
+          +recurse
+        '';
+
+        packages = with pkgs; [
+          calibre
+          element-desktop
+          fd
+          imv
+          libreoffice-fresh
+          mumble
+          ripgrep
+          sd
+          telegram-desktop
+          tldr
+          tor-browser-bundle-bin
+        ];
+      };
 
       programs.bash.shellAliases.open = "xdg-open";
     };
@@ -79,7 +104,15 @@ in
       psd.enable = true;
     };
 
-    environment.systemPackages = with pkgs; [ lm_sensors ];
+    environment.systemPackages = with pkgs; [
+      arping
+      dnsutils
+      inetutils
+      ldns
+      lm_sensors
+      socat
+      tcpdump
+    ];
 
     my.extraGroups = [
       "audio"
diff --git a/modules/nixos/profiles/headless.nix b/modules/profiles/headless.nix
index f3f3572..7733f3e 100644
--- a/modules/nixos/profiles/headless.nix
+++ b/modules/profiles/headless.nix
@@ -2,6 +2,7 @@
   config,
   lib,
   pkgs,
+  this,
   ...
 }:
 with lib;
@@ -9,6 +10,10 @@ let
   cfg = config.nixfiles.modules.profiles.headless;
 in
 {
+  options.nixfiles.modules.profiles.headless.enable = mkEnableOption "headless profile" // {
+    default = this.isHeadless;
+  };
+
   config = mkIf cfg.enable {
     nixfiles.modules = {
       openssh.server.enable = true;
@@ -20,6 +25,11 @@ in
       promtail.enable = false; # FIXME High RAM usage.
     };
 
+    hm.home.file = {
+      ".hushlogin".text = "";
+      ".bash_history".source = config.hm.lib.file.mkOutOfStoreSymlink "/dev/null";
+    };
+
     # Pin version to prevent any surprises. Try keeping this up-to-date[1] with
     # the latest LTS release + hardened patches (just in case).
     #
@@ -39,6 +49,11 @@ in
       };
     };
 
+    environment.systemPackages = with pkgs; [
+      alacritty.terminfo
+      foot.terminfo
+    ];
+
     services.udisks2.enable = false;
 
     xdg.sounds.enable = false;
diff --git a/modules/nixos/prometheus.nix b/modules/prometheus.nix
index 9f28cd5..9f28cd5 100644
--- a/modules/nixos/prometheus.nix
+++ b/modules/prometheus.nix
diff --git a/modules/nixos/promtail.nix b/modules/promtail.nix
index 65d88d4..65d88d4 100644
--- a/modules/nixos/promtail.nix
+++ b/modules/promtail.nix
diff --git a/modules/nixos/psd.nix b/modules/psd.nix
index f974af2..f974af2 100644
--- a/modules/nixos/psd.nix
+++ b/modules/psd.nix
diff --git a/modules/common/qutebrowser.nix b/modules/qutebrowser.nix
index 8fdcf48..8fdcf48 100644
--- a/modules/common/qutebrowser.nix
+++ b/modules/qutebrowser.nix
diff --git a/modules/nixos/radarr.nix b/modules/radarr.nix
index 9e4e13f..9e4e13f 100644
--- a/modules/nixos/radarr.nix
+++ b/modules/radarr.nix
diff --git a/modules/nixos/radicale.nix b/modules/radicale.nix
index 59fb4a2..59fb4a2 100644
--- a/modules/nixos/radicale.nix
+++ b/modules/radicale.nix
diff --git a/modules/nixos/redis.nix b/modules/redis.nix
index e2151c7..e2151c7 100644
--- a/modules/nixos/redis.nix
+++ b/modules/redis.nix
diff --git a/modules/nixos/rss-bridge.nix b/modules/rss-bridge.nix
index de1d6b6..c890872 100644
--- a/modules/nixos/rss-bridge.nix
+++ b/modules/rss-bridge.nix
@@ -20,7 +20,7 @@ in
   };
 
   config = mkIf cfg.enable {
-    ark.directories = [ "/var/lib/rss-bridge" ];
+    ark.directories = [ config.services.rss-bridge.dataDir ];
 
     nixfiles.modules.nginx = {
       enable = true;
@@ -30,7 +30,13 @@ in
     services.rss-bridge = {
       enable = true;
       virtualHost = cfg.domain;
-      whitelist = [ "*" ];
+      config = {
+        system.enabled_bridges = [ "*" ];
+        FileCache = {
+          path = "${config.services.rss-bridge.dataDir}/cache";
+          enable_purge = true;
+        };
+      };
     };
   };
 }
diff --git a/modules/nixos/rtorrent.nix b/modules/rtorrent.nix
index 82ef1b2..82ef1b2 100644
--- a/modules/nixos/rtorrent.nix
+++ b/modules/rtorrent.nix
diff --git a/modules/nixos/searx.nix b/modules/searx.nix
index de51a20..de51a20 100644
--- a/modules/nixos/searx.nix
+++ b/modules/searx.nix
diff --git a/modules/nixos/shadowsocks.nix b/modules/shadowsocks.nix
index 670faec..670faec 100644
--- a/modules/nixos/shadowsocks.nix
+++ b/modules/shadowsocks.nix
diff --git a/modules/nixos/soju.nix b/modules/soju.nix
index f8212b5..f8212b5 100644
--- a/modules/nixos/soju.nix
+++ b/modules/soju.nix
diff --git a/modules/nixos/solaar.nix b/modules/solaar.nix
index 17a04de..17a04de 100644
--- a/modules/nixos/solaar.nix
+++ b/modules/solaar.nix
diff --git a/modules/nixos/sonarr.nix b/modules/sonarr.nix
index b11dda0..b11dda0 100644
--- a/modules/nixos/sonarr.nix
+++ b/modules/sonarr.nix
diff --git a/modules/nixos/sound.nix b/modules/sound.nix
index ff90dfc..ff90dfc 100644
--- a/modules/nixos/sound.nix
+++ b/modules/sound.nix
diff --git a/modules/common/subversion.nix b/modules/subversion.nix
index 9398592..9398592 100644
--- a/modules/common/subversion.nix
+++ b/modules/subversion.nix
diff --git a/modules/nixos/syncthing.nix b/modules/syncthing.nix
index 74d4afe..74d4afe 100644
--- a/modules/nixos/syncthing.nix
+++ b/modules/syncthing.nix
diff --git a/modules/nixos/throttled.nix b/modules/throttled.nix
index 7d37cd4..7d37cd4 100644
--- a/modules/nixos/throttled.nix
+++ b/modules/throttled.nix
diff --git a/modules/nixos/thunderbird.nix b/modules/thunderbird.nix
index 74af3b5..74af3b5 100644
--- a/modules/nixos/thunderbird.nix
+++ b/modules/thunderbird.nix
diff --git a/modules/common/tmux.nix b/modules/tmux.nix
index a754222..a754222 100644
--- a/modules/common/tmux.nix
+++ b/modules/tmux.nix
diff --git a/modules/nixos/unbound.nix b/modules/unbound.nix
index e71d48c..e71d48c 100644
--- a/modules/nixos/unbound.nix
+++ b/modules/unbound.nix
diff --git a/modules/nixos/vaultwarden.nix b/modules/vaultwarden.nix
index 2cacb6c..2cacb6c 100644
--- a/modules/nixos/vaultwarden.nix
+++ b/modules/vaultwarden.nix
diff --git a/modules/nixos/victoriametrics.nix b/modules/victoriametrics.nix
index 88dff1b..ac4ac58 100644
--- a/modules/nixos/victoriametrics.nix
+++ b/modules/victoriametrics.nix
@@ -6,10 +6,10 @@
 }:
 with lib;
 let
-  cfg = config.nixfiles.modules.prometheus;
+  cfg = config.nixfiles.modules.victoriametrics;
 in
 {
-  options.nixfiles.modules.prometheus = {
+  options.nixfiles.modules.victoriametrics = {
     enable = mkEnableOption "VictoriaMetrics";
 
     port = mkOption {
diff --git a/modules/nixos/vim/default.nix b/modules/vim/default.nix
index 5d62e35..94cc7af 100644
--- a/modules/nixos/vim/default.nix
+++ b/modules/vim/default.nix
@@ -9,7 +9,33 @@ let
   cfg = config.nixfiles.modules.vim;
 in
 {
+  options.nixfiles.modules.vim = {
+    enable = mkEnableOption "Vim";
+
+    rc = mkOption {
+      type = types.str;
+      default = readFile ./rc.vim;
+      description = "Configuration file.";
+    };
+
+    plugins = mkOption {
+      type = with types; listOf package;
+      default = with pkgs.vimPlugins; [
+        editorconfig-vim
+        vim-eunuch
+        vim-nix
+        vim-sensible
+        vim-sleuth
+        vim-surround
+        vim-unimpaired
+      ];
+      description = "Plugins.";
+    };
+  };
+
   config = mkIf cfg.enable {
+    hm.stylix.targets.vim.enable = false;
+
     programs.vim.package =
       (pkgs.vim-full.override {
         cscopeSupport = false;
@@ -33,5 +59,13 @@ in
             packages.myVimPackage.start = plugins;
           };
         };
+
+    environment = {
+      systemPackages = [ config.programs.vim.package ];
+      variables = rec {
+        EDITOR = "vim";
+        VISUAL = EDITOR;
+      };
+    };
   };
 }
diff --git a/modules/common/vim/rc.vim b/modules/vim/rc.vim
index 3bd9eb7..3bd9eb7 100644
--- a/modules/common/vim/rc.vim
+++ b/modules/vim/rc.vim
diff --git a/modules/common/vscode.nix b/modules/vscode.nix
index bd840d8..bd840d8 100644
--- a/modules/common/vscode.nix
+++ b/modules/vscode.nix
diff --git a/modules/nixos/wayland.nix b/modules/wayland.nix
index e3dba79..e3dba79 100644
--- a/modules/nixos/wayland.nix
+++ b/modules/wayland.nix
diff --git a/modules/common/wget.nix b/modules/wget.nix
index 0e8ee64..0e8ee64 100644
--- a/modules/common/wget.nix
+++ b/modules/wget.nix
diff --git a/modules/nixos/wireguard.nix b/modules/wireguard.nix
index f645a90..f645a90 100644
--- a/modules/nixos/wireguard.nix
+++ b/modules/wireguard.nix
diff --git a/modules/nixos/x11.nix b/modules/x11.nix
index 55ba0b5..55ba0b5 100644
--- a/modules/nixos/x11.nix
+++ b/modules/x11.nix
diff --git a/modules/nixos/xmonad.nix b/modules/xmonad.nix
index 7b49f52..7b49f52 100644
--- a/modules/nixos/xmonad.nix
+++ b/modules/xmonad.nix
diff --git a/modules/common/zathura.nix b/modules/zathura.nix
index bc92258..cef841c 100644
--- a/modules/common/zathura.nix
+++ b/modules/zathura.nix
@@ -7,6 +7,11 @@ in
   options.nixfiles.modules.zathura.enable = mkEnableOption "Zathura PDF reader";
 
   config = mkIf cfg.enable {
+    nixfiles.modules.common.xdg.defaultApplications."org.pwmt.zathura" = [
+      "application/pdf"
+      "application/epub+zip"
+    ];
+
     hm.programs.zathura = {
       enable = true;
 

Consider giving Nix/NixOS a try! <3