diff --git a/options/custom/default.nix b/options/custom/default.nix
index 9b2928a..4a57510 100644
--- a/options/custom/default.nix
+++ b/options/custom/default.nix
@@ -30,7 +30,7 @@ in {
     hidpi = mkOption {default = cfg.scale > 1;};
     scale = mkOption {default = 1;};
     border = mkOption {default = 2;};
-    gap = mkOption {default = 20;};
+    gap = mkOption {default = 10;};
     padding = mkOption {default = 51;}; # ?? journalctl --user -u waybar.service | grep height:
     rounding = mkOption {default = 15;};
 
@@ -38,7 +38,7 @@ in {
     desktop = mkOption {
       default =
         if config.custom.full
-        then "niri"
+        then "hyprland"
         else "gnome";
     };
 
diff --git a/options/custom/desktops/hyprland/binds.nix b/options/custom/desktops/hyprland/binds.nix
index 0fc2400..c02d51e 100644
--- a/options/custom/desktops/hyprland/binds.nix
+++ b/options/custom/desktops/hyprland/binds.nix
@@ -1,54 +1,44 @@
 {
   config,
-  inputs,
   lib,
   pkgs,
   ...
 }:
 with lib; let
-  audio = "~/.local/bin/audio";
-  cat = "${pkgs.coreutils}/bin/cat";
-  clipse = "${pkgs.clipse}/bin/clipse";
-  codium = "${config.home-manager.users.${config.custom.username}.programs.vscode.package}/bin/codium";
-  gnome-text-editor = "${pkgs.gnome-text-editor}/bin/gnome-text-editor";
-  hyprctl = "${config.programs.hyprland.package}/bin/hyprctl";
-  hyprlock = "${config.home-manager.users.${config.custom.username}.programs.hyprlock.package}/bin/hyprlock";
-  hyprpicker = "${pkgs.hyprpicker}/bin/hyprpicker";
-  inhibit = config.home-manager.users.${config.custom.username}.home.file.".local/bin/inhibit".source;
-  jq = "${pkgs.jq}/bin/jq";
-  kill = "${pkgs.procps}/bin/kill";
-  kitty = "${config.home-manager.users.${config.custom.username}.programs.kitty.package}/bin/kitty";
-  left = config.home-manager.users.${config.custom.username}.home.file.".local/bin/left".source;
-  libreoffice = "${config.custom.programs.libreoffice.package}/bin/libreoffice";
-  loginctl = "${pkgs.systemd}/bin/loginctl";
-  menu = config.home-manager.users.${config.custom.username}.home.file.".local/bin/menu".source;
-  nautilus = "${pkgs.nautilus}/bin/nautilus";
-  networkmanager_dmenu = "${pkgs.networkmanager_dmenu}/bin/networkmanager_dmenu";
-  notify-send = "${pkgs.libnotify}/bin/notify-send";
-  obsidian = "${pkgs.obsidian}/bin/obsidian";
-  onlyoffice-desktopeditors = "${pkgs.onlyoffice-bin}/bin/onlyoffice-desktopeditors --system-title-bar --xdg-desktop-portal";
-  pkill = "${pkgs.procps}/bin/pkill";
-  playerctl = "${pkgs.playerctl}/bin/playerctl";
-  power = config.home-manager.users.${config.custom.username}.home.file.".local/bin/power".source;
-  remote = config.home-manager.users.${config.custom.username}.home.file.".local/bin/remote".source;
-  rofi-rbw = "${pkgs.rofi-rbw}/bin/rofi-rbw";
-  rm = "${pkgs.coreutils}/bin/rm";
-  screenshot = "~/.local/bin/screenshot";
-  sleep = "${pkgs.coreutils}/bin/sleep";
-  smile = "${pkgs.smile}/bin/smile";
-  steam = "${config.programs.steam.package}/bin/steam";
-  swayosd-client = "${pkgs.swayosd}/bin/swayosd-client";
-  systemctl = "${pkgs.systemd}/bin/systemctl";
-  toggle = "~/.local/bin/toggle";
-  virt-manager = "${config.programs.virt-manager.package}/bin/virt-manager";
-  vrr = config.home-manager.users.${config.custom.username}.home.file.".local/bin/vrr".source;
-  walker = "${config.home-manager.users.${config.custom.username}.programs.walker.package}/bin/walker";
-  waydroid = "${pkgs.waydroid}/bin/waydroid";
-  window = config.home-manager.users.${config.custom.username}.home.file.".local/bin/window".source;
-  workspace = config.home-manager.users.${config.custom.username}.home.file.".local/bin/workspace".source;
-  zoom = config.home-manager.users.${config.custom.username}.home.file.".local/bin/zoom".source;
-
   cfg = config.custom.desktops.hyprland.binds;
+  hm = config.home-manager.users.${config.custom.username};
+
+  audio = hm.home.file.".local/bin/audio".source;
+  cat = getExe' pkgs.coreutils "cat";
+  codium = getExe hm.programs.vscode.package;
+  ghostty = getExe hm.programs.ghostty.package;
+  gnome-text-editor = getExe pkgs.gnome-text-editor;
+  hyprctl = getExe' config.programs.hyprland.package "hyprctl";
+  hyprlock = getExe hm.programs.hyprlock.package;
+  hyprpicker = getExe pkgs.hyprpicker;
+  inhibit = hm.home.file.".local/bin/inhibit".source;
+  jq = getExe pkgs.jq;
+  kill = getExe' pkgs.procps "kill";
+  kitty = getExe hm.programs.kitty.package;
+  left = hm.home.file.".local/bin/left".source;
+  loginctl = getExe' pkgs.systemd "loginctl";
+  nautilus = getExe pkgs.nautilus;
+  notify-send = getExe pkgs.libnotify;
+  obsidian = getExe pkgs.obsidian;
+  pkill = getExe' pkgs.procps "pkill";
+  playerctl = getExe pkgs.playerctl;
+  power = hm.home.file.".local/bin/power".source;
+  remote = hm.home.file.".local/bin/remote".source;
+  screenshot = hm.home.file.".local/bin/screenshot".source;
+  sleep = getExe' pkgs.coreutils "sleep";
+  steam = getExe config.programs.steam.package;
+  swayosd-client = getExe' pkgs.swayosd "swayosd-client";
+  toggle = hm.home.file.".local/bin/toggle".source;
+  virt-manager = getExe config.programs.virt-manager.package;
+  vrr = hm.home.file.".local/bin/vrr".source;
+  waydroid = getExe pkgs.waydroid;
+  window = hm.home.file.".local/bin/window".source;
+  zoom = hm.home.file.".local/bin/zoom".source;
 in {
   options.custom.desktops.hyprland.binds.enable = mkOption {default = false;};
 
@@ -66,31 +56,45 @@ in {
           then ""
           else ", ${params}"
         }";
+
+        dropdown = concatStringsSep " " [
+          "${toggle}"
+          "--focus"
+          "--type class"
+          "--expression '^dropdown$'"
+          "--workspace special:dropdown"
+          "--"
+          "${ghostty} --class=dropdown"
+        ];
+
+        pip-switch = with config.custom;
+          concatStringsSep " " [
+            "${window} move"
+            "--current"
+            "--property title"
+            "'^Picture.in.[Pp]icture$'"
+            "${toString (gap + border)},${toString (gap + border)}"
+          ];
+
+        pip-toggle = concatStringsSep " " [
+          "${toggle}"
+          "--type title"
+          "--expression '^Picture.in.[Pp]icture$'"
+          "--workspace special:pip"
+        ];
+
+        vm = ''${remote} --vm --client xfreerdp --username Myned --password "$(${cat} ${config.age.secrets."desktop/vm/myndows.pass".path})" ${
+            if config.custom.hidpi
+            then "--scale 140"
+            else ""
+          } myndows'';
       in {
         # https://wiki.hyprland.org/Configuring/Binds
         #?? bind = MODS, KEY, DISPATCHER, [PARAMS]
         #?? wev
 
-        # Lockscreen binds
-        bindl = [
-          (key "Delete" "Ctrl" "exec" "${hyprctl} reload")
-          (key "Delete" "Ctrl+Alt" "exec" "${loginctl} terminate-user ''") # Current user sessions
-          (key "Delete" "Super" "exec" inhibit)
-
-          (key "L" "Super" "exec" "${hyprlock} --immediate & ${sleep} 1 && ${hyprctl} dispatch dpms off")
-
-          # Laptop lid switches
-          # https://wiki.hyprland.org/Configuring/Binds/#switches
-          #?? hyprctl devices
-          #// (key "switch:off:Lid Switch" null "dpms" "on") # Open
-          #// (key "switch:on:Lid Switch" null "dpms" "off") # Close
-        ];
-
-        # Mouse binds
-        bindm = [
-          (key "mouse:272" "Super" "movewindow" null) # LMB
-          (key "mouse:273" "Super" "resizewindow" null) # RMB
-        ];
+        # Regular binds
+        bind = [];
 
         # Repeat binds
         binde = [
@@ -106,96 +110,42 @@ in {
           (key "XF86MonBrightnessUp" null "exec" "${swayosd-client} --brightness raise") # F8
           (key "XF86AudioMedia" null "exec" "${notify-send} test") # F12
 
+          # Meta alternatives
           (key "0" "Super" "exec" "${swayosd-client} --output-volume mute-toggle")
           (key "Minus" "Super" "exec" "${swayosd-client} --output-volume lower")
           (key "Equal" "Super" "exec" "${swayosd-client} --output-volume raise")
           (key "Left" "Super" "exec" "${playerctl} previous")
-          (key "Space" "Super" "exec" "${playerctl} play-pause")
+          (key "Delete" "Super" "exec" "${playerctl} play-pause")
           (key "Right" "Super" "exec" "${playerctl} next")
           (key "Down" "Super" "exec" "${swayosd-client} --brightness lower")
           (key "Up" "Super" "exec" "${swayosd-client} --brightness raise")
-        ];
 
-        # Release binds
-        bindr = [
-          (key "Alt_L" "Super+Alt" "togglespecialworkspace" "music")
-          (key "Alt_L" "Super+Alt+Shift" "movetoworkspacesilent" "special:music")
-          (key "Control_L" "Super+Ctrl" "togglespecialworkspace" "office")
-          (key "Control_L" "Super+Ctrl+Shift" "movetoworkspacesilent" "special:office")
-          (key "Shift_L" "Super+Shift" "workspace" "previous")
-          (key "Super_L" "Super" "exec" menu)
-          (key "Super_L" "Super+Ctrl+Shift" "exec" "${menu} network")
-          (key "Super_L" "Super+Shift" "exec" "${menu} search")
-        ];
-
-        # Regular binds
-        bind = [
-          (key "mouse:274" "Super" "layoutmsg" "swapwithmaster auto")
-          (key "mouse:274" "Super+Shift" "layoutmsg" "addmaster")
-          (key "mouse:274" "Super+Ctrl+Shift" "layoutmsg" "removemaster")
-
-          (key "Backslash" "Super" "splitratio" "exact 0.5") # Reset layout ratio
-          (key "Backslash" "Super+Shift" "layoutmsg" "orientationcycle center left")
-          (key "Backspace" "Super" "changegroupactive" "f")
-          (key "Backspace" "Super+Ctrl" "togglegroup" null)
-          (key "Backspace" "Super+Ctrl+Shift" "lockactivegroup" "toggle")
-          (key "Backspace" "Super+Shift" "movegroupwindow" null)
-          (key "Bracketleft" "Super" "splitratio" "-0.1")
-          (key "Bracketleft" "Super+Shift" "layoutmsg" "rollnext")
-          (key "Bracketright" "Super" "splitratio" "+0.1")
-          (key "Bracketright" "Super+Shift" "layoutmsg" "rollprev")
-          (key "Comma" "Super" "layoutmsg" "swapprev")
-          (key "Delete" "Super+Shift" "exec" power)
-          (key "Down" "Super+Shift" "movewindoworgroup" "d")
+          # Special keys
+          (key "Apostrophe" "Super" "exec" "${screenshot} selection")
+          (key "Apostrophe" "Super+Alt" "exec" "${screenshot} selection --edit")
+          (key "Apostrophe" "Super+Alt+Shift" "exec" "${screenshot} display --edit")
+          (key "Apostrophe" "Super+Shift" "exec" "${screenshot} display")
+          (key "Backslash" "Super+Shift" "exec" power)
+          (key "Backspace" "Super" "scroller:alignwindow" "middle")
+          (key "Backspace" "Super+Shift" "scroller:fitsize" "visible")
           (key "Equal" "Super+Shift" "exec" "${zoom} +0.1")
           (key "Escape" "Super" "togglefloating" null)
           (key "Escape" "Super+Alt" "exec" "lifx state --color red")
-          (key "Escape" "Super+Shift" "centerwindow" null)
-          (key "Grave" "Super" "togglespecialworkspace" "scratchpad")
-          (key "Grave" "Super+Shift" "movetoworkspacesilent" "special:scratchpad")
-          (key "Left" "Super+Alt" "exec" "${left} --scroll kensington-orbit-wireless-tb-mouse")
-          (key "Left" "Super+Shift" "movewindoworgroup" "l")
+          (key "Escape" "Super+Shift" "scroller:pin" null)
+          (key "Left" "Super+Ctrl+Shift" "exec" "${left} --scroll kensington-orbit-wireless-tb-mouse")
           (key "Minus" "Super+Shift" "exec" "${zoom} -0.1")
-          (key "Period" "Super" "layoutmsg" "swapnext")
-          (key "Apostrophe" "Super" "exec" "${screenshot} selection")
-          (key "Apostrophe" "Super+Shift" "exec" "${screenshot} display")
-          (key "Apostrophe" "Super+Alt" "exec" "${screenshot} selection --edit")
-          (key "Apostrophe" "Super+Alt+Shift" "exec" "${screenshot} display --edit")
           (key "Return" "Super" "fullscreen" "1") # Maximize
           (key "Return" "Super+Shift" "fullscreen" "0") # Fullscreen
-          (key "Right" "Super+Shift" "movewindoworgroup" "r")
-          (key "Semicolon" "Super" "exec" "${hyprpicker} --autocopy")
-          (key "Semicolon" "Super+Shift" "exec" "${hyprpicker} --autocopy --format rgb")
           (key "Slash" "Super" "exec" vrr)
-          (key "Space" "Ctrl" "exec" (concatStringsSep " " [
-            "${toggle}"
-            "--focus"
-            "--type class"
-            "--expression '^dropdown$'"
-            "--workspace special:dropdown"
-            "--"
-            "${kitty} --app-id dropdown --override font_size=12"
-          ]))
+          (key "Space" "Ctrl" "exec" dropdown)
           (key "Space" "Ctrl+Alt" "exec" "lifx toggle")
-          (key "Space" "Ctrl+Shift" "exec" (concatStringsSep " " [
-            "${toggle}"
-            "--type title"
-            "--expression '^Picture.in.[Pp]icture$'"
-            "--workspace special:pip"
-          ]))
-          (key "Space" "Super+Ctrl+Shift" "exec" (with config.custom;
-            concatStringsSep " " [
-              "${window} move"
-              "--current"
-              "--property title"
-              "'^Picture.in.[Pp]icture$'"
-              "${toString (gap + border)},${toString (gap + border)}"
-            ]))
-          (key "Tab" "Super" "layoutmsg" "cyclenext")
-          (key "Tab" "Super+Shift" "alterzorder" "top")
-          (key "Tab" "Super+Shift" "cyclenext" "floating")
-          (key "Up" "Super+Shift" "movewindoworgroup" "u")
+          (key "Space" "Ctrl+Shift" "exec" pip-toggle)
+          (key "Space" "Super" "togglespecialworkspace" "scratchpad")
+          (key "Space" "Super+Ctrl+Shift" "exec" pip-switch)
+          (key "Space" "Super+Shift" "movetoworkspacesilent" "special:scratchpad")
+          (key "Tab" "Super" "scroller:toggleoverview" null)
 
+          # Alphanumeric keys
           (key "0" "Super+Shift" "exec" zoom)
           (key "1" "Ctrl+Alt" "exec" "lifx state --brightness 0.01")
           (key "1" "Super" "workspace" "1")
@@ -225,47 +175,84 @@ in {
           (key "8" "Super+Shift" "movetoworkspacesilent" "8")
           (key "9" "Super" "exec" audio)
           (key "A" "Ctrl+Alt" "exec" "${waydroid} session stop")
-          (key "A" "Super" "togglespecialworkspace" "android")
-          (key "A" "Super+Shift" "movetoworkspacesilent" "special:android")
+          (key "A" "Super" "scroller:movefocus" "l")
+          (key "A" "Super+Ctrl" "scroller:alignwindow" "left")
+          (key "A" "Super+Shift" "scroller:movewindow" "l")
           (key "B" "Super" "exec" config.custom.browser.command)
-          (key "C" "Super" "exec" codium)
+          (key "C" "Super" "exec" config.custom.menus.clipboard.show)
+          (key "C" "Super+Shift" "exec" config.custom.menus.clipboard.clear)
+          (key "D" "Super" "togglespecialworkspace" "android")
+          (key "D" "Super+Shift" "movetoworkspacesilent" "special:android")
           (key "E" "Super" "exec" gnome-text-editor)
           (key "F" "Super" "exec" "${nautilus} --new-window")
-          (key "G" "Super" "workspace" "name:game")
-          (key "G" "Super+Alt" "togglespecialworkspace" "gamescope")
-          (key "G" "Super+Ctrl+Alt" "exec" "${pkill} gamescope")
-          (key "G" "Super+Shift" "movetoworkspacesilent" "name:game")
+          (key "G" "Super" "togglespecialworkspace" "game")
+          (key "G" "Super+Ctrl" "exec" steam)
+          (key "G" "Super+Shift" "movetoworkspacesilent" "special:game")
+          (key "I" "Super" "exec" codium)
           (key "K" "Super" "exec" obsidian)
-          (key "O" "Super" "togglespecialworkspace" "wallpaper")
-          (key "O" "Super+Shift" "movetoworkspacesilent" "special:wallpaper")
-          (key "P" "Ctrl+Alt" "exec" "${pkill} 1password")
+          (key "M" "Super" "togglespecialworkspace" "music")
+          (key "M" "Super+Shift" "movetoworkspacesilent" "special:music")
+          (key "O" "Super" "exec" "${hyprpicker} --autocopy")
+          (key "O" "Super+Shift" "exec" "${hyprpicker} --autocopy --format rgb")
+          (key "P" "Ctrl+Alt" "exec" "${pkill} --full --exact 1password")
           (key "P" "Super" "togglespecialworkspace" "password")
           (key "P" "Super+Shift" "movetoworkspacesilent" "special:password")
           (key "Q" "Ctrl+Alt" "exec" "${kill} -9 $(${hyprctl} -j activewindow | ${jq} .pid)")
-          #// (key "Q" "Ctrl+Alt+Shift" "exec" "close") # Quit all windows
           (key "Q" "Super" "killactive" null)
-          (key "S" "Ctrl+Alt" "exec" "${pkill} steam")
-          (key "S" "Super" "togglespecialworkspace" "steam")
-          (key "S" "Super+Shift" "movetoworkspacesilent" "special:steam")
-          (key "S" "Super+Ctrl" "exec" steam)
-          (key "T" "Ctrl+Alt" "exec" "${pkill} kitty")
+          (key "R" "Super" "scroller:movefocus" "d")
+          (key "R" "Super+Ctrl" "scroller:alignwindow" "down")
+          (key "R" "Super+Shift" "scroller:movewindow" "d")
+          (key "S" "Ctrl+Alt" "exec" "${pkill} --full --exact steam")
+          (key "S" "Super" "scroller:movefocus" "r")
+          (key "S" "Super+Ctrl" "scroller:alignwindow" "right")
+          (key "S" "Super+Shift" "scroller:movewindow" "r")
+          (key "T" "Ctrl+Alt" "exec" "${pkill} --full --exact ghostty")
           (key "T" "Super" "togglespecialworkspace" "terminal")
-          (key "T" "Super+Ctrl" "exec" kitty)
+          (key "T" "Super+Ctrl" "exec" ghostty)
           (key "T" "Super+Shift" "movetoworkspacesilent" "special:terminal")
-          (key "V" "Super" "exec" "${menu} clipboard")
-          (key "V" "Super+Shift" "exec" "${rm} ~/.cache/walker/clipboard.gob && ${notify-send} menu 'Clipboard cleared' --urgency low")
-          (key "W" "Super" "togglespecialworkspace" "vm")
-          (key "W" "Super+Ctrl" "exec" ''${remote} --vm --client xfreerdp --username Myned --password "$(${cat} ${config.age.secrets."desktop/vm/myndows.pass".path})" ${
-              if config.custom.hidpi
-              then "--scale 140"
-              else ""
-            } myndows'')
-          (key "W" "Super+Ctrl+Shift" "exec" virt-manager)
-          (key "W" "Super+Shift" "movetoworkspacesilent" "special:vm")
-          (key "X" "Super" "workspace" "+1")
-          (key "X" "Super+Shift" "movetoworkspacesilent" "+1")
-          (key "Z" "Super" "workspace" "-1")
-          (key "Z" "Super+Shift" "movetoworkspacesilent" "-1")
+          (key "V" "Super" "togglespecialworkspace" "vm")
+          (key "V" "Super+Ctrl" "exec" vm)
+          (key "V" "Super+Ctrl+Shift" "exec" virt-manager)
+          (key "V" "Super+Shift" "movetoworkspacesilent" "special:vm")
+          (key "W" "Super" "scroller:movefocus" "u")
+          (key "W" "Super+Ctrl" "scroller:alignwindow" "up")
+          (key "W" "Super+Shift" "scroller:movewindow" "u")
+          (key "X" "Super" "scroller:cyclesize" "next")
+          (key "Z" "Super" "scroller:cyclesize" "previous")
+        ];
+
+        # Lockscreen binds
+        bindl = [
+          (key "Delete" "Ctrl" "exec" "${hyprctl} reload")
+          (key "Delete" "Ctrl+Alt" "exec" "${loginctl} terminate-user ''") # Current user sessions
+          (key "Delete" "Super" "exec" inhibit)
+          (key "L" "Super" "exec" "${hyprlock} --immediate & ${sleep} 1 && ${hyprctl} dispatch dpms off")
+
+          # Laptop lid switches
+          # https://wiki.hyprland.org/Configuring/Binds/#switches
+          #?? hyprctl devices
+          #// (key "switch:off:Lid Switch" null "dpms" "on") # Open
+          #// (key "switch:on:Lid Switch" null "dpms" "off") # Close
+        ];
+
+        # Mouse binds
+        bindm = [
+          (key "mouse:272" "Super" "movewindow" null) # LMB
+          (key "mouse:273" "Super" "resizewindow" null) # RMB
+        ];
+
+        # Release binds
+        bindr = [
+          (key "Alt_L" "Super+Alt" "togglespecialworkspace" "wallpaper")
+          (key "Alt_L" "Super+Alt+Shift" "movetoworkspacesilent" "special:wallpaper")
+          (key "Control_L" "Super+Ctrl" "scroller:admitwindow" null)
+          (key "Control_L" "Super+Ctrl+Shift" "scroller:expelwindow" null)
+          (key "Shift_L" "Super+Ctrl+Shift" "scroller:setmode" "row")
+          (key "Shift_L" "Super+Shift" "scroller:setmode" "column")
+          (key "Super_L" "Super" "exec" config.custom.menus.show)
+          (key "Super_L" "Super+Alt" "exec" config.custom.menus.vault.show)
+          (key "Super_L" "Super+Ctrl+Shift" "exec" config.custom.menus.network.show)
+          (key "Super_L" "Super+Shift" "exec" config.custom.menus.search.show)
         ];
       };
     };
diff --git a/options/custom/desktops/hyprland/default.nix b/options/custom/desktops/hyprland/default.nix
index cfc09d4..f15b574 100644
--- a/options/custom/desktops/hyprland/default.nix
+++ b/options/custom/desktops/hyprland/default.nix
@@ -6,16 +6,21 @@
 }:
 with lib; let
   cfg = config.custom.desktops.hyprland;
+  hm = config.home-manager.users.${config.custom.username};
 in {
-  options.custom.desktops.hyprland.enable = mkOption {default = false;};
+  options.custom.desktops.hyprland = {
+    enable = mkOption {default = false;};
+  };
 
   config = mkIf cfg.enable {
     custom.desktops = mkIf config.custom.full {
       hyprland = {
         binds.enable = true;
+        keywords.enable = true;
+        monitors.enable = true;
         plugins.enable = true;
         rules.enable = true;
-        settings.enable = true;
+        variables.enable = true;
       };
 
       gnome = {
@@ -24,24 +29,25 @@ in {
       };
     };
 
+    # https://wiki.hyprland.org
     # https://github.com/hyprwm/Hyprland
-    programs.hyprland.enable = true;
+    programs.hyprland = {
+      enable = true;
+      package = hm.wayland.windowManager.hyprland.finalPackage;
+      withUWSM = true;
+    };
 
     xdg.portal = {
       enable = true;
       extraPortals = [pkgs.xdg-desktop-portal-gtk];
-
-      # Prefer hyprland over gtk portal
-      config.common.default = [
-        "hyprland"
-        "gtk"
-      ];
     };
 
-    # https://wiki.hyprland.org
-    home-manager.users.${config.custom.username}.wayland.windowManager.hyprland = {
-      enable = true;
-      systemd.variables = ["--all"]; # Import some environment variables into session
-    };
+    home-manager.sharedModules = [
+      {
+        wayland.windowManager.hyprland = {
+          enable = true;
+        };
+      }
+    ];
   };
 }
diff --git a/options/custom/desktops/hyprland/keywords.nix b/options/custom/desktops/hyprland/keywords.nix
new file mode 100644
index 0000000..3abad8b
--- /dev/null
+++ b/options/custom/desktops/hyprland/keywords.nix
@@ -0,0 +1,115 @@
+{
+  config,
+  lib,
+  pkgs,
+  ...
+}:
+with lib; let
+  cfg = config.custom.desktops.hyprland.keywords;
+  hm = config.home-manager.users.${config.custom.username};
+
+  audio = hm.home.file.".local/bin/audio".source;
+  grep = getExe pkgs.gnugrep;
+  left = hm.home.file.".local/bin/left".source;
+  loupe = getExe pkgs.loupe;
+  modprobe = getExe' pkgs.kmod "modprobe";
+  nautilus = getExe pkgs.nautilus;
+  sway-audio-idle-inhibit = getExe pkgs.sway-audio-idle-inhibit;
+  virsh = getExe' config.virtualisation.libvirtd.package "virsh";
+in {
+  options.custom.desktops.hyprland.keywords = {
+    enable = mkOption {default = false;};
+  };
+
+  config = mkIf cfg.enable {
+    home-manager.sharedModules = [
+      {
+        wayland.windowManager.hyprland.settings = {
+          # https://wiki.hyprland.org/Configuring/Keywords/#per-device-input-configs
+          #?? device = { name = NAME ... }
+          # https://wiki.hyprland.org/Configuring/Variables/#custom-accel-profiles
+          # https://wayland.freedesktop.org/libinput/doc/latest/pointer-acceleration.html#the-custom-acceleration-profile
+          #?? custom <STEP> <POINTS...>
+          device = let
+            # Combine duplicate devices into one attrset
+            #?? (devices ["NAME"] {ATTRS})
+            devices = names: attrs: map (name: {inherit name;} // attrs) names;
+          in
+            flatten [
+              ### Trackballs
+              (devices ["compx-2.4g-receiver-mouse" "protoarc-em04"] {
+                accel_profile = "custom 1 0 1 5 10";
+              })
+
+              (devices ["kensington-orbit-wireless-tb-mouse" "orbit-bt5.0-mouse"] {
+                left_handed = true;
+                middle_button_emulation = true;
+                natural_scroll = true;
+                sensitivity = -0.6;
+              })
+
+              (devices ["logitech-m570"] {
+                accel_profile = "custom 1 0 1 3";
+                sensitivity = -0.2;
+              })
+
+              ### Mice
+              (devices ["nordic-2.4g-wireless-receiver-mouse" "protoarc-em11-nl-mouse"] {
+                accel_profile = "flat";
+                sensitivity = -0.1;
+              })
+
+              (devices ["razer-razer-viper-ultimate" "razer-razer-viper-ultimate-dongle" "razer-razer-viper-ultimate-dongle-1"] {
+                accel_profile = "flat";
+                sensitivity = -0.1;
+              })
+
+              ### Touchpads
+              (devices ["wireless-controller-touchpad"] {
+                enabled = false;
+              })
+            ];
+
+          # https://wiki.hyprland.org/Configuring/Keywords/#setting-the-environment
+          #?? envd = VARIABLE, VALUE
+          # HACK: Mapped home-manager variables to envd in lieu of upstream fix
+          # https://github.com/nix-community/home-manager/issues/2659
+          envd = with builtins;
+            attrValues (
+              mapAttrs (
+                name: value: "${name}, ${toString value}"
+              )
+              hm.home.sessionVariables
+            )
+            ++ [
+              "EDITOR, gnome-text-editor"
+            ];
+
+          # https://wiki.hyprland.org/Configuring/Keywords/#executing
+          exec = [
+            "${left} --init --scroll kensington-orbit-wireless-tb-mouse" # Enforce left-pawed state
+          ];
+
+          # https://wiki.hyprland.org/Configuring/Keywords/#executing
+          exec-once =
+            [
+              sway-audio-idle-inhibit # Inhibit idle while audio is playing
+              "${audio} --init" # Enforce audio profile state
+              config.custom.menus.clipboard.clear-silent # Clear clipboard history
+
+              # HACK: Launch hidden GTK windows to reduce startup time
+              "[workspace special:hidden silent] ${loupe}"
+              "[workspace special:hidden silent] ${nautilus}"
+            ]
+            ++ optionals config.custom.wallpaper [
+              "wallpaper"
+            ]
+            # HACK: Delay driver initialization to work around reset issues
+            ++ optionals config.custom.settings.vm.passthrough.blacklist [
+              "${virsh} list | ${grep} ${config.custom.settings.vm.passthrough.guest} || sudo ${modprobe} ${config.custom.settings.vm.passthrough.driver}"
+            ];
+        };
+      }
+    ];
+  };
+}
diff --git a/options/custom/desktops/hyprland/monitors.nix b/options/custom/desktops/hyprland/monitors.nix
new file mode 100644
index 0000000..984eb8a
--- /dev/null
+++ b/options/custom/desktops/hyprland/monitors.nix
@@ -0,0 +1,30 @@
+{
+  config,
+  lib,
+  ...
+}:
+with lib; let
+  cfg = config.custom.desktops.hyprland.monitors;
+in {
+  options.custom.desktops.hyprland.monitors = {
+    enable = mkOption {default = false;};
+  };
+
+  config = mkIf cfg.enable {
+    home-manager.sharedModules = [
+      {
+        wayland.windowManager.hyprland.settings = {
+          # https://wiki.hyprland.org/Configuring/Monitors
+          #?? monitor = NAME, RESOLUTION, POSITION, SCALE
+          monitor = mkBefore [
+            ", highrr, auto, ${toString config.custom.scale}"
+
+            # HACK: Ensure the fallback output has a sane resolution
+            # https://github.com/hyprwm/Hyprland/issues/7276#issuecomment-2323346668
+            #// "FALLBACK, ${toString config.custom.width}x${toString config.custom.height}@60, auto, ${toString config.custom.scale}"
+          ];
+        };
+      }
+    ];
+  };
+}
diff --git a/options/custom/desktops/hyprland/plugins.nix b/options/custom/desktops/hyprland/plugins.nix
index 6d9bf27..3df163e 100644
--- a/options/custom/desktops/hyprland/plugins.nix
+++ b/options/custom/desktops/hyprland/plugins.nix
@@ -5,64 +5,67 @@
   ...
 }:
 with lib; let
-  hyprctl = "${config.programs.hyprland.package}/bin/hyprctl";
-
   cfg = config.custom.desktops.hyprland.plugins;
+
+  hyprctl = getExe' config.programs.hyprland.package "hyprctl";
 in {
-  options.custom.desktops.hyprland.plugins.enable = mkOption {default = false;};
+  options.custom.desktops.hyprland.plugins = {
+    enable = mkOption {default = false;};
+    hyprbars = mkOption {default = true;};
+    hyprscroller = mkOption {default = true;};
+  };
 
-  config.home-manager.users.${config.custom.username} = mkIf cfg.enable {
-    wayland.windowManager.hyprland = {
-      # https://github.com/hyprwm/hyprland-plugins/tree/main/hyprbars
-      # https://wiki.hyprland.org/Plugins/Using-Plugins
-      plugins = with pkgs.hyprlandPlugins; [hyprbars];
-
-      settings = {
-        #!! Static rules
-        windowrulev2 = [
-          "plugin:hyprbars:bar_color rgb(073642), focus:0"
-          "plugin:hyprbars:title_color rgb(586e75), focus:0"
-
-          "plugin:hyprbars:nobar, floating:0"
-          "plugin:hyprbars:nobar, class:^1Password$, title:^1Password$"
-          "plugin:hyprbars:nobar, class:^clipboard$"
-          "plugin:hyprbars:nobar, class:^dev\\.benz\\.walker$"
-          "plugin:hyprbars:nobar, class:^discord$, title:^Discord Updater$"
-          "plugin:hyprbars:nobar, class:^dropdown$"
-          "plugin:hyprbars:nobar, class:^looking-glass-client$"
-          "plugin:hyprbars:nobar, class:^moe\\.launcher\\..+$"
-          "plugin:hyprbars:nobar, class:^org\\.gnome\\.Nautilus$, title:^New Folder$"
-          "plugin:hyprbars:nobar, class:^org\\.gnome\\.NautilusPreviewer$"
-          "plugin:hyprbars:nobar, class:^steam$"
-          "plugin:hyprbars:nobar, class:^steam_app_.+$"
-          "plugin:hyprbars:nobar, class:^[Ww]aydroid.*$"
-          "plugin:hyprbars:nobar, class:^Xdg-desktop-portal-gtk$"
-          "plugin:hyprbars:nobar, title:^Picture.in.[Pp]icture$"
-        ];
-
-        # Plugin settings
-        plugin = {
-          hyprbars = {
-            bar_button_padding = 10;
-            bar_color = "rgb(002b36)";
-            bar_height = 30;
-            bar_padding = 10;
-            bar_precedence_over_border = true; # Render borders around hyprbars
-            bar_text_align = "left";
-            bar_text_font = config.custom.settings.fonts.monospace;
-            bar_text_size = 11;
-            #// bar_title_enabled = false;
-            "col.text" = "rgb(93a1a1)";
-
-            #?? hyprbars-button = COLOR, SIZE, ICON, EXEC
-            hyprbars-button = [
-              "rgb(dc322f), 16,, ${hyprctl} dispatch killactive" # Close
-              "rgb(d33682), 16,, ${hyprctl} dispatch fullscreen 1" # Maximize
-              "rgb(6c71c4), 16,, minimize" # Minimize
+  config = mkIf cfg.enable {
+    home-manager.sharedModules = [
+      {
+        wayland.windowManager.hyprland = {
+          # https://wiki.hyprland.org/Plugins/Using-Plugins
+          plugins = with pkgs.hyprlandPlugins;
+            optionals cfg.hyprbars [
+              # https://github.com/hyprwm/hyprland-plugins/tree/main/hyprbars
+              hyprbars
+            ]
+            ++ optionals cfg.hyprscroller [
+              # https://github.com/dawsers/hyprscroller
+              hyprscroller
             ];
+
+          settings.plugin = {
+            # https://github.com/hyprwm/hyprland-plugins/tree/main/hyprbars#config
+            hyprbars = mkIf cfg.hyprbars {
+              bar_button_padding = 10;
+              bar_color = "rgb(002b36)";
+              bar_height = 30;
+              bar_padding = 10;
+              bar_precedence_over_border = true; # Render borders around hyprbars
+              bar_text_align = "left";
+              bar_text_font = config.custom.settings.fonts.monospace;
+              bar_text_size = 11;
+              #// bar_title_enabled = false;
+              "col.text" = "rgb(93a1a1)";
+
+              # https://github.com/hyprwm/hyprland-plugins/tree/main/hyprbars#buttons-config
+              #?? hyprbars-button = COLOR, SIZE, ICON, EXEC
+              hyprbars-button = [
+                "rgb(dc322f), 16,, ${hyprctl} dispatch killactive" # Close
+                "rgb(d33682), 16,, ${hyprctl} dispatch fullscreen 1" # Maximize
+                "rgb(6c71c4), 16,, minimize" # Minimize
+              ];
+            };
+
+            # https://github.com/dawsers/hyprscroller?tab=readme-ov-file#options
+            scroller = mkIf cfg.hyprscroller {
+              "col.selection_border" = "rgb(d33682)";
+              #// center_row_if_space_available = true;
+              column_default_width = "onethird";
+              #// column_widths = "onethird onehalf twothirds one";
+              #// window_heights = "onethird onehalf twothirds one";
+              cyclesize_wrap = false;
+              focus_wrap = false;
+            };
           };
         };
-      };
-    };
+      }
+    ];
   };
 }
diff --git a/options/custom/desktops/hyprland/rules.nix b/options/custom/desktops/hyprland/rules.nix
index b90643c..2f87d77 100644
--- a/options/custom/desktops/hyprland/rules.nix
+++ b/options/custom/desktops/hyprland/rules.nix
@@ -5,23 +5,23 @@
   ...
 }:
 with lib; let
-  _1password = "${config.programs._1password-gui.package}/bin/1password";
-  gamescope = "${config.programs.gamescope.package}/bin/gamescope";
-  hyprctl = "${config.programs.hyprland.package}/bin/hyprctl";
-  kitty = "${config.home-manager.users.${config.custom.username}.programs.kitty.package}/bin/kitty";
-  launch = config.home-manager.users.${config.custom.username}.home.file.".local/bin/launch".source;
-  libreoffice = "${config.custom.programs.libreoffice.package}/bin/libreoffice";
-  loupe = "${pkgs.loupe}/bin/loupe";
-  onlyoffice-desktopeditors = "${pkgs.onlyoffice-bin}/bin/onlyoffice-desktopeditors --system-title-bar --xdg-desktop-portal";
-  pgrep = "${pkgs.procps}/bin/pgrep";
-  steam = "${config.programs.steam.package}/bin/steam";
-  virt-manager = "${pkgs.virt-manager}/bin/virt-manager";
-  waydroid = "${pkgs.waydroid}/bin/waydroid";
-  youtube-music = "${pkgs.youtube-music}/bin/youtube-music";
-
   cfg = config.custom.desktops.hyprland.rules;
+  hm = config.home-manager.users.${config.custom.username};
+
+  _1password = getExe config.programs._1password-gui.package;
+  gamescope = getExe config.programs.gamescope.package;
+  ghostty = getExe hm.programs.ghostty.package;
+  launch = hm.home.file.".local/bin/launch".source;
+  libreoffice = getExe config.custom.programs.libreoffice.package;
+  loupe = getExe pkgs.loupe;
+  steam = getExe config.programs.steam.package;
+  virt-manager = getExe pkgs.virt-manager;
+  waydroid = getExe pkgs.waydroid;
+  youtube-music = getExe pkgs.youtube-music;
 in {
-  options.custom.desktops.hyprland.rules.enable = mkOption {default = false;};
+  options.custom.desktops.hyprland.rules = {
+    enable = mkOption {default = false;};
+  };
 
   config.home-manager.users.${config.custom.username} = mkIf cfg.enable {
     wayland.windowManager.hyprland.settings = {
@@ -31,12 +31,11 @@ in {
       #?? workspace = WORKSPACE, RULES
       workspace = [
         "special:android, on-created-empty:${launch} --workspace special:android --empty ${waydroid} app launch com.YoStarEN.Arknights"
-        "special:gamescope, on-created-empty:MANGOHUD=0 ${gamescope} --fullscreen --steam ${steam}"
+        "special:game, on-created-empty:${steam}"
         "special:music, on-created-empty:${youtube-music}"
         "special:office, on-created-empty:${launch} --workspace special:office --empty --tile -- ${libreoffice}"
         "special:password, on-created-empty:${launch} --workspace special:password --empty ${_1password}"
-        "special:steam, on-created-empty:${steam}"
-        "special:terminal, on-created-empty:${kitty}"
+        "special:terminal, on-created-empty:${ghostty}"
         "special:vm, on-created-empty:${launch} --workspace special:vm --empty ${virt-manager}"
         "special:wallpaper, on-created-empty:${loupe} /tmp/wallpaper.png"
       ];
@@ -165,19 +164,20 @@ in {
           rules;
 
         class = expr: rules: merge "class" "^${expr}$" rules;
+        fields = fields: rules: merge fields null rules;
         floating = expr: rules: merge "floating" expr rules;
+        focus = expr: rules: merge "focus" expr rules;
         fullscreen = expr: rules: merge "fullscreen" expr rules;
         pinned = expr: rules: merge "pinned" expr rules;
         title = expr: rules: merge "title" "^${expr}$" rules;
 
-        fields = fields: rules: merge fields null rules;
-
         ### Pseudo-tags
         # Wrap generated rules in Nix categories
         tag = {
           android = rules: [
             (class "[Ww]aydroid.*" rules)
           ];
+
           browser = rules: [
             (class "^brave-browser$" rules)
             (class "^chromium-browser$" rules)
@@ -185,64 +185,79 @@ in {
             (class "^google-chrome$" rules)
             (class "^vivaldi.*$" rules)
           ];
+
           clipboard = rules: [
             (class "clipboard" rules)
           ];
+
           dropdown = rules: [
             (class "dropdown" rules)
           ];
+
           editor = rules: [
             (class "codium" rules) # VSCode
-            (class "obsidian" (rules ++ ["group barred"]))
+            (class "obsidian" rules)
           ];
+
           files = rules: [
             (class "org\\.gnome\\.Nautilus" rules)
           ];
+
           game = rules: [
             (class ".*\\.(exe|x86_64)" rules) # Wine
-            (class "moe\\.launcher\\..+" (rules ++ ["size 1280 730"])) # An Anime Game Launcher
+            (class "moe\\.launcher\\..+" (rules ++ ["size 1280 730" "plugin:hyprbars:nobar"])) # An Anime Game Launcher
             (class "net.retrodeck.retrodeck" rules) # Emulators
             (class "steam_app_.+" rules) # Proton
           ];
+
           media = rules: [
             (class "org\\.gnome\\.Loupe" rules)
             (class "totem" rules)
           ];
+
           music = rules: [
             (class "Spotify" rules)
             (class "YouTube Music" rules)
             (title "Spotify Premium" rules)
           ];
+
           office = rules: [
             (class "draw\\.io" rules)
             (class "libreoffice.+" rules)
             (class "ONLYOFFICE Desktop Editors" rules)
           ];
+
           password = rules: [
             (class "1Password" rules)
             (class "Bitwarden" rules)
           ];
+
           pip = rules: [
             (title "Picture.in.[Pp]icture" rules)
           ];
+
           social = rules: [
             (class "cinny" rules)
             (class "discord" rules)
             (class "Element" rules)
             (class "org\\.telegram\\.desktop" rules)
           ];
+
           steam = rules: [
             (class "SDL Application" rules) # Steam
             (class "steam" rules)
           ];
+
           terminal = rules: [
             (class "foot" rules)
+            (class "com\\.mitchellh\\.ghostty" rules)
             (class "kitty" rules)
             (class "org\\.wezfurlong\\.wezterm" rules)
           ];
+
           vm = rules: [
             (class "(sdl-|wl|x)freerdp" (rules ++ ["nomaxsize" "tile"]))
-            (class "looking-glass-client" rules)
+            (class "looking-glass-client" (rules ++ ["plugin:hyprbars:nobar"]))
             (class "org\\.remmina\\.Remmina" (rules ++ ["tile"]))
             (class "virt-manager" rules)
           ];
@@ -250,36 +265,38 @@ in {
       in
         flatten [
           ### Defaults
-          (class ".*" ["float" "group barred" "suppressevent maximize"])
-          (floating false ["noshadow"])
+          (class ".*" ["float" "suppressevent maximize"])
+          (floating false ["noshadow" "plugin:hyprbars:nobar"])
           (floating true ["noborder"])
+          (focus false ["plugin:hyprbars:bar_color rgb(073642)" "plugin:hyprbars:title_color rgb(586e75)"])
           (fullscreen true ["idleinhibit focus"])
           (pinned true ["bordercolor rgb(073642) rgb(073642)"])
 
-          (tag.android ["idleinhibit always" "move ${android.x} ${android.y}" "size ${android.w} ${android.h}" "workspace special:android silent"])
-          (tag.browser ["group override set" "tile" "workspace 1"])
-          (tag.clipboard ["move ${clipboard.x} ${clipboard.y}" "pin" "size ${clipboard.w} ${clipboard.h}" "stayfocused"])
-          (tag.dropdown ["move ${dropdown.x} ${dropdown.y}" "pin" "size ${dropdown.w} ${dropdown.h}"])
-          (tag.editor ["group override set" "tile"])
+          (tag.android ["idleinhibit always" "move ${android.x} ${android.y}" "size ${android.w} ${android.h}" "workspace special:android silent" "plugin:hyprbars:nobar"])
+          (tag.browser ["tile" "workspace 1"])
+          (tag.clipboard ["move ${clipboard.x} ${clipboard.y}" "pin" "size ${clipboard.w} ${clipboard.h}" "stayfocused" "plugin:hyprbars:nobar"])
+          (tag.dropdown ["move ${dropdown.x} ${dropdown.y}" "pin" "size ${dropdown.w} ${dropdown.h}" "plugin:hyprbars:nobar"])
+          (tag.editor ["tile"])
           (tag.files ["center"])
-          (tag.game ["focusonactivate" "idleinhibit always" "noborder" "noshadow" "renderunfocused" "workspace name:game"])
+          (tag.game ["focusonactivate" "idleinhibit always" "noborder" "noshadow" "renderunfocused" "workspace name:game" "plugin:hyprbars:nobar"])
           (tag.media ["center" "keepaspectratio" "size <90% <90%"])
           (tag.music ["tile" "workspace special:music silent"])
-          (tag.office ["group override set" "tile" "workspace special:office silent"])
-          (tag.password ["center" "tile" "workspace special:password silent"])
-          (tag.pip ["keepaspectratio" "move ${pip.x} ${pip.y}" "noinitialfocus" "pin" "size ${pip.w} ${pip.h}"])
-          (tag.social ["group override set" "tile"])
-          (tag.steam ["suppressevent activate activatefocus" "workspace special:steam silent"])
+          (tag.office ["tile" "workspace special:office silent"])
+          (tag.password ["center" "tile" "workspace special:password silent" "plugin:hyprbars:nobar"])
+          (tag.pip ["keepaspectratio" "move ${pip.x} ${pip.y}" "noinitialfocus" "pin" "size ${pip.w} ${pip.h}" "plugin:hyprbars:nobar"])
+          (tag.social ["tile"])
+          (tag.steam ["suppressevent activate activatefocus" "workspace special:steam silent" "plugin:hyprbars:nobar"])
           (tag.terminal ["tile"])
           (tag.vm ["workspace special:vm silent"])
 
           ### Overrides
-          (class "dev\\.benz\\.walker" ["noanim" "noshadow" "pin" "stayfocused"]) # Imitate layer
-          (class "org\\.gnome\\.NautilusPreviewer" ["stayfocused"]) # Sushi
-          (class "signal" ["group override new" "tile"]) # Initial window in social group
+          (class "dev\\.benz\\.walker" ["noanim" "noshadow" "pin" "stayfocused" "plugin:hyprbars:nobar"]) # Imitate layer
+          (class "org\\.gnome\\.NautilusPreviewer" ["stayfocused" "plugin:hyprbars:nobar"]) # Sushi
+          (class "signal" ["tile"]) # Initial window in social group
           (class "steam_app_1473350" ["workspace 0"]) # (the) Gnorp Apologue
           (class "Tap Wizard 2\\.x86_64" ["workspace 0"])
-          (class "Xdg-desktop-portal-gtk" ["noborder" "noshadow"])
+          (class "Xdg-desktop-portal-gtk" ["noborder" "noshadow" "plugin:hyprbars:nobar"])
+
           (title "File Upload" ["center" "float" "size 1000 625"])
           (title "Open" ["center" "float" "size 1000 625"])
           (title "Save As" ["center" "float" "size 1000 625"])
@@ -292,7 +309,7 @@ in {
           (fields {
             class = "^discord$";
             title = "^Discord Updater$"; # Update dialog
-          } ["float" "nofocus"])
+          } ["float" "nofocus" "plugin:hyprbars:nobar"])
           (fields {
             class = "^lutris$";
             title = "^Lutris$"; # Main window
@@ -305,6 +322,10 @@ in {
             class = "^org\\.gnome\\.Nautilus$";
             title = "^Home$"; # Main window
           } ["size 1000 625"])
+          (fields {
+            class = "^org\\.gnome\\.Nautilus$";
+            title = "^New Folder$";
+          } ["plugin:hyprbars:nobar"])
           (fields {
             class = "^org\\.remmina\\.Remmina$";
             title = "^Remmina.*$"; # Main windows
@@ -320,7 +341,7 @@ in {
           (fields {
             class = "^virt-manager$";
             title = "^.+on QEMU/KVM$"; # VM window
-          } ["group override set" "tile"])
+          } ["tile"])
         ];
     };
   };
diff --git a/options/custom/desktops/hyprland/settings.nix b/options/custom/desktops/hyprland/settings.nix
deleted file mode 100644
index c8e3c4d..0000000
--- a/options/custom/desktops/hyprland/settings.nix
+++ /dev/null
@@ -1,298 +0,0 @@
-{
-  config,
-  lib,
-  pkgs,
-  ...
-}:
-with lib; let
-  _1password = "${config.programs._1password-gui.package}/bin/1password";
-  audio = config.home-manager.users.${config.custom.username}.home.file.".local/bin/audio".source;
-  clipse = "${pkgs.clipse}/bin/clipse";
-  grep = "${pkgs.gnugrep}/bin/grep";
-  left = config.home-manager.users.${config.custom.username}.home.file.".local/bin/left".source;
-  loupe = "${pkgs.loupe}/bin/loupe";
-  modprobe = "${pkgs.kmod}/bin/modprobe";
-  nautilus = "${pkgs.nautilus}/bin/nautilus";
-  pkill = "${pkgs.procps}/bin/pkill";
-  rm = "${pkgs.coreutils}/bin/rm";
-  sleep = "${pkgs.coreutils}/bin/sleep";
-  sway-audio-idle-inhibit = "${pkgs.sway-audio-idle-inhibit}/bin/sway-audio-idle-inhibit";
-  systemctl = "${pkgs.systemd}/bin/systemctl";
-  virsh = "${config.virtualisation.libvirtd.package}/bin/virsh";
-  waybar = "${config.home-manager.users.${config.custom.username}.programs.waybar.package}/bin/waybar";
-
-  cfg = config.custom.desktops.hyprland.settings;
-in {
-  options.custom.desktops.hyprland.settings.enable = mkOption {default = false;};
-
-  config.home-manager.users.${config.custom.username} = mkIf cfg.enable {
-    wayland.windowManager.hyprland.settings = {
-      # https://wiki.hyprland.org/Configuring/Variables/#debug
-      debug = {
-        #// disable_logs = false;
-        enable_stdout_logs = true; # systemd-cat
-
-        #!! May result in resolution oddities
-        disable_scale_checks = true;
-      };
-
-      # https://wiki.hyprland.org/Configuring/Monitors
-      #?? monitor = NAME, RESOLUTION, POSITION, SCALE
-      monitor = mkBefore [
-        ", highrr, auto, ${toString config.custom.scale}"
-
-        # HACK: Ensure the fallback output has a sane resolution
-        # https://github.com/hyprwm/Hyprland/issues/7276#issuecomment-2323346668
-        "FALLBACK, ${toString config.custom.width}x${toString config.custom.height}@60, auto, ${toString config.custom.scale}"
-      ];
-
-      # https://wiki.hyprland.org/Configuring/Keywords/#setting-the-environment
-      #?? envd = VARIABLE, VALUE
-      # HACK: Mapped home-manager variables to envd in lieu of upstream fix
-      # https://github.com/nix-community/home-manager/issues/2659
-      envd = with builtins;
-        attrValues (
-          mapAttrs (
-            name: value: "${name}, ${toString value}"
-          )
-          config.home-manager.users.${config.custom.username}.home.sessionVariables
-        )
-        ++ [
-          "EDITOR, gnome-text-editor"
-        ];
-
-      # https://wiki.hyprland.org/Configuring/Keywords/#executing
-      exec = [
-        "${left} --init --scroll kensington-orbit-wireless-tb-mouse" # Enforce left-pawed state
-      ];
-
-      # https://wiki.hyprland.org/Configuring/Keywords/#executing
-      exec-once =
-        [
-          sway-audio-idle-inhibit # Inhibit idle while audio is playing
-          "${audio} --init" # Enforce audio profile state
-          "${rm} ~/.cache/walker/clipboard.gob" # Clear clipboard history
-          "${_1password} --silent" # Launch password manager in background
-
-          # HACK: Launch hidden GTK windows to reduce startup time
-          "[workspace special:hidden silent] ${loupe}"
-          "[workspace special:hidden silent] ${nautilus}"
-        ]
-        ++ optionals config.custom.wallpaper [
-          "wallpaper"
-        ]
-        # HACK: Delay driver initialization to work around reset issues
-        ++ optionals config.custom.settings.vm.passthrough.init [
-          "${virsh} list | ${grep} ${config.custom.settings.vm.passthrough.guest} || sudo ${modprobe} ${config.custom.settings.vm.passthrough.driver}"
-        ];
-
-      # https://wiki.hyprland.org/Configuring/Variables/#xwayland
-      xwayland = {
-        force_zero_scaling = true;
-      };
-
-      # https://wiki.hyprland.org/Configuring/Dwindle-Layout/
-      dwindle = {
-        default_split_ratio = 1.25;
-        force_split = 2; # Right
-        split_bias = 1; # Larger active window
-        split_width_multiplier = 1.5;
-      };
-
-      # https://wiki.hyprland.org/Configuring/Master-Layout/
-      # Optimized for ultrawide use by default
-      master = {
-        allow_small_split = true;
-        always_center_master = true;
-        mfact = 0.5;
-        orientation =
-          if config.custom.ultrawide
-          then "center"
-          else "top";
-      };
-
-      # https://wiki.hyprland.org/Configuring/Variables/#general
-      general = {
-        "col.active_border" = "rgb(93a1a1)";
-        "col.inactive_border" = "rgba(93a1a140)";
-        "col.nogroup_border_active" = "rgb(dc322f)";
-        "col.nogroup_border" = "rgba(dc322f40)";
-        #// allow_tearing = true;
-        border_size = config.custom.border;
-        extend_border_grab_area = 5;
-        gaps_in = config.custom.gap / 2;
-        gaps_out = config.custom.gap;
-        layout = "master";
-        #// no_border_on_floating = true;
-        #// resize_corner = 3; # Bottom-right
-        resize_on_border = true;
-        snap.enabled = true;
-      };
-
-      # https://wiki.hyprland.org/Configuring/Animations
-      #?? animation = NAME, ONOFF, SPEED, CURVE, [STYLE]
-      animation = [
-        "global, 1, 3, default"
-        "specialWorkspace, 1, 3, default, fade"
-        "windows, 1, 3, default, slide"
-        "layers, 0"
-      ];
-
-      # https://wiki.hyprland.org/Configuring/Variables/#decoration
-      decoration = {
-        blur.enabled = false;
-        dim_special = 0.25;
-        rounding = config.custom.rounding;
-
-        shadow = {
-          color = "rgba(00000040)";
-          color_inactive = "rgba(0000001a)";
-          range = 50;
-          render_power = 4; # Distance falloff
-        };
-      };
-
-      # https://wiki.hyprland.org/Configuring/Variables/#group
-      group = {
-        "col.border_active" = "rgb(6c71c4)";
-        "col.border_inactive" = "rgba(6c71c440)";
-        "col.border_locked_active" = "rgb(d33682)";
-        "col.border_locked_inactive" = "rgba(d3368240)";
-        #// auto_group = false;
-        #// insert_after_current = false;
-
-        # https://wiki.hyprland.org/Configuring/Variables/#groupbar
-        groupbar = {
-          "col.active" = "rgb(6c71c4)";
-          "col.inactive" = "rgba(6c71c440)";
-          "col.locked_active" = "rgb(d33682)";
-          "col.locked_inactive" = "rgba(d3368240)";
-          font_size =
-            if config.custom.hidpi
-            then 16
-            else 10;
-          height = 5;
-          render_titles = false;
-          text_color = "rgb(93a1a1)";
-        };
-      };
-
-      # https://wiki.hyprland.org/Configuring/Variables/#misc
-      misc = {
-        #// animate_manual_resizes = true;
-        #// animate_mouse_windowdragging = true;
-        background_color = "rgb(073642)";
-        disable_hyprland_logo = true;
-        disable_splash_rendering = true;
-        focus_on_activate = true;
-        font_family = config.custom.settings.fonts.monospace;
-        force_default_wallpaper = 0;
-        initial_workspace_tracking = 2; # All children
-        key_press_enables_dpms = true;
-        middle_click_paste = false;
-
-        # BUG: Still causes hard freezes
-        #// vrr = 2; # VRR in fullscreen
-      };
-
-      # https://wiki.hyprland.org/Configuring/Variables/#binds
-      binds = {
-        allow_workspace_cycles = true;
-        disable_keybind_grabbing = true;
-        ignore_group_lock = true;
-        scroll_event_delay = 0;
-      };
-
-      # https://wiki.hyprland.org/Configuring/Variables/#input
-      input = {
-        accel_profile = "adaptive";
-        float_switch_override_focus = 0; # Disable float to tile hover focus
-        #// focus_on_close = 1; # Focus window under mouse
-        follow_mouse = 1; # Hover focus
-
-        # BUG: Refocusing causes multiple issues related to mouse cursor
-        # https://github.com/hyprwm/Hyprland/issues/8057
-        mouse_refocus = false; # Required to focus last window on close
-
-        repeat_delay = 250;
-        repeat_rate = 30;
-        sensitivity = 0.5;
-        #// scroll_factor = 0.75;
-        special_fallthrough = true; # Focus windows under special workspace
-
-        touchpad = {
-          clickfinger_behavior = true; # Multi-finger clicks
-          natural_scroll = true;
-          scroll_factor = 0.5;
-        };
-      };
-
-      # https://wiki.hyprland.org/Configuring/Variables/#render
-      render = {
-        #// explicit_sync = 1;
-        #// explicit_sync_kms = 1;
-      };
-
-      # https://wiki.hyprland.org/Configuring/Variables/#cursor
-      cursor = {
-        hide_on_key_press = true;
-        #// hotspot_padding = config.custom.gap;
-        #// min_refresh_rate = 60; # !! Hardware dependent
-        #// no_break_fs_vrr = true;
-        #// no_hardware_cursors = true;
-        no_warps = true;
-        zoom_rigid = true;
-      };
-
-      # https://wiki.hyprland.org/Configuring/Variables/#gestures
-      gestures = {
-        workspace_swipe = true;
-        workspace_swipe_cancel_ratio = 0.2;
-        workspace_swipe_distance = 1000;
-        #// workspace_swipe_forever = true;
-        workspace_swipe_min_speed_to_force = 10;
-      };
-
-      # https://wiki.hyprland.org/Configuring/Keywords/#per-device-input-configs
-      #?? device = { name = NAME ... }
-      # https://wiki.hyprland.org/Configuring/Variables/#custom-accel-profiles
-      # https://wayland.freedesktop.org/libinput/doc/latest/pointer-acceleration.html#the-custom-acceleration-profile
-      #?? custom <STEP> <POINTS...>
-      device = let
-        # Combine duplicate devices into one attrset
-        #?? (devices ["NAME"] {ATTRS})
-        devices = names: attrs: map (name: {inherit name;} // attrs) names;
-      in
-        flatten [
-          (devices ["compx-2.4g-receiver-mouse" "protoarc-em04"] {
-            accel_profile = "custom 1 0 1 5 10";
-          })
-
-          (devices ["kensington-orbit-wireless-tb-mouse" "orbit-bt5.0-mouse"] {
-            accel_profile = "adaptive";
-            left_handed = true;
-            middle_button_emulation = true;
-            natural_scroll = true;
-            sensitivity = -0.6;
-          })
-
-          (devices ["logitech-m570"] {
-            accel_profile = "custom 1 0 1 3";
-            sensitivity = -0.2;
-          })
-
-          (devices ["nordic-2.4g-wireless-receiver-mouse" "protoarc-em11-nl-mouse"] {
-            sensitivity = -0.7;
-          })
-
-          (devices ["razer-razer-viper-ultimate" "razer-razer-viper-ultimate-dongle" "razer-razer-viper-ultimate-dongle-1"] {
-            sensitivity = -0.7;
-          })
-
-          (devices ["wireless-controller-touchpad"] {
-            enabled = false;
-          })
-        ];
-    };
-  };
-}
diff --git a/options/custom/desktops/hyprland/variables.nix b/options/custom/desktops/hyprland/variables.nix
new file mode 100644
index 0000000..bae04bf
--- /dev/null
+++ b/options/custom/desktops/hyprland/variables.nix
@@ -0,0 +1,191 @@
+{
+  config,
+  lib,
+  ...
+}:
+with lib; let
+  cfg = config.custom.desktops.hyprland.variables;
+in {
+  options.custom.desktops.hyprland.variables = {
+    enable = mkOption {default = false;};
+  };
+
+  config = mkIf cfg.enable {
+    home-manager.sharedModules = [
+      {
+        wayland.windowManager.hyprland.settings = {
+          # https://wiki.hyprland.org/Configuring/Animations/
+          #?? animation = NAME, ONOFF, SPEED, CURVE, [STYLE]
+          animation = [
+            "global, 1, 4, default"
+            "specialWorkspace, 1, 4, default, fade"
+            "windows, 1, 4, default, slide"
+            "workspaces, 1, 4, default, slidevert"
+            "layers, 0"
+          ];
+
+          # https://wiki.hyprland.org/Configuring/Variables/#binds
+          binds = {
+            allow_workspace_cycles = true;
+            disable_keybind_grabbing = true;
+            ignore_group_lock = true;
+            scroll_event_delay = 0;
+          };
+
+          # https://wiki.hyprland.org/Configuring/Variables/#cursor
+          cursor = {
+            #// hide_on_key_press = true;
+            #// hotspot_padding = config.custom.gap;
+            #// min_refresh_rate = 60; # !! Hardware dependent
+            #// no_break_fs_vrr = true;
+            #// no_hardware_cursors = true;
+            no_warps = true;
+            zoom_rigid = true;
+          };
+
+          # https://wiki.hyprland.org/Configuring/Variables/#decoration
+          decoration = {
+            blur.enabled = false;
+            dim_special = 0.25;
+            rounding = config.custom.rounding;
+
+            shadow = {
+              color = "rgba(00000040)";
+              color_inactive = "rgba(0000001a)";
+              range = 50;
+              render_power = 4; # Distance falloff
+            };
+          };
+
+          # https://wiki.hyprland.org/Configuring/Dwindle-Layout/
+          dwindle = {
+            default_split_ratio = 1.25;
+            force_split = 2; # Right
+            split_bias = 1; # Larger active window
+            split_width_multiplier = 1.5;
+          };
+
+          # https://wiki.hyprland.org/Configuring/Variables/#general
+          general = {
+            "col.active_border" = "rgb(d33682)";
+            "col.inactive_border" = "rgba(00000000)";
+            "col.nogroup_border_active" = "rgb(dc322f)";
+            "col.nogroup_border" = "rgba(00000000)";
+            #// allow_tearing = true;
+            border_size = config.custom.border;
+            extend_border_grab_area = 5;
+            gaps_in = config.custom.gap / 4;
+            gaps_out = config.custom.gap;
+            layout = "scroller";
+            #// no_border_on_floating = true;
+            #// resize_corner = 3; # Bottom-right
+            resize_on_border = true;
+            snap.enabled = true;
+          };
+
+          # https://wiki.hyprland.org/Configuring/Variables/#gestures
+          gestures = {
+            workspace_swipe = !config.custom.desktops.hyprland.plugins.hyprscroller;
+            workspace_swipe_cancel_ratio = 0.2;
+            workspace_swipe_distance = 1000;
+            #// workspace_swipe_forever = true;
+            workspace_swipe_min_speed_to_force = 10;
+          };
+
+          # https://wiki.hyprland.org/Configuring/Variables/#group
+          group = {
+            "col.border_active" = "rgb(6c71c4)";
+            "col.border_inactive" = "rgba(00000000)";
+            "col.border_locked_active" = "rgb(cb4b16)";
+            "col.border_locked_inactive" = "rgba(00000000)";
+            #// auto_group = false;
+            #// insert_after_current = false;
+
+            # https://wiki.hyprland.org/Configuring/Variables/#groupbar
+            groupbar = {
+              "col.active" = "rgb(6c71c4)";
+              "col.inactive" = "rgba(00000000)";
+              "col.locked_active" = "rgb(cb4b16)";
+              "col.locked_inactive" = "rgba(00000000)";
+
+              font_size =
+                if config.custom.hidpi
+                then 16
+                else 10;
+
+              height = 5;
+              render_titles = false;
+              text_color = "rgb(93a1a1)";
+            };
+          };
+
+          # https://wiki.hyprland.org/Configuring/Variables/#input
+          input = {
+            accel_profile = "adaptive";
+            float_switch_override_focus = 0; # Disable float to tile hover focus
+            #// focus_on_close = 1; # Focus window under mouse
+            follow_mouse = 1; # Hover focus
+
+            # BUG: Refocusing causes multiple issues related to mouse cursor
+            # https://github.com/hyprwm/Hyprland/issues/8057
+            mouse_refocus = false; # Required to focus last window on close
+
+            repeat_delay = 250;
+            repeat_rate = 30;
+            sensitivity = 0.5;
+            scroll_factor = 1.25;
+            #// special_fallthrough = true; # Focus windows under special workspace
+
+            touchpad = {
+              clickfinger_behavior = true; # Multi-finger clicks
+              natural_scroll = true;
+              scroll_factor = 0.5;
+            };
+          };
+
+          # https://wiki.hyprland.org/Configuring/Master-Layout/
+          # Optimized for ultrawide use by default
+          master = {
+            allow_small_split = true;
+            mfact = 0.4;
+            slave_count_for_center_master = 0;
+
+            orientation =
+              if config.custom.ultrawide
+              then "center"
+              else "top";
+          };
+
+          # https://wiki.hyprland.org/Configuring/Variables/#misc
+          misc = {
+            #// animate_manual_resizes = true;
+            #// animate_mouse_windowdragging = true;
+            background_color = "rgb(073642)";
+            disable_hyprland_logo = true;
+            disable_splash_rendering = true;
+            focus_on_activate = true;
+            font_family = config.custom.settings.fonts.monospace;
+            force_default_wallpaper = 0;
+            #// initial_workspace_tracking = 2; # All children
+            key_press_enables_dpms = true;
+            middle_click_paste = false;
+
+            # BUG: Still causes hard freezes
+            #// vrr = 2; # VRR in fullscreen
+          };
+
+          # https://wiki.hyprland.org/Configuring/Variables/#render
+          render = {
+            #// explicit_sync = 1;
+            #// explicit_sync_kms = 1;
+          };
+
+          # https://wiki.hyprland.org/Configuring/Variables/#xwayland
+          xwayland = {
+            force_zero_scaling = true;
+          };
+        };
+      }
+    ];
+  };
+}
diff --git a/options/custom/scripts/default.nix b/options/custom/scripts/default.nix
index 46f8931..f1bea83 100644
--- a/options/custom/scripts/default.nix
+++ b/options/custom/scripts/default.nix
@@ -6,7 +6,7 @@
 }:
 with lib; let
   git = config.home-manager.users.${config.custom.username}.programs.git.package;
-  hyprland = config.home-manager.users.${config.custom.username}.wayland.windowManager.hyprland.finalPackage;
+  hyprland = config.programs.hyprland.package;
   walker = config.home-manager.users.${config.custom.username}.programs.walker.package;
   wofi = config.home-manager.users.${config.custom.username}.programs.wofi.package;
 in {