diff --git a/docs/superpowers/specs/2026-05-25-hyprlock-replace-gtklock-design.md b/docs/superpowers/specs/2026-05-25-hyprlock-replace-gtklock-design.md
new file mode 100644
index 0000000..69c9fbe
--- /dev/null
+++ b/docs/superpowers/specs/2026-05-25-hyprlock-replace-gtklock-design.md
@@ -0,0 +1,175 @@
+# Replace gtklock with hyprlock Design
+
+**Date:** 2026-05-25
+**Status:** Approved
+
+## Summary
+
+Migrate the lockscreen from `gtklock` to `hyprlock`. Hyprlock has native fprintd polling: touching the reader on the lockscreen unlocks immediately, without the user having to first type / press Enter to trigger PAM (the limitation that motivated this change).
+
+## Current Behaviour
+
+- `gtklock` is the lockscreen, bound to `Mod+Shift+E` and to swayidle's 10-minute lock + before-sleep hooks.
+- `gtklock/style.css` (72 lines) + `gtklock/config.ini` are tracked and symlinked to `~/.config/gtklock/`.
+- `/etc/pam.d/gtklock` has `auth sufficient pam_fprintd.so` (from `scripts/enable-fingerprint.sh`).
+- Pain point: gtklock doesn't poll fprintd until PAM is invoked, which only happens once the user submits something in the password field. Touching the reader on a freshly-locked screen does nothing.
+
+## Target Behaviour
+
+- `hyprlock` is the lockscreen, bound to the same keybind, called by the same swayidle hooks.
+- Touch the reader on the locked screen → unlocks immediately.
+- Type the password and press Enter → also unlocks (fallback).
+- Visual: centred 96 px clock, smaller date below, password input field with placeholder text, blurred-screenshot background. Colors map the Tomorrow Night palette.
+
+## Implementation
+
+### `hyprlock/hyprlock.conf` (new)
+
+Single Hyprlang file, deployed to `~/.config/hypr/hyprlock.conf`:
+
+```hyprlang
+general {
+ grace = 0
+ hide_cursor = true
+}
+
+background {
+ monitor =
+ path = screenshot
+ blur_passes = 3
+ blur_size = 8
+}
+
+label {
+ monitor =
+ text = cmd[update:1000] date +"%-I:%M %p"
+ font_size = 96
+ color = rgba(c5c8c6ff)
+ position = 0, 150
+ halign = center
+ valign = center
+}
+
+label {
+ monitor =
+ text = cmd[update:60000] date +"%A, %B %-d"
+ font_size = 24
+ color = rgba(969896ff)
+ position = 0, 40
+ halign = center
+ valign = center
+}
+
+input-field {
+ monitor =
+ size = 300, 50
+ outline_thickness = 2
+ dots_size = 0.25
+ dots_spacing = 0.4
+ inner_color = rgba(282a2eff)
+ outer_color = rgba(81a2beff)
+ font_color = rgba(c5c8c6ff)
+ fail_color = rgba(cc6666ff)
+ check_color = rgba(b5bd68ff)
+ placeholder_text = Touch fingerprint or type password
+ fail_text = $FAIL
+ fade_on_empty = false
+ position = 0, -50
+ halign = center
+ valign = center
+}
+```
+
+Color mapping:
+- `c5c8c6` = `@tn-fg` (clock text, input font)
+- `969896` = `@tn-fg-dim` (date label)
+- `282a2e` = `@tn-bg-alt` (input fill)
+- `81a2be` = `@tn-blue` (focus ring)
+- `cc6666` = `@tn-red` (auth failure)
+- `b5bd68` = `@tn-green` (auth success)
+
+### `packages.txt`
+
+Swap `gtklock` → `hyprlock`. Drop the AUR `gtklock-userinfo-module` entry too (not used in the new config). `hyprlock` is in the `extra` repo — no AUR helper needed for it.
+
+### `install.sh`
+
+Remove the two gtklock symlink lines:
+```bash
+ln -sf "$(pwd)/gtklock/config.ini" ~/.config/gtklock/config
+ln -sf "$(pwd)/gtklock/style.css" ~/.config/gtklock/style.css
+```
+
+Replace with:
+```bash
+mkdir -p ~/.config/hypr
+ln -sf "$(pwd)/hyprlock/hyprlock.conf" ~/.config/hypr/hyprlock.conf
+```
+
+Also drop the `gtklock` entry from the brace-expansion `mkdir -p` near the top of install.sh.
+
+### `niri/config.kdl`
+
+Three changes:
+1. The keybind `Mod+Shift+E { spawn "gtklock" "-d"; }` → `Mod+Shift+E { spawn "hyprlock"; }`
+2. Swayidle's 600 s timer action `"gtklock" "-d"` → `"hyprlock"`
+3. Swayidle's `before-sleep` action `"gtklock" "-d"` → `"hyprlock"`
+
+`hyprlock` takes no `-d` flag — it daemonises by default.
+
+### `scripts/enable-fingerprint.sh`
+
+Change `TARGETS=(/etc/pam.d/sudo /etc/pam.d/gtklock)` → `TARGETS=(/etc/pam.d/sudo /etc/pam.d/hyprlock)`. The script remains idempotent for the new target. Existing `/etc/pam.d/gtklock` pam_fprintd line stays untouched (harmless dead config; the user can `sed -i '/pam_fprintd/d' /etc/pam.d/gtklock` if they want).
+
+### `gtklock/` (deletion)
+
+Delete the tracked directory: `gtklock/config.ini` + `gtklock/style.css`. The packages get uninstalled (or remain installed, user's call); the tracked config files are gone.
+
+### Documentation updates
+
+- `README.md`: change Tooling table row for Lockscreen from `gtklock` to `hyprlock`. Update the `### One-time fingerprint setup` subsection's reference to gtklock's lockscreen (test instruction mentions `Mod+Shift+E`, still valid).
+- `ARCHITECTURE.md`: same table row change.
+- `CLAUDE.md`: replace "gtklock" mentions with "hyprlock" in the Theming + Tooling sections.
+
+### Theme
+
+The repo's `theme/colors.css` is the source of truth for GTK CSS variables. Hyprlock doesn't use CSS — colors are hand-mapped in `hyprlock.conf`. Not a regression in DRY (the values map 1:1 to entries in `theme/colors.json`); no new color source created.
+
+## Files Touched
+
+| File | Action |
+|---|---|
+| `hyprlock/hyprlock.conf` | created |
+| `packages.txt` | swap `gtklock` → `hyprlock`; drop `gtklock-userinfo-module` if present |
+| `install.sh` | swap symlinks (and mkdir entry) |
+| `niri/config.kdl` | swap 3 gtklock invocations to hyprlock |
+| `scripts/enable-fingerprint.sh` | swap target in `TARGETS` array |
+| `gtklock/config.ini` | deleted |
+| `gtklock/style.css` | deleted |
+| `README.md` | update lockscreen reference |
+| `ARCHITECTURE.md` | update lockscreen reference |
+| `CLAUDE.md` | update lockscreen reference |
+
+## Manual user steps after merge
+
+1. `bash install.sh` — installs hyprlock, deploys config, replaces symlinks.
+2. `sudo bash scripts/enable-fingerprint.sh` — re-runs idempotently; adds `pam_fprintd.so` to the new `/etc/pam.d/hyprlock`.
+3. Test: `Mod+Shift+E` to lock → touch reader → unlocks immediately.
+4. Optional cleanup: `sudo pacman -Rns gtklock gtklock-userinfo-module` if you want the old package gone.
+
+## Verification
+
+- `which hyprlock` returns `/usr/bin/hyprlock`
+- `grep pam_fprintd /etc/pam.d/hyprlock` shows the line
+- `hyprlock` (run from terminal) launches the lockscreen with clock, date, input field; Ctrl-C in the terminal won't kill it (it's its own GPU surface); use the password to unlock.
+- Touching the reader unlocks without typing anything first.
+
+## Out of Scope
+
+- **Porting gtklock's CSS layout / theming verbatim.** Hyprlock doesn't use CSS. The new config achieves a comparable look via the palette mapping; further visual polish (avatars, music controls, last-login time) is a future incremental edit to `hyprlock.conf`.
+- **Migrating swayidle's behaviour beyond changing the lock command.** Timers stay (300/600/1800 s).
+- **Cleaning up `/etc/pam.d/gtklock`** — the existing pam_fprintd line in that file becomes harmless dead config since gtklock won't be launched. Manual cleanup if desired.
+- **Uninstalling the `gtklock` system package** — out of scope; user decides.
+- **Hyprlock styling beyond colors + clock + input field** — keep it minimal.
+- **Solid-color background fallback** if the blurred screenshot renders poorly — easy follow-up edit, not part of this spec.
+- **Custom font selection** — uses system default (likely JetBrainsMono Nerd Font since it's installed).