diff --git a/apps/hyprlock/default.nix b/apps/hyprlock/default.nix
index 4d2c876..7c2303a 100644
--- a/apps/hyprlock/default.nix
+++ b/apps/hyprlock/default.nix
@@ -1,9 +1,162 @@
-{ ... }:
-{
+{ config, pkgs, ... }:
+let
+ cacheWallpaper = "${config.home.homeDirectory}/.cache/current_wallpaper";
+ clockFont = "JetBrains Mono";
+
+ typewriter = pkgs.writeShellScript "hyprlock-typewriter" ''
+ text="Welcome back"
+ state_file="/tmp/hyprlock_typewriter"
+ lock_pid="/tmp/hyprlock_pid"
+ blink_file="/tmp/hyprlock_blink"
+
+ # Get current hyprlock PID
+ current_pid=$(pgrep -x hyprlock | head -1)
+
+ # Reset if this is a new hyprlock session
+ if [ -f "$lock_pid" ]; then
+ old_pid=$(cat "$lock_pid")
+ if [ "$current_pid" != "$old_pid" ]; then
+ rm -f "$state_file" "$blink_file"
+ echo "$current_pid" > "$lock_pid"
+ fi
+ else
+ echo "$current_pid" > "$lock_pid"
+ fi
+
+ # Initialize position
+ if [ ! -f "$state_file" ]; then
+ echo 0 > "$state_file"
+ fi
+
+ pos=$(cat "$state_file")
+ len=''${#text}
+
+ # Increment position only if not complete
+ if [ "$pos" -lt "$len" ]; then
+ pos=$((pos + 1))
+ echo "$pos" > "$state_file"
+ echo "''${text:0:$pos}_"
+ else
+ # Blink cursor via foreground color toggle
+ if [ ! -f "$blink_file" ]; then
+ echo 0 > "$blink_file"
+ fi
+ blink=$(cat "$blink_file")
+ if [ "$blink" -eq 0 ]; then
+ echo 1 > "$blink_file"
+ echo "''${text}_"
+ else
+ echo 0 > "$blink_file"
+ echo "''${text}_"
+ fi
+ fi
+ '';
+in {
programs.hyprlock = {
enable = true;
extraConfig = ''
source = ~/.config/hypr/hyprlock-colors.conf
+
+ general {
+ hide_cursor = true
+ grace = 0
+ }
+
+ background {
+ monitor =
+ path = ${cacheWallpaper}
+ blur_passes = 3
+ blur_size = 8
+ contrast = 0.9
+ brightness = 0.7
+ vibrancy = 0.2
+ }
+
+ # Typewriter greeting (above clock)
+ label {
+ monitor =
+ text = cmd[update:120] ${typewriter}
+ color = $on_surface_variant
+ font_size = 24
+ font_family = ${clockFont}
+ position = 0, 200
+ halign = center
+ valign = center
+ }
+
+ # Hours (top)
+ label {
+ monitor =
+ text = cmd[update:1000] date +%H
+ color = $on_surface
+ font_size = 140
+ font_family = ${clockFont} Bold
+ position = 0, 80
+ halign = center
+ valign = center
+ }
+
+ # Minutes (bottom)
+ label {
+ monitor =
+ text = cmd[update:1000] date +%M
+ color = $primary
+ font_size = 140
+ font_family = ${clockFont} Bold
+ position = 0, -80
+ halign = center
+ valign = center
+ }
+
+ # Date
+ label {
+ monitor =
+ text = cmd[update:60000] date '+%A, %B %d'
+ color = $on_surface_variant
+ font_size = 18
+ font_family = ${clockFont}
+ position = 0, -320
+ halign = center
+ valign = center
+ }
+
+ # Caps Lock indicator (above input)
+ label {
+ monitor =
+ text = cmd[update:100] cat /sys/class/leds/*capslock*/brightness 2>/dev/null | grep -q 1 && echo 'CAPS LOCK'
+ color = $tertiary
+ font_size = 12
+ font_family = ${clockFont}
+ position = 0, -210
+ halign = center
+ valign = center
+ }
+
+ input-field {
+ monitor =
+ size = 300, 50
+ outline_thickness = 3
+ dots_size = 0.33
+ dots_spacing = 0.15
+ dots_center = true
+ outer_color = $primary
+ inner_color = $surface
+ font_color = $on_surface
+ fade_on_empty = false
+ placeholder_text = Password...
+ hide_input = false
+ rounding = 15
+ position = 0, -250
+ halign = center
+ valign = center
+
+ # Auth feedback
+ check_color = $secondary
+ fail_color = $error
+ fail_text = $FAIL ($ATTEMPTS)
+ fail_timeout = 2000
+ fail_transition = 300
+ }
'';
};
}