{
  lib,
  pkgs,
  ...
}:
with lib; let
  power-menu = pkgs.writeScript "power-menu" ''
    SELECTION="$(printf "󰌾 Lock\n󰶐 Power off monitors\n󰗽 Log out\n󰤄 Suspend\n Reboot\n󰐥 Shutdown" | fuzzel --dmenu -l 6 -p "⚡ ")"

    case $SELECTION in
    	*"Lock")
    		loginctl lock-session;;
    	*"Power off monitors")
    		niri msg action power-off-monitors;;
    	*"Log out")
    		niri msg action exit;;
    	*"Suspend")
    		systemctl suspend;;
    	*"Reboot")
    		systemctl reboot;;
    	*"Shutdown")
    		systemctl poweroff;;
    esac
  '';
in {
  imports = [../home.nix];

  # Consistent theming.
  qt.enable = true;
  gtk.enable = true;

  stylix.icons = {
    enable = true;
    package = pkgs.papirus-icon-theme;
    light = "Papirus-Light";
    dark = "Papirus-Dark";
  };

  # XDG portals.
  xdg.portal = {
    enable = true;
    config.common.default = "*";
    extraPortals = [
      pkgs.xdg-desktop-portal-gnome
      pkgs.xdg-desktop-portal-gtk
    ];
  };

  # Create home directories.
  xdg.userDirs.createDirectories = true;

  # Niri WM.
  programs.niri = {
    settings = {
      # Wayland environment variables.
      environment = {
        CLUTTER_BACKEND = "wayland";
        GDK_BACKEND = "wayland,x11";
        MOZ_ENABLE_WAYLAND = "1";
        NIXOS_OZONE_WL = "1";
        QT_QPA_PLATFORM = "wayland;xcb";
        QT_WAYLAND_DISABLE_WINDOWDECORATION = "1";
        SDL_VIDEODRIVER = "wayland";
        GTK_CSD = "0";
      };

      # X11 support.
      xwayland-satellite = {
        enable = true;
        path = getExe pkgs.xwayland-satellite-unstable;
      };

      # Don't show client-side window decorations.
      prefer-no-csd = true;

      # Don't show hotkeys at startup.
      hotkey-overlay.skip-at-startup = true;

      # Disable hot corner.
      gestures.hot-corners.enable = false;

      # Keyboard, mouse, trackpad, trackpoint.
      input = {
        touchpad.natural-scroll = false;
        keyboard.repeat-rate = 60;
      };

      binds = {
        # Spawn programs.
        "Mod+Return".action.spawn = "ghostty";
        "Mod+Space".action.spawn = "fuzzel";
        "Mod+E".action.spawn = "bemoji";
        "Mod+Alt+L".action.spawn = "hyprlock";

        # Show overview
        "Mod+Escape".action.toggle-overview = {};

        # Media & brightness control.
        "XF86AudioRaiseVolume" = {
          allow-when-locked = true;
          action.spawn = ["wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "5%+"];
        };

        "XF86AudioLowerVolume" = {
          allow-when-locked = true;
          action.spawn = ["wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "5%-"];
        };

        "XF86AudioMute" = {
          allow-when-locked = true;
          action.spawn = ["wpctl" "set-mute" "@DEFAULT_AUDIO_SINK@" "toggle"];
        };

        "XF86AudioMicMute" = {
          allow-when-locked = true;
          action.spawn = ["wpctl" "set-mute" "@DEFAULT_AUDIO_SOURCE@" "toggle"];
        };

        "XF86AudioPlay" = {
          allow-when-locked = true;
          action.spawn = ["playerctl" "play-pause"];
        };

        "XF86AudioStop" = {
          allow-when-locked = true;
          action.spawn = ["playerctl" "pause"];
        };

        "XF86AudioPrev" = {
          allow-when-locked = true;
          action.spawn = ["playerctl" "previous"];
        };

        "XF86AudioNext" = {
          allow-when-locked = true;
          action.spawn = ["playerctl" "next"];
        };

        "XF86MonBrightnessUp" = {
          allow-when-locked = true;
          action.spawn = ["brillo" "-A" "5"];
        };

        "XF86MonBrightnessDown" = {
          allow-when-locked = true;
          action.spawn = ["brillo" "-U" "5"];
        };

        # Close windows.
        "Mod+Q".action.close-window = {};

        # Power menu.
        "Mod+Shift+E".action.spawn = "${power-menu}";

        # Take a screenshot.
        "Mod+P".action.screenshot = {};
        "Mod+Shift+P".action.screenshot-screen = {};
        "Mod+Shift+Ctrl+P".action.screenshot-window = {};

        # Focus and move columns.
        "Mod+H".action.focus-column-left = {};
        "Mod+J".action.focus-window-down = {};
        "Mod+K".action.focus-window-up = {};
        "Mod+L".action.focus-column-right = {};

        "Mod+Shift+H".action.move-column-left = {};
        "Mod+Shift+J".action.move-window-down = {};
        "Mod+Shift+K".action.move-window-up = {};
        "Mod+Shift+L".action.move-column-right = {};

        "Mod+Home".action.focus-column-first = {};
        "Mod+End".action.focus-column-last = {};

        "Mod+Shift+Home".action.move-column-to-first = {};
        "Mod+Shift+End".action.move-column-to-last = {};

        # Focus monitors.
        "Mod+bracketleft".action.focus-monitor-left = {};
        "Mod+bracketright".action.focus-monitor-right = {};

        # Move columns between monitors.
        "Mod+Shift+bracketleft".action.move-column-to-monitor-left = {};
        "Mod+Shift+bracketright".action.move-column-to-monitor-right = {};

        # Focus workspaces.
        "Mod+U".action.focus-workspace-down = {};
        "Mod+I".action.focus-workspace-up = {};

        "Mod+1".action.focus-workspace = 1;
        "Mod+2".action.focus-workspace = 2;
        "Mod+3".action.focus-workspace = 3;
        "Mod+4".action.focus-workspace = 4;
        "Mod+5".action.focus-workspace = 5;
        "Mod+6".action.focus-workspace = 6;
        "Mod+7".action.focus-workspace = 7;
        "Mod+8".action.focus-workspace = 8;
        "Mod+9".action.focus-workspace = 9;

        # Move columns to workspaces.
        "Mod+Shift+U".action.move-column-to-workspace-down = {};
        "Mod+Shift+I".action.move-column-to-workspace-up = {};

        "Mod+Shift+1".action.move-column-to-workspace = 1;
        "Mod+Shift+2".action.move-column-to-workspace = 2;
        "Mod+Shift+3".action.move-column-to-workspace = 3;
        "Mod+Shift+4".action.move-column-to-workspace = 4;
        "Mod+Shift+5".action.move-column-to-workspace = 5;
        "Mod+Shift+6".action.move-column-to-workspace = 6;
        "Mod+Shift+7".action.move-column-to-workspace = 7;
        "Mod+Shift+8".action.move-column-to-workspace = 8;
        "Mod+Shift+9".action.move-column-to-workspace = 9;

        # Expel & consume windows into columns.
        "Mod+Comma".action.consume-window-into-column = {};
        "Mod+Period".action.expel-window-from-column = {};

        # Resize columns.
        "Mod+R".action.switch-preset-column-width = {};
        "Mod+Shift+R".action.reset-window-height = {};

        "Mod+F".action.maximize-column = {};
        "Mod+Shift+F".action.fullscreen-window = {};

        "Mod+C".action.center-column = {};

        "Mod+Minus".action.set-column-width = "-10%";
        "Mod+Equal".action.set-column-width = "+10%";

        "Mod+Shift+Minus".action.set-window-height = "-10%";
        "Mod+Shift+Equal".action.set-window-height = "+10%";
      };

      layout = {
        gaps = 4;
        border.width = 1;
        preset-column-widths = [
          {proportion = 1.0 / 3.0;}
          {proportion = 1.0 / 2.0;}
          {proportion = 2.0 / 6.0;}
        ];
        default-column-width = {
          proportion = 1.0 / 2.0;
        };
      };
    };
  };

  # Lock screen.
  programs.hyprlock = {
    enable = true;
    settings = {
      input-field = {
        fade_on_empty = false;
        rounding = 0;
        outline_thickness = 1;
        valign = "center";
        halign = "center";
        position = "0%, -10%";
        size = "20%, 5%";
      };
      label = {
        valign = "center";
        halign = "center";
        position = "0%, 10%";
        text = "$TIME";
        font_size = 128;
        font_family = "Adwaita Sans Bold";
      };
    };
  };

  stylix.targets.hyprlock.useWallpaper = false;

  # Auto-lock.
  services.hypridle = {
    enable = true;
    settings = {
      general = {
        lock_cmd = "pidof hyprlock || hyprlock";
        before_sleep_cmd = "loginctl lock-session";
        after_sleep_cmd = "niri msg action power-on-monitors";
      };

      listener = [
        {
          timeout = 300;
          on-timeout = "brillo -O; brillo -u 500000 -S 10";
          on-resume = "brillo -I -u 250000";
        }
        {
          timeout = 600;
          on-timeout = "loginctl lock-session";
        }
        {
          timeout = 900;
          on-timeout = "niri msg action power-off-monitors";
        }
      ];
    };
  };

  # Launcher.
  programs.fuzzel = {
    enable = true;
    settings = {
      main = {
        terminal = "ghostty";
        horizontal-pad = 8;
        vertical-pad = 8;
        inner-pad = 8;
      };
      border.radius = 0;
    };
  };

  # Panel.
  programs.waybar = {
    enable = true;
    systemd.enable = true;

    settings.main = {
      modules-left = ["niri/workspaces"];
      modules-center = ["clock"];
      modules-right = ["network" "wireplumber" "battery#0" "battery#1"];

      "battery#0" = {
        bat = "BAT0";
        format-icons = ["󰁺" "󰁻" "󰁼" "󰁽" "󰁾" "󰁿" "󰂁" "󰂂" "󰁹"];
        format = "{icon} {capacity}%";
        format-charging = "󱐋 {icon} {capacity}%";
        tooltip = false;
      };

      "battery#1" = {
        bat = "BAT1";
        format-icons = ["󰁺" "󰁻" "󰁼" "󰁽" "󰁾" "󰁿" "󰂁" "󰂂" "󰁹"];
        format = "{icon} {capacity}%";
        tooltip = false;
      };

      "network" = {
        format-icons = ["󰤯" "󰤟" "󰤢" "󰤥" "󰤨"];
        format = "{icon}";
        format-disconnected = "";
        tooltip = true;
        tooltip-format = "{essid}";
        on-click = "nm-connection-editor";
      };

      "wireplumber" = {
        format-icons = ["" "" ""];
        format = "{icon} {volume}%";
        format-muted = " ";
        tooltip = false;
        on-click = "pwvucontrol";
      };

      "clock" = {
        format = "{:%a %b %d · %H:%M}";
        tooltip = false;
      };
    };
  };

  stylix.targets.waybar.font = "sansSerif"; # use sans-serif font, not monospaced.

  # Enable polkit-gnome.
  services.polkit-gnome.enable = true;

  # Wallpaper manager.
  services.hyprpaper.enable = true;

  # Notifications
  services.mako.enable = true;

  # Day/night gamma adjustment.
  services.wlsunset = {
    sunset = "18:00";
    sunrise = "06:00";
  };

  # Clipboard manager.
  services.cliphist.enable = true;

  # Nextcloud client.
  services.nextcloud-client.enable = true;

  # Install some software.
  programs.ghostty = {
    enable = true;
    settings = {
      window-padding-x = 4;
      window-padding-y = 4;
    };
  };

  programs.firefox = {
    enable = true;
    profiles.default = {
      extensions.force = true;
      settings."identity.sync.tokenserver.uri" = "https://fxsync.fern.garden/1.0/sync/1.5";
    };
  };

  stylix.targets.firefox = {
    profileNames = ["default"];
    colorTheme.enable = true;
  };

  fonts.fontconfig.enable = true; # discover fonts installed by home.packages.

  home.packages = with pkgs; [
    bemoji
    caligula
    celluloid
    decibels
    deploy-rs
    feishin
    file-roller
    fluffychat
    fusee-nano
    gimp3
    glabels-qt
    gnome-calculator
    gnome-characters
    gnome-font-viewer
    hyprpicker
    jellyfin-media-player
    libreoffice
    loupe
    nautilus
    nerd-fonts.symbols-only
    networkmanagerapplet
    noto-fonts
    noto-fonts-cjk-sans
    noto-fonts-cjk-serif
    ns-usbloader
    nwg-clipman
    obsidian
    papers
    playerctl
    prismlauncher
    protonmail-desktop
    pwvucontrol
    rockbox-utility
    seahorse
    signal-desktop
    simple-scan
    system-config-printer
    via
    wdisplays
    webcord
    wl-clipboard
    yubioath-flutter
  ];
}
