diff --git a/flake.lock b/flake.lock
index 524d78b..d0c9d44 100644
--- a/flake.lock
+++ b/flake.lock
@@ -5,11 +5,11 @@
         "nixpkgs": "nixpkgs"
       },
       "locked": {
-        "lastModified": 1737579274,
-        "narHash": "sha256-8kBIYfn8TI9jbffhDNS12SdbQHb9ITXflwcgIJBeGqw=",
+        "lastModified": 1745352209,
+        "narHash": "sha256-u3vJEzi6zxgG59KXjMR5koERsdKT5nd1OEKCpr6zgn8=",
         "owner": "catppuccin",
         "repo": "nix",
-        "rev": "06f0ea19334bcc8112e6d671fd53e61f9e3ad63a",
+        "rev": "6268e50dbb0ac9375e110560395b5dc199e4dfb8",
         "type": "github"
       },
       "original": {
@@ -46,11 +46,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1736373539,
-        "narHash": "sha256-dinzAqCjenWDxuy+MqUQq0I4zUSfaCvN9rzuCmgMZJY=",
+        "lastModified": 1744743431,
+        "narHash": "sha256-iyn/WBYDc7OtjSawbegINDe/gIkok888kQxk3aVnkgg=",
         "owner": "nix-community",
         "repo": "home-manager",
-        "rev": "bd65bc3cde04c16755955630b344bc9e35272c56",
+        "rev": "c61bfe3ae692f42ce688b5865fac9e0de58e1387",
         "type": "github"
       },
       "original": {
@@ -62,11 +62,11 @@
     },
     "nixpkgs": {
       "locked": {
-        "lastModified": 1736012469,
-        "narHash": "sha256-/qlNWm/IEVVH7GfgAIyP6EsVZI6zjAx1cV5zNyrs+rI=",
+        "lastModified": 1744463964,
+        "narHash": "sha256-LWqduOgLHCFxiTNYi3Uj5Lgz0SR+Xhw3kr/3Xd0GPTM=",
         "owner": "NixOS",
         "repo": "nixpkgs",
-        "rev": "8f3e1f807051e32d8c95cd12b9b421623850a34d",
+        "rev": "2631b0b7abcea6e640ce31cd78ea58910d31e650",
         "type": "github"
       },
       "original": {
@@ -78,11 +78,11 @@
     },
     "nixpkgs-unstable": {
       "locked": {
-        "lastModified": 1738410390,
-        "narHash": "sha256-xvTo0Aw0+veek7hvEVLzErmJyQkEcRk6PSR4zsRQFEc=",
+        "lastModified": 1745234285,
+        "narHash": "sha256-GfpyMzxwkfgRVN0cTGQSkTC0OHhEkv3Jf6Tcjm//qZ0=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "3a228057f5b619feb3186e986dbe76278d707b6e",
+        "rev": "c11863f1e964833214b767f4a369c6e6a7aba141",
         "type": "github"
       },
       "original": {
@@ -94,11 +94,11 @@
     },
     "nixpkgs_2": {
       "locked": {
-        "lastModified": 1738435198,
-        "narHash": "sha256-5+Hmo4nbqw8FrW85FlNm4IIrRnZ7bn0cmXlScNsNRLo=",
+        "lastModified": 1745279238,
+        "narHash": "sha256-AQ7M9wTa/Pa/kK5pcGTgX/DGqMHyzsyINfN7ktsI7Fo=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "f6687779bf4c396250831aa5a32cbfeb85bb07a3",
+        "rev": "9684b53175fc6c09581e94cc85f05ab77464c7e3",
         "type": "github"
       },
       "original": {
@@ -110,11 +110,11 @@
     },
     "nixpkgs_3": {
       "locked": {
-        "lastModified": 1738142207,
-        "narHash": "sha256-NGqpVVxNAHwIicXpgaVqJEJWeyqzoQJ9oc8lnK9+WC4=",
+        "lastModified": 1745234285,
+        "narHash": "sha256-GfpyMzxwkfgRVN0cTGQSkTC0OHhEkv3Jf6Tcjm//qZ0=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "9d3ae807ebd2981d593cddd0080856873139aa40",
+        "rev": "c11863f1e964833214b767f4a369c6e6a7aba141",
         "type": "github"
       },
       "original": {
@@ -131,11 +131,11 @@
         "treefmt-nix": "treefmt-nix"
       },
       "locked": {
-        "lastModified": 1738362438,
-        "narHash": "sha256-EO2dVkMVLThWqv4hobEZEZGWBEuH2Z9SYqQDrbLSclU=",
+        "lastModified": 1745419524,
+        "narHash": "sha256-oDRzqjH44hOEvJAyA1A+pCp01+rkjEvW1+AXCCvEYNE=",
         "owner": "nix-community",
         "repo": "NUR",
-        "rev": "95ddad0ff0e67c90314c6ca46324dce5f9a910d2",
+        "rev": "a5724250ee4c962f1fbfe992061e296955277961",
         "type": "github"
       },
       "original": {
diff --git a/nate-work/default.nix b/nate-work/default.nix
index 664cf5e..a328da4 100644
--- a/nate-work/default.nix
+++ b/nate-work/default.nix
@@ -11,6 +11,7 @@
   imports = [
       ./desktop-configuration.nix
       ./nixos/hardware-configuration.nix
+      ./nixos/auto-update.nix
   ];
 
   deskCfg = {
@@ -30,19 +31,8 @@
     options = "--delete-older-than 14d";
   };
 
-  ### TODO add these to security.nix file
-  # Auto Update System
-  system.autoUpgrade = {
-    enable = true;
-    flake = inputs.self.outPath;
-    flags = [
-      "--update-input"
-      "nixpkgs"
-      "nixpkgs-unstable"
-      "-L" # print build logs
-    ];
-    dates = "05:00";
-    randomizedDelaySec = "45min";
+  autoCfg = {
+    userName = userName;
   };
 
   services.clamav.daemon.enable = true;
diff --git a/nate-work/desktop-configuration.nix b/nate-work/desktop-configuration.nix
index c63d09a..f98f0ee 100644
--- a/nate-work/desktop-configuration.nix
+++ b/nate-work/desktop-configuration.nix
@@ -61,7 +61,12 @@ in
     networking.networkmanager.enable = true;  # Easiest to use and most distros use this by default.
   
     time.timeZone = timeZone;
-   
+
+    hardware.sane = {
+      enable = true;
+      brscan5.enable = true;
+    };
+
     main_user = {
       enable = true;
       userName = deskCfg.userName;
diff --git a/nate-work/modules/home-manager/home.nix b/nate-work/modules/home-manager/home.nix
index 5ec4e2e..e77a61f 100644
--- a/nate-work/modules/home-manager/home.nix
+++ b/nate-work/modules/home-manager/home.nix
@@ -75,6 +75,7 @@
       mariadb
       lsp-ai
       python3
+      cmake
 
       # Go stuff
       go
@@ -83,6 +84,14 @@
       go-tools
       golangci-lint
 
+      # clojure
+      jre17_minimal
+      clojure
+      clojure-lsp
+      cljfmt
+      leiningen
+      emacs
+
       ### LSP's
       gopls
       nil # Nix LSP
@@ -92,6 +101,8 @@
       python311Packages.python-lsp-server
       gopls
       delve
+      yaml-language-server
+      elixir-ls
 
       ### Misc
       usbutils
@@ -133,6 +144,7 @@
       yt-dlp
       libimobiledevice
       ifuse
+      simple-scan
 
       #
       # Communication
@@ -149,7 +161,7 @@
       kdePackages.filelight
       hugo
       go-swag
-      llama-cpp
+      unstable.llama-cpp
       
       #
       # Style
@@ -194,7 +206,6 @@
   home.sessionVariables = {
     # BAT_THEME="Catppuccin Macchiato";
     EDITOR = "hx";
-    NIXOS_OZONE_WL = "1";
     XCURSOR_THEME = "Bibata-Modern-Classic";
     XCURSOR_SIZE = "24";
     HYPRCURSOR_THEME = "Bibata-Modern-Classic";
diff --git a/nate-work/modules/hypr/hypr_home.nix b/nate-work/modules/hypr/hypr_home.nix
index 99a354f..e1ecc07 100644
--- a/nate-work/modules/hypr/hypr_home.nix
+++ b/nate-work/modules/hypr/hypr_home.nix
@@ -46,6 +46,8 @@ in
         touchpad = {
           natural_scroll = true;
         };
+        follow_mouse = 0; # cursor movement will change focus
+        float_switch_override_focus = 0;
       };
       bezier = [
         "easeout, 0, 0.55, 0.45, 1"
@@ -155,30 +157,32 @@ in
       bindl = [
         # trigger when the switch is turning on
         ", switch:on:Lid Switch, exec, hyprctl keyword monitor 'eDP-1, disable' && nwg-panel"
-        # ", switch:on:[switch name], exec, hyprctl dispatch dpms off eDP-1 "
+
         # trigger when the switch is turning off
         ", switch:off:Lid Switch, exec, hyprctl keyword monitor 'eDP-1, 2560x1600@165, 0x0, 1.00' && nwg-panel"
-        # ", switch:off:[switch name], exec, hyprctl dispatch dpms on eDP-1"
       ];
       windowrulev2 = [
         # float keepass windows, put main window in scratch
         "float, class:^(org.keepassxc.KeePassXC)$"
         "workspace special:scratch silent, class:^(org.keepassxc.KeePassXC)$ title:\[Locked\]"
+        
         # float music windows and move to music workspace
-        "tag +fmusic, class:^(firefox)$, title:^(YouTube — Mozilla Firefox)$"
-        "float, tag:^(fmusic)$"# class:^(firefox)$, title:YouTube"
-        "workspace special:music silent, tag:^(fmusic)$"# class:^(firefox)$, title:YouTube"
-        "size 800 400, tag:^(fmusic)$"# class:^(firefox)$, title:YouTube"
-        "move 100%-w-20 100%-h-20, tag:^(fmusic)$"# class:^(firefox)$, title:YouTube"
+        # "tag +fmusic, class:^(firefox)$, title:^(YouTube — Mozilla Firefox)$"
+        # "float, tag:^(fmusic)$"# class:^(firefox)$, title:YouTube"
+        # "workspace special:music silent, tag:^(fmusic)$"# class:^(firefox)$, title:YouTube"
+        # "size 800 400, tag:^(fmusic)$"# class:^(firefox)$, title:YouTube"
+        # "move 100%-w-20 100%-h-20, tag:^(fmusic)$"# class:^(firefox)$, title:YouTube"
 
       ];
-      # Auto tile new unspecified monitors to the right, in preferred resolution
       monitor = [
         "eDP-1, 2560x1600@165, 0x0, 1.00"
         # At home monitor setup, 144 for hdmi bandwidth
         "desc:LG Electronics LG ULTRAGEAR+ 406NTJJ6B876, 3840x2160@144, auto, 1, vrr, 1"
-        "desc:LG Electronics LG HDR WQHD 403MXVW10247, 3440x1440@84.96, auto, 1, vrr, 1"
-        ", preferred, auto, 1"
+        # Work monitor over USBC
+        "eDP-2, 3440x1440@99.98Hz, auto, 1, vrr, 1"
+        "eDP-3, 3440x1440@99.98Hz, auto, 1, vrr, 1"
+        # Auto tile new unspecified monitors to the right, in preferred resolution
+        ", preferred, auto-right, 1"
       ];
       cursor = {
         no_hardware_cursors = true;
@@ -189,6 +193,11 @@ in
         force_default_wallpaper = 0;
         disable_hyprland_logo = true;
       };
+      render = {
+        explicit_sync = 1;
+        explicit_sync_kms = 1;
+        direct_scanout = "no";
+      };
     };
     wayland.windowManager.hyprland.systemd.variables = ["--all"];
 
diff --git a/nate-work/modules/hypr/hyprland.nix b/nate-work/modules/hypr/hyprland.nix
index a8c5938..127d070 100644
--- a/nate-work/modules/hypr/hyprland.nix
+++ b/nate-work/modules/hypr/hyprland.nix
@@ -55,10 +55,11 @@ in
       sessionVariables = {
         # use wayland
         MOZ_ENABLE_WAYLAND = "1";
-        # NIXOS_OZONE_WL = "1";
         T_QPA_PLATFORM = "wayland";
         GDK_BACKEND = "wayland";
         WLR_NO_HARDWARE_CURSORS = "1";
+        ELECTRON_OZONE_PLATFORM_HINT = "auto";
+        NIXOS_OZONE_WL = "1";
         # For hyprland
         # Only enable if not using on-the-go
         GBM_BACKEND = if isOnTheGo then "" else "nvidia-drm";
@@ -79,18 +80,32 @@ in
         ];
     };
 
+    programs.virt-manager.enable = true;
     virtualisation = {
         docker = {
           enable = true;
           enableOnBoot = true;
           package = unstable.docker_25;
         };
+        libvirtd = {
+          enable = true;
+          qemu = {
+            swtpm.enable = true;
+            ovmf.enable = true;
+            ovmf.packages = [ pkgs.OVMFFull.fd ];
+           };
+        };
+        spiceUSBRedirection.enable = true;
+
         # containers.cdi.dynamic.nvidia.enable = true;
         # podman = {
         #     enable = true;
         #     dockerCompat = true;
         # };
     };
+    boot.initrd.supportedFilesystems = { nfs = true; };
+
+    users.groups.libvirtd.members = ["nate"];
     # enable nvidia passthru for containers
     # hardware.nvidia-container-toolkit.enable = true;
 
@@ -222,11 +237,11 @@ in
         # Enable this if you have graphical corruption issues or application crashes after waking
         # up from sleep. This fixes it by saving the entire VRAM memory to /tmp/ instead 
         # of just the bare essentials.
-        powerManagement.enable = true;
+        powerManagement.enable = false;
 
         # Fine-grained power management. Turns off GPU when not in use.
         # Experimental and only works on modern Nvidia GPUs (Turing or newer).
-        powerManagement.finegrained = true;
+        powerManagement.finegrained = false;
 
         # Use the NVidia open source kernel module (not to be confused with the
         # independent third-party "nouveau" open source driver).
@@ -235,7 +250,7 @@ in
         # https://github.com/NVIDIA/open-gpu-kernel-modules#compatible-gpus 
         # Only available from driver 515.43.04+
         # Currently alpha-quality/buggy, so false is currently the recommended setting.
-        open = false;
+        open = true;
 
         # Enable the Nvidia settings menu,
   	    # accessible via `nvidia-settings`.
diff --git a/nate-work/modules/user/main_user.nix b/nate-work/modules/user/main_user.nix
index 6789ea1..ac57f03 100644
--- a/nate-work/modules/user/main_user.nix
+++ b/nate-work/modules/user/main_user.nix
@@ -38,18 +38,18 @@ in
             })
             (lib.mkIf cfg.isDesktopUser {
                 extraGroups = [
-                    "wheel"
-                    "networkmanager"
-                    cfg.userName
-                    "video"
-                    "audio"
-                    # For android
                     "adbusers"
-                    # For serial interfaces
+                    "audio"
+                    cfg.userName
                     "dialout"
-                    # For docker
                     "docker"
+                    "lp"
+                    "networkmanager"
+                    "scanner"
                     "syncthing"
+                    "video"
+                    "wheel"
+
                 ];
             })
         ];
diff --git a/nate-work/nixos/auto-update.nix b/nate-work/nixos/auto-update.nix
new file mode 100644
index 0000000..aecd43f
--- /dev/null
+++ b/nate-work/nixos/auto-update.nix
@@ -0,0 +1,113 @@
+{ config, pkgs, lib, ...}:
+let
+  autoCfg = config.autoCfg;
+in
+{
+
+  options.autoCfg= {
+      userName = lib.mkOption {
+          type = lib.types.str;
+          description = "username for enabling sudo-less system updates";
+      };
+  };
+
+  config = {
+    # Make sure the user can use sudo for nixos-rebuild without password
+    security.sudo.extraRules = [
+      {
+        users = [ autoCfg.userName ];
+        commands = [
+          {
+            command = "${pkgs.nixos-rebuild}/bin/nixos-rebuild";
+            options = [ "NOPASSWD" ];
+          }
+        ];
+      }
+    ];
+
+    # Disable builtin auto-update because we hand-rollin
+    system.autoUpgrade.enable = false;
+
+    # Define user services and timers
+    systemd.user.services.nixos-flake-update = {
+      description = "Update NixOS Flake Inputs";
+      serviceConfig = {
+        Type = "oneshot";
+        ExecStart = pkgs.writeShellScript "nixos-flake-update.sh" ''
+          set -e
+          cd ~/nixos
+        
+          echo "Updating flake inputs..."
+          ${pkgs.nix}/bin/nix flake lock \
+            --update-input nixpkgs \
+            --update-input nixpkgs-unstable
+          
+          echo "Flake inputs updated successfully"
+        '';
+      };
+      environment = {
+        NIX_CONFIG = "experimental-features = nix-command flakes";
+      };
+    };
+
+    systemd.user.services.nixos-rebuild = {
+      description = "Rebuild NixOS";
+      serviceConfig = {
+        Type = "oneshot";
+        ExecStart = pkgs.writeShellScript "nixos-rebuild.sh" ''
+          set -e
+        
+          echo "Rebuilding NixOS..."
+          ${pkgs.nixos-rebuild}/bin/nixos-rebuild switch \
+            -L \
+            --flake ~/nixos#nate-work
+          
+          echo "NixOS rebuild completed successfully"
+        '';
+      };
+    };
+
+    # Combined service that runs both update and rebuild in sequence
+    systemd.user.services.nixos-upgrade = {
+      description = "Update and Rebuild NixOS";
+      serviceConfig = {
+        Type = "oneshot";
+        # Use a shell script to run both operations in sequence
+        ExecStart = pkgs.writeShellScript "nixos-complete-upgrade.sh" ''
+          set -e
+        
+          echo "Starting complete NixOS upgrade process..."
+        
+          # First update the flake inputs
+          systemctl --user start nixos-flake-update.service
+          systemctl --user status nixos-flake-update.service --no-pager
+        
+          # Then rebuild if the update was successful
+          if [ $? -eq 0 ]; then
+            systemctl --user start nixos-rebuild.service
+            systemctl --user status nixos-rebuild.service --no-pager
+          else
+            echo "Flake update failed, skipping rebuild"
+            exit 1
+          fi
+        
+          echo "Complete NixOS upgrade process finished"
+        '';
+      };
+      environment = {
+        NIX_CONFIG = "experimental-features = nix-command flakes";
+      };
+    };
+
+    # Timer to run the upgrade service
+    systemd.user.timers.nixos-upgrade = {
+      description = "Timer for NixOS Upgrade";
+      wantedBy = [ "timers.target" ];
+      timerConfig = {
+        OnCalendar = "12:00";
+        RandomizedDelaySec = "45min";
+        Persistent = true; # Run immediately if last run was missed
+      };
+    };
+  };
+}
diff --git a/nate/modules/user/main_user.nix b/nate/modules/user/main_user.nix
index be730ac..90b97bf 100644
--- a/nate/modules/user/main_user.nix
+++ b/nate/modules/user/main_user.nix
@@ -38,18 +38,16 @@ in
             })
             (lib.mkIf cfg.isDesktopUser {
                 extraGroups = [
-                    "wheel"
-                    "networkmanager"
-                    "corectrl"
-                    cfg.userName
-                    "video"
-                    "audio"
-                    # For android
                     "adbusers"
-                    # For serial interfaces
+                    "audio"
+                    cfg.userName
+                    "corectrl"
                     "dialout"
-                    # For docker
                     "docker"
+                    "networkmanager"
+                    "video"
+                    "wheel"
+
                 ];
             })
         ];