diff --git a/.gitignore b/.gitignore
index 511d463..589556f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,2 @@
-# Jetbrains configuration directory
-/.idea
+### Jetbrains
+/.idea
\ No newline at end of file
diff --git a/.idea/nix-config.iml b/.idea/nix-config.iml
index c956989..d6da34e 100644
--- a/.idea/nix-config.iml
+++ b/.idea/nix-config.iml
@@ -1,7 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <module type="WEB_MODULE" version="4">
   <component name="NewModuleRootManager">
-    <content url="file://$MODULE_DIR$" />
+    <content url="file://$MODULE_DIR$">
+      <excludeFolder url="file://$MODULE_DIR$/.idea/codeStyles" />
+    </content>
     <orderEntry type="inheritedJdk" />
     <orderEntry type="sourceFolder" forTests="false" />
   </component>
diff --git a/flake.nix b/flake.nix
index 59217b8..4c178b0 100644
--- a/flake.nix
+++ b/flake.nix
@@ -2,87 +2,60 @@
   description = "Jo's NixOS configuration";
 
   inputs = {
-    # Nixpkgs
+    # Nixpkgs instance.
     nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
 
-    # Home manager
-    home-manager = {
-      url = "github:nix-community/home-manager/master";
+    # Snowfall lib imposes an opinionated file-structure, which makes things a little easier sometimes.
+    snowfall-lib = {
+      url = "github:snowfallorg/lib";
       inputs.nixpkgs.follows = "nixpkgs";
     };
 
+    # Home manager for managing the /home directory.
+    home-manager = {
+      url = "github:nix-community/home-manager";
+      inputs.nixpkgs.follows = "nixpkgs";
+    };
+
+    # Hardware specific tweaks and performance optimizations.
     hardware.url = "github:NixOS/nixos-hardware/master";
 
+    # Catppuccin theme nix configuration.
     catppuccin.url = "github:catppuccin/nix";
 
+    # Declarative management of Flatpak packages.
     nix-flatpak.url = "github:gmodena/nix-flatpak/?ref=v0.4.1";
   };
 
-  outputs = { self, nixpkgs, home-manager, hardware, catppuccin, nix-flatpak, ... } @inputs:
-  let
-    inherit (self) outputs;
+  outputs = inputs:
+    inputs.snowfall-lib.mkFlake {
+      inherit inputs; # Providing flake inputs to Snowfall Lib.
+      src = ./.; # "src" must point to the root of the flake.
 
-    # Supported systems for this flake
-    systems = [
-      "x86_64-linux"
-    ];
+      snowfall = {
+        # "root" can be used, to tell Snowfall Lib where to look for Nix files.
+        # root = ./nix;
 
-    # Function that generates an attribute by calling a function you pass to it
-    # It takes each system as an argument
-    forAllSystems = nixpkgs.lib.genAttrs systems;
-  in {
-    # My custom packagess
-    packages = forAllSystems (system: import ./pkgs nixpkgs.legacyPackages.${system});
+        # Namespace for this flake's packages, library and overlays.
+        namespace = "puzzlevision";
 
-    # External resources (wallpapers, icons, dotfiles)
-    resources = import ./resources;
-
-    # My reusable modules for nixos
-    nixosModules = import ./modules/nixos;
-
-    # My reusable modules for home-manager
-    homeManagerModules = import ./modules/home-manager;
-
-    # NixOS configuration entrypoint
-    # Available through 'nixos-rebuild --flake .#your-hostname'
-    nixosConfigurations = {
-      puzzlevision = nixpkgs.lib.nixosSystem {
-        specialArgs = {inherit inputs outputs;};
-        modules = [
-          home-manager.nixosModules.home-manager
-          ./hosts/puzzlevision/configuration.nix
-        ];
+        meta = {
+          name = "jos-nixos-configuration"; # Used in certain places, like documentations. No spaces.
+          title = "Jo's NixOS configuration"; # Basically just for decorational purposes.
+        };
       };
+
+      channels-config = {
+        allowUnfree = true; # Allow unfree packages.
+      };
+
+      # Apply some home-manager modules globally.
+      homes.modules = with inputs; [
+        nix-flatpak.homeManagerModules.nix-flatpak
+      ];
+
+      homes.users."jo@puzzlevision".modules = with inputs; [
+        catppuccin.homeManagerModules.catppuccin
+      ];
     };
-
-    # Standalone home-manager configuration entrypoint
-    # Available through 'home-manager --flake .#your-username@your-hostname'
-    homeConfigurations = {
-      "jo@puzzlevision" = home-manager.lib.homeManagerConfiguration {
-        pkgs = nixpkgs.legacyPackages.x86_64-linux; # Home-manager requires 'pkgs' instance
-        extraSpecialArgs = {inherit inputs outputs;};
-        modules = [
-          ./users/jo/home.nix
-          nix-flatpak.homeManagerModules.nix-flatpak
-          catppuccin.homeManagerModules.catppuccin
-        ];
-      };
-
-      "work@puzzlevision" = home-manager.lib.homeManagerConfiguration {
-        pkgs = nixpkgs.legacyPackages.x86_64-linux; # Home-manager requires 'pkgs' instance
-        extraSpecialArgs = {inherit inputs outputs;};
-        modules = [
-          ./users/work/home.nix
-        ];
-      };
-
-      "gaming@puzzlevision" = home-manager.lib.homeManagerConfiguration {
-        pkgs = nixpkgs.legacyPackages.x86_64-linux; # Home-manager requires 'pkgs' instance
-        extraSpecialArgs = {inherit inputs outputs;};
-        modules = [
-          ./users/gaming/home.nix
-        ];
-      };
-    };
-  };
 }
diff --git a/homes/x86_64-linux/jo@puzzlevision/default.nix b/homes/x86_64-linux/jo@puzzlevision/default.nix
new file mode 100644
index 0000000..08e0026
--- /dev/null
+++ b/homes/x86_64-linux/jo@puzzlevision/default.nix
@@ -0,0 +1,70 @@
+{
+  # Snowfall Lib provides a customized `lib` instance with access to your flake's library
+  # as well as the libraries available from your flake's inputs.
+  lib,
+  # Instance of `pkgs` with overlays and custom packages applied.
+  pkgs,
+  # All flake inputs.
+  inputs,
+
+  # Additional metadata, provided by Snowfall Lib.
+  namespace, # The flake namespace, set in flake.nix. If not set, defaults to "internal".
+  home, # The home architecture for this host (eg. `x86_64-linux`).
+  target, # The Snowfall Lib target for this home (eg. `x86_64-home`).
+  format, # A normalized name for the home target (eg. `home`).
+  virtual, # A boolean to determine whether this home is a virtual target using nixos-generators.
+  host, # The host name for this home.
+
+  # All other arguments come from the home home.
+  config,
+  ...
+}: {
+  imports = [
+    inputs.homeModules.themes.catppuccin
+    inputs.homeModules.themes.catppuccin.gnome
+    inputs.homeModules.development.ssh
+  ];
+
+  # Flatpak configuration.
+  services.flatpak = {
+    enable = true;
+    update.auto.enable = true;
+    uninstallUnmanaged = true;
+
+    packages = [
+      "com.jeffser.Alpaca"
+    ];
+  };
+
+  # Declare user packages.
+  home.packages = with pkgs; [
+    ### General
+    qflipper
+    wineWowPackages.waylandFull
+    vesktop
+    lunar-client
+    steam
+    g4music
+
+    ### Development
+    avra
+    avrdude
+    jetbrains.phpstorm
+    git
+    nodejs_22
+    bun
+    kitty
+    forge-sparks
+    devenv
+
+    ### Work
+    teams-for-linux
+    enpass
+
+    ### Notes & Organisation
+    obsidian
+
+    ### Backups & Synchronization
+    celeste
+  ];
+}
\ No newline at end of file
diff --git a/modules/home/development/ssh/default.nix b/modules/home/development/ssh/default.nix
new file mode 100644
index 0000000..303aa1f
--- /dev/null
+++ b/modules/home/development/ssh/default.nix
@@ -0,0 +1,48 @@
+{
+  lib,
+  pkgs,
+  inputs,
+
+  namespace, # The flake namespace, set in flake.nix. If not set, defaults to "internal".
+  home, # The home architecture for this host (eg. `x86_64-linux`).
+  target, # The Snowfall Lib target for this home (eg. `x86_64-home`).
+  format, # A normalized name for the home target (eg. `home`).
+  virtual, # A boolean to determine whether this home is a virtual target using nixos-generators.
+  host, # The host name for this home.
+
+  config,
+  ...
+}: let
+  sshDir = "${config.home.homeDirectory}/.ssh";
+in {
+  home.packages = with pkgs; [
+    openssh
+  ];
+
+  programs.ssh = {
+    enable = true;
+    extraConfig = ''
+      AddKeysToAgent yes
+    '';
+  };
+
+  matchBlocks = {
+    "github.com" = {
+      identityFile = "${sshDir}/id_ed25519";
+      identitiesOnly = true;
+      user = "git";
+    };
+
+    "gitlab.com" = {
+      identityFile = "${sshDir}/id_ed25519";
+      identitiesOnly = true;
+      user = "git";
+    };
+
+    "bitbucket.org" = {
+      identityFile = "${sshDir}/id_ed25519";
+      identitiesOnly = true;
+      user = "git";
+    };
+  };
+}
\ No newline at end of file
diff --git a/modules/home/themes/catppuccin/default.nix b/modules/home/themes/catppuccin/default.nix
new file mode 100644
index 0000000..73990ad
--- /dev/null
+++ b/modules/home/themes/catppuccin/default.nix
@@ -0,0 +1,25 @@
+{
+  lib,
+  pkgs,
+  inputs,
+
+  namespace, # The flake namespace, set in flake.nix. If not set, defaults to "internal".
+  home, # The home architecture for this host (eg. `x86_64-linux`).
+  target, # The Snowfall Lib target for this home (eg. `x86_64-home`).
+  format, # A normalized name for the home target (eg. `home`).
+  virtual, # A boolean to determine whether this home is a virtual target using nixos-generators.
+  host, # The host name for this home.
+
+  config,
+  ...
+}: {
+  catppuccin = {
+    enable = true;
+    accent = "blue";
+    flavor = "frappe";
+
+    pointerCursor.enable = true;
+    pointerCursor.accent = "blue";
+    pointerCursor.flavor = "frappe";
+  };
+}
\ No newline at end of file
diff --git a/modules/home/themes/catppuccin/gnome/default.nix b/modules/home/themes/catppuccin/gnome/default.nix
new file mode 100644
index 0000000..b1c2d71
--- /dev/null
+++ b/modules/home/themes/catppuccin/gnome/default.nix
@@ -0,0 +1,54 @@
+{
+  lib,
+  pkgs,
+  inputs,
+
+  namespace, # The flake namespace, set in flake.nix. If not set, defaults to "internal".
+  home, # The home architecture for this host (eg. `x86_64-linux`).
+  target, # The Snowfall Lib target for this home (eg. `x86_64-home`).
+  format, # A normalized name for the home target (eg. `home`).
+  virtual, # A boolean to determine whether this home is a virtual target using nixos-generators.
+  host, # The host name for this home.
+
+  config,
+  ...
+}: {
+  gtk = {
+    enable = true;
+
+    font = {
+      name = "Cantarell";
+      size = 12;
+      package = pkgs.cantarell-fonts;
+    };
+
+    catppuccin = {
+      icon = {
+        enable = true;
+        accent = "blue";
+        flavor = "frappe";
+      };
+    };
+
+    theme = {
+      name = "Colloid-Dark-Catppuccin";
+      package = pkgs.colloid-gtk-theme.override {
+        themeVariants = ["default"];
+        colorVariants = ["dark"];
+        sizeVariants = ["standard"];
+        tweaks = ["catppuccin"];
+      };
+    };
+  };
+
+  dconf.settings = {
+    "org/gnome/desktop/background" = {
+      picture-uri = lib.snowfall.fs.get-file "resources/wallpapers/pond_sidewalk_dusk.jpg";
+      picture-uri-dark = lib.snowfall.fs.get-file "resources/wallpapers/pond_sidewalk_dusk.jpg";
+    };
+
+    "org/gnome/shell/extensions/user-theme" = {
+      name = "Colloid-Dark-Catppuccin";
+    };
+  };
+}
\ No newline at end of file
diff --git a/modules/nixos/common/gnome/default.nix b/modules/nixos/common/gnome/default.nix
new file mode 100644
index 0000000..b5047d5
--- /dev/null
+++ b/modules/nixos/common/gnome/default.nix
@@ -0,0 +1,48 @@
+{
+  lib,
+  pkgs,
+  inputs,
+
+  namespace, # The flake namespace, set in flake.nix. If not set, defaults to "internal".
+  system, # The system architecture for this host (eg. `x86_64-linux`).
+  target, # The Snowfall Lib target for this system (eg. `x86_64-iso`).
+  format, # A normalized name for the system target (eg. `iso`).
+  virtual, # A boolean to determine whether this system is a virtual target using nixos-generators.
+  systems, # An attribute map of your defined hosts.
+
+  config,
+  ...
+}: {
+  # Enable GNOME and GDM.
+  services.xserver.displayManager.gdm.enable = true;
+  services.xserver.desktopManager.gnome.enable = true;
+
+  environment.gnome.excludePackages =  (with pkgs; [
+    gnome-tour
+    gedit
+    cheese
+    geary
+  ]) ++ (with pkgs.gnome; [
+    gnome-music
+    epiphany # Gnome web
+    tali # Poker game
+    iagno # Go game
+    hitori # Sudoku game
+    yelp # Help view
+    gnome-contacts
+    gnome-initial-setup
+  ]);
+
+  programs.dconf.enable = true;
+
+  services.gnome.gnome-keyring.enable = true;
+
+  programs.kdeconnect = {
+    enable = true;
+    package = pkgs.gnomeExtensions.gsconnect;
+  };
+
+  environment.systemPackages = with pkgs; [
+    gnome.gnome-tweaks
+  ];
+}
\ No newline at end of file
diff --git a/resources/wallpapers/pond_sidewalk_dusk.jpg b/resources/wallpapers/pond_sidewalk_dusk.jpg
new file mode 100644
index 0000000..cfbf7d6
Binary files /dev/null and b/resources/wallpapers/pond_sidewalk_dusk.jpg differ
diff --git a/systems/x86_64-linux/puzzlevision/default.nix b/systems/x86_64-linux/puzzlevision/default.nix
new file mode 100644
index 0000000..1482a93
--- /dev/null
+++ b/systems/x86_64-linux/puzzlevision/default.nix
@@ -0,0 +1,177 @@
+{
+  # Snowfall Lib provides a customized `lib` instance with access to your flake's library
+  # as well as the libraries available from your flake's inputs.
+  lib,
+  # Instance of `pkgs` with overlays and custom packages applied.
+  pkgs,
+  # All flake inputs.
+  inputs,
+
+  # Additional metadata, provided by Snowfall Lib.
+  namespace, # The flake namespace, set in flake.nix. If not set, defaults to "internal".
+  system, # The system architecture for this host (eg. `x86_64-linux`).
+  target, # The Snowfall Lib target for this system (eg. `x86_64-iso`).
+  format, # A normalized name for the system target (eg. `iso`).
+  virtual, # A boolean to determine whether this system is a virtual target using nixos-generators.
+  systems, # An attribute map of your defined hosts.
+
+  # All other arguments come from the system system.
+  config,
+  ...
+}: {
+  imports = [
+    ./hardware-configuration.nix
+    inputs.hardware.nixosModules.common-pc-laptop
+    inputs.hardware.nixosModules.common-cpu-intel
+    inputs.hardware.nixosModules.common-pc-laptop-ssd
+    inputs.nixosModules.common.gnome
+  ];
+
+  nix = {
+    # Add flake inputs as registries.
+    # Keeps nix3 commands consistent with flake.
+    registry = lib.mapAttrs (_: value: {flake = value;});
+
+    # Add inputs to system's legacy channels.
+    # Makes legacy nix commands consistent with flake as well.
+    nixPath = lib.mapAttrsToList (key: value: "${key}=${value.to.path}") config.nix.registry;
+
+    settings = {
+      auto-optimise-store = true;
+      builders-use-substitutes = true;
+      experimental-features = [ "nix-command" "flakes" "repl-flake" ];
+      keep-derivations = true;
+      keep-outputs = true;
+      max-jobs = "auto";
+      warn-dirty = false;
+    };
+
+    # Garbage collection configuration.
+    gc = {
+      automatic = true;
+      dates = "daily";
+      options = "--delete-older-than 3d";
+    };
+  };
+
+  # Set hostname
+  networking.hostname = "puzzlevision";
+
+  # Enable networking through networkmanager (required for most desktop environments).
+  networking.networkmanager.enable = true;
+
+  boot = {
+    # Always run the latest kernel.
+    kernelPackages = pkgs.linuxPackages_latest;
+
+    # Configure additional kernel modules.
+    extraModulePackages = [
+      pkgs.linuxPackages_latest.rtl8821ce # Use custom network-card driver.
+    ];
+
+    blacklistedKernelModules = [
+      "rtw88_8821ce" # Block the default network-card driver.
+    ];
+
+    # Grub configuration.
+    loader.grub = {
+      enable = true;
+      devices = [ "nodev" ];
+      efiInstallAsRemovable = true;
+      efiSupport = true;
+
+      extraEntries = ''
+        menuentry "Reboot" {
+          reboot
+        }
+        menuentry "Poweroff" {
+          halt
+        }
+      '';
+    };
+  };
+
+  # Set timezone.
+  time.timeZone = "Europe/Berlin";
+
+  # Internationalisation properties.
+  i18n.defaultLocale = "en_US.UTF-8";
+  i18n.extraLocaleSettings = {
+    LC_ADDRESS = "de_DE.UTF-8";
+    LC_IDENTIFICATION = "de_DE.UTF-8";
+    LC_MEASUREMENT = "de_DE.UTF-8";
+    LC_MONETARY = "de_DE.UTF-8";
+    LC_NAME = "de_DE.UTF-8";
+    LC_NUMERIC = "de_DE.UTF-8";
+    LC_PAPER = "de_DE.UTF-8";
+    LC_TELEPHONE = "de_DE.UTF-8";
+    LC_TIME = "de_DE.UTF-8";
+  };
+
+  # Set console keymap.
+  console.keyMap = "de";
+
+  # Enable the power-profiles-daemon service for improved battery management.
+  services.power-profiles-daemon.enable = true;
+
+  # Enable printing.
+  services.printing.enable = true;
+
+  # Sound configuration based on pipewire.
+  hardware.pulseaudio.enable = false;
+  security.rtkit.enable = true;
+  services.pipewire = {
+    enable = true;
+    alsa.enable = true;
+    alsa.support32Bit = true;
+    pulse.enable = true;
+  };
+
+  # Bluetooth configuration.
+  hardware.bluetooth = {
+    enable = true;
+    powerOnBoot = true;
+    package = pkgs.bluez;
+
+    settings = {
+      General = {
+        ControllerMode = "dual";
+        FastConnectable = "true";
+        Experimental = "true";
+        KernelExperimental = "true";
+      };
+    };
+  };
+
+  # Enable flatpak support.
+  services.flatpak.enable = true;
+
+  # Enable iio-sensor for automatic screen rotation and similar features.
+  hardware.sensor.iio.enable = true;
+
+  # Configure system-wide default shell.
+  environment.shells = with pkgs; [ zsh ];
+  users.defaultUserShell = pkgs.zsh;
+  programs.zsh.enable = true;
+
+  # Configure users.
+  snowfallorg.users.jo.admin = true;
+
+  # Provide users with some sane default packages.
+  environment.systemPackages = with pkgs; [
+    ### General
+    nano
+    firefox
+    vlc
+    spotify
+
+    ### Bluetooth
+    bluez
+
+    ### Fonts
+    noto-fonts
+    noto-fonts-color-emoji
+  ];
+
+  system.stateVersion = "24.05";
+}
\ No newline at end of file
diff --git a/systems/x86_64-linux/puzzlevision/hardware-configuration.nix b/systems/x86_64-linux/puzzlevision/hardware-configuration.nix
new file mode 100644
index 0000000..322cf24
--- /dev/null
+++ b/systems/x86_64-linux/puzzlevision/hardware-configuration.nix
@@ -0,0 +1,68 @@
+# Do not modify this file!  It was generated by ‘nixos-generate-config’
+# and may be overwritten by future invocations.  Please make changes
+# to /etc/nixos/configuration.nix instead.
+{ config, lib, pkgs, modulesPath, ... }:
+
+{
+  imports =
+    [ (modulesPath + "/installer/scan/not-detected.nix")
+    ];
+
+  boot.initrd.availableKernelModules = [ "xhci_pci" "vmd" "nvme" "usbhid" "rtsx_pci_sdmmc" ];
+  boot.initrd.kernelModules = [ ];
+  boot.kernelModules = [ "kvm-intel" ];
+  boot.extraModulePackages = [ ];
+
+  fileSystems."/" =
+    { device = "/dev/disk/by-uuid/864b1287-89fd-4cc0-98a5-40a3caf804c6";
+      fsType = "btrfs";
+      options = [ "subvol=@" ];
+    };
+
+  boot.initrd.luks.devices."luks-5fd4fc76-d5c5-46c3-b952-1a7a7ff3a1fc".device = "/dev/disk/by-uuid/5fd4fc76-d5c5-46c3-b952-1a7a7ff3a1fc";
+
+  fileSystems."/var/lib/docker/btrfs" =
+    { device = "/@/@/var/lib/docker/btrfs";
+      fsType = "none";
+      options = [ "bind" ];
+    };
+
+  fileSystems."/boot" =
+    { device = "/dev/disk/by-uuid/2429-4141";
+      fsType = "vfat";
+      options = [ "fmask=0022" "dmask=0022" ];
+    };
+
+  fileSystems."/var/lib/docker/overlay2/eec00b6d746d533d213790aa0c8e5cca329148c50c0ab1b035020d27e218ed16/merged" =
+    { device = "overlay";
+      fsType = "overlay";
+    };
+
+  fileSystems."/var/lib/docker/overlay2/bc060caf80f8891cd68f21563b8ece131b24b28772c2971a703bac1f5b54e8d1/merged" =
+    { device = "overlay";
+      fsType = "overlay";
+    };
+
+  swapDevices = [ ];
+
+  # Enables DHCP on each ethernet and wireless interface. In case of scripted networking
+  # (the default) this is the recommended approach. When using systemd-networkd it's
+  # still possible to use this option, but it's recommended to use it in conjunction
+  # with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
+  networking.useDHCP = lib.mkDefault true;
+  # networking.interfaces.br-01571e4eda2f.useDHCP = lib.mkDefault true;
+  # networking.interfaces.br-20785fae249b.useDHCP = lib.mkDefault true;
+  # networking.interfaces.br-64a49a5722c1.useDHCP = lib.mkDefault true;
+  # networking.interfaces.br-71e5fc5962fc.useDHCP = lib.mkDefault true;
+  # networking.interfaces.br-7df9905783da.useDHCP = lib.mkDefault true;
+  # networking.interfaces.br-9b746f4e7e2f.useDHCP = lib.mkDefault true;
+  # networking.interfaces.br-e2f470a56dfe.useDHCP = lib.mkDefault true;
+  # networking.interfaces.docker0.useDHCP = lib.mkDefault true;
+  # networking.interfaces.enp0s13f0u4u4.useDHCP = lib.mkDefault true;
+  # networking.interfaces.veth4e96b46.useDHCP = lib.mkDefault true;
+  # networking.interfaces.veth96a5ccd.useDHCP = lib.mkDefault true;
+  # networking.interfaces.wlo1.useDHCP = lib.mkDefault true;
+
+  nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
+  hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
+}