From 569bc3153ed557516ab583b4cb0f91957a6c26f5 Mon Sep 17 00:00:00 2001
From: prescientmoon <git@moonythm.dev>
Date: Sun, 1 Jun 2025 20:43:24 +0200
Subject: [PATCH] Make hyprland work nicely with the GTK portals, and move some
 modules around into being active by default in home manager

---
 README.md                                     |   3 +
 common/themes/default.nix                     |   8 +-
 flake.lock                                    | 137 +++++++++++++++---
 flake.nix                                     |   7 +-
 home/calypso.nix                              |  54 ++-----
 home/features/cli/bat.nix                     |   6 +-
 home/features/cli/default.nix                 |  49 ++++---
 home/features/cli/direnv.nix                  |  11 +-
 home/features/cli/fish/config.fish            |  28 ++--
 home/features/cli/fish/default.nix            |  18 +--
 home/features/cli/nix-index.nix               |   5 -
 .../cli/productivity/secrets.example.yaml     |   2 -
 home/features/cli/productivity/secrets.yaml   |  12 +-
 home/features/cli/scripts/default.nix         |   6 -
 home/features/cli/scripts/uptimes.sh          |  27 ----
 home/features/cli/ssh.nix                     |   4 -
 home/features/cli/starship.nix                |   3 -
 home/features/cli/tealdeer.nix                |   5 +-
 home/features/cli/yazi.nix                    |   2 +-
 home/features/cli/zellij.nix                  |   4 -
 home/features/desktop/default.nix             |  25 +++-
 home/features/desktop/gaming/default.nix      |   1 +
 home/features/desktop/inlyne.nix              |  19 +++
 home/features/neovim/config/lua/my/lazy.lua   |   2 +-
 .../features/neovim/config/spell/en.utf-8.add |   5 +
 home/features/wayland/global.nix              |   7 +-
 home/features/wayland/hyprland/default.nix    |  20 ++-
 home/features/wayland/hyprland/hyprland.conf  |   5 +-
 home/tethys.nix                               |  55 +------
 .../common/optional/desktop/xdg-portal.nix    |  12 +-
 hosts/nixos/lapetus/services/vaultwarden.nix  |  18 ++-
 justfile                                      |   4 +-
 32 files changed, 302 insertions(+), 262 deletions(-)
 delete mode 100644 home/features/cli/nix-index.nix
 delete mode 100644 home/features/cli/scripts/default.nix
 delete mode 100755 home/features/cli/scripts/uptimes.sh
 delete mode 100644 home/features/cli/starship.nix
 delete mode 100644 home/features/cli/zellij.nix
 create mode 100644 home/features/desktop/inlyne.nix

diff --git a/README.md b/README.md
index be63142..c16ea63 100644
--- a/README.md
+++ b/README.md
@@ -138,6 +138,9 @@ Most services are served over [tailscale](https://tailscale.com/), using certifi
 
 This section contains links to things which used to be in the previous section but are not used anymore. This section was created in June 2023, hence stuff I dropped earlier might not be here. Moreover, this list is sorted with the most recently dropped things at the top, as a sort of reverse-timeline.
 
+- [ncdu](https://dev.yorhel.nl/ncdu) — A neat project I used on a regular basis. Ended up switching to [dua](https://github.com/Byron/dua-cli) (in interactive mode)
+- [peek](https://github.com/phw/peek) — Doesn't seem to work on Wayland + GIFs are not a very efficient format
+- [bc](https://github.com/gavinhoward/bc) — I was rarely using this
 - [lovely-forks](https://github.com/musically-ut/lovely-forks) — I was rarely using this
 - [Octotree](https://www.octotree.io/) — GitHub supports this natively now
 - [Tmux](https://github.com/tmux/tmux/wiki) — I now simply use multiple WM windows / no longer persist sessions
diff --git a/common/themes/default.nix b/common/themes/default.nix
index 80dea2e..bc66dc9 100644
--- a/common/themes/default.nix
+++ b/common/themes/default.nix
@@ -1,4 +1,4 @@
-{ inputs, ... }:
+{ inputs, pkgs, ... }:
 let
   transparency = amount: {
     desktop = amount;
@@ -100,4 +100,10 @@ in
 
   # Requires me to manually turn targets on!
   stylix.autoEnable = false;
+
+  stylix.cursor = {
+    package = inputs.rose-pine-hyprcursor.packages.${pkgs.system}.default;
+    name = "BreezX-RosePine-Linux";
+    size = 36;
+  };
 }
diff --git a/flake.lock b/flake.lock
index 555397b..edf7860 100644
--- a/flake.lock
+++ b/flake.lock
@@ -620,7 +620,7 @@
     },
     "flake-utils_3": {
       "inputs": {
-        "systems": "systems_2"
+        "systems": "systems_4"
       },
       "locked": {
         "lastModified": 1710146030,
@@ -638,7 +638,7 @@
     },
     "flake-utils_4": {
       "inputs": {
-        "systems": "systems_3"
+        "systems": "systems_5"
       },
       "locked": {
         "lastModified": 1710146030,
@@ -656,7 +656,7 @@
     },
     "flake-utils_5": {
       "inputs": {
-        "systems": "systems_4"
+        "systems": "systems_6"
       },
       "locked": {
         "lastModified": 1685518550,
@@ -674,7 +674,7 @@
     },
     "flake-utils_6": {
       "inputs": {
-        "systems": "systems_5"
+        "systems": "systems_7"
       },
       "locked": {
         "lastModified": 1710146030,
@@ -987,19 +987,42 @@
         ]
       },
       "locked": {
-        "lastModified": 1747763032,
-        "narHash": "sha256-9j3oCbemeH7bTVXJ3pDWxOptbxDx2SdK1jY2AHpjQiw=",
+        "lastModified": 1748627093,
+        "narHash": "sha256-1hFy+bZRZoYb7RaUXsW+9YFtjjFrQpschd8qZpy9org=",
         "owner": "nix-community",
         "repo": "home-manager",
-        "rev": "29dda415f5b2178278283856c6f9f7b48a2a4353",
+        "rev": "afe9ce8b2014fa1230ade38bf07156cdcef63658",
         "type": "github"
       },
       "original": {
         "owner": "nix-community",
+        "ref": "release-25.05",
         "repo": "home-manager",
         "type": "github"
       }
     },
+    "hyprlang": {
+      "inputs": {
+        "nixpkgs": [
+          "rose-pine-hyprcursor",
+          "nixpkgs"
+        ],
+        "systems": "systems_2"
+      },
+      "locked": {
+        "lastModified": 1709914708,
+        "narHash": "sha256-bR4o3mynoTa1Wi4ZTjbnsZ6iqVcPGriXp56bZh5UFTk=",
+        "owner": "hyprwm",
+        "repo": "hyprlang",
+        "rev": "a685493fdbeec01ca8ccdf1f3655c044a8ce2fe2",
+        "type": "github"
+      },
+      "original": {
+        "owner": "hyprwm",
+        "repo": "hyprlang",
+        "type": "github"
+      }
+    },
     "ical": {
       "flake": false,
       "locked": {
@@ -1331,16 +1354,16 @@
     },
     "nixpkgs_11": {
       "locked": {
-        "lastModified": 1747542820,
-        "narHash": "sha256-GaOZntlJ6gPPbbkTLjbd8BMWaDYafhuuYRNrxCGnPJw=",
+        "lastModified": 1748437600,
+        "narHash": "sha256-hYKMs3ilp09anGO7xzfGs3JqEgUqFMnZ8GMAqI6/k04=",
         "owner": "NixOS",
         "repo": "nixpkgs",
-        "rev": "292fa7d4f6519c074f0a50394dbbe69859bb6043",
+        "rev": "7282cb574e0607e65224d33be8241eae7cfe0979",
         "type": "github"
       },
       "original": {
         "owner": "NixOS",
-        "ref": "nixos-unstable",
+        "ref": "nixos-25.05",
         "repo": "nixpkgs",
         "type": "github"
       }
@@ -1679,6 +1702,7 @@
         "nixos-hardware": "nixos-hardware",
         "nixpkgs": "nixpkgs_5",
         "nixpkgs-unstable": "nixpkgs-unstable",
+        "rose-pine-hyprcursor": "rose-pine-hyprcursor",
         "shimmeringmoon": "shimmeringmoon",
         "smos": "smos",
         "sops-nix": "sops-nix",
@@ -1686,6 +1710,28 @@
         "stylix": "stylix"
       }
     },
+    "rose-pine-hyprcursor": {
+      "inputs": {
+        "hyprlang": "hyprlang",
+        "nixpkgs": [
+          "nixpkgs"
+        ],
+        "utils": "utils"
+      },
+      "locked": {
+        "lastModified": 1748096947,
+        "narHash": "sha256-ouuA8LVBXzrbYwPW2vNjh7fC9H2UBud/1tUiIM5vPvM=",
+        "owner": "ndom91",
+        "repo": "rose-pine-hyprcursor",
+        "rev": "4b02963d0baf0bee18725cf7c5762b3b3c1392f1",
+        "type": "github"
+      },
+      "original": {
+        "owner": "ndom91",
+        "repo": "rose-pine-hyprcursor",
+        "type": "github"
+      }
+    },
     "safe-coloured-text": {
       "flake": false,
       "locked": {
@@ -1901,7 +1947,7 @@
         "nixpkgs": [
           "nixpkgs"
         ],
-        "systems": "systems_6"
+        "systems": "systems_8"
       },
       "locked": {
         "lastModified": 1748147548,
@@ -1931,7 +1977,7 @@
         "home-manager": "home-manager_3",
         "nixpkgs": "nixpkgs_11",
         "nur": "nur",
-        "systems": "systems_7",
+        "systems": "systems_9",
         "tinted-foot": "tinted-foot",
         "tinted-kitty": "tinted-kitty",
         "tinted-schemes": "tinted-schemes",
@@ -1939,15 +1985,16 @@
         "tinted-zed": "tinted-zed"
       },
       "locked": {
-        "lastModified": 1748572239,
-        "narHash": "sha256-Of7bmWQUEVILpx1GJz0gLHmRoGrEP/G7q9RnidxW5Go=",
+        "lastModified": 1748573182,
+        "narHash": "sha256-nnvjhz1PtS/Vfw8bgU0AkXq1U42gilzfFak65EmHW4g=",
         "owner": "danth",
         "repo": "stylix",
-        "rev": "0512b0f685ab2ac0586c897460c247f49670460b",
+        "rev": "79ec2e885e2b66f2fc6e6b6db15c49c81ebaf7d8",
         "type": "github"
       },
       "original": {
         "owner": "danth",
+        "ref": "release-25.05",
         "repo": "stylix",
         "type": "github"
       }
@@ -2001,16 +2048,16 @@
     },
     "systems_2": {
       "locked": {
-        "lastModified": 1681028828,
-        "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+        "lastModified": 1689347949,
+        "narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=",
         "owner": "nix-systems",
-        "repo": "default",
-        "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
+        "repo": "default-linux",
+        "rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68",
         "type": "github"
       },
       "original": {
         "owner": "nix-systems",
-        "repo": "default",
+        "repo": "default-linux",
         "type": "github"
       }
     },
@@ -2089,6 +2136,36 @@
         "type": "github"
       }
     },
+    "systems_8": {
+      "locked": {
+        "lastModified": 1681028828,
+        "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+        "owner": "nix-systems",
+        "repo": "default",
+        "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
+        "type": "github"
+      },
+      "original": {
+        "owner": "nix-systems",
+        "repo": "default",
+        "type": "github"
+      }
+    },
+    "systems_9": {
+      "locked": {
+        "lastModified": 1681028828,
+        "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+        "owner": "nix-systems",
+        "repo": "default",
+        "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
+        "type": "github"
+      },
+      "original": {
+        "owner": "nix-systems",
+        "repo": "default",
+        "type": "github"
+      }
+    },
     "template-haskell-reload": {
       "flake": false,
       "locked": {
@@ -2252,6 +2329,24 @@
         "type": "github"
       }
     },
+    "utils": {
+      "inputs": {
+        "systems": "systems_3"
+      },
+      "locked": {
+        "lastModified": 1710146030,
+        "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
+        "owner": "numtide",
+        "repo": "flake-utils",
+        "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
+        "type": "github"
+      },
+      "original": {
+        "owner": "numtide",
+        "repo": "flake-utils",
+        "type": "github"
+      }
+    },
     "validity": {
       "flake": false,
       "locked": {
diff --git a/flake.nix b/flake.nix
index b2ad8d9..41de310 100644
--- a/flake.nix
+++ b/flake.nix
@@ -1,5 +1,4 @@
 {
-  # {{{ Inputs
   inputs = {
     # {{{ Nixpkgs instances
     nixpkgs.url = "github:nixos/nixpkgs/nixos-25.05";
@@ -58,15 +57,17 @@
     darkmatter-grub-theme.url = "gitlab:VandalByte/darkmatter-grub-theme";
     darkmatter-grub-theme.inputs.nixpkgs.follows = "nixpkgs";
 
-    stylix.url = "github:danth/stylix";
+    stylix.url = "github:danth/stylix/release-25.05";
     # stylix.inputs.nixpkgs.follows = "nixpkgs";
     # stylix.inputs.home-manager.follows = "home-manager";
 
     base16-schemes.url = "github:tinted-theming/schemes";
     base16-schemes.flake = false;
+
+    rose-pine-hyprcursor.url = "github:ndom91/rose-pine-hyprcursor";
+    rose-pine-hyprcursor.inputs.nixpkgs.follows = "nixpkgs";
     # }}}
   };
-  # }}}
 
   outputs =
     {
diff --git a/home/calypso.nix b/home/calypso.nix
index ae8be15..5023a01 100644
--- a/home/calypso.nix
+++ b/home/calypso.nix
@@ -3,68 +3,42 @@
   imports = [
     ./global.nix
 
-    ./features/cli/catgirl.nix
-    ./features/cli/lazygit.nix
-    ./features/cli/nix-index.nix
     ./features/cli/productivity
-    ./features/cli/zellij.nix
-    ./features/desktop/discord
     ./features/desktop/gaming
     ./features/desktop/gaming/edopro.nix
-    ./features/desktop/firefox
-    ./features/desktop/foot.nix
-    ./features/desktop/obsidian.nix
-    ./features/desktop/spotify.nix
-    ./features/desktop/zathura.nix
     ./features/wayland/hyprland
+
     ./features/neovim
   ];
 
+  home.stateVersion = "24.05";
+  home.username = "moon";
+
   # Arbitrary extra packages
   home.packages = with pkgs; [
-    # {{{ Communication
+    # Communication
+    whatsapp-for-linux
     # signal-desktop # Signal client
     # element-desktop # Matrix client
     # zoom-us # Zoom client 🤮
-    whatsapp-for-linux
-    # }}}
-    # {{{ Documents & editors
-    gimp # Image editing
-    okular # Useful for reading pdf annotations (which zathura does not support)
+
+    # Documents & editors
+    libsForQt5.okular # Useful for reading pdf annotations (which zathura does not support)
     # lmms # Music software
     # kicad # PCB editing
     # libreoffice # Free office suite
-    # }}}
-    # {{{ Gaming
-    # wine # Windows compat layer or whatever
-    lutris # Game launcher
-    # }}}
-    # {{{ Clis
-    sops # Secret editing
+
+    # Clis
     # sherlock # Search for usernames across different websites
-    # }}}
-    # {{{ Misc
-    bitwarden # Password-manager
-    qbittorrent # Torrent client
+
+    # Misc
     # google-chrome # Not my primary browser, but sometimes needed in webdev
     # plover.dev # steno engine
-    overskride # Bluetooth client
     freetube # youtube client
-    # }}}
-    # {{{ Media playing/recording
-    mpv # Video player
-    imv # Image viewer
-    peek # GIF recorder
-    obs-studio # video recorder
-    # }}}
   ];
 
-  home.username = "moon";
-  home.stateVersion = "24.05";
-
   satellite = {
-    # Symlink some commonly modified dotfiles outside the nix store
-    dev.enable = true;
+    dev.enable = true; # Enable symlinks outside the nix store
 
     monitors = [
       {
diff --git a/home/features/cli/bat.nix b/home/features/cli/bat.nix
index 81adbd8..457e3ba 100644
--- a/home/features/cli/bat.nix
+++ b/home/features/cli/bat.nix
@@ -1,10 +1,12 @@
+# 'cat' alternative
 {
-  # Enabling this produces an uglier theme for some reason.
-  # options.stylix.targets.bat.enable = true;
   programs.bat = {
     enable = true;
     config.theme = "base16-256";
   };
 
   home.shellAliases.cat = "bat";
+
+  # Enabling this produces an uglier theme for some reason.
+  # options.stylix.targets.bat.enable = true;
 }
diff --git a/home/features/cli/default.nix b/home/features/cli/default.nix
index a325761..e839996 100644
--- a/home/features/cli/default.nix
+++ b/home/features/cli/default.nix
@@ -1,47 +1,59 @@
 { pkgs, ... }:
 {
   imports = [
-    ./scripts
-    ./eza.nix
     ./bat.nix
-    ./ssh.nix
-    ./git.nix
-    ./starship.nix
+    ./catgirl.nix
     ./direnv.nix
+    ./eza.nix
+    ./git.nix
+    ./lazygit.nix
+    ./ssh.nix
     ./tealdeer.nix
     ./yazi.nix
     ./fish
   ];
 
+  # Enable basic CLI thingies
   programs.bash.enable = true;
+  programs.broot.enable = true;
+  programs.starship.enable = true;
+
+  # Enable nix-index
+  programs.nix-index-database.comma.enable = true;
+  programs.nix-index.enable = true;
+  programs.command-not-found.enable = false;
 
   home.packages = with pkgs; [
-    # {{{ System information
+    # System information
     acpi # Battery stats
     neofetch # Display system information
     tokei # Useless but fun line of code counter (sloc alternative)
     bottom # System monitor
-    # }}}
-    # {{{ Storage
-    ncdu # TUI disk usage
-    du-dust # Similar to du and ncdu in purpose.
-    # }}}
-    # {{{ Alternatives to usual commands
+    bandwhich # Network bandwhich info
+
+    # Storage
+    dua # du + ncdu replacement
+    dust # Similar to du, but with prettier output
+    dysk # Similar to df, but with prettier output
+
+    # Alternatives to usual commands
     ripgrep # Better grep
     fd # Better find
     sd # Better sed
     httpie # Better curl
-    # }}}
-    # {{{ Misc
-    bc # Calculator
+
+    # Misc
     ouch # Unified compression / decompression tool
     mkpasswd # Hash passwords
-    jq # Json maniuplation
-    # }}}
+    jq # JSON manipulation
+    ffsend # File sharing
+
+    # Normally, I'd recommend against installing this globally, although
+    # it seems the completions don't play nicely with direnv otherwise.
+    just
   ];
 
   home.shellAliases = {
-    # {{{ Storage
     # -h: humans readable units
     df = "df -h";
     du = "du -h";
@@ -49,6 +61,5 @@
     # duh: short for `du here`
     # -d: depth
     duh = "du -hd 1";
-    # }}}
   };
 }
diff --git a/home/features/cli/direnv.nix b/home/features/cli/direnv.nix
index 65263e3..182d0b9 100644
--- a/home/features/cli/direnv.nix
+++ b/home/features/cli/direnv.nix
@@ -1,17 +1,12 @@
 { config, ... }:
-let statePath = "${config.xdg.dataHome}/direnv/allow";
+let
+  statePath = "${config.xdg.dataHome}/direnv/allow";
 in
 {
   programs.direnv.enable = true;
+  programs.direnv.silent = true;
   programs.direnv.nix-direnv.enable = true;
 
-  home.sessionVariables = {
-    # No more long command warnings
-    DIRENV_WARN_TIMEOUT = "24h";
-    # No more usesless logs
-    DIRENV_LOG_FORMAT = "";
-  };
-
   # Only save allowed paths for 30d
   systemd.user.tmpfiles.rules = [ "d ${statePath} - - - 30d" ];
   satellite.persistence.at.state.apps.direnv.directories = [ statePath ];
diff --git a/home/features/cli/fish/config.fish b/home/features/cli/fish/config.fish
index fde69de..23b45c7 100644
--- a/home/features/cli/fish/config.fish
+++ b/home/features/cli/fish/config.fish
@@ -1,32 +1,24 @@
-# {{{ Start tmux if not already inside tmux
-if status is-interactive
-and not set -q TMUX
-and not set -q NO_TMUX
-and set -q ALWAYS_TMUX
-    exec tmux attach -t Welcome || tmux || echo "Something went wrong trying to start tmux"
-end
-# }}}
-# {{{ Sets cursor based on vim mode
-set fish_cursor_default block # Set the normal and visual mode cursors to a block
+# Set cursor based on vim mode
+set fish_cursor_default block # Set the normal & visual mode cursors to a block
 set fish_cursor_insert line # Set the insert mode cursor to a line
 set fish_cursor_replace_one underscore # Set the replace mode cursor to an underscore
 
 # Force fish to skip some checks (I think?)
 set fish_vi_force_cursor
-# }}}
-# {{{ Disable greeting
+
+# Disable greeting
 set fish_greeting
-# }}}
-# {{{ Keybinds
+
+# Key-binds
 function fish_user_key_bindings
   fish_vi_key_bindings
   fish_nix_key_bindings
 
-  bind -M insert -m default -k f10 'commandline -f repaint' # Exit insert mode with <f10>
+  # Exit insert mode with <f10>
+  bind -M insert -m default f10 'commandline -f repaint'
 end
-# }}}
-# {{{ Helpers
+
+# Helpers
 function take -d "Create a directory and cd into it"
   mkdir -p $argv; and cd $argv
 end
-# }}}
diff --git a/home/features/cli/fish/default.nix b/home/features/cli/fish/default.nix
index a588962..51aa9ce 100644
--- a/home/features/cli/fish/default.nix
+++ b/home/features/cli/fish/default.nix
@@ -8,21 +8,21 @@ let
   repaint = "commandline -f repaint";
   fishKeybinds = {
     # C-x to clear screen
-    "\\cx" = "clear && ${repaint}";
+    "ctrl-x" = "clear && ${repaint}";
     # C-z to return to background process
-    "\\cz" = "fg && ${repaint}";
+    "ctrl-z" = "fg && ${repaint}";
     # C-y to yank current command
-    "\\cy" = "wl-copy \$(commandline)";
+    "ctrl-y" = "wl-copy \$(commandline)";
     # C-e to launch $EDITOR
-    "\\ce" = "$EDITOR";
+    "ctrl-e" = "$EDITOR";
     # C-S-e to edit commandline using $EDITOR
-    "\\e\\[69\\;5u" = "edit_command_buffer";
+    "ctrl-E" = "edit_command_buffer";
     # C-enter to run command through a pager
-    "\\e\\[13\\;2u" = "commandline -a ' | $PAGER' && commandline -f execute";
+    "ctrl-enter" = "commandline -a ' | $PAGER' && commandline -f execute";
     # C-g to open lazygit
-    "\\cg" = "lazygit";
+    "ctrl-g" = "lazygit";
     # C-S-f to open mini.files
-    "\\e\\[70\\;5u" = ''nvim +":lua require('mini.files').open()"'';
+    "ctrl-F" = ''nvim +":lua require('mini.files').open()"'';
   };
 
   mkKeybind =
@@ -59,7 +59,7 @@ in
 
       ${builtins.readFile ./config.fish}
 
-      # Modify nix-shell to use `fish` as it's default shell
+      # Modify nix-shell to use `fish` as its default shell
       ${lib.getExe pkgs.nix-your-shell} fish | source
     '';
 
diff --git a/home/features/cli/nix-index.nix b/home/features/cli/nix-index.nix
deleted file mode 100644
index 28b6c15..0000000
--- a/home/features/cli/nix-index.nix
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-  programs.nix-index-database.comma.enable = true;
-  programs.nix-index.enable = true;
-  programs.command-not-found.enable = false;
-}
diff --git a/home/features/cli/productivity/secrets.example.yaml b/home/features/cli/productivity/secrets.example.yaml
index 5d63374..57dfa50 100644
--- a/home/features/cli/productivity/secrets.example.yaml
+++ b/home/features/cli/productivity/secrets.example.yaml
@@ -1,5 +1,3 @@
 smos_github_token: ...
 smos_password: ...
 moonythm_mail_pass: ...
-vaultwarden_env: |
-    ADMIN_TOKEN=...
diff --git a/home/features/cli/productivity/secrets.yaml b/home/features/cli/productivity/secrets.yaml
index e6bd20b..d70cfd1 100644
--- a/home/features/cli/productivity/secrets.yaml
+++ b/home/features/cli/productivity/secrets.yaml
@@ -1,12 +1,7 @@
 smos_github_token: ENC[AES256_GCM,data:kqy5mQf96DoPN1iEt2akJWFfD3IJWdSkvZa0MeAyF0WJ/+V5P5C4iQ==,iv:QwmIdV/vzGTLE89XJVi3prgfmXqRa/OYcp9CA7KJDYc=,tag:+S1EZBcxoOQO2ADjDx9STQ==,type:str]
 smos_password: ENC[AES256_GCM,data:s+WuVJpe+bSZ7IPYKqA=,iv:fH4k1VTxkcgBwabX7TwZFu1bdWtinK8vug71xa0PiSo=,tag:epqGvDj5pfh9IVLFQLcifA==,type:str]
 moonythm_mail_pass: ENC[AES256_GCM,data:FmBUICHDxmn72EGnYVSh,iv:L45AeAiXUfz4jH+4q+PDGwvKnEb4r/XDP+55Cf+Q+Nc=,tag:171ImWbCqdEUUK/nlrldCQ==,type:str]
-vaultwarden_env: ENC[AES256_GCM,data:dKAkO1pckFVpuN3srD99aGln8fhT69ZNCO1QbdfyJMHlypyNX3YOReR7BoAeDK5DYGRs//8/PLPynRzKPAICng7+yfNDsHHzaF+QNpY=,iv:oNntDA4cXlg5gbTZwqnpyx5nGkYzmLvds5BsAdpdUdc=,tag:IXYS+CKnVb9ZfBm/zcG3JA==,type:str]
 sops:
-    kms: []
-    gcp_kms: []
-    azure_kv: []
-    hc_vault: []
     age:
         - recipient: age14mga4r0xa82a2uus3wq5q7rqnvflms3jmhknz4f3hsda8wttk9gsv2k9fs
           enc: |
@@ -35,8 +30,7 @@ sops:
             a3Vzak1qM2lGUWFUS2lPa1loY0tkM0UKF9IGvrJM8BdivLQBnetZz2OeH6FCNaCZ
             JeqqJXM96LKzPBCXxFqclpoPgy8zUb1yNpKg3CRUroC7VO0tBG3KJg==
             -----END AGE ENCRYPTED FILE-----
-    lastmodified: "2025-05-30T03:01:52Z"
-    mac: ENC[AES256_GCM,data:DNEOMhZIspChJh30AcULXA2hcSYgArCqY8ct4GIojkFutuHeJcHGZFQ+NNgUB5MUIVJHEJ6f5qeWrwDJCAeAarlwgUhcFUQMilZ0jwU+o6w1mUWwZeWV7W467YQ/zWUBZqwb3udeSsI6KTmsMkIpBdYON7UHQ/LFXrkzqrUkhSc=,iv:Ur94AGkiqcet9Vz97XyqfM5PQzJBMQ2NZ9yj4dDFVJ8=,tag:EiVThawyfm0LjJ7jg4pTEQ==,type:str]
-    pgp: []
+    lastmodified: "2025-05-30T19:26:28Z"
+    mac: ENC[AES256_GCM,data:2yBG1RRTA8z5u9XqMXzI7TPMBYPf9LW4DRpqJbVkiMqJyFcAKIoQ5NXI8kqi6dKar2sYQMu/3kq4ISGaTHoMsikP3UWDOHDn6aWIZNGx/Psm9AyQv8LyxIizLybF7XIn/Z99NdlaIsUCB0yUD742xkU3pHPLNL1K9BwuWpRbtbQ=,iv:JfMIB2+HQ941yTT/rhUbh1PnH9vmj+2GVWRHe7KOcPU=,tag:deMUz5Oji7Hh1XBGyl95Vw==,type:str]
     unencrypted_suffix: _unencrypted
-    version: 3.9.4
+    version: 3.10.2
diff --git a/home/features/cli/scripts/default.nix b/home/features/cli/scripts/default.nix
deleted file mode 100644
index 87584fe..0000000
--- a/home/features/cli/scripts/default.nix
+++ /dev/null
@@ -1,6 +0,0 @@
-{ pkgs, ... }:
-let uptimes = pkgs.writeShellScriptBin "uptimes" (builtins.readFile ./uptimes.sh);
-in
-{
-  home.packages = [ uptimes ];
-}
diff --git a/home/features/cli/scripts/uptimes.sh b/home/features/cli/scripts/uptimes.sh
deleted file mode 100755
index 20422c1..0000000
--- a/home/features/cli/scripts/uptimes.sh
+++ /dev/null
@@ -1,27 +0,0 @@
-print_uptime() {
-  local HOST=$1
-  local EMOJI=$2
-
-  # -n: do not echo a newline
-  echo -n "$EMOJI $HOST: ~"
-
-  # The output of `uptime` looks like this:
-  # `18:40:54  up 1 day  0:51,  0 users,  load average: 0.79, 0.68, 0.69`,
-  # so we use awk to trim it down to the parts we care about.
-  #
-  # For awk:
-  # -F: splits the input by a string
-  ssh $USER@$HOST uptime \
-    | awk -F '(up |,)' '{print $2}'
-}
-
-echo "Uptimes:"
-
-{
-  print_uptime "tethys" "🔥"
-  print_uptime "lapetus" "⛵"
-} |
-column --table -R 2 -s "~"
-# ^ We use the column command to align things nicely:
-# -R 2 aligns the second column to the right
-# -s ~ will split on occurrences of ~
diff --git a/home/features/cli/ssh.nix b/home/features/cli/ssh.nix
index 54d6931..4be345d 100644
--- a/home/features/cli/ssh.nix
+++ b/home/features/cli/ssh.nix
@@ -1,8 +1,4 @@
 {
   programs.ssh.enable = true;
   satellite.persistence.at.state.apps.ssh.directories = [ ".ssh" ];
-
-  # This allows me to push/pull to my forgejo server via SSH.
-  # See the docs for more details: https://developers.cloudflare.com/cloudflare-one/tutorials/gitlab/#configuring-ssh
-  # programs.ssh.matchBlocks."ssh.git.moonythm.dev".proxyCommand = "${lib.getExe pkgs.cloudflared} access ssh --hostname %h";
 }
diff --git a/home/features/cli/starship.nix b/home/features/cli/starship.nix
deleted file mode 100644
index 796f0ea..0000000
--- a/home/features/cli/starship.nix
+++ /dev/null
@@ -1,3 +0,0 @@
-{
-  programs.starship.enable = true;
-}
diff --git a/home/features/cli/tealdeer.nix b/home/features/cli/tealdeer.nix
index f93ed11..42001ed 100644
--- a/home/features/cli/tealdeer.nix
+++ b/home/features/cli/tealdeer.nix
@@ -1,6 +1,7 @@
-# Example based cli docs
+# Example-based CLI documentation
 # https://dbrgn.github.io/tealdeer/
-{ config, pkgs, ... }: {
+{ config, pkgs, ... }:
+{
   home.packages = [ pkgs.tealdeer ];
 
   xdg.configFile."tealdeer/config.toml".text = ''
diff --git a/home/features/cli/yazi.nix b/home/features/cli/yazi.nix
index d6b81e5..3129db7 100644
--- a/home/features/cli/yazi.nix
+++ b/home/features/cli/yazi.nix
@@ -4,8 +4,8 @@
 }:
 {
   stylix.targets.yazi.enable = true;
+  programs.yazi.enable = true;
   home.packages = [
-    pkgs.yazi # Terminal file explorer
     pkgs.exiftool # Read file metadata
   ];
 }
diff --git a/home/features/cli/zellij.nix b/home/features/cli/zellij.nix
deleted file mode 100644
index 6e26a53..0000000
--- a/home/features/cli/zellij.nix
+++ /dev/null
@@ -1,4 +0,0 @@
-{
-  programs.zellij.enable = true;
-  stylix.targets.zellij.enable = true;
-}
diff --git a/home/features/desktop/default.nix b/home/features/desktop/default.nix
index a231960..f43cdc2 100644
--- a/home/features/desktop/default.nix
+++ b/home/features/desktop/default.nix
@@ -1,7 +1,15 @@
 { pkgs, ... }:
 {
   imports = [
-    ./dunst.nix # notifaction handler
+    ./dunst.nix
+    ./discord
+    ./firefox
+
+    ./foot.nix
+    ./obsidian.nix
+    ./spotify.nix
+    ./zathura.nix
+    ./inlyne.nix
   ];
 
   # Notifies on low battery percentages
@@ -18,4 +26,19 @@
 
   # Bigger text in qt apps
   home.sessionVariables.QT_SCREEN_SCALE_FACTORS = 1.4;
+
+  # Base packages
+  home.packages = with pkgs; [
+    gimp # Image editing
+    krita # drawing
+    libreoffice # document editing
+
+    bitwarden # Password-manager
+    qbittorrent # Torrent client
+    overskride # Bluetooth client
+
+    mpv # Video player
+    imv # Image viewer
+    obs-studio # video recorder
+  ];
 }
diff --git a/home/features/desktop/gaming/default.nix b/home/features/desktop/gaming/default.nix
index 24e9b8f..d1af9d1 100644
--- a/home/features/desktop/gaming/default.nix
+++ b/home/features/desktop/gaming/default.nix
@@ -2,6 +2,7 @@
 {
   home.packages = [
     pkgs.vvvvvv
+    pkgs.lutris
   ];
 
   # {{{ Persistence
diff --git a/home/features/desktop/inlyne.nix b/home/features/desktop/inlyne.nix
new file mode 100644
index 0000000..ce37fdb
--- /dev/null
+++ b/home/features/desktop/inlyne.nix
@@ -0,0 +1,19 @@
+# 'inlyne' is a markdown reader
+{ pkgs, lib, ... }:
+{
+  home.packages = [ pkgs.inlyne ];
+
+  # Create a hidden desktop entry in order for this to become the default way
+  # to open markdown files.
+  #
+  # See https://specifications.freedesktop.org/desktop-entry-spec/latest/recognized-keys.html
+  xdg.desktopEntries.inlyne = {
+    noDisplay = true;
+
+    name = "Inlyne";
+    type = "Application";
+
+    exec = "${lib.getExe pkgs.inlyne} %U";
+    mimeType = [ "text/markdown" ];
+  };
+}
diff --git a/home/features/neovim/config/lua/my/lazy.lua b/home/features/neovim/config/lua/my/lazy.lua
index 8bebd72..9d84a6c 100644
--- a/home/features/neovim/config/lua/my/lazy.lua
+++ b/home/features/neovim/config/lua/my/lazy.lua
@@ -8,7 +8,7 @@ function M.setup()
   require("lazy").setup({
     require("my.themes"),
     {
-      dir = "/home/moon/projects/sibilantmoon/vim",
+      dir = "/home/moon/projects/personal/sibilantmoon/vim",
       ft = "sibilantmoon",
       name = "sibilantmoon",
     },
diff --git a/home/features/neovim/config/spell/en.utf-8.add b/home/features/neovim/config/spell/en.utf-8.add
index 60fea81..a26d98a 100644
--- a/home/features/neovim/config/spell/en.utf-8.add
+++ b/home/features/neovim/config/spell/en.utf-8.add
@@ -2,3 +2,8 @@ Yu-Gi-Oh!
 sudo
 nixos
 neovim
+bandwhich
+JSON
+LLM
+Ultrakill
+Horia
diff --git a/home/features/wayland/global.nix b/home/features/wayland/global.nix
index 7b88461..4ba61e8 100644
--- a/home/features/wayland/global.nix
+++ b/home/features/wayland/global.nix
@@ -2,11 +2,11 @@
 { lib, pkgs, ... }:
 {
   imports = [
+    ../desktop
+
     ./wlsunset.nix
     ./wlogout.nix
     ./anyrun.nix
-
-    ../desktop
   ];
 
   home.sessionVariables.NIXOS_OZONES_WL = "1";
@@ -40,10 +40,11 @@
     with pkgs;
     [
       libnotify # Send notifications
-      wl-ocr # Custom ocr script
+      wl-ocr # Custom OCR script
       wl-qr # Custom qr scanner script
       wl-clipboard # Clipboard manager
       hyprpicker # Color picker
       grimblast # Screenshot tool
+      wl-screenrec # video recorder (with daemon support!)
     ];
 }
diff --git a/home/features/wayland/hyprland/default.nix b/home/features/wayland/hyprland/default.nix
index a9af089..52a7593 100644
--- a/home/features/wayland/hyprland/default.nix
+++ b/home/features/wayland/hyprland/default.nix
@@ -1,7 +1,7 @@
 {
+  config,
   pkgs,
   lib,
-  config,
   ...
 }:
 {
@@ -11,17 +11,22 @@
   ];
 
   home.packages = [
-    pkgs.gtk3 # Contains gtk-launch
+    # Contains gtk-launch, which I use for launching 'obsidiantui'
+    pkgs.gtk3
   ];
 
-  # TODO: systemd-xdg-autostart-generator?
   stylix.targets.hyprland.enable = true;
   wayland.windowManager.hyprland = {
     enable = true;
-    package = pkgs.hyprland;
-    extraConfig = builtins.readFile ./hyprland.conf;
+
+    # set the Hyprland and XDPH packages to null to use the ones from the NixOS module
+    package = null;
+    portalPackage = null;
+
+    # TODO: systemd-xdg-autostart-generator?
     # systemd.enable = false; # Handled by uwsm
 
+    extraConfig = builtins.readFile ./hyprland.conf;
     settings = {
       # {{{ Decoration
       decoration = {
@@ -58,6 +63,11 @@
         m: lib.lists.optional (m.workspace != null) "${m.name},${m.workspace}"
       ) config.satellite.monitors;
       # }}}
+
+      env = [
+        "HYPRCURSOR_THEME,rose-pine-hyprcursor"
+        "HYPRCURSOR_SIZE,36"
+      ];
     };
 
     plugins = [ pkgs.hyprlandPlugins.hyprexpo ];
diff --git a/home/features/wayland/hyprland/hyprland.conf b/home/features/wayland/hyprland/hyprland.conf
index a455daa..597023d 100644
--- a/home/features/wayland/hyprland/hyprland.conf
+++ b/home/features/wayland/hyprland/hyprland.conf
@@ -120,10 +120,7 @@ bindm = $mod, mouse:272, movewindow
 bindm = $mod, mouse:273, resizewindow
 # }}}
 # {{{ Move focus
-bind = $mod, h, movefocus, l
-bind = $mod, l, movefocus, r
-bind = $mod, k, movefocus, u
-bind = $mod, j, movefocus, d
+bind = $mod, k, cyclenext,
 # }}}
 # {{{ Switch to workspace
 bind = $mod, 1, workspace, 1
diff --git a/home/tethys.nix b/home/tethys.nix
index bc837c7..8d32a21 100644
--- a/home/tethys.nix
+++ b/home/tethys.nix
@@ -3,67 +3,18 @@
   imports = [
     ./global.nix
 
-    ./features/cli/catgirl.nix
-    ./features/cli/lazygit.nix
-    ./features/cli/nix-index.nix
     ./features/cli/productivity
-    ./features/cli/zellij.nix
-    ./features/desktop/discord
-    ./features/desktop/firefox
+    ./features/desktop/gaming
     ./features/desktop/gaming/edopro.nix
-    ./features/desktop/foot.nix
-    ./features/desktop/obsidian.nix
-    ./features/desktop/spotify.nix
-    ./features/desktop/zathura.nix
     ./features/wayland/hyprland
+
     ./features/neovim
   ];
 
-  # Arbitrary extra packages
-  home.packages = with pkgs; [
-    # {{{ Communication
-    # signal-desktop # Signal client
-    element-desktop # Matrix client
-    # zoom-us # Zoom client 🤮
-    # }}}
-    # {{{ Editors for different formats
-    gimp # Image editing
-    krita # drawing
-    # lmms # Music software
-    # kicad # PCB editing
-    # libreoffice # Free office suite
-    # }}}
-    # {{{ Gaming
-    # wine # Windows compat layer or whatever
-    # lutris # Game launcher
-    # }}}
-    # {{{ Clis
-    sops # Secret editing
-    # sherlock # Search for usernames across different websites
-    # }}}
-    # {{{ Misc
-    bitwarden # Password-manager
-    qbittorrent # Torrent client
-    # google-chrome # Not my primary browser, but sometimes needed in webdev
-    # plover.dev # steno engine
-    overskride # Bluetooth client
-    freetube # youtube client
-    # }}}
-    # {{{ Media playing/recording
-    mpv # Video player
-    imv # Image viewer
-    # peek # GIF recorder
-    # obs-studio # video recorder
-    wl-screenrec
-    # }}}
-  ];
-
-  home.sessionVariables.QT_SCREEN_SCALE_FACTORS = 1.4; # Bigger text in qt apps
   home.stateVersion = "23.05";
 
   satellite = {
-    # Symlink some commonly modified dotfiles outside the nix store
-    dev.enable = true;
+    dev.enable = true; # Enable symlinks outside the nix store
 
     monitors = [
       {
diff --git a/hosts/nixos/common/optional/desktop/xdg-portal.nix b/hosts/nixos/common/optional/desktop/xdg-portal.nix
index 6d55a98..7ba348c 100644
--- a/hosts/nixos/common/optional/desktop/xdg-portal.nix
+++ b/hosts/nixos/common/optional/desktop/xdg-portal.nix
@@ -6,6 +6,7 @@
 }:
 {
   services.dbus.enable = true;
+  programs.dconf.enable = true;
   environment.systemPackages = [ pkgs.xdg-utils ];
   xdg.portal = {
     enable = true;
@@ -15,9 +16,16 @@
       pkgs.xdg-desktop-portal-termfilechooser
     ];
 
-    config.hyprland.default = "hyprland";
+    config.hyprland.default = [
+      "hyprland"
+      "gtk"
+    ];
     config.hyprland."org.freedesktop.impl.portal.FileChooser" = "termfilechooser";
-    config.common.default = "hyprland";
+
+    config.common.default = [
+      "hyprland"
+      "gtk"
+    ];
     config.common."org.freedesktop.impl.portal.FileChooser" = "termfilechooser";
   };
 
diff --git a/hosts/nixos/lapetus/services/vaultwarden.nix b/hosts/nixos/lapetus/services/vaultwarden.nix
index 41932b9..cf30127 100644
--- a/hosts/nixos/lapetus/services/vaultwarden.nix
+++ b/hosts/nixos/lapetus/services/vaultwarden.nix
@@ -2,7 +2,7 @@
 {
   satellite.nginx.at.warden.port = config.satellite.ports.vaultwarden;
 
-  # {{{ Secrets 
+  # {{{ Secrets
   sops.secrets.vaultwarden_env = {
     sopsFile = ../secrets.yaml;
     owner = config.users.users.vaultwarden.name;
@@ -29,12 +29,14 @@
     };
   };
   # }}}
-  # {{{ Storage 
-  environment.persistence."/persist/state".directories = [{
-    directory = "/var/lib/bitwarden_rs";
-    mode = "u=rwx,g=,o=";
-    user = config.users.users.vaultwarden.name;
-    group = config.users.users.vaultwarden.group;
-  }];
+  # {{{ Storage
+  environment.persistence."/persist/state".directories = [
+    {
+      directory = "/var/lib/bitwarden_rs";
+      mode = "u=rwx,g=,o=";
+      user = config.users.users.vaultwarden.name;
+      group = config.users.users.vaultwarden.group;
+    }
+  ];
   # }}}
 }
diff --git a/justfile b/justfile
index 0a4be5c..10936c3 100644
--- a/justfile
+++ b/justfile
@@ -7,7 +7,7 @@ hostname := `hostname`
 # {{{ Nixos rebuilds
 [doc("Wrapper around `nixos-rebuild`, taking care of the generic arguments")]
 [group("nix")]
-nixos-rebuild action="rebuild" host=hostname:
+nixos-rebuild action="switch" host=hostname:
   #!/usr/bin/env python3
   import subprocess
 
@@ -30,7 +30,7 @@ nixos-rebuild action="rebuild" host=hostname:
 
   if "{{host}}" == "{{hostname}}": 
     print("🧬 Switching nixos configuration (locally) for '{{BLUE + host + NORMAL}}'")
-    args.prepend("sudo")
+    args = ["sudo", *args]
   else:
     print("🧬 Switching nixos configuration (remotely) for '{{BLUE + host + NORMAL}}'")
     args.append("--use-remote-sudo")