diff --git a/.beads/interactions.jsonl b/.beads/interactions.jsonl
index 018b5eb..0109a82 100644
--- a/.beads/interactions.jsonl
+++ b/.beads/interactions.jsonl
@@ -19,3 +19,6 @@
{"id":"int-ec238d3e","kind":"field_change","created_at":"2026-08-09T18:53:14.795389276Z","actor":"Prad Nukala","issue_id":"chezmoi-21v","extra":{"field":"status","new_value":"closed","old_value":"open","reason":"Closed"}}
{"id":"int-1e6b9af3","kind":"field_change","created_at":"2026-08-09T18:53:15.496566548Z","actor":"Prad Nukala","issue_id":"chezmoi-a2k","extra":{"field":"status","new_value":"in_progress","old_value":"open"}}
{"id":"int-bcfce2e0","kind":"field_change","created_at":"2026-08-09T18:53:15.63271081Z","actor":"Prad Nukala","issue_id":"chezmoi-exq","extra":{"field":"status","new_value":"in_progress","old_value":"open"}}
+{"id":"int-bca8b819","kind":"field_change","created_at":"2026-08-09T18:53:47.081117456Z","actor":"Prad Nukala","issue_id":"chezmoi-a2k","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Closed"}}
+{"id":"int-35ca5bf4","kind":"field_change","created_at":"2026-08-09T18:53:47.230104215Z","actor":"Prad Nukala","issue_id":"chezmoi-exq","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Closed"}}
+{"id":"int-e46b03b9","kind":"field_change","created_at":"2026-08-09T18:53:55.604366711Z","actor":"Prad Nukala","issue_id":"chezmoi-9sg","extra":{"field":"status","new_value":"in_progress","old_value":"open"}}
diff --git a/.beads/issues.jsonl b/.beads/issues.jsonl
index 300160b..36a6bf1 100644
--- a/.beads/issues.jsonl
+++ b/.beads/issues.jsonl
@@ -3,13 +3,13 @@
{"_type":"issue","id":"chezmoi-rnv","title":"Inventory: disposition table for all dotstate synced paths","description":"Parse .dotstate-profiles.toml (Noctalia/Inir/Rogz/Vertical-Rogz_AppleStudio). Every synced path gets decision: universal / arch-gated / defer / drop / secret. Output table in MIGRATION-NOTES.md. Blocks all content.","status":"closed","priority":1,"issue_type":"task","owner":"prad@sonr.io","created_at":"2026-08-09T18:41:50Z","created_by":"Prad Nukala","updated_at":"2026-08-09T18:45:28Z","started_at":"2026-08-09T18:44:23Z","closed_at":"2026-08-09T18:45:28Z","close_reason":"Closed","dependency_count":0,"dependent_count":13,"comment_count":0}
{"_type":"issue","id":"chezmoi-42m","title":"Validation: Arch fresh bring-up in container","description":"docker run archlinux: bootstrap one-liner, packages install, chezmoi doctor clean, niri validate, fish -n all files, nvim --headless +Lazy! sync, tmux -f cfg new -d; kill-server, gh extension list matches manifest. Plus live machine chezmoi diff ~ empty.","status":"open","priority":2,"issue_type":"task","owner":"prad@sonr.io","created_at":"2026-08-09T18:42:17Z","created_by":"Prad Nukala","updated_at":"2026-08-09T18:42:17Z","dependencies":[{"issue_id":"chezmoi-42m","depends_on_id":"chezmoi-21v","type":"blocks","created_at":"2026-08-09T14:42:58Z","created_by":"Prad Nukala","metadata":"{}"},{"issue_id":"chezmoi-42m","depends_on_id":"chezmoi-4sj","type":"blocks","created_at":"2026-08-09T14:42:58Z","created_by":"Prad Nukala","metadata":"{}"},{"issue_id":"chezmoi-42m","depends_on_id":"chezmoi-9sg","type":"blocks","created_at":"2026-08-09T14:42:59Z","created_by":"Prad Nukala","metadata":"{}"},{"issue_id":"chezmoi-42m","depends_on_id":"chezmoi-a2k","type":"blocks","created_at":"2026-08-09T14:42:59Z","created_by":"Prad Nukala","metadata":"{}"},{"issue_id":"chezmoi-42m","depends_on_id":"chezmoi-exq","type":"blocks","created_at":"2026-08-09T14:42:59Z","created_by":"Prad Nukala","metadata":"{}"},{"issue_id":"chezmoi-42m","depends_on_id":"chezmoi-fde","type":"blocks","created_at":"2026-08-09T14:42:59Z","created_by":"Prad Nukala","metadata":"{}"},{"issue_id":"chezmoi-42m","depends_on_id":"chezmoi-hou","type":"blocks","created_at":"2026-08-09T14:42:58Z","created_by":"Prad Nukala","metadata":"{}"},{"issue_id":"chezmoi-42m","depends_on_id":"chezmoi-iu2","type":"blocks","created_at":"2026-08-09T14:42:59Z","created_by":"Prad Nukala","metadata":"{}"},{"issue_id":"chezmoi-42m","depends_on_id":"chezmoi-sd9","type":"blocks","created_at":"2026-08-09T14:42:58Z","created_by":"Prad Nukala","metadata":"{}"},{"issue_id":"chezmoi-42m","depends_on_id":"chezmoi-utl","type":"blocks","created_at":"2026-08-09T14:42:58Z","created_by":"Prad Nukala","metadata":"{}"},{"issue_id":"chezmoi-42m","depends_on_id":"chezmoi-uw2","type":"blocks","created_at":"2026-08-09T14:42:57Z","created_by":"Prad Nukala","metadata":"{}"},{"issue_id":"chezmoi-42m","depends_on_id":"chezmoi-x7f","type":"blocks","created_at":"2026-08-09T14:42:58Z","created_by":"Prad Nukala","metadata":"{}"},{"issue_id":"chezmoi-42m","depends_on_id":"chezmoi-xi5","type":"blocks","created_at":"2026-08-09T14:42:58Z","created_by":"Prad Nukala","metadata":"{}"}],"dependency_count":13,"dependent_count":1,"comment_count":0}
{"_type":"issue","id":"chezmoi-5by","title":"Cutover: freeze dotstate for migrated paths","description":"After both validations: remove migrated paths from .dotstate-profiles.toml, tag dotstate pre-chezmoi-freeze, stop Dolt sync for those paths. Archive, never delete.","status":"open","priority":2,"issue_type":"task","owner":"prad@sonr.io","created_at":"2026-08-09T18:42:17Z","created_by":"Prad Nukala","updated_at":"2026-08-09T18:42:17Z","dependencies":[{"issue_id":"chezmoi-5by","depends_on_id":"chezmoi-42m","type":"blocks","created_at":"2026-08-09T14:42:25Z","created_by":"Prad Nukala","metadata":"{}"},{"issue_id":"chezmoi-5by","depends_on_id":"chezmoi-udp","type":"blocks","created_at":"2026-08-09T14:42:25Z","created_by":"Prad Nukala","metadata":"{}"}],"dependency_count":2,"dependent_count":0,"comment_count":0}
-{"_type":"issue","id":"chezmoi-9sg","title":"Arch layer: niri, noctalia, fontconfig, mimeapps, systemd user units — linux-gated","description":"niri config.d split preserved with exact_ dir; noctalia; fontconfig; mimeapps.list; systemd user units; foot/alacritty if live. All gated in .chezmoiignore.tmpl for darwin. niri validate must pass.","status":"open","priority":2,"issue_type":"task","owner":"prad@sonr.io","created_at":"2026-08-09T18:42:17Z","created_by":"Prad Nukala","updated_at":"2026-08-09T18:42:17Z","dependencies":[{"issue_id":"chezmoi-9sg","depends_on_id":"chezmoi-byc","type":"blocks","created_at":"2026-08-09T14:42:52Z","created_by":"Prad Nukala","metadata":"{}"},{"issue_id":"chezmoi-9sg","depends_on_id":"chezmoi-rnv","type":"blocks","created_at":"2026-08-09T14:42:52Z","created_by":"Prad Nukala","metadata":"{}"}],"dependency_count":2,"dependent_count":2,"comment_count":0}
+{"_type":"issue","id":"chezmoi-9sg","title":"Arch layer: niri, noctalia, fontconfig, mimeapps, systemd user units — linux-gated","description":"niri config.d split preserved with exact_ dir; noctalia; fontconfig; mimeapps.list; systemd user units; foot/alacritty if live. All gated in .chezmoiignore.tmpl for darwin. niri validate must pass.","status":"in_progress","priority":2,"issue_type":"task","owner":"prad@sonr.io","created_at":"2026-08-09T18:42:17Z","created_by":"Prad Nukala","updated_at":"2026-08-09T18:53:56Z","started_at":"2026-08-09T18:53:56Z","dependencies":[{"issue_id":"chezmoi-9sg","depends_on_id":"chezmoi-byc","type":"blocks","created_at":"2026-08-09T14:42:52Z","created_by":"Prad Nukala","metadata":"{}"},{"issue_id":"chezmoi-9sg","depends_on_id":"chezmoi-rnv","type":"blocks","created_at":"2026-08-09T14:42:52Z","created_by":"Prad Nukala","metadata":"{}"}],"dependency_count":2,"dependent_count":2,"comment_count":0}
{"_type":"issue","id":"chezmoi-iu2","title":"packages.yaml: translate dotstate manifests + live state into declarative manifest","description":"Curate Noctalia pacman list (drop base-system noise), custom installers, cargo/go tools, shared gh_extensions; darwin brew/cask section. Install scripts run_onchange keyed on yaml hash: pacman --needed + paru | brew loop; gh extension install loop; linux systemctl --user enable; post: fc-cache, bat cache.","status":"open","priority":2,"issue_type":"task","owner":"prad@sonr.io","created_at":"2026-08-09T18:42:17Z","created_by":"Prad Nukala","updated_at":"2026-08-09T18:42:17Z","dependencies":[{"issue_id":"chezmoi-iu2","depends_on_id":"chezmoi-byc","type":"blocks","created_at":"2026-08-09T14:42:53Z","created_by":"Prad Nukala","metadata":"{}"},{"issue_id":"chezmoi-iu2","depends_on_id":"chezmoi-rnv","type":"blocks","created_at":"2026-08-09T14:42:53Z","created_by":"Prad Nukala","metadata":"{}"}],"dependency_count":2,"dependent_count":2,"comment_count":0}
{"_type":"issue","id":"chezmoi-udp","title":"Validation: darwin simulation","description":"chezmoi execute-template with os=darwin on every .tmpl; darwin-mode dry-run apply writes zero linux-gated paths, errors on nothing. Full Mac apply deferred until hardware available.","status":"open","priority":2,"issue_type":"task","owner":"prad@sonr.io","created_at":"2026-08-09T18:42:17Z","created_by":"Prad Nukala","updated_at":"2026-08-09T18:42:17Z","dependencies":[{"issue_id":"chezmoi-udp","depends_on_id":"chezmoi-21v","type":"blocks","created_at":"2026-08-09T14:43:01Z","created_by":"Prad Nukala","metadata":"{}"},{"issue_id":"chezmoi-udp","depends_on_id":"chezmoi-4sj","type":"blocks","created_at":"2026-08-09T14:43:00Z","created_by":"Prad Nukala","metadata":"{}"},{"issue_id":"chezmoi-udp","depends_on_id":"chezmoi-9sg","type":"blocks","created_at":"2026-08-09T14:43:01Z","created_by":"Prad Nukala","metadata":"{}"},{"issue_id":"chezmoi-udp","depends_on_id":"chezmoi-a2k","type":"blocks","created_at":"2026-08-09T14:43:01Z","created_by":"Prad Nukala","metadata":"{}"},{"issue_id":"chezmoi-udp","depends_on_id":"chezmoi-exq","type":"blocks","created_at":"2026-08-09T14:43:01Z","created_by":"Prad Nukala","metadata":"{}"},{"issue_id":"chezmoi-udp","depends_on_id":"chezmoi-fde","type":"blocks","created_at":"2026-08-09T14:43:01Z","created_by":"Prad Nukala","metadata":"{}"},{"issue_id":"chezmoi-udp","depends_on_id":"chezmoi-hou","type":"blocks","created_at":"2026-08-09T14:43:00Z","created_by":"Prad Nukala","metadata":"{}"},{"issue_id":"chezmoi-udp","depends_on_id":"chezmoi-iu2","type":"blocks","created_at":"2026-08-09T14:43:01Z","created_by":"Prad Nukala","metadata":"{}"},{"issue_id":"chezmoi-udp","depends_on_id":"chezmoi-sd9","type":"blocks","created_at":"2026-08-09T14:43:00Z","created_by":"Prad Nukala","metadata":"{}"},{"issue_id":"chezmoi-udp","depends_on_id":"chezmoi-utl","type":"blocks","created_at":"2026-08-09T14:43:00Z","created_by":"Prad Nukala","metadata":"{}"},{"issue_id":"chezmoi-udp","depends_on_id":"chezmoi-uw2","type":"blocks","created_at":"2026-08-09T14:42:59Z","created_by":"Prad Nukala","metadata":"{}"},{"issue_id":"chezmoi-udp","depends_on_id":"chezmoi-x7f","type":"blocks","created_at":"2026-08-09T14:43:00Z","created_by":"Prad Nukala","metadata":"{}"},{"issue_id":"chezmoi-udp","depends_on_id":"chezmoi-xi5","type":"blocks","created_at":"2026-08-09T14:43:00Z","created_by":"Prad Nukala","metadata":"{}"}],"dependency_count":13,"dependent_count":1,"comment_count":0}
{"_type":"issue","id":"chezmoi-21v","title":"gh: config file + declarative extension list","description":"~/.config/gh config.yml (hosts.yml has oauth token - exclude/encrypt). Extensions: clean-branches, commit, dash, notify into packages.yaml shared.gh_extensions.","status":"closed","priority":2,"issue_type":"task","owner":"prad@sonr.io","created_at":"2026-08-09T18:42:06Z","created_by":"Prad Nukala","updated_at":"2026-08-09T18:53:15Z","closed_at":"2026-08-09T18:53:15Z","close_reason":"Closed","dependencies":[{"issue_id":"chezmoi-21v","depends_on_id":"chezmoi-1a0","type":"blocks","created_at":"2026-08-09T14:42:24Z","created_by":"Prad Nukala","metadata":"{}"},{"issue_id":"chezmoi-21v","depends_on_id":"chezmoi-byc","type":"blocks","created_at":"2026-08-09T14:42:51Z","created_by":"Prad Nukala","metadata":"{}"},{"issue_id":"chezmoi-21v","depends_on_id":"chezmoi-rnv","type":"blocks","created_at":"2026-08-09T14:42:51Z","created_by":"Prad Nukala","metadata":"{}"}],"dependency_count":3,"dependent_count":2,"comment_count":0}
{"_type":"issue","id":"chezmoi-4sj","title":"lazydocker: static config from live","description":"~/.config/lazydocker (not in dotstate).","status":"closed","priority":2,"issue_type":"task","owner":"prad@sonr.io","created_at":"2026-08-09T18:42:06Z","created_by":"Prad Nukala","updated_at":"2026-08-09T18:53:15Z","closed_at":"2026-08-09T18:53:15Z","close_reason":"Closed","dependencies":[{"issue_id":"chezmoi-4sj","depends_on_id":"chezmoi-byc","type":"blocks","created_at":"2026-08-09T14:42:51Z","created_by":"Prad Nukala","metadata":"{}"},{"issue_id":"chezmoi-4sj","depends_on_id":"chezmoi-rnv","type":"blocks","created_at":"2026-08-09T14:42:51Z","created_by":"Prad Nukala","metadata":"{}"}],"dependency_count":2,"dependent_count":2,"comment_count":0}
-{"_type":"issue","id":"chezmoi-a2k","title":"claude: settings, commands, agents, hooks, skills only","description":"~/.claude: settings.json, commands/, hooks/, skills/, CLAUDE.md. Never credentials/history/projects/sessions.","status":"in_progress","priority":2,"issue_type":"task","owner":"prad@sonr.io","created_at":"2026-08-09T18:42:06Z","created_by":"Prad Nukala","updated_at":"2026-08-09T18:53:15Z","started_at":"2026-08-09T18:53:15Z","dependencies":[{"issue_id":"chezmoi-a2k","depends_on_id":"chezmoi-1a0","type":"blocks","created_at":"2026-08-09T14:42:24Z","created_by":"Prad Nukala","metadata":"{}"},{"issue_id":"chezmoi-a2k","depends_on_id":"chezmoi-byc","type":"blocks","created_at":"2026-08-09T14:42:52Z","created_by":"Prad Nukala","metadata":"{}"},{"issue_id":"chezmoi-a2k","depends_on_id":"chezmoi-rnv","type":"blocks","created_at":"2026-08-09T14:42:52Z","created_by":"Prad Nukala","metadata":"{}"}],"dependency_count":3,"dependent_count":2,"comment_count":0}
-{"_type":"issue","id":"chezmoi-exq","title":"git: dot_gitconfig.tmpl with templated email/signing key","description":"~/.gitconfig from live; email + signing key from chezmoi data.","status":"in_progress","priority":2,"issue_type":"task","owner":"prad@sonr.io","created_at":"2026-08-09T18:42:06Z","created_by":"Prad Nukala","updated_at":"2026-08-09T18:53:16Z","started_at":"2026-08-09T18:53:16Z","dependencies":[{"issue_id":"chezmoi-exq","depends_on_id":"chezmoi-byc","type":"blocks","created_at":"2026-08-09T14:42:52Z","created_by":"Prad Nukala","metadata":"{}"},{"issue_id":"chezmoi-exq","depends_on_id":"chezmoi-rnv","type":"blocks","created_at":"2026-08-09T14:42:52Z","created_by":"Prad Nukala","metadata":"{}"}],"dependency_count":2,"dependent_count":2,"comment_count":0}
+{"_type":"issue","id":"chezmoi-a2k","title":"claude: settings, commands, agents, hooks, skills only","description":"~/.claude: settings.json, commands/, hooks/, skills/, CLAUDE.md. Never credentials/history/projects/sessions.","status":"closed","priority":2,"issue_type":"task","owner":"prad@sonr.io","created_at":"2026-08-09T18:42:06Z","created_by":"Prad Nukala","updated_at":"2026-08-09T18:53:47Z","started_at":"2026-08-09T18:53:15Z","closed_at":"2026-08-09T18:53:47Z","close_reason":"Closed","dependencies":[{"issue_id":"chezmoi-a2k","depends_on_id":"chezmoi-1a0","type":"blocks","created_at":"2026-08-09T14:42:24Z","created_by":"Prad Nukala","metadata":"{}"},{"issue_id":"chezmoi-a2k","depends_on_id":"chezmoi-byc","type":"blocks","created_at":"2026-08-09T14:42:52Z","created_by":"Prad Nukala","metadata":"{}"},{"issue_id":"chezmoi-a2k","depends_on_id":"chezmoi-rnv","type":"blocks","created_at":"2026-08-09T14:42:52Z","created_by":"Prad Nukala","metadata":"{}"}],"dependency_count":3,"dependent_count":2,"comment_count":0}
+{"_type":"issue","id":"chezmoi-exq","title":"git: dot_gitconfig.tmpl with templated email/signing key","description":"~/.gitconfig from live; email + signing key from chezmoi data.","status":"closed","priority":2,"issue_type":"task","owner":"prad@sonr.io","created_at":"2026-08-09T18:42:06Z","created_by":"Prad Nukala","updated_at":"2026-08-09T18:53:47Z","started_at":"2026-08-09T18:53:16Z","closed_at":"2026-08-09T18:53:47Z","close_reason":"Closed","dependencies":[{"issue_id":"chezmoi-exq","depends_on_id":"chezmoi-byc","type":"blocks","created_at":"2026-08-09T14:42:52Z","created_by":"Prad Nukala","metadata":"{}"},{"issue_id":"chezmoi-exq","depends_on_id":"chezmoi-rnv","type":"blocks","created_at":"2026-08-09T14:42:52Z","created_by":"Prad Nukala","metadata":"{}"}],"dependency_count":2,"dependent_count":2,"comment_count":0}
{"_type":"issue","id":"chezmoi-fde","title":"starship: prompt config, universal","description":"Keep starship (user decision — omp dropped). dot_config/starship.toml from live; starship in packages.yaml both OSes. Noctalia palette block is auto-generated on linux — noctalia rewrites it in place; acceptable drift, noted.","status":"closed","priority":2,"issue_type":"task","owner":"prad@sonr.io","created_at":"2026-08-09T18:42:06Z","created_by":"Prad Nukala","updated_at":"2026-08-09T18:51:26Z","closed_at":"2026-08-09T18:51:26Z","close_reason":"starship.toml added from live; packages updated","dependencies":[{"issue_id":"chezmoi-fde","depends_on_id":"chezmoi-byc","type":"blocks","created_at":"2026-08-09T14:42:52Z","created_by":"Prad Nukala","metadata":"{}"},{"issue_id":"chezmoi-fde","depends_on_id":"chezmoi-rnv","type":"blocks","created_at":"2026-08-09T14:42:51Z","created_by":"Prad Nukala","metadata":"{}"}],"dependency_count":2,"dependent_count":2,"comment_count":0}
{"_type":"issue","id":"chezmoi-x7f","title":"lazygit: static config","description":"~/.config/lazygit. Already partially in repo — reconcile.","status":"closed","priority":2,"issue_type":"task","owner":"prad@sonr.io","created_at":"2026-08-09T18:42:06Z","created_by":"Prad Nukala","updated_at":"2026-08-09T18:53:14Z","closed_at":"2026-08-09T18:53:14Z","close_reason":"Closed","dependencies":[{"issue_id":"chezmoi-x7f","depends_on_id":"chezmoi-byc","type":"blocks","created_at":"2026-08-09T14:42:51Z","created_by":"Prad Nukala","metadata":"{}"},{"issue_id":"chezmoi-x7f","depends_on_id":"chezmoi-rnv","type":"blocks","created_at":"2026-08-09T14:42:50Z","created_by":"Prad Nukala","metadata":"{}"}],"dependency_count":2,"dependent_count":2,"comment_count":0}
{"_type":"issue","id":"chezmoi-hou","title":"yazi: config, opener rules OS-branched","description":"~/.config/yazi. open vs xdg-open template branch.","status":"closed","priority":2,"issue_type":"task","owner":"prad@sonr.io","created_at":"2026-08-09T18:42:05Z","created_by":"Prad Nukala","updated_at":"2026-08-09T18:53:14Z","closed_at":"2026-08-09T18:53:14Z","close_reason":"Closed","dependencies":[{"issue_id":"chezmoi-hou","depends_on_id":"chezmoi-byc","type":"blocks","created_at":"2026-08-09T14:42:50Z","created_by":"Prad Nukala","metadata":"{}"},{"issue_id":"chezmoi-hou","depends_on_id":"chezmoi-rnv","type":"blocks","created_at":"2026-08-09T14:42:50Z","created_by":"Prad Nukala","metadata":"{}"}],"dependency_count":2,"dependent_count":2,"comment_count":0}
diff --git a/.chezmoiscripts/run_once_after_30-user-services.sh.tmpl b/.chezmoiscripts/run_once_after_30-user-services.sh.tmpl
new file mode 100644
index 0000000..dbe35d5
--- /dev/null
+++ b/.chezmoiscripts/run_once_after_30-user-services.sh.tmpl
@@ -0,0 +1,15 @@
+{{ if eq .chezmoi.os "linux" -}}
+#!/bin/sh
+# Enable session-critical user services. Personal automation units
+# (brain-lens, omp-loop, rclone, hermes, voxtype) ship as files only —
+# enable manually per machine. See MIGRATION-NOTES.md.
+set -eu
+
+if [ -f "$HOME/.config/systemd/user/nirinit.service" ] && command -v systemctl >/dev/null 2>&1; then
+ systemctl --user daemon-reload || true
+ systemctl --user enable nirinit.service || true
+fi
+{{ else -}}
+#!/bin/sh
+exit 0
+{{ end -}}
diff --git a/.chezmoiscripts/run_onchange_after_20-gh-extensions.sh.tmpl b/.chezmoiscripts/run_onchange_after_20-gh-extensions.sh.tmpl
new file mode 100644
index 0000000..4182694
--- /dev/null
+++ b/.chezmoiscripts/run_onchange_after_20-gh-extensions.sh.tmpl
@@ -0,0 +1,12 @@
+#!/bin/sh
+# Install gh extensions declared in .chezmoidata/packages.yaml.
+# gh_extensions hash: {{ .packages.shared.gh_extensions | toJson | sha256sum }}
+set -eu
+
+command -v gh >/dev/null 2>&1 || { echo "warning: gh not installed — skipping extensions" >&2; exit 0; }
+gh auth status >/dev/null 2>&1 || { echo "warning: gh not authenticated — run 'gh auth login', then 'chezmoi apply' again" >&2; exit 0; }
+
+installed=$(gh extension list 2>/dev/null | cut -f2 || true)
+{{ range .packages.shared.gh_extensions }}
+echo "$installed" | grep -qxF "{{ . }}" || gh extension install "{{ . }}"
+{{ end }}
diff --git a/.chezmoiscripts/run_onchange_after_40-post.sh.tmpl b/.chezmoiscripts/run_onchange_after_40-post.sh.tmpl
new file mode 100644
index 0000000..3990826
--- /dev/null
+++ b/.chezmoiscripts/run_onchange_after_40-post.sh.tmpl
@@ -0,0 +1,14 @@
+#!/bin/sh
+# Post-apply housekeeping. Re-runs when this file's rendered content changes.
+set -eu
+
+# tmux plugin manager — tmux.conf expects tpm at this path
+if command -v tmux >/dev/null 2>&1 && [ ! -d "$HOME/.config/tmux/plugins/tpm" ]; then
+ git clone --depth=1 https://github.com/tmux-plugins/tpm "$HOME/.config/tmux/plugins/tpm" || true
+fi
+
+if command -v bat >/dev/null 2>&1; then bat cache --build >/dev/null || true; fi
+
+{{ if eq .chezmoi.os "linux" -}}
+if command -v fc-cache >/dev/null 2>&1; then fc-cache -f >/dev/null || true; fi
+{{ end -}}
diff --git a/.chezmoiscripts/run_onchange_before_10-packages.sh.tmpl b/.chezmoiscripts/run_onchange_before_10-packages.sh.tmpl
new file mode 100644
index 0000000..d9b59e5
--- /dev/null
+++ b/.chezmoiscripts/run_onchange_before_10-packages.sh.tmpl
@@ -0,0 +1,44 @@
+#!/bin/sh
+# Install packages declared in .chezmoidata/packages.yaml.
+# packages.yaml hash: {{ include ".chezmoidata/packages.yaml" | sha256sum }}
+set -eu
+
+{{ if eq .chezmoi.os "linux" -}}
+if [ "$(id -u)" -eq 0 ]; then PACMAN="pacman"; else PACMAN="sudo pacman"; fi
+
+# shellcheck disable=SC2086 # word splitting intended
+$PACMAN -S --needed --noconfirm \
+{{ range .packages.arch.pacman }} {{ . }} \
+{{ end }} && true
+
+{{ if or (eq .role "desktop") (eq .role "laptop") -}}
+$PACMAN -S --needed --noconfirm \
+{{ range .packages.arch.desktop.pacman }} {{ . }} \
+{{ end }} && true
+
+aur_pkgs="{{ range .packages.arch.desktop.aur }}{{ . }} {{ end }}{{ range .packages.arch.aur }}{{ . }} {{ end }}"
+{{ else -}}
+aur_pkgs="{{ range .packages.arch.aur }}{{ . }} {{ end }}"
+{{ end -}}
+if [ -n "$(echo "$aur_pkgs" | tr -d ' ')" ]; then
+ if command -v paru >/dev/null 2>&1; then
+ # shellcheck disable=SC2086
+ paru -S --needed --noconfirm $aur_pkgs
+ else
+ echo "warning: paru not found — skipping AUR packages: $aur_pkgs" >&2
+ fi
+fi
+
+{{ else if eq .chezmoi.os "darwin" -}}
+if ! command -v brew >/dev/null 2>&1; then
+ echo "error: homebrew not installed — https://brew.sh" >&2
+ exit 1
+fi
+brew install \
+{{ range .packages.darwin.brew }} {{ . }} \
+{{ end }} && true
+
+brew install --cask \
+{{ range .packages.darwin.cask }} {{ . }} \
+{{ end }} && true
+{{ end -}}
diff --git a/dot_config/fontconfig/fonts.conf b/dot_config/fontconfig/fonts.conf
new file mode 100644
index 0000000..f450859
--- /dev/null
+++ b/dot_config/fontconfig/fonts.conf
@@ -0,0 +1,9 @@
+
+
+
+
+
+ none
+
+
+
diff --git a/dot_config/mimeapps.list b/dot_config/mimeapps.list
new file mode 100644
index 0000000..68d1685
--- /dev/null
+++ b/dot_config/mimeapps.list
@@ -0,0 +1,51 @@
+[Default Applications]
+text/plain=vim.desktop
+text/x-shellscript=vim.desktop
+text/x-python=vim.desktop
+text/x-script.python=vim.desktop
+text/html=brave-origin-nightly.desktop
+x-scheme-handler/http=brave-origin-nightly.desktop
+x-scheme-handler/https=brave-origin-nightly.desktop
+x-scheme-handler/about=chromium.desktop
+x-scheme-handler/unknown=chromium.desktop
+x-scheme-handler/chrome=brave-origin-nightly.desktop
+application/x-extension-htm=brave-origin-nightly.desktop
+application/x-extension-html=brave-origin-nightly.desktop
+application/x-extension-shtml=brave-origin-nightly.desktop
+application/xhtml+xml=brave-origin-nightly.desktop
+application/x-extension-xhtml=brave-origin-nightly.desktop
+application/x-extension-xht=brave-origin-nightly.desktop
+x-scheme-handler/figma=figma-linux.desktop
+x-scheme-handler/claude=com.anthropic.Claude.desktop
+x-scheme-handler/claude-cli=claude-code-url-handler.desktop
+x-scheme-handler/com.todoist=todoist.desktop
+x-scheme-handler/todoist=todoist.desktop
+x-scheme-handler/openhuman=OpenHuman-handler.desktop
+application/vnd.microsoft.portable-executable=wine.desktop
+x-scheme-handler/slack=slack.desktop
+x-scheme-handler/mailto=userapp-Evolution-PCEYQ3.desktop
+x-scheme-handler/anytype=anytype.desktop
+x-scheme-handler/piebald=piebald-handler.desktop
+x-scheme-handler/discord-647066573147996161=discord-647066573147996161.desktop
+x-scheme-handler/tolaria=tolaria-handler.desktop
+x-scheme-handler/antigravity=antigravity.desktop
+application/pdf=com.brave.Origin.nightly.desktop
+x-scheme-handler/opencode=ai.opencode.desktop.desktop
+x-scheme-handler/follow=folo.desktop
+x-scheme-handler/folo=folo.desktop
+
+[Added Associations]
+x-scheme-handler/http=brave-origin-nightly.desktop;userapp-Floorp-9MTFP3.desktop;
+x-scheme-handler/https=brave-origin-nightly.desktop;userapp-Floorp-9MTFP3.desktop;
+x-scheme-handler/chrome=brave-origin-nightly.desktop;userapp-Floorp-9MTFP3.desktop;
+text/html=brave-origin-nightly.desktop;userapp-Floorp-9MTFP3.desktop;
+application/x-extension-htm=brave-origin-nightly.desktop;userapp-Floorp-9MTFP3.desktop;
+application/x-extension-html=brave-origin-nightly.desktop;userapp-Floorp-9MTFP3.desktop;
+application/x-extension-shtml=brave-origin-nightly.desktop;userapp-Floorp-9MTFP3.desktop;
+application/xhtml+xml=brave-origin-nightly.desktop;userapp-Floorp-9MTFP3.desktop;
+application/x-extension-xhtml=brave-origin-nightly.desktop;userapp-Floorp-9MTFP3.desktop;
+application/x-extension-xht=brave-origin-nightly.desktop;userapp-Floorp-9MTFP3.desktop;
+application/vnd.microsoft.portable-executable=wine.desktop;
+x-scheme-handler/mailto=userapp-Evolution-PCEYQ3.desktop;
+application/pdf=com.brave.Origin.nightly.desktop;
+x-scheme-handler/opencode=ai.opencode.desktop.desktop;
diff --git a/dot_config/niri-dynamic-workspaces/config.toml b/dot_config/niri-dynamic-workspaces/config.toml
new file mode 100644
index 0000000..989ace7
--- /dev/null
+++ b/dot_config/niri-dynamic-workspaces/config.toml
@@ -0,0 +1,76 @@
+[general]
+workspace_prefix = "ndw-" # prefix for dynamic workspace names
+default_programs = ["kitty"] # programs launched when creating any new workspace
+auto_delete_empty = true # daemon: auto-delete empty unfocused workspaces
+hover_preview = false # preview workspaces by hovering over cards
+layout = "qwerty" # keyboard layout for the overlay (see table below)
+
+[keybinds]
+close = ["Escape", "Ctrl+c", "Ctrl+w", "Ctrl+q"] # keys to dismiss the overlay
+
+[workspace.y] # digit workspaces work too
+name = "YouTube"
+programs = ["vicinae vicinae://launch/applications/WebApp-YouTube7881"]
+
+[workspace.m] # digit workspaces work too
+name = "Messages"
+programs = [
+ "vicinae vicinae://launch/applications/beeper",
+ "vicinae vicinae://launch/applications/org.gnome.Evolution",
+]
+
+[workspace.l] # digit workspaces work too
+name = "Linear"
+programs = ["vicinae vicinae://launch/applications/WebApp-Linear3312"]
+
+[workspace.d] # digit workspaces work too
+name = "Chrome"
+programs = ["vicinae vicinae://launch/applications/google-chrome"]
+
+[workspace.x] # digit workspaces work too
+name = "Twitter"
+programs = ["vicinae vicinae://launch/applications/WebApp-X1000"]
+
+[workspace.h]
+name = "Herdr"
+programs = ["kitty --class kitty-herdr -e herdr"]
+
+# digit workspaces work too
+[workspace.f]
+name = "Frontend"
+programs = [
+ "kitty-nvim walletbases/website",
+ "kitty-claude walletbases/website",
+]
+
+[workspace.c]
+name = "Contracts"
+programs = [
+ "kitty-nvim walletbases/contracts",
+ "kitty --class kitty-claude -d /home/prad/Developer/github.com/walletbases/contracts -e claude",
+]
+
+
+[workspace.b]
+name = "Backend"
+programs = [
+ "kitty --class kitty-nvim -d /home/prad/Developer/github.com/walletbases/backend -e nvim",
+ "kitty --class kitty-claude -d /home/prad/Developer/github.com/walletbases/backend -e claude",
+]
+
+[workspace.s]
+name = "SDK"
+programs = [
+ "kitty --class kitty-nvim -d /home/prad/Developer/github.com/walletbases/core -e nvim",
+ "kitty --class kitty-claude -d /home/prad/Developer/github.com/walletbases/core -e claude",
+]
+
+[workspace.w]
+name = "Web"
+programs = [
+ "kitty --class kitty-nvim -d /home/prad/Developer/github.com/walletbases/website -e nvim",
+ "kitty --class kitty-claude -d /home/prad/Developer/github.com/walletbases/website -e claude",
+]
+
+[hooks]
+on_create = ['''~/.config/niri/scripts/ndw-route-workspace.sh''']
diff --git a/dot_config/niri/config.kdl b/dot_config/niri/config.kdl
new file mode 100644
index 0000000..08726e8
--- /dev/null
+++ b/dot_config/niri/config.kdl
@@ -0,0 +1,195 @@
+// ============================================================================
+// NIRI CONFIGURATION - Base for iNiR (ii)
+// ============================================================================
+// Minimal base config - customize to your needs
+// Wiki: https://github.com/YaLTeR/niri/wiki/Configuration:-Introduction
+// ============================================================================
+
+
+hotkey-overlay {
+ skip-at-startup
+}
+
+screenshot-path "~/Pictures/Screenshots/Screenshot from %Y-%m-%d %H-%M-%S.png"
+
+include "config.d/10-input-and-cursor.kdl"
+
+include "config.d/20-layout-and-overview.kdl"
+
+include "config.d/30-window-rules.kdl"
+
+include "config.d/40-environment.kdl"
+
+include "config.d/50-startup.kdl"
+
+include "config.d/60-animations.kdl"
+
+include "config.d/70-binds.kdl"
+
+include "config.d/80-layer-rules.kdl"
+
+include "config.d/90-outputs.kdl"
+
+// ============================================================================
+// Layer rules added by iNiR (required for backdrop in overview)
+// ============================================================================
+
+input {
+ keyboard {
+ xkb {
+ layout "us"
+ }
+ repeat-delay 400
+ repeat-rate 50
+ }
+ touchpad {
+ natural-scroll
+ tap
+ tap-button-map "left-right-middle"
+ }
+
+ mod-key "Super"
+ mod-key-nested "Alt"
+}
+
+// ============================================================================
+// LAYOUT
+// ============================================================================
+
+layout {
+ background-color "transparent"
+ default-column-width { proportion 0.5; }
+
+ preset-column-widths {
+ proportion 0.33333
+ proportion 0.5
+ proportion 0.66667
+ }
+
+ focus-ring {
+ width 1.5
+ active-color "#7fc8ff"
+ inactive-color "transparent"
+ }
+
+ border {
+ off
+ width 1.5
+ active-color "#ffc87f"
+ inactive-color "transparent"
+ urgent-color "#9b0000"
+ }
+
+ shadow {
+ off
+ softness 30
+ spread 5
+ offset x=0 y=5
+ color "#0007"
+ }
+
+ tab-indicator {
+ place-within-column
+ hide-when-single-tab
+ position "left" // Can be "left", "right", "top", or "bottom"
+ }
+
+}
+
+gestures {
+ hot-corners {
+ off
+ }
+}
+
+cursor {
+ xcursor-theme "capitaine-cursors-light"
+ xcursor-size 24
+ hide-when-typing
+}
+
+overview {
+ zoom 0.4
+ workspace-shadow { off; }
+}
+// ============================================================================
+// WINDOW RULES
+// ============================================================================
+
+window-rule {
+ geometry-corner-radius 8
+ clip-to-geometry true
+}
+
+// ============================================================================
+// ANIMATIONS
+// ============================================================================
+// Tuned to complement quickshell's expressive Material motion curves
+// QS uses ~500ms for main movements, ~400ms enter, ~200ms exit
+
+animations {
+ workspace-switch {
+ spring damping-ratio=0.78 stiffness=1350 epsilon=0.0001
+ }
+ window-open {
+ spring damping-ratio=0.82 stiffness=1125 epsilon=0.0001
+ }
+ window-close {
+ spring damping-ratio=0.88 stiffness=2025 epsilon=0.0001
+ }
+ horizontal-view-movement {
+ spring damping-ratio=0.80 stiffness=1238 epsilon=0.0001
+ }
+ window-movement {
+ spring damping-ratio=0.85 stiffness=1463 epsilon=0.0001
+ }
+ window-resize {
+ spring damping-ratio=0.88 stiffness=1575 epsilon=0.0001
+ }
+ config-notification-open-close {
+ spring damping-ratio=0.90 stiffness=1800 epsilon=0.0001
+ }
+ screenshot-ui-open {
+ spring damping-ratio=0.85 stiffness=1688 epsilon=0.0001
+ }
+}
+
+// ============================================================================
+// ENVIRONMENT
+// ============================================================================
+
+environment {
+ XDG_CURRENT_DESKTOP "niri"
+ XDG_MENU_PREFIX "plasma-" // Required for Dolphin/KDE app file associations
+ QT_QPA_PLATFORM "wayland"
+ ELECTRON_OZONE_PLATFORM_HINT "auto"
+ QT_LOGGING_RULES "quickshell.dbus.properties=false"
+
+ // Qt theming: kde platform reads colors from kdeglobals (requires plasma-integration pkg)
+ // The installer falls back to qt6ct only if plasma-integration is not installed
+ QT_QPA_PLATFORMTHEME "kde"
+ QT_STYLE_OVERRIDE "Darkly"
+
+ // Quickshell Python virtual environment
+ INIR_VENV "$HOME/.local/state/quickshell/.venv"
+ ILLOGICAL_IMPULSE_VIRTUAL_ENV "$HOME/.local/state/quickshell/.venv"
+}
+
+// ============================================================================
+// STARTUP — commands live in config.d/50-startup.kdl
+// ============================================================================
+
+// Noctalia v5: allows notification actions and window activation from Noctalia.
+debug {
+ honor-xdg-activation-with-invalid-serial
+}
+
+
+// ============================================================================
+// KEYBINDINGS
+// ============================================================================
+
+
+include "./noctalia.kdl"
+
+prefer-no-csd
diff --git a/dot_config/niri/exact_config.d/10-input-and-cursor.kdl b/dot_config/niri/exact_config.d/10-input-and-cursor.kdl
new file mode 100644
index 0000000..d7cb00f
--- /dev/null
+++ b/dot_config/niri/exact_config.d/10-input-and-cursor.kdl
@@ -0,0 +1,44 @@
+// Outputs (example - disabled by default)
+// Run `niri msg outputs` inside a niri session to see connector names and modes.
+// Then edit and uncomment this block to pin a specific monitor layout.
+
+// ============================================================================
+// INPUT
+// ============================================================================
+
+input {
+ keyboard {
+ xkb {
+ layout "us"
+ }
+ repeat-delay 400
+ repeat-rate 50
+ }
+ touchpad {
+ natural-scroll
+ tap
+ tap-button-map "left-right-middle"
+ accel-speed 1.0
+ }
+
+ tablet {
+ map-to-output "eDP-1"
+ }
+
+ touch {
+ map-to-output "eDP-1"
+ }
+
+ mod-key "Super"
+ mod-key-nested "Alt"
+}
+
+gestures {
+
+}
+
+cursor {
+ xcursor-theme "capitaine-cursors-light"
+ xcursor-size 24
+ hide-when-typing
+}
diff --git a/dot_config/niri/exact_config.d/20-layout-and-overview.kdl b/dot_config/niri/exact_config.d/20-layout-and-overview.kdl
new file mode 100644
index 0000000..a19ca5f
--- /dev/null
+++ b/dot_config/niri/exact_config.d/20-layout-and-overview.kdl
@@ -0,0 +1,57 @@
+layout {
+ center-focused-column "never"
+ background-color "transparent"
+ default-column-width { proportion 0.5; }
+
+ preset-column-widths {
+ proportion 0.33333
+ proportion 0.5
+ proportion 0.66667
+ }
+
+ focus-ring {
+ width 1.5
+ active-color "#7fc8ff"
+ inactive-color "transparent"
+ }
+
+ border {
+ off
+ width 1.5
+ active-color "#ffc87f"
+ inactive-color "transparent"
+ urgent-color "#9b0000"
+ }
+
+ shadow {
+ off
+ softness 30
+ spread 5
+ offset x=0 y=5
+ color "#0007"
+ }
+
+ tab-indicator {
+ place-within-column
+ hide-when-single-tab
+ position "left" // Can be "left", "right", "top", or "bottom"
+ }
+
+
+}
+
+gestures {
+ hot-corners {
+ }
+}
+
+cursor {
+ xcursor-theme "capitaine-cursors-light"
+ xcursor-size 24
+ hide-when-typing
+}
+
+overview {
+ zoom 0.4
+ workspace-shadow { off; }
+}
diff --git a/dot_config/niri/exact_config.d/30-window-rules.kdl b/dot_config/niri/exact_config.d/30-window-rules.kdl
new file mode 100644
index 0000000..beef1cb
--- /dev/null
+++ b/dot_config/niri/exact_config.d/30-window-rules.kdl
@@ -0,0 +1,135 @@
+// ============================================================================
+// WINDOW RULES
+// ============================================================================
+
+window-rule {
+ geometry-corner-radius 10
+ clip-to-geometry true
+}
+
+window-rule {
+ background-effect {
+ blur true
+ xray false
+ }
+}
+
+// Noctalia v5: floating settings window.
+window-rule {
+ match app-id="dev.noctalia.Noctalia"
+ open-floating true
+ default-column-width { fixed 1080; }
+ default-window-height { fixed 920; }
+}
+
+blur {
+ passes 4
+ offset 5.0
+ noise 0.02
+ saturation 2.0
+}
+
+window-rule {
+ match app-id="Folo"
+ match app-id="Spotify"
+ match app-id="zen"
+ match app-id="brave-origin-nightly"
+ match app-id="gemini-desktop"
+ match app-id="claude-desktop"
+ opacity 0.9
+ open-floating false
+ draw-border-with-background false
+ background-effect {
+ blur true
+ xray false
+ }
+ open-focused true
+}
+
+window-rule {
+ match app-id="kitty"
+ match app-id="zed"
+ match app-id="obsidian"
+ match app-id="Beeper"
+ match app-id="chromium"
+ match app-id="com.mitchellh.ghostty"
+ opacity 0.9
+ open-floating false
+ draw-border-with-background false
+ open-focused true
+ background-effect {
+ blur true
+ xray false
+ }
+}
+
+window-rule {
+ match app-id="org.gnome.Nautilus"
+ match app-id="com.gabm.satty"
+ open-floating true
+ open-focused true
+ draw-border-with-background false
+ default-column-width { proportion 0.5; }
+}
+
+window-rule {
+ match app-id="kitty-dropdown"
+ open-floating true
+ opacity 1.0
+ default-floating-position x=32 y=32 relative-to="top"
+}
+
+window-rule {
+ match title="ostt"
+ open-floating true
+ open-focused true
+ default-column-width { proportion 0.1; }
+ default-window-height { proportion 0.15; }
+ opacity 0.8
+
+ draw-border-with-background false
+ default-floating-position x=64 y=64 relative-to="bottom-right"
+}
+
+
+window-rule {
+ match title="Picture-in-Picture" app-id="zen"
+ match title="Picture in picture"
+ open-floating true
+ open-focused false
+ opacity 1.0
+
+ // default-floating-position x=28 y=28 relative-to="top-right"
+ default-floating-position x=28 y=28 relative-to="bottom-left"
+ // open-on-output "eDP-1"
+ open-on-output "HDMI-A-1"
+ // open-on-output "Apple Computer Inc StudioDisplay 0x984262A7"
+}
+
+window-rule {
+ // open-on-output "HDMI-A-1"
+}
+
+window-rule {
+ match app-id="sticky-notest-canvas"
+ match title="Sticky Notes"
+ match app-id="vacuumtube"
+ match app-id="Fladder"
+ match app-id="gemini-desktop"
+ match app-id="com-fastmail-fastmail"
+ match app-id="Beeper"
+ match app-id="todoist"
+ match app-id="com.anthropic.Claude"
+ match app-id="Hermes"
+
+
+ open-on-output "eDP-1"
+}
+
+window-rule {
+ match app-id="kitty"
+ match app-id="zed"
+ match app-id="obsidian"
+
+ open-on-output "Apple Computer Inc StudioDisplay 0x984262A7"
+}
diff --git a/dot_config/niri/exact_config.d/40-environment.kdl b/dot_config/niri/exact_config.d/40-environment.kdl
new file mode 100644
index 0000000..1ffe0bc
--- /dev/null
+++ b/dot_config/niri/exact_config.d/40-environment.kdl
@@ -0,0 +1,22 @@
+// ============================================================================
+// ENVIRONMENT
+// ============================================================================
+
+environment {
+ XDG_CURRENT_DESKTOP "niri"
+ XDG_MENU_PREFIX "plasma-" // Required for Dolphin/KDE app file associations
+ QT_QPA_PLATFORM "wayland"
+ ELECTRON_OZONE_PLATFORM_HINT "auto"
+ QT_LOGGING_RULES "quickshell.dbus.properties=false"
+
+ // Qt theming: kde platform reads colors from kdeglobals (requires plasma-integration pkg)
+ // The installer falls back to qt6ct only if plasma-integration is not installed
+ QT_QPA_PLATFORMTHEME "kde"
+ QT_STYLE_OVERRIDE "Darkly"
+
+ // Quickshell Python virtual environment
+ INIR_VENV "$HOME/.local/state/quickshell/.venv"
+ ILLOGICAL_IMPULSE_VIRTUAL_ENV "$HOME/.local/state/quickshell/.venv"
+}
+
+
diff --git a/dot_config/niri/exact_config.d/50-startup.kdl b/dot_config/niri/exact_config.d/50-startup.kdl
new file mode 100644
index 0000000..7154a9c
--- /dev/null
+++ b/dot_config/niri/exact_config.d/50-startup.kdl
@@ -0,0 +1,11 @@
+// ============================================================================
+// STARTUP
+// ============================================================================
+
+// Import XDG_MENU_PREFIX to systemd for Dolphin/KDE app file associations
+spawn-at-startup "bash" "-c" "systemctl --user import-environment XDG_MENU_PREFIX && kbuildsycoca6"
+spawn-at-startup "/usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1"
+spawn-at-startup "noctalia"
+spawn-at-startup "niri-dynamic-workspaces" "daemon"
+spawn-at-startup "vicinae" "server"
+spawn-at-startup "bash" "-c" "wl-paste --watch cliphist store &"
diff --git a/dot_config/niri/exact_config.d/60-animations.kdl b/dot_config/niri/exact_config.d/60-animations.kdl
new file mode 100644
index 0000000..ed2a530
--- /dev/null
+++ b/dot_config/niri/exact_config.d/60-animations.kdl
@@ -0,0 +1,32 @@
+// ============================================================================
+// ANIMATIONS
+// ============================================================================
+// Tuned to complement quickshell's expressive Material motion curves
+// QS uses ~500ms for main movements, ~400ms enter, ~200ms exit
+
+animations {
+ workspace-switch {
+spring damping-ratio=1.0 stiffness=4000 epsilon=0.0001
+ }
+ window-open {
+ spring damping-ratio=1.0 stiffness=5000 epsilon=0.0001
+ }
+ window-close {
+ spring damping-ratio=1.0 stiffness=6000 epsilon=0.0001
+ }
+ horizontal-view-movement {
+ spring damping-ratio=1.0 stiffness=4500 epsilon=0.0001
+ }
+ window-movement {
+ spring damping-ratio=1.0 stiffness=5000 epsilon=0.0001
+ }
+ window-resize {
+ spring damping-ratio=1.0 stiffness=5500 epsilon=0.0001
+ }
+ config-notification-open-close {
+ spring damping-ratio=1.0 stiffness=5000 epsilon=0.0001
+ }
+ screenshot-ui-open {
+ spring damping-ratio=1.0 stiffness=5000 epsilon=0.0001
+ }
+}
diff --git a/dot_config/niri/exact_config.d/70-binds.kdl b/dot_config/niri/exact_config.d/70-binds.kdl
new file mode 100644
index 0000000..ffe7fd8
--- /dev/null
+++ b/dot_config/niri/exact_config.d/70-binds.kdl
@@ -0,0 +1,154 @@
+// ============================================================================
+// KEYBINDINGS
+// ============================================================================
+
+
+binds {
+ // System
+ Mod+Tab repeat=false { toggle-overview; }
+ Mod+Shift+E { quit; }
+ Mod+Escape allow-inhibiting=false { toggle-keyboard-shortcuts-inhibit; }
+
+ // ii Overview (daemon)
+ Mod+Space repeat=false { spawn "vicinae" "toggle"; }
+ Mod+Shift+Space repeat=false { spawn "vicinae" "vicinae://launch/core/search-emojis"; }
+ Mod+Shift+Return repeat=false { spawn "vicinae" "vicinae://launch/wm/switch-windows"; }
+ Mod+BackSpace { focus-window-previous; }
+
+ // ii Clipboard
+ Mod+P { spawn "vicinae" "vicinae://launch/clipboard/history"; }
+ Mod+Ctrl+R { spawn "noctalia" "msg" "plugin" "prdlk/ostt:recorder" "focused" "toggle"; }
+
+ // ii Region tools
+ Mod+Shift+G { spawn "kitty" "--title=goliath" "ssh" "-t" "goliath" "tmux" "new-session" "-A" "-s" "main"; }
+ Mod+S { spawn "dot-screenshot" "region"; }
+ Mod+Shift+S { spawn "dot-screenshot" "window"; }
+ Mod+Ctrl+S { spawn "dot-screenshot" "monitor-focused"; }
+ Mod+Ctrl+Shift+S { spawn "dot-screenshot" "monitor-all"; }
+ // v4: Mod+Period { spawn-sh "qs -c noctalia-shell ipc call controlCenter toggle"; }
+ // v4: Mod+Comma { spawn-sh "qs -c noctalia-shell ipc call settings toggle"; }
+ Mod+Period { spawn-sh "noctalia msg panel-toggle control-center"; }
+ Mod+Comma { spawn-sh "noctalia msg settings-toggle"; }
+
+ Super+Ctrl+A { spawn "vicinae" "vicinae://launch/applications/com.anthropic.Claude"; }
+ Super+Ctrl+G { spawn "vicinae" "vicinae://launch/applications/gemini-desktop"; }
+ Super+Alt+Ctrl+H { spawn "hermes" "desktop"; }
+
+ Super+Alt+Ctrl+J { spawn "niri-launch" "kitty"; }
+ Super+Alt+Ctrl+K { spawn "niri-launch" "brave-origin-nightly"; }
+ Super+Alt+Ctrl+O { spawn "niri-launch" "obsidian"; }
+ Super+Alt+Ctrl+E { spawn "vicinae" "vicinae://launch/applications/com.fastmail.Fastmail"; }
+ Super+Alt+Ctrl+B { spawn "vicinae" "vicinae://launch/applications/beeper"; }
+ Super+Alt+Ctrl+L { spawn "vicinae" "vicinae://launch/applications/WebApp-Linear3312"; }
+ Super+Alt+Ctrl+M { spawn "vicinae" "vicinae://launch/applications/beeper"; }
+ Super+Alt+Ctrl+T { spawn "vicinae" "vicinae://launch/applications/todoist"; }
+ Super+Alt+Ctrl+N { spawn "noctalia" "msg" "panel-open" "noctalia/notes:panel"; }
+ Super+Alt+Ctrl+F { spawn "vicinae" "vicinae://launch/applications/org.gnome.Nautilus"; }
+ Super+Alt+Ctrl+Space { spawn "vicinae" "vicinae://launch/applications/io.github.faridjaff.StickyNotesCanvas"; }
+ Super+Alt+Ctrl+Return { spawn "vicinae" "vicinae://launch/wm/switch-windows"; }
+
+ Super+Shift+Alt+Ctrl+W { spawn "niri-dynamic-workspaces" "switch" "w"; }
+ Super+Shift+Alt+Ctrl+H { spawn "niri-dynamic-workspaces" "switch" "h"; }
+ Super+Alt+Ctrl+Y { spawn "vicinae" "vicinae://launch/applications/rocks.shy.VacuumTube"; }
+ Super+Alt+Ctrl+X { spawn "niri-dynamic-workspaces" "switch" "x"; }
+
+ // ─── Monitors ─── (Vertical)
+ Mod+Left { focus-monitor-left; }
+ Mod+Up { focus-monitor-up; }
+ Mod+Right { focus-monitor-right; }
+ Mod+Shift+Down { move-column-to-monitor-right; }
+ Mod+Shift+Up { move-column-to-monitor-left; }
+
+ // ─── Layout ───
+ Mod+R { switch-preset-column-width; }
+ Mod+Shift+R { switch-preset-window-height; }
+ Mod+Shift+F { maximize-column; }
+ Mod+F { expand-column-to-available-width; }
+ Super+C { center-column; }
+ Mod+Ctrl+C { center-visible-columns; }
+ Mod+Ctrl+F { fullscreen-window; }
+ Mod+Ctrl+O { toggle-window-floating; }
+
+ // ─── Window Sizing: hjkl ───
+ Alt+Shift+H { set-column-width "-10%"; }
+ Alt+Shift+J { set-window-height "-10%"; }
+ Alt+Shift+K { set-window-height "+10%"; }
+ Alt+Shift+L { set-column-width "+10%"; }
+
+
+
+ // Window management
+ Mod+Q repeat=false { spawn "/home/prad/.local/bin/niri-smart-close"; }
+
+ // Focus
+ Mod+H { focus-column-left-or-last; }
+ Mod+L { focus-column-right-or-first; }
+ Mod+J { focus-window-or-workspace-down; }
+ Mod+K { focus-window-or-workspace-up; }
+
+ // Workspaces
+ Mod+Shift+J { move-column-to-workspace-down; }
+ Mod+Shift+K { move-column-to-workspace-up; }
+
+ // Monitors
+ Super+O { focus-monitor-next; }
+ Super+Ctrl+J { focus-monitor-next; }
+ Super+Ctrl+K { focus-monitor-previous; }
+ Super+Shift+O { move-column-to-monitor-next; }
+ Mod+Ctrl+Shift+J { move-column-to-monitor-next; }
+ Mod+Ctrl+Shift+K { move-column-to-monitor-previous; }
+
+ // Columns
+ Super+Ctrl+H { focus-column-first; }
+ Super+Ctrl+L { focus-column-last; }
+ Super+Ctrl+Shift+H { move-column-to-first; }
+ Super+Ctrl+Shift+L { move-column-to-last; }
+
+ // Tabs
+ Mod+W { toggle-column-tabbed-display; }
+ Mod+Shift+H { spawn "/home/prad/.local/bin/niri-smart-move" "left"; }
+ Mod+Shift+L { spawn "/home/prad/.local/bin/niri-smart-move" "right"; }
+
+ // Screenshots (native)
+ Print { screenshot; }
+ Ctrl+Print { screenshot-screen; }
+ Alt+Print { screenshot-window; }
+
+ // ========================================================================
+ // HARDWARE KEYS - Audio, Brightness, Media
+ // ========================================================================
+ // These use noctalia IPC so the OSD (On Screen Display) shows feedback
+
+ Mod+F24 { spawn "voxtype" "record" "toggle" "--profile" "hermes"; }
+
+ // ─── Media Controls ───
+ // v4: XF86AudioRaiseVolume allow-when-locked=true { spawn-sh "qs -c noctalia-shell ipc call volume increase"; }
+ // v4: XF86AudioLowerVolume allow-when-locked=true { spawn-sh "qs -c noctalia-shell ipc call volume decrease"; }
+ // v4: XF86AudioMute allow-when-locked=true { spawn-sh "qs -c noctalia-shell ipc call volume muteOutput"; }
+ // v4: XF86AudioMicMute allow-when-locked=true { spawn-sh "qs -c noctalia-shell ipc call volume muteInput"; }
+ // v4: XF86AudioNext allow-when-locked=true { spawn-sh "qs -c noctalia-shell ipc call media next"; }
+ // v4: XF86AudioPrev allow-when-locked=true { spawn-sh "qs -c noctalia-shell ipc call media previous"; }
+ // v4: XF86AudioPlay allow-when-locked=true { spawn-sh "qs -c noctalia-shell ipc call media playPause"; }
+ // v4: XF86AudioPause allow-when-locked=true { spawn-sh "qs -c noctalia-shell ipc call media playPause"; }
+ XF86AudioRaiseVolume allow-when-locked=true { spawn-sh "noctalia msg volume-up"; }
+ XF86AudioLowerVolume allow-when-locked=true { spawn-sh "noctalia msg volume-down"; }
+ XF86AudioMute allow-when-locked=true { spawn-sh "noctalia msg volume-mute"; }
+ XF86AudioMicMute allow-when-locked=true { spawn-sh "noctalia msg mic-mute"; }
+ XF86AudioNext allow-when-locked=true { spawn-sh "noctalia msg media next"; }
+ XF86AudioPrev allow-when-locked=true { spawn-sh "noctalia msg media previous"; }
+ XF86AudioPlay allow-when-locked=true { spawn-sh "noctalia msg media toggle"; }
+ XF86AudioPause allow-when-locked=true { spawn-sh "noctalia msg media toggle"; }
+
+ // ─── Brightness Controls ───
+ // v4: XF86MonBrightnessUp allow-when-locked=true { spawn-sh "qs -c noctalia-shell ipc call brightness increase"; }
+ // v4: XF86MonBrightnessDown allow-when-locked=true { spawn-sh "qs -c noctalia-shell ipc call brightness decrease"; }
+ XF86MonBrightnessUp allow-when-locked=true { spawn-sh "noctalia msg brightness-up"; }
+ XF86MonBrightnessDown allow-when-locked=true { spawn-sh "noctalia msg brightness-down"; }
+
+ // Power / Session
+ // v4: Mod+Shift+Q { spawn-sh "qs -c noctalia-shell ipc call sessionMenu toggle"; }
+ Mod+Shift+Q hotkey-overlay-title="Session Menu: noctalia session" { spawn-sh "noctalia msg panel-toggle session"; }
+
+}
+
+
diff --git a/dot_config/niri/exact_config.d/80-layer-rules.kdl b/dot_config/niri/exact_config.d/80-layer-rules.kdl
new file mode 100644
index 0000000..fee5ce8
--- /dev/null
+++ b/dot_config/niri/exact_config.d/80-layer-rules.kdl
@@ -0,0 +1,34 @@
+
+
+
+/*
+ Noctalia v5: disable xray on all our surfaces so blur looks more realistic.
+ Noctalia publishes blur regions automatically when ext-background-effects is available.
+*/
+layer-rule {
+ match namespace="^noctalia-(bar-[^\"]+|notification|dock|panel|attached-panel|osd)$"
+ background-effect {
+ xray false
+ //blur false
+ }
+}
+
+// Option 2 (Stationary Wallpaper): place the regular wallpaper on the backdrop.
+layer-rule {
+ match namespace="^noctalia-wallpaper"
+ place-within-backdrop true
+}
+
+// Set transparent workspace background color so you see the backdrop at all times.
+layout {
+ background-color "transparent"
+}
+
+// Optionally, disable the workspace shadows in the overview.
+overview {
+ workspace-shadow {
+ off
+ }
+}
+
+
diff --git a/dot_config/niri/exact_config.d/90-outputs.kdl b/dot_config/niri/exact_config.d/90-outputs.kdl
new file mode 100644
index 0000000..c5bf0c2
--- /dev/null
+++ b/dot_config/niri/exact_config.d/90-outputs.kdl
@@ -0,0 +1,47 @@
+// ============================================================================
+// OUTPUTS
+// ============================================================================
+//
+// // Apple Display
+// output "Apple Computer Inc StudioDisplay 0x984262A7" {
+// position x=0 y=0
+// scale 1.5
+// layout {
+// center-focused-column "never"
+// always-center-single-column true
+// gaps 8
+// default-column-width {
+// proportion 0.75
+// }
+// preset-column-widths {
+// proportion 0.25
+// proportion 0.5
+// proportion 0.75
+// }
+// }
+// }
+//
+//
+//
+// output "DP-5" {
+// off
+// }
+//
+//
+output "DP-4" {
+ off
+}
+// ============================================================================
+// OUTPUTS
+// ============================================================================
+// The Studio Display exposes a phantom second connector (DP-4/5/6, varies per
+// boot) whose only mode is 640x480. Connector name and EDID both shift, so it
+// can't be matched in config — this script finds it by mode signature instead.
+// spawn-at-startup "/home/prad/.config/niri/scripts/kill-phantom-display.fish"
+
+
+include "91-internal-display.kdl"
+// include "92-ultrawide.kdl"
+include "93-apple-display.kdl"
+include "94-portable-hdmi.kdl"
+// include "95-portable-usbc.kdl"
diff --git a/dot_config/niri/exact_config.d/91-internal-display.kdl b/dot_config/niri/exact_config.d/91-internal-display.kdl
new file mode 100644
index 0000000..43d7a37
--- /dev/null
+++ b/dot_config/niri/exact_config.d/91-internal-display.kdl
@@ -0,0 +1,32 @@
+
+// Internal Display
+output "Tianma Microelectronics Ltd. TL134ADXP03 Unknown" {
+ position x=1920 y=0
+ scale 1.5
+ variable-refresh-rate on-demand=true
+ layout {
+ always-center-single-column true
+ center-focused-column "never"
+ gaps 8
+ default-column-width { proportion 0.9; }
+ preset-column-widths {
+ proportion 0.5
+ proportion 1.0
+ }
+ }
+}
+
+workspace "1" {
+ open-on-output "Tianma Microelectronics Ltd. TL134ADXP03 Unknown"
+}
+
+window-rule {
+ match app-id="org.gnome.Calendar"
+ match app-id="discord"
+ match app-id="slack"
+ draw-border-with-background false
+
+ open-focused true
+ open-maximized true
+ open-on-workspace "1"
+}
diff --git a/dot_config/niri/exact_config.d/92-ultrawide.kdl b/dot_config/niri/exact_config.d/92-ultrawide.kdl
new file mode 100644
index 0000000..777249d
--- /dev/null
+++ b/dot_config/niri/exact_config.d/92-ultrawide.kdl
@@ -0,0 +1,24 @@
+// ============================================================================
+// OUTPUTS
+// ============================================================================
+
+output "Samsung Electric Company S34CG50 HNTY501103" {
+ position x=0 y=0
+ mode "3440x1440@100.00"
+ scale 1
+ variable-refresh-rate on-demand=true
+ layout {
+ center-focused-column "never"
+ always-center-single-column true
+ gaps 16
+ default-column-width {
+ proportion 0.3333
+ }
+ preset-column-widths {
+ proportion 0.3333
+ proportion 0.5
+ proportion 0.6667
+ }
+ }
+}
+
diff --git a/dot_config/niri/exact_config.d/93-apple-display.kdl b/dot_config/niri/exact_config.d/93-apple-display.kdl
new file mode 100644
index 0000000..8a77ebe
--- /dev/null
+++ b/dot_config/niri/exact_config.d/93-apple-display.kdl
@@ -0,0 +1,24 @@
+// ============================================================================
+// OUTPUTS
+// ============================================================================
+
+// Apple Display
+output "Apple Computer Inc StudioDisplay 0x984262A7" {
+ position x=0 y=0
+ scale 1.5
+ layout {
+ center-focused-column "never"
+ always-center-single-column true
+ gaps 8
+ default-column-width {
+ proportion 0.5
+ }
+ preset-column-widths {
+ proportion 0.25
+ proportion 0.3333
+ proportion 0.5
+ proportion 0.6667
+ }
+ }
+}
+
diff --git a/dot_config/niri/exact_config.d/94-portable-hdmi.kdl b/dot_config/niri/exact_config.d/94-portable-hdmi.kdl
new file mode 100644
index 0000000..321c925
--- /dev/null
+++ b/dot_config/niri/exact_config.d/94-portable-hdmi.kdl
@@ -0,0 +1,22 @@
+// ============================================================================
+// OUTPUTS
+// ============================================================================
+
+// Portable Display #1
+output "PNP(AOP) 16PM1QB 14490001D3X00" {
+ transform "90"
+ layout {
+ always-center-single-column true
+ center-focused-column "never"
+ gaps 2
+ default-column-width {
+ proportion 1.0
+ }
+ preset-column-widths {
+ proportion 0.5
+ proportion 1.0
+ }
+ }
+}
+
+
diff --git a/dot_config/niri/exact_config.d/95-portable-usbc.kdl b/dot_config/niri/exact_config.d/95-portable-usbc.kdl
new file mode 100644
index 0000000..2c1c831
--- /dev/null
+++ b/dot_config/niri/exact_config.d/95-portable-usbc.kdl
@@ -0,0 +1,20 @@
+// ============================================================================
+// OUTPUTS
+// ============================================================================
+
+output "ASUSTek COMPUTER INC ASUS MB16AC M8LMTF195749" {
+ position x=0 y=0
+ layout {
+ always-center-single-column true
+ center-focused-column "never"
+ gaps 2
+ default-column-width {
+ proportion 1.0
+ }
+ preset-column-widths {
+ proportion 0.5
+ proportion 1.0
+ }
+ }
+}
+
diff --git a/dot_config/niri/noctalia.kdl b/dot_config/niri/noctalia.kdl
new file mode 100644
index 0000000..28d5427
--- /dev/null
+++ b/dot_config/niri/noctalia.kdl
@@ -0,0 +1,35 @@
+layout {
+
+ focus-ring {
+ active-color "#a398b3"
+ inactive-color "#1e1c21"
+ urgent-color "#fd4663"
+ }
+
+ border {
+ active-color "#a398b3"
+ inactive-color "#1e1c21"
+ urgent-color "#fd4663"
+ }
+
+ shadow {
+ color "#1e1c2170"
+ }
+
+ tab-indicator {
+ active-color "#a398b3"
+ inactive-color "#4a4158"
+ urgent-color "#fd4663"
+ }
+
+ insert-hint {
+ color "#a398b380"
+ }
+}
+
+recent-windows {
+ highlight {
+ active-color "#a398b3"
+ urgent-color "#fd4663"
+ }
+}
diff --git a/dot_config/niri/scripts/executable_kill-phantom-display.fish b/dot_config/niri/scripts/executable_kill-phantom-display.fish
new file mode 100755
index 0000000..aecb043
--- /dev/null
+++ b/dot_config/niri/scripts/executable_kill-phantom-display.fish
@@ -0,0 +1,20 @@
+#!/usr/bin/env fish
+# Turn off the phantom Studio Display leg (DP-4/5/6, varies per boot).
+# Its signature is a single 640x480 mode — connector name and EDID are unreliable.
+# ponytail: one-shot with retry at startup; doesn't handle mid-session hotplug —
+# switch to a `niri msg event-stream` watcher if that starts biting.
+for i in (seq 10)
+ set -l phantoms (niri msg -j outputs 2>/dev/null | jq -r '
+ to_entries[]
+ | select((.value.modes | length) == 1
+ and .value.modes[0].width == 640
+ and .value.modes[0].height == 480)
+ | .key')
+ if test -n "$phantoms"
+ for out in $phantoms
+ niri msg output $out off
+ end
+ exit 0
+ end
+ sleep 1
+end
diff --git a/dot_config/niri/scripts/executable_ndw-route-workspace.sh b/dot_config/niri/scripts/executable_ndw-route-workspace.sh
new file mode 100755
index 0000000..0e76e78
--- /dev/null
+++ b/dot_config/niri/scripts/executable_ndw-route-workspace.sh
@@ -0,0 +1,42 @@
+#!/usr/bin/env bash
+# ndw-route-workspace.sh
+# Routes a niri-dynamic-workspaces workspace to the correct monitor by
+# resolving the Apple Studio Display's connector at runtime.
+#
+# Inputs: NDW_WORKSPACE_KEY env var (set by ndw on_create), or $1.
+# Exits silently on unknown keys so it's safe to call for all workspaces.
+
+set -euo pipefail
+
+KEY="${NDW_WORKSPACE_KEY:-${1:-}}"
+[ -z "$KEY" ] && exit 0
+
+INTERNAL="HDMI-A-1"
+
+# Resolve the external Apple Studio Display connector.
+# Match by make+model; fall back to eDP-1 if not currently connected.
+resolve_external() {
+ niri msg --json outputs | jq -r '
+ to_entries
+ | map(select(
+ .value.make == "Apple Computer Inc"
+ and .value.model == "StudioDisplay"
+ ))
+ | .[0].key // empty
+ '
+}
+
+case "$KEY" in
+ y|g|m|x|z|p|l|a)
+ target="$INTERNAL"
+ ;;
+ b|f|s|w|c|d|o)
+ target="$(resolve_external)"
+ [ -z "$target" ] && target="$INTERNAL" # external not connected
+ ;;
+ *)
+ exit 0
+ ;;
+esac
+
+exec niri msg action move-workspace-to-monitor "$target"
diff --git a/dot_config/niri/scripts/executable_niri-floating-sidebar.sh b/dot_config/niri/scripts/executable_niri-floating-sidebar.sh
new file mode 100755
index 0000000..c4900be
--- /dev/null
+++ b/dot_config/niri/scripts/executable_niri-floating-sidebar.sh
@@ -0,0 +1,367 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+#=============================================================================
+# Niri Sidebar Manager
+#=============================================================================
+# This script manages floating windows in the Niri window manager,
+# organizing them into a toggleable sidebar.
+#=============================================================================
+
+### --- DIMENSION SETTINGS --- ###
+readonly WIN_W=550 # Floating window width
+readonly BASE_SLOTS=4 # Default number of slots in the sidebar
+readonly GAP_BETWEEN=15 # Gap between windows
+readonly BOTTOM_MARGIN=50 # Bottom screen margin
+readonly TOP_MARGIN=30 # Top screen margin
+readonly SIDE_MARGIN=20 # Side screen margin
+readonly VISIBLE_SLIVER=70 # Pixels visible when sidebar is hidden
+
+### --- STATE FILES --- ###
+# Get current workspace ID
+WORKSPACE_ID=$(niri msg --json workspaces | jq -r '.[] | select(.is_focused).id')
+
+# File paths for state tracking
+readonly FLAG_FILE="/tmp/niri.toggle.${WORKSPACE_ID}.floating"
+readonly STATE_FILE="/tmp/niri.toggle.${WORKSPACE_ID}.state"
+readonly ORDER_STATE_FILE="/tmp/niri.toggle.${WORKSPACE_ID}.order"
+readonly HIDE_STATE_FILE="/tmp/niri.toggle.${WORKSPACE_ID}.hide_state"
+
+### --- SCREEN INFO --- ###
+readonly SCREEN_W=$(niri msg --json outputs | jq -r 'to_entries[0].value.logical.width')
+readonly SCREEN_H=$(niri msg --json outputs | jq -r 'to_entries[0].value.logical.height')
+
+#=============================================================================
+# FUNCTION: get_focused_window
+# Description: Returns JSON info of the currently focused window
+#=============================================================================
+get_focused_window() {
+ niri msg --json windows | jq -r '.[] | select(.is_focused)'
+}
+
+#=============================================================================
+# FUNCTION: ensure_files_exist
+# Description: Creates necessary state files if they don't exist
+#=============================================================================
+ensure_files_exist() {
+ touch "$FLAG_FILE" "$STATE_FILE" "$HIDE_STATE_FILE" "$ORDER_STATE_FILE"
+
+ if [ ! -s "$HIDE_STATE_FILE" ]; then
+ echo "visible" >"$HIDE_STATE_FILE"
+ fi
+
+ if [ ! -s "$ORDER_STATE_FILE" ]; then
+ echo "bottom-up" >"$ORDER_STATE_FILE"
+ fi
+}
+
+#=============================================================================
+# FUNCTION: get_floating_windows
+# Description: Gets a list of floating window IDs in the current workspace
+#=============================================================================
+get_floating_windows() {
+ niri msg --json windows |
+ jq -r ".[] | select(.is_floating==true and .workspace_id==$WORKSPACE_ID) | .id"
+}
+
+#=============================================================================
+# FUNCTION: cleanup_state_file
+# Description: Removes closed windows from the state file
+# Parameters:
+# $1 - List of currently active floating windows
+#=============================================================================
+cleanup_state_file() {
+ local actual_floating="$1"
+
+ if [ ! -s "$STATE_FILE" ]; then
+ return
+ fi
+
+ local tmp_state
+ tmp_state=$(mktemp)
+
+ while IFS= read -r line; do
+ local id_in_file
+ id_in_file=$(echo "$line" | cut -d: -f1)
+
+ if echo "$actual_floating" | grep -q "^${id_in_file}$"; then
+ echo "$line" >>"$tmp_state"
+ fi
+ done <"$STATE_FILE"
+
+ mv "$tmp_state" "$STATE_FILE"
+}
+
+#=============================================================================
+# FUNCTION: calculate_window_dimensions
+# Description: Calculates dynamic window height and X position
+# Parameters:
+# $1 - Window count
+# Returns: Sets WIN_H and X global variables
+#=============================================================================
+calculate_window_dimensions() {
+ local count="$1"
+ local slots="$BASE_SLOTS"
+
+ # Increase slots if window count exceeds default
+ if [ "$count" -gt "$BASE_SLOTS" ]; then
+ slots="$count"
+ fi
+
+ # Calculate available vertical space
+ local total_gaps_space=$(((slots - 1) * GAP_BETWEEN))
+ local available_h=$((SCREEN_H - TOP_MARGIN - BOTTOM_MARGIN - total_gaps_space))
+
+ # Export calculated dimensions
+ WIN_H=$((available_h / slots))
+ X=$((SCREEN_W - WIN_W - SIDE_MARGIN))
+}
+
+#=============================================================================
+# FUNCTION: position_window
+# Description: Moves and resizes a specific window
+# Parameters:
+# $1 - Window ID
+# $2 - X position
+# $3 - Y position
+#=============================================================================
+position_window() {
+ local id="$1"
+ local x="$2"
+ local y="$3"
+
+ niri msg action set-window-width "$WIN_W" --id "$id" 2>/dev/null || true
+ niri msg action set-window-height "$WIN_H" --id "$id" 2>/dev/null || true
+ niri msg action move-floating-window --id "$id" --x "$x" --y "$y" 2>/dev/null || true
+}
+
+#=============================================================================
+# FUNCTION: reorder_sidebar
+# Description: Syncs state and updates all window positions on screen
+#=============================================================================
+reorder_sidebar() {
+ local actual_floating
+ actual_floating=$(get_floating_windows)
+
+ cleanup_state_file "$actual_floating"
+
+ local sorted_ids
+ sorted_ids=$(grep -Ff <(echo "$actual_floating") "$STATE_FILE" 2>/dev/null | cut -d: -f1 || true)
+
+ local count
+ count=$(echo "$sorted_ids" | grep -c . || echo 0)
+
+ if [ "$count" -eq 0 ]; then
+ >"$FLAG_FILE"
+ echo "visible" >"$HIDE_STATE_FILE"
+ return
+ fi
+
+ calculate_window_dimensions "$count"
+
+ local order
+ order=$(cat "$ORDER_STATE_FILE" 2>/dev/null || echo "bottom-up")
+
+ >"$FLAG_FILE"
+ local index=0
+
+ while IFS= read -r id; do
+ [ -z "$id" ] && continue
+
+ local pos_y
+ if [ "$order" = "top-down" ]; then
+ pos_y=$((TOP_MARGIN + index * (WIN_H + GAP_BETWEEN)))
+ else
+ pos_y=$((SCREEN_H - BOTTOM_MARGIN - WIN_H - index * (WIN_H + GAP_BETWEEN)))
+ fi
+
+ position_window "$id" "$X" "$pos_y"
+ echo "${id}:${X}:${pos_y}" >>"$FLAG_FILE"
+
+ index=$((index + 1))
+ done <<<"$sorted_ids"
+
+ echo "visible" >"$HIDE_STATE_FILE"
+}
+
+#=============================================================================
+# FUNCTION: toggle_float
+# Description: Toggles focused window between sidebar and tiling mode
+#=============================================================================
+toggle_float() {
+ local focused_json
+ focused_json=$(get_focused_window)
+
+ local focused_id
+ focused_id=$(echo "$focused_json" | jq -r '.id')
+
+ if [ -z "$focused_id" ] || [ "$focused_id" = "null" ]; then
+ echo "Error: No focused window"
+ return 1
+ fi
+
+ if grep -q "^$focused_id:" "$STATE_FILE" 2>/dev/null; then
+ # Restore to tiling mode
+ local old_dim
+ old_dim=$(grep "^$focused_id:" "$STATE_FILE")
+
+ local old_w old_h
+ old_w=$(echo "$old_dim" | cut -d: -f2)
+ old_h=$(echo "$old_dim" | cut -d: -f3)
+
+ # Remove from state
+ sed -i "/^$focused_id:/d" "$STATE_FILE"
+
+ # Action: Move to tiling
+ niri msg action move-window-to-tiling
+
+ # Restore original dimensions
+ [ "$old_w" != "null" ] && niri msg action set-column-width "$old_w" 2>/dev/null || true
+ [ "$old_h" != "null" ] && niri msg action set-window-height "$old_h" 2>/dev/null || true
+
+ reorder_sidebar
+ echo "✓ Window removed from sidebar"
+ else
+ # Add to sidebar
+ local orig_w orig_h
+ orig_w=$(echo "$focused_json" | jq -r '.layout.window_size[0] // 800')
+ orig_h=$(echo "$focused_json" | jq -r '.layout.window_size[1] // 600')
+
+ # Save original size
+ echo "$focused_id:$orig_w:$orig_h" >>"$STATE_FILE"
+
+ # Action: Move to floating
+ niri msg action move-window-to-floating
+
+ # Refresh sidebar
+ reorder_sidebar
+
+ # Keep focus on the window
+ niri msg action focus-window --id "$focused_id" 2>/dev/null || true
+
+ echo "✓ Window added to sidebar"
+ fi
+}
+
+#=============================================================================
+# FUNCTION: toggle_hide
+# Description: Hides/Shows the entire sidebar by pushing windows off-screen
+#=============================================================================
+toggle_hide() {
+
+ # Save current hide state
+ local previous_state
+ previous_state=$(cat "$HIDE_STATE_FILE" 2>/dev/null || echo "visible")
+
+ # Reorder sidebar to fix any desync without breaking hide/show state
+ local actual_floating
+ actual_floating=$(get_floating_windows)
+
+ if [ -n "$actual_floating" ]; then
+ reorder_sidebar
+ # reorder_sidebar forces visible, restore previous state
+ echo "$previous_state" >"$HIDE_STATE_FILE"
+ fi
+
+ if [ ! -s "$FLAG_FILE" ]; then
+ echo "No floating windows detected"
+ return 0
+ fi
+
+ local current_state
+ current_state=$(cat "$HIDE_STATE_FILE")
+
+ if [ "$current_state" = "visible" ]; then
+ # Hide: push windows off-screen
+ while IFS=: read -r id x y; do
+ [ -z "$id" ] && continue
+ local new_x=$((SCREEN_W - VISIBLE_SLIVER))
+ niri msg action move-floating-window --id "$id" --x "$new_x" --y "$y" 2>/dev/null || true
+ done <"$FLAG_FILE"
+
+ echo "hidden" >"$HIDE_STATE_FILE"
+ echo "✓ Sidebar hidden"
+ else
+ # Show: restore original positions
+ while IFS=: read -r id x y; do
+ [ -z "$id" ] && continue
+ niri msg action move-floating-window --id "$id" --x "$x" --y "$y" 2>/dev/null || true
+ done <"$FLAG_FILE"
+
+ echo "visible" >"$HIDE_STATE_FILE"
+ echo "✓ Sidebar visible"
+ fi
+}
+
+#=============================================================================
+# FUNCTION: flip_sidebar_order
+# Description: Flip the order of the sidebar
+#=============================================================================
+
+flip_sidebar_order() {
+ local current
+ current=$(cat "$ORDER_STATE_FILE" 2>/dev/null || echo "bottom-up")
+
+ if [ "$current" = "bottom-up" ]; then
+ echo "top-down" >"$ORDER_STATE_FILE"
+ else
+ echo "bottom-up" >"$ORDER_STATE_FILE"
+ fi
+
+ reorder_sidebar
+ echo "✓ Sidebar order flipped"
+}
+
+#=============================================================================
+# FUNCTION: show_usage
+# Description: Displays help information
+#=============================================================================
+show_usage() {
+ cat </dev/null 2>&1 || true
+[ "$(win)" != "$w0" ] && exit 0
+
+# 2) occupied workspace in that direction (skip the empty trailing one)
+wss=$(niri msg --json workspaces)
+wins=$(niri msg --json windows)
+cwsid=$(jq -r 'map(select(.is_focused)) | .[0].id' <<<"$wss")
+real_neighbor=$(jq -n --argjson wss "$wss" --argjson wins "$wins" \
+ --argjson cwsid "$cwsid" --arg dir "$dir" '
+ ($wss[] | select(.id==$cwsid)) as $c
+ | [ $wss[]
+ | select(.output==$c.output)
+ | select(if $dir=="down" then .idx>$c.idx else .idx<$c.idx end)
+ | .id as $wid
+ | select([$wins[] | select(.workspace_id==$wid)] | length > 0) ]
+ | length > 0')
+
+if [ "$real_neighbor" = "true" ]; then
+ niri msg action "focus-workspace-$dir" >/dev/null 2>&1 || true
+ exit 0
+fi
+
+# 3) adjacent monitor… or wrap to the far-end monitor
+o0=$(out); niri msg action "focus-monitor-$dir" >/dev/null 2>&1 || true
+[ "$(out)" != "$o0" ] && exit 0
+while :; do
+ prev=$(out)
+ niri msg action "focus-monitor-$opp" >/dev/null 2>&1 || true
+ [ "$(out)" = "$prev" ] && break
+done
diff --git a/dot_config/niri/scripts/executable_niri-move.sh b/dot_config/niri/scripts/executable_niri-move.sh
new file mode 100755
index 0000000..e279201
--- /dev/null
+++ b/dot_config/niri/scripts/executable_niri-move.sh
@@ -0,0 +1,29 @@
+#!/usr/bin/env bash
+# Cascade move: column → workspace (incl. empty trailing) → monitor (cycles)
+# usage: niri-move.sh up|down
+set -euo pipefail
+dir="${1:?usage: niri-move.sh up|down}"
+opp=$([ "$dir" = down ] && echo up || echo down)
+
+cur=$(niri msg --json focused-window)
+[ "$cur" = "null" ] && exit 0
+
+out() { niri msg --json focused-output | jq -r '.name // "none"'; }
+sig() { niri msg --json focused-window | jq -rc '[.workspace_id, (.layout.pos_in_scrolling_layout // null)]'; }
+
+# 1) reorder within the column
+s0=$(sig); niri msg action "move-window-$dir" >/dev/null 2>&1 || true
+[ "$(sig)" != "$s0" ] && exit 0
+
+# 2) workspace in that direction (including the empty trailing one)
+s0=$(sig); niri msg action "move-window-to-workspace-$dir" >/dev/null 2>&1 || true
+[ "$(sig)" != "$s0" ] && exit 0
+
+# 3) adjacent monitor… or wrap to the far-end monitor
+o0=$(out); niri msg action "move-window-to-monitor-$dir" >/dev/null 2>&1 || true
+[ "$(out)" != "$o0" ] && exit 0
+while :; do
+ prev=$(out)
+ niri msg action "move-window-to-monitor-$opp" >/dev/null 2>&1 || true
+ [ "$(out)" = "$prev" ] && break
+done
diff --git a/dot_config/noctalia/colors.json b/dot_config/noctalia/colors.json
new file mode 100644
index 0000000..285aa4b
--- /dev/null
+++ b/dot_config/noctalia/colors.json
@@ -0,0 +1,25 @@
+{
+ "mPrimary": "#a398b3",
+ "mOnPrimary": "#100f13",
+
+ "mSecondary": "#9c8da5",
+ "mOnSecondary": "#1e1c22",
+
+ "mTertiary": "#a18fa3",
+ "mOnTertiary": "#1e1c22",
+
+ "mError": "#fd4663",
+ "mOnError": "#1e1c22",
+
+ "mSurface": "#1e1c21",
+ "mOnSurface": "#f2f2f3",
+
+ "mSurfaceVariant": "#322f37",
+ "mOnSurfaceVariant": "#b2b0b5",
+
+ "mOutline": "#6a6670",
+ "mShadow": "#1e1c21",
+
+ "mHover": "#a18fa3",
+ "mOnHover": "#1e1c22"
+}
\ No newline at end of file
diff --git a/dot_config/noctalia/colorschemes/Monochrome/Monochrome.json b/dot_config/noctalia/colorschemes/Monochrome/Monochrome.json
new file mode 100644
index 0000000..ed065e2
--- /dev/null
+++ b/dot_config/noctalia/colorschemes/Monochrome/Monochrome.json
@@ -0,0 +1,94 @@
+{
+ "dark": {
+ "mPrimary": "#aaaaaa",
+ "mOnPrimary": "#111111",
+ "mSecondary": "#a7a7a7",
+ "mOnSecondary": "#111111",
+ "mTertiary": "#cccccc",
+ "mOnTertiary": "#111111",
+ "mError": "#dddddd",
+ "mOnError": "#111111",
+ "mSurface": "#111111",
+ "mOnSurface": "#828282",
+ "mSurfaceVariant": "#191919",
+ "mOnSurfaceVariant": "#5d5d5d",
+ "mOutline": "#3c3c3c",
+ "mShadow": "#000000",
+ "mHover": "#cccccc",
+ "mOnHover": "#111111",
+ "terminal": {
+ "foreground": "#828282",
+ "background": "#111111",
+ "selectionFg": "#111111",
+ "selectionBg": "#828282",
+ "cursorText": "#111111",
+ "cursor": "#aaaaaa",
+ "normal": {
+ "black": "#191919",
+ "red": "#dddddd",
+ "green": "#cccccc",
+ "yellow": "#aaaaaa",
+ "blue": "#a7a7a7",
+ "magenta": "#dddddd",
+ "cyan": "#cccccc",
+ "white": "#828282"
+ },
+ "bright": {
+ "black": "#3c3c3c",
+ "red": "#dddddd",
+ "green": "#cccccc",
+ "yellow": "#aaaaaa",
+ "blue": "#a7a7a7",
+ "magenta": "#dddddd",
+ "cyan": "#cccccc",
+ "white": "#ffffff"
+ }
+ }
+ },
+ "light": {
+ "mPrimary": "#555555",
+ "mOnPrimary": "#eeeeee",
+ "mSecondary": "#505058",
+ "mOnSecondary": "#eeeeee",
+ "mTertiary": "#333333",
+ "mOnTertiary": "#eeeeee",
+ "mError": "#222222",
+ "mOnError": "#efefef",
+ "mSurface": "#d4d4d4",
+ "mOnSurface": "#696969",
+ "mSurfaceVariant": "#e8e8e8",
+ "mOnSurfaceVariant": "#9e9e9e",
+ "mOutline": "#c3c3c3",
+ "mShadow": "#fafafa",
+ "mHover": "#333333",
+ "mOnHover": "#eeeeee",
+ "terminal": {
+ "foreground": "#696969",
+ "background": "#d4d4d4",
+ "selectionFg": "#d4d4d4",
+ "selectionBg": "#696969",
+ "cursorText": "#d4d4d4",
+ "cursor": "#555555",
+ "normal": {
+ "black": "#e8e8e8",
+ "red": "#222222",
+ "green": "#333333",
+ "yellow": "#555555",
+ "blue": "#505058",
+ "magenta": "#222222",
+ "cyan": "#333333",
+ "white": "#696969"
+ },
+ "bright": {
+ "black": "#c3c3c3",
+ "red": "#222222",
+ "green": "#333333",
+ "yellow": "#555555",
+ "blue": "#505058",
+ "magenta": "#222222",
+ "cyan": "#333333",
+ "white": "#000000"
+ }
+ }
+ }
+}
diff --git a/dot_config/noctalia/palettes/wallhaven-k81776-vib.json b/dot_config/noctalia/palettes/wallhaven-k81776-vib.json
new file mode 100644
index 0000000..1bb3a44
--- /dev/null
+++ b/dot_config/noctalia/palettes/wallhaven-k81776-vib.json
@@ -0,0 +1,94 @@
+{
+ "dark": {
+ "mPrimary": "#ef5ce9",
+ "mOnPrimary": "#0c070b",
+ "mSecondary": "#ed4592",
+ "mOnSecondary": "#251824",
+ "mTertiary": "#ed4c45",
+ "mOnTertiary": "#251824",
+ "mError": "#fd4663",
+ "mOnError": "#251824",
+ "mSurface": "#291428",
+ "mOnSurface": "#f3f2f3",
+ "mSurfaceVariant": "#452143",
+ "mOnSurfaceVariant": "#b6afb6",
+ "mOutline": "#756073",
+ "mShadow": "#291428",
+ "mHover": "#ed4c45",
+ "mOnHover": "#251824",
+ "terminal": {
+ "normal": {
+ "black": "#371b36",
+ "red": "#fd4663",
+ "green": "#ef5ce9",
+ "yellow": "#ed4592",
+ "blue": "#ed4c45",
+ "magenta": "#f48bef",
+ "cyan": "#f48bbb",
+ "white": "#f3f2f3"
+ },
+ "bright": {
+ "black": "#756073",
+ "red": "#fd4663",
+ "green": "#ef5ce9",
+ "yellow": "#ed4592",
+ "blue": "#ed4c45",
+ "magenta": "#f48bef",
+ "cyan": "#f48bbb",
+ "white": "#f3f2f3"
+ },
+ "foreground": "#f3f2f3",
+ "background": "#291428",
+ "cursor": "#f3f2f3",
+ "cursorText": "#291428",
+ "selectionFg": "#b6afb6",
+ "selectionBg": "#371b36"
+ }
+ },
+ "light": {
+ "mPrimary": "#d114c9",
+ "mOnPrimary": "#faf9fa",
+ "mSecondary": "#ba125f",
+ "mOnSecondary": "#faf9fa",
+ "mTertiary": "#a31610",
+ "mOnTertiary": "#faf9fa",
+ "mError": "#fd4663",
+ "mOnError": "#faf9fa",
+ "mSurface": "#fbd0f9",
+ "mOnSurface": "#1b181b",
+ "mSurfaceVariant": "#f8bff5",
+ "mOnSurfaceVariant": "#50484f",
+ "mOutline": "#a569a3",
+ "mShadow": "#d9bfd8",
+ "mHover": "#a31610",
+ "mOnHover": "#faf9fa",
+ "terminal": {
+ "normal": {
+ "black": "#f49af0",
+ "red": "#fd4663",
+ "green": "#d114c9",
+ "yellow": "#ba125f",
+ "blue": "#a31610",
+ "magenta": "#8c0d86",
+ "cyan": "#8c0d47",
+ "white": "#1b181b"
+ },
+ "bright": {
+ "black": "#b061ad",
+ "red": "#fd4663",
+ "green": "#d114c9",
+ "yellow": "#ba125f",
+ "blue": "#a31610",
+ "magenta": "#8c0d86",
+ "cyan": "#8c0d47",
+ "white": "#1b181b"
+ },
+ "foreground": "#1b181b",
+ "background": "#fbd0f9",
+ "cursor": "#1b181b",
+ "cursorText": "#fbd0f9",
+ "selectionFg": "#50484f",
+ "selectionBg": "#f49af0"
+ }
+ }
+}
\ No newline at end of file
diff --git a/dot_config/noctalia/plugins.json b/dot_config/noctalia/plugins.json
new file mode 100644
index 0000000..5d49da2
--- /dev/null
+++ b/dot_config/noctalia/plugins.json
@@ -0,0 +1,32 @@
+{
+ "sources": [
+ {
+ "enabled": true,
+ "name": "Noctalia Plugins",
+ "url": "https://github.com/noctalia-dev/noctalia-plugins"
+ }
+ ],
+ "states": {
+ "github-feed": {
+ "enabled": true,
+ "sourceUrl": "https://github.com/noctalia-dev/noctalia-plugins"
+ },
+ "habitica": {
+ "enabled": true,
+ "sourceUrl": "https://github.com/noctalia-dev/noctalia-plugins"
+ },
+ "kde-connect": {
+ "enabled": true,
+ "sourceUrl": "https://github.com/noctalia-dev/noctalia-plugins"
+ },
+ "khal-agenda-widget": {
+ "enabled": true,
+ "sourceUrl": "https://github.com/noctalia-dev/noctalia-plugins"
+ },
+ "weather-indicator": {
+ "enabled": true,
+ "sourceUrl": "https://github.com/noctalia-dev/noctalia-plugins"
+ }
+ },
+ "version": 2
+}
diff --git a/dot_config/noctalia/settings.json b/dot_config/noctalia/settings.json
new file mode 100644
index 0000000..ba49f0e
--- /dev/null
+++ b/dot_config/noctalia/settings.json
@@ -0,0 +1,904 @@
+{
+ "appLauncher": {
+ "autoPasteClipboard": false,
+ "clipboardWatchImageCommand": "wl-paste --type image --watch cliphist store",
+ "clipboardWatchTextCommand": "wl-paste --type text --watch cliphist store",
+ "clipboardWrapText": true,
+ "customLaunchPrefix": "",
+ "customLaunchPrefixEnabled": false,
+ "density": "default",
+ "enableClipPreview": true,
+ "enableClipboardChips": true,
+ "enableClipboardHistory": false,
+ "enableClipboardSmartIcons": true,
+ "enableSessionSearch": true,
+ "enableSettingsSearch": true,
+ "enableWindowsSearch": true,
+ "iconMode": "tabler",
+ "ignoreMouseInput": false,
+ "overviewLayer": true,
+ "pinnedApps": [
+ ],
+ "position": "center",
+ "screenshotAnnotationTool": "",
+ "showCategories": true,
+ "showIconBackground": false,
+ "sortByMostUsed": true,
+ "terminalCommand": "alacritty -e",
+ "viewMode": "list"
+ },
+ "audio": {
+ "mprisBlacklist": [
+ ],
+ "preferredPlayer": "",
+ "spectrumFrameRate": 30,
+ "spectrumMirrored": true,
+ "visualizerType": "linear",
+ "volumeFeedback": false,
+ "volumeFeedbackSoundFile": "",
+ "volumeOverdrive": false,
+ "volumeStep": 5
+ },
+ "bar": {
+ "autoHideDelay": 500,
+ "autoShowDelay": 150,
+ "backgroundOpacity": 0.71,
+ "barType": "simple",
+ "capsuleColorKey": "none",
+ "capsuleOpacity": 1,
+ "contentPadding": 2,
+ "density": "default",
+ "displayMode": "always_visible",
+ "enableExclusionZoneInset": true,
+ "fontScale": 1,
+ "frameRadius": 8,
+ "frameThickness": 8,
+ "hideOnOverview": true,
+ "marginHorizontal": 4,
+ "marginVertical": 4,
+ "middleClickAction": "settings",
+ "middleClickCommand": "",
+ "middleClickFollowMouse": false,
+ "monitors": [
+ "DP-5",
+ "DP-4",
+ "DP-1",
+ "eDP-1"
+ ],
+ "mouseWheelAction": "volume",
+ "mouseWheelWrap": true,
+ "outerCorners": false,
+ "position": "top",
+ "reverseScroll": false,
+ "rightClickAction": "controlCenter",
+ "rightClickCommand": "",
+ "rightClickFollowMouse": true,
+ "screenOverrides": [
+ {
+ "enabled": false,
+ "name": "DP-4"
+ },
+ {
+ "density": "mini",
+ "displayMode": "auto_hide",
+ "enabled": true,
+ "name": "eDP-1",
+ "position": "top"
+ },
+ {
+ "density": "mini",
+ "enabled": true,
+ "name": "HDMI-A-1",
+ "position": "right",
+ "widgets": {
+ "center": [
+ {
+ "compactMode": false,
+ "diskPath": "/",
+ "iconColor": "none",
+ "id": "SystemMonitor",
+ "showCpuCores": true,
+ "showCpuFreq": false,
+ "showCpuTemp": false,
+ "showCpuUsage": true,
+ "showDiskAvailable": false,
+ "showDiskUsage": true,
+ "showDiskUsageAsPercent": true,
+ "showGpuTemp": false,
+ "showLoadAverage": false,
+ "showMemoryAsPercent": true,
+ "showMemoryUsage": true,
+ "showNetworkStats": false,
+ "showSwapUsage": false,
+ "textColor": "none",
+ "useMonospaceFont": true,
+ "usePadding": false
+ }
+ ],
+ "left": [
+ {
+ "clockColor": "none",
+ "customFont": "",
+ "formatHorizontal": "HH:mm ddd, MMM dd",
+ "formatVertical": "HH mm - dd MM",
+ "id": "Clock",
+ "tooltipFormat": "HH:mm ddd, MMM dd",
+ "useCustomFont": false
+ }
+ ],
+ "right": [
+ {
+ "characterCount": 2,
+ "colorizeIcons": true,
+ "emptyColor": "secondary",
+ "enableScrollWheel": true,
+ "focusedColor": "primary",
+ "followFocusedScreen": false,
+ "fontWeight": "semibold",
+ "groupedBorderOpacity": 1,
+ "hideUnoccupied": true,
+ "iconScale": 0.8,
+ "id": "Workspace",
+ "labelMode": "none",
+ "occupiedColor": "secondary",
+ "pillSize": 0.6,
+ "showApplications": true,
+ "showApplicationsHover": false,
+ "showBadge": true,
+ "showLabelsOnlyWhenOccupied": true,
+ "unfocusedIconsOpacity": 1
+ },
+ {
+ "id": "plugin:habitica"
+ },
+ {
+ "id": "plugin:github-feed"
+ },
+ {
+ "id": "plugin:kde-connect"
+ }
+ ]
+ }
+ }
+ ],
+ "showCapsule": false,
+ "showOnWorkspaceSwitch": true,
+ "showOutline": false,
+ "useSeparateOpacity": false,
+ "widgetSpacing": 6,
+ "widgets": {
+ "center": [
+ {
+ "defaultSettings": {
+ "customColor": "none",
+ "showConditionIcon": true,
+ "showTempUnit": true,
+ "showTempValue": true,
+ "tooltipOption": "everything"
+ },
+ "id": "plugin:weather-indicator"
+ },
+ {
+ "characterCount": 2,
+ "colorizeIcons": true,
+ "emptyColor": "secondary",
+ "enableScrollWheel": true,
+ "focusedColor": "primary",
+ "followFocusedScreen": false,
+ "fontWeight": "bold",
+ "groupedBorderOpacity": 1,
+ "hideUnoccupied": true,
+ "iconScale": 0.8,
+ "id": "Workspace",
+ "labelMode": "none",
+ "occupiedColor": "secondary",
+ "pillSize": 0.6,
+ "showApplications": true,
+ "showApplicationsHover": true,
+ "showBadge": true,
+ "showLabelsOnlyWhenOccupied": true,
+ "unfocusedIconsOpacity": 1
+ },
+ {
+ "compactMode": true,
+ "hideMode": "hidden",
+ "hideWhenIdle": false,
+ "id": "MediaMini",
+ "maxWidth": 145,
+ "panelShowAlbumArt": true,
+ "scrollingMode": "hover",
+ "showAlbumArt": true,
+ "showArtistFirst": false,
+ "showProgressRing": true,
+ "showVisualizer": true,
+ "textColor": "none",
+ "useFixedWidth": true,
+ "visualizerType": "linear"
+ }
+ ],
+ "left": [
+ {
+ "colorizeIcons": true,
+ "hideMode": "hidden",
+ "id": "ActiveWindow",
+ "maxWidth": 500,
+ "scrollingMode": "hover",
+ "showIcon": true,
+ "showText": true,
+ "textColor": "none",
+ "useFixedWidth": true
+ }
+ ],
+ "right": [
+ {
+ "defaultSettings": {
+ },
+ "id": "plugin:kde-connect"
+ },
+ {
+ "defaultSettings": {
+ "colorizationBadge": "Primary",
+ "colorizationBadgeText": "Primary",
+ "colorizationEnabled": false,
+ "colorizationIcon": "Primary",
+ "defaultTab": 0,
+ "enableSystemNotifications": false,
+ "githubUrl": "",
+ "maxEvents": 50,
+ "notifyForks": true,
+ "notifyGitHubNotifications": true,
+ "notifyMyRepoForks": true,
+ "notifyMyRepoStars": true,
+ "notifyPRs": true,
+ "notifyRepoCreations": true,
+ "notifyStars": true,
+ "openInBrowser": true,
+ "refreshInterval": 1800,
+ "showForks": true,
+ "showMyRepoForks": true,
+ "showMyRepoStars": true,
+ "showNotificationBadge": true,
+ "showPRs": true,
+ "showRepoCreations": true,
+ "showStars": true,
+ "token": "",
+ "username": ""
+ },
+ "id": "plugin:github-feed"
+ },
+ {
+ "hideWhenZero": false,
+ "hideWhenZeroUnread": false,
+ "iconColor": "none",
+ "id": "NotificationHistory",
+ "showUnreadBadge": true,
+ "unreadBadgeColor": "primary"
+ },
+ {
+ "displayMode": "onhover",
+ "iconColor": "none",
+ "id": "Volume",
+ "middleClickCommand": "pwvucontrol || pavucontrol",
+ "textColor": "none"
+ },
+ {
+ "colorizeDistroLogo": false,
+ "colorizeSystemIcon": "none",
+ "colorizeSystemText": "none",
+ "customIconPath": "",
+ "enableColorization": false,
+ "icon": "settings-2",
+ "id": "ControlCenter",
+ "useDistroLogo": false
+ },
+ {
+ "clockColor": "none",
+ "customFont": "",
+ "formatHorizontal": "ddd MMM d h:mmAP",
+ "formatVertical": "HH mm - dd MM",
+ "id": "Clock",
+ "tooltipFormat": "MM/dd/yyyy HH:mm:ss",
+ "useCustomFont": false
+ }
+ ]
+ }
+ },
+ "brightness": {
+ "backlightDeviceMappings": [
+ ],
+ "brightnessStep": 5,
+ "enableDdcSupport": true,
+ "enforceMinimum": true
+ },
+ "calendar": {
+ "cards": [
+ {
+ "enabled": true,
+ "id": "calendar-header-card"
+ },
+ {
+ "enabled": false,
+ "id": "calendar-month-card"
+ },
+ {
+ "enabled": true,
+ "id": "weather-card"
+ }
+ ]
+ },
+ "colorSchemes": {
+ "darkMode": true,
+ "generationMethod": "muted",
+ "manualSunrise": "06:30",
+ "manualSunset": "18:30",
+ "monitorForColors": "",
+ "predefinedScheme": "Monochrome",
+ "schedulingMode": "off",
+ "syncGsettings": true,
+ "useWallpaperColors": true
+ },
+ "controlCenter": {
+ "cards": [
+ {
+ "enabled": true,
+ "id": "profile-card"
+ },
+ {
+ "enabled": true,
+ "id": "shortcuts-card"
+ },
+ {
+ "enabled": true,
+ "id": "audio-card"
+ },
+ {
+ "enabled": false,
+ "id": "brightness-card"
+ },
+ {
+ "enabled": true,
+ "id": "weather-card"
+ },
+ {
+ "enabled": true,
+ "id": "media-sysmon-card"
+ }
+ ],
+ "diskPath": "/",
+ "position": "close_to_bar_button",
+ "shortcuts": {
+ "left": [
+ {
+ "id": "Network"
+ },
+ {
+ "id": "Bluetooth"
+ },
+ {
+ "id": "WallpaperSelector"
+ },
+ {
+ "id": "NoctaliaPerformance"
+ }
+ ],
+ "right": [
+ {
+ "id": "Notifications"
+ },
+ {
+ "id": "PowerProfile"
+ },
+ {
+ "id": "KeepAwake"
+ },
+ {
+ "id": "NightLight"
+ }
+ ]
+ }
+ },
+ "desktopWidgets": {
+ "enabled": false,
+ "gridSnap": true,
+ "gridSnapScale": true,
+ "monitorWidgets": [
+ {
+ "name": "eDP-1",
+ "widgets": [
+ {
+ "clockColor": "none",
+ "clockStyle": "digital",
+ "customFont": "",
+ "format": "HH:mm\\nd MMMM yyyy",
+ "id": "Clock",
+ "roundedCorners": true,
+ "showBackground": true,
+ "useCustomFont": false,
+ "x": 1440,
+ "y": 960
+ },
+ {
+ "id": "Weather",
+ "roundedCorners": true,
+ "showBackground": true,
+ "x": 1630,
+ "y": 1084
+ },
+ {
+ "diskPath": "/",
+ "id": "SystemStat",
+ "layout": "bottom",
+ "roundedCorners": true,
+ "scale": 1.085295715771401,
+ "showBackground": true,
+ "statType": "CPU",
+ "x": 1620,
+ "y": 920
+ }
+ ]
+ }
+ ],
+ "overviewEnabled": true
+ },
+ "dock": {
+ "animationSpeed": 1,
+ "backgroundOpacity": 0.92,
+ "colorizeIcons": false,
+ "deadOpacity": 0.6,
+ "displayMode": "auto_hide",
+ "dockType": "floating",
+ "enabled": false,
+ "floatingRatio": 1,
+ "groupApps": false,
+ "groupClickAction": "cycle",
+ "groupContextMenuMode": "extended",
+ "groupIndicatorStyle": "dots",
+ "inactiveIndicators": false,
+ "indicatorColor": "primary",
+ "indicatorOpacity": 0.6,
+ "indicatorThickness": 3,
+ "launcherIcon": "",
+ "launcherIconColor": "none",
+ "launcherPosition": "end",
+ "launcherUseDistroLogo": false,
+ "monitors": [
+ ],
+ "onlySameOutput": true,
+ "pinnedApps": [
+ ],
+ "pinnedStatic": false,
+ "position": "bottom",
+ "showDockIndicator": false,
+ "showLauncherIcon": false,
+ "sitOnFrame": false,
+ "size": 1
+ },
+ "general": {
+ "allowPanelsOnScreenWithoutBar": true,
+ "allowPasswordWithFprintd": false,
+ "animationDisabled": false,
+ "animationSpeed": 1,
+ "autoStartAuth": false,
+ "avatarImage": "/home/prad/Pictures/Prad/prad2.jpg",
+ "boxRadiusRatio": 1,
+ "clockFormat": "hh\\nmm",
+ "clockStyle": "custom",
+ "compactLockScreen": false,
+ "dimmerOpacity": 0.2,
+ "enableBlurBehind": true,
+ "enableLockScreenCountdown": true,
+ "enableLockScreenMediaControls": false,
+ "enableShadows": false,
+ "forceBlackScreenCorners": false,
+ "iRadiusRatio": 1,
+ "keybinds": {
+ "keyDown": [
+ "Down"
+ ],
+ "keyEnter": [
+ "Return",
+ "Enter"
+ ],
+ "keyEscape": [
+ "Esc"
+ ],
+ "keyLeft": [
+ "Left"
+ ],
+ "keyRemove": [
+ "Del"
+ ],
+ "keyRight": [
+ "Right"
+ ],
+ "keyUp": [
+ "Up"
+ ]
+ },
+ "language": "",
+ "lockOnSuspend": true,
+ "lockScreenAnimations": false,
+ "lockScreenBlur": 0,
+ "lockScreenCountdownDuration": 10000,
+ "lockScreenMonitors": [
+ ],
+ "lockScreenTint": 0,
+ "passwordChars": false,
+ "radiusRatio": 1,
+ "reverseScroll": true,
+ "scaleRatio": 0.9500000000000001,
+ "screenRadiusRatio": 1,
+ "shadowDirection": "bottom_right",
+ "shadowOffsetX": 2,
+ "shadowOffsetY": 3,
+ "showChangelogOnStartup": true,
+ "showHibernateOnLockScreen": false,
+ "showScreenCorners": false,
+ "showSessionButtonsOnLockScreen": true,
+ "smoothScrollEnabled": true,
+ "telemetryEnabled": false
+ },
+ "hooks": {
+ "colorGeneration": "",
+ "darkModeChange": "",
+ "enabled": false,
+ "performanceModeDisabled": "",
+ "performanceModeEnabled": "",
+ "screenLock": "",
+ "screenUnlock": "",
+ "session": "",
+ "startup": "",
+ "wallpaperChange": ""
+ },
+ "idle": {
+ "customCommands": "[]",
+ "enabled": false,
+ "fadeDuration": 5,
+ "lockCommand": "",
+ "lockTimeout": 660,
+ "resumeLockCommand": "",
+ "resumeScreenOffCommand": "",
+ "resumeSuspendCommand": "",
+ "screenOffCommand": "",
+ "screenOffTimeout": 600,
+ "suspendCommand": "",
+ "suspendTimeout": 1800
+ },
+ "location": {
+ "analogClockInCalendar": false,
+ "autoLocate": true,
+ "firstDayOfWeek": -1,
+ "hideWeatherCityName": false,
+ "hideWeatherTimezone": false,
+ "name": "Ashburn",
+ "showCalendarEvents": true,
+ "showCalendarWeather": true,
+ "showWeekNumberInCalendar": true,
+ "use12hourFormat": true,
+ "useFahrenheit": true,
+ "weatherEnabled": true,
+ "weatherShowEffects": true,
+ "weatherTaliaMascotAlways": false
+ },
+ "network": {
+ "bluetoothAutoConnect": true,
+ "bluetoothDetailsViewMode": "grid",
+ "bluetoothHideUnnamedDevices": false,
+ "bluetoothRssiPollIntervalMs": 60000,
+ "bluetoothRssiPollingEnabled": false,
+ "disableDiscoverability": false,
+ "networkPanelView": "wifi",
+ "wifiDetailsViewMode": "grid"
+ },
+ "nightLight": {
+ "autoSchedule": true,
+ "dayTemp": "6500",
+ "enabled": true,
+ "forced": false,
+ "manualSunrise": "06:30",
+ "manualSunset": "18:30",
+ "nightTemp": "2813"
+ },
+ "noctaliaPerformance": {
+ "disableDesktopWidgets": true,
+ "disableWallpaper": true
+ },
+ "notifications": {
+ "backgroundOpacity": 0.75,
+ "clearDismissed": true,
+ "criticalUrgencyDuration": 15,
+ "density": "default",
+ "enableBatteryToast": true,
+ "enableKeyboardLayoutToast": true,
+ "enableMarkdown": false,
+ "enableMediaToast": false,
+ "enabled": true,
+ "location": "top_right",
+ "lowUrgencyDuration": 3,
+ "monitors": [
+ "HDMI-A-1",
+ "DP-2",
+ "eDP-1"
+ ],
+ "normalUrgencyDuration": 8,
+ "overlayLayer": true,
+ "respectExpireTimeout": false,
+ "saveToHistory": {
+ "critical": true,
+ "low": true,
+ "normal": true
+ },
+ "sounds": {
+ "criticalSoundFile": "",
+ "enabled": false,
+ "excludedApps": "discord,firefox,chrome,chromium,edge",
+ "lowSoundFile": "",
+ "normalSoundFile": "",
+ "separateSounds": false,
+ "volume": 0.5
+ }
+ },
+ "osd": {
+ "autoHideMs": 2000,
+ "backgroundOpacity": 1,
+ "enabled": true,
+ "enabledTypes": [
+ 0,
+ 1,
+ 2
+ ],
+ "location": "top_right",
+ "monitors": [
+ ],
+ "overlayLayer": true
+ },
+ "plugins": {
+ "autoUpdate": true,
+ "notifyUpdates": true
+ },
+ "sessionMenu": {
+ "countdownDuration": 10000,
+ "enableCountdown": true,
+ "largeButtonsLayout": "single-row",
+ "largeButtonsStyle": true,
+ "position": "center",
+ "powerOptions": [
+ {
+ "action": "lock",
+ "command": "",
+ "countdownEnabled": true,
+ "enabled": true,
+ "keybind": "1"
+ },
+ {
+ "action": "suspend",
+ "command": "",
+ "countdownEnabled": true,
+ "enabled": true,
+ "keybind": "2"
+ },
+ {
+ "action": "hibernate",
+ "command": "",
+ "countdownEnabled": true,
+ "enabled": true,
+ "keybind": "3"
+ },
+ {
+ "action": "reboot",
+ "command": "",
+ "countdownEnabled": true,
+ "enabled": true,
+ "keybind": "4"
+ },
+ {
+ "action": "logout",
+ "command": "",
+ "countdownEnabled": true,
+ "enabled": true,
+ "keybind": "5"
+ },
+ {
+ "action": "shutdown",
+ "command": "",
+ "countdownEnabled": true,
+ "enabled": true,
+ "keybind": "6"
+ },
+ {
+ "action": "rebootToUefi",
+ "command": "",
+ "countdownEnabled": true,
+ "enabled": true,
+ "keybind": "7"
+ },
+ {
+ "action": "userspaceReboot",
+ "command": "",
+ "countdownEnabled": true,
+ "enabled": false,
+ "keybind": ""
+ }
+ ],
+ "showHeader": true,
+ "showKeybinds": true
+ },
+ "settingsVersion": 59,
+ "systemMonitor": {
+ "batteryCriticalThreshold": 5,
+ "batteryWarningThreshold": 20,
+ "cpuCriticalThreshold": 90,
+ "cpuWarningThreshold": 80,
+ "criticalColor": "#ffb4ab",
+ "diskAvailCriticalThreshold": 10,
+ "diskAvailWarningThreshold": 20,
+ "diskCriticalThreshold": 90,
+ "diskWarningThreshold": 80,
+ "enableDgpuMonitoring": false,
+ "externalMonitor": "resources || missioncenter || jdsystemmonitor || corestats || system-monitoring-center || gnome-system-monitor || plasma-systemmonitor || mate-system-monitor || ukui-system-monitor || deepin-system-monitor || pantheon-system-monitor",
+ "gpuCriticalThreshold": 90,
+ "gpuWarningThreshold": 80,
+ "memCriticalThreshold": 90,
+ "memWarningThreshold": 80,
+ "swapCriticalThreshold": 90,
+ "swapWarningThreshold": 80,
+ "tempCriticalThreshold": 90,
+ "tempWarningThreshold": 80,
+ "useCustomColors": false,
+ "warningColor": "#f0b8c6"
+ },
+ "templates": {
+ "activeTemplates": [
+ {
+ "enabled": true,
+ "id": "niri"
+ },
+ {
+ "enabled": true,
+ "id": "kitty"
+ },
+ {
+ "enabled": true,
+ "id": "gtk"
+ },
+ {
+ "enabled": true,
+ "id": "btop"
+ },
+ {
+ "enabled": true,
+ "id": "yazi"
+ },
+ {
+ "enabled": true,
+ "id": "zed"
+ },
+ {
+ "enabled": true,
+ "id": "vicinae"
+ },
+ {
+ "enabled": true,
+ "id": "alacritty"
+ },
+ {
+ "enabled": true,
+ "id": "ghostty"
+ },
+ {
+ "enabled": true,
+ "id": "starship"
+ },
+ {
+ "enabled": true,
+ "id": "telegram"
+ },
+ {
+ "enabled": true,
+ "id": "qt"
+ },
+ {
+ "enabled": true,
+ "id": "kcolorscheme"
+ },
+ {
+ "enabled": true,
+ "id": "zenBrowser"
+ },
+ {
+ "enabled": true,
+ "id": "mango"
+ },
+ {
+ "enabled": true,
+ "id": "cava"
+ },
+ {
+ "enabled": true,
+ "id": "fuzzel"
+ },
+ {
+ "enabled": true,
+ "id": "helix"
+ }
+ ],
+ "enableUserTheming": false
+ },
+ "ui": {
+ "boxBorderEnabled": false,
+ "fontDefault": "VictorMono NFP",
+ "fontDefaultScale": 0.9,
+ "fontFixed": "VictorMono NF",
+ "fontFixedScale": 0.95,
+ "panelBackgroundOpacity": 0.6,
+ "panelsAttachedToBar": true,
+ "scrollbarAlwaysVisible": false,
+ "settingsPanelMode": "attached",
+ "settingsPanelSideBarCardStyle": true,
+ "tooltipsEnabled": true,
+ "translucentWidgets": true
+ },
+ "wallpaper": {
+ "automationEnabled": false,
+ "directory": "/home/prad/Pictures/Wallpapers",
+ "enableMultiMonitorDirectories": false,
+ "enabled": true,
+ "favorites": [
+ {
+ "appearance": "dark",
+ "colorScheme": "Monochrome",
+ "darkMode": true,
+ "generationMethod": "muted",
+ "paletteColors": [
+ "#a398b3",
+ "#9c8da5",
+ "#a18fa3",
+ "#fd4663"
+ ],
+ "path": "/home/prad/Pictures/Wallpapers/wallhaven-k81776.jpg",
+ "useWallpaperColors": true
+ }
+ ],
+ "fillColor": "#000000",
+ "fillMode": "crop",
+ "hideWallpaperFilenames": false,
+ "linkLightAndDarkWallpapers": true,
+ "monitorDirectories": [
+ ],
+ "overviewBlur": 0.4,
+ "overviewEnabled": true,
+ "overviewTint": 0.6,
+ "panelPosition": "follow_bar",
+ "randomIntervalSec": 300,
+ "setWallpaperOnAllMonitors": true,
+ "showHiddenFiles": false,
+ "skipStartupTransition": true,
+ "solidColor": "#1a1a2e",
+ "sortOrder": "name",
+ "transitionDuration": 1500,
+ "transitionEdgeSmoothness": 0.05,
+ "transitionType": [
+ "fade",
+ "disc",
+ "stripes",
+ "wipe",
+ "pixelate",
+ "honeycomb"
+ ],
+ "useOriginalImages": false,
+ "useSolidColor": false,
+ "useWallhaven": false,
+ "viewMode": "browse",
+ "wallhavenApiKey": "",
+ "wallhavenCategories": "111",
+ "wallhavenOrder": "desc",
+ "wallhavenPurity": "100",
+ "wallhavenQuery": "new york",
+ "wallhavenRatios": "",
+ "wallhavenResolutionHeight": "",
+ "wallhavenResolutionMode": "atleast",
+ "wallhavenResolutionWidth": "",
+ "wallhavenSorting": "relevance",
+ "wallpaperChangeMode": "random"
+ }
+}
diff --git a/dot_config/systemd/user/brain-lens@.service b/dot_config/systemd/user/brain-lens@.service
new file mode 100644
index 0000000..57a809e
--- /dev/null
+++ b/dot_config/systemd/user/brain-lens@.service
@@ -0,0 +1,6 @@
+[Unit]
+Description=Second-brain lens %i
+
+[Service]
+Type=oneshot
+ExecStart=%h/Documents/Obsidian/Brain/_System/Brain/run-lens.sh %i
diff --git a/dot_config/systemd/user/brain-lens@build-next.timer b/dot_config/systemd/user/brain-lens@build-next.timer
new file mode 100644
index 0000000..be7a9ff
--- /dev/null
+++ b/dot_config/systemd/user/brain-lens@build-next.timer
@@ -0,0 +1,9 @@
+[Unit]
+Description=Second-brain lens build-next schedule
+
+[Timer]
+OnCalendar=*-*-* 01,07,13,19:37:00
+Persistent=true
+
+[Install]
+WantedBy=timers.target
diff --git a/dot_config/systemd/user/brain-lens@coach.timer b/dot_config/systemd/user/brain-lens@coach.timer
new file mode 100644
index 0000000..9b245db
--- /dev/null
+++ b/dot_config/systemd/user/brain-lens@coach.timer
@@ -0,0 +1,9 @@
+[Unit]
+Description=Second-brain lens coach schedule
+
+[Timer]
+OnCalendar=*-*-* 03,09,15,21:07:00
+Persistent=true
+
+[Install]
+WantedBy=timers.target
diff --git a/dot_config/systemd/user/brain-lens@digest.timer b/dot_config/systemd/user/brain-lens@digest.timer
new file mode 100644
index 0000000..43f087e
--- /dev/null
+++ b/dot_config/systemd/user/brain-lens@digest.timer
@@ -0,0 +1,9 @@
+[Unit]
+Description=Second-brain lens digest schedule
+
+[Timer]
+OnCalendar=*-*-* 08:03:00
+Persistent=true
+
+[Install]
+WantedBy=timers.target
diff --git a/dot_config/systemd/user/brain-lens@what-worked.timer b/dot_config/systemd/user/brain-lens@what-worked.timer
new file mode 100644
index 0000000..acaae49
--- /dev/null
+++ b/dot_config/systemd/user/brain-lens@what-worked.timer
@@ -0,0 +1,9 @@
+[Unit]
+Description=Second-brain lens what-worked schedule
+
+[Timer]
+OnCalendar=*-*-* 00,06,12,18:07:00
+Persistent=true
+
+[Install]
+WantedBy=timers.target
diff --git a/dot_config/systemd/user/brain-lens@write-next.timer b/dot_config/systemd/user/brain-lens@write-next.timer
new file mode 100644
index 0000000..e6300b4
--- /dev/null
+++ b/dot_config/systemd/user/brain-lens@write-next.timer
@@ -0,0 +1,9 @@
+[Unit]
+Description=Second-brain lens write-next schedule
+
+[Timer]
+OnCalendar=*-*-* 04,10,16,22:37:00
+Persistent=true
+
+[Install]
+WantedBy=timers.target
diff --git a/dot_config/systemd/user/hermes-gateway.service b/dot_config/systemd/user/hermes-gateway.service
new file mode 100644
index 0000000..58ea3b3
--- /dev/null
+++ b/dot_config/systemd/user/hermes-gateway.service
@@ -0,0 +1,27 @@
+[Unit]
+Description=Hermes Agent Gateway - Messaging Platform Integration
+After=network-online.target
+Wants=network-online.target
+StartLimitIntervalSec=0
+
+[Service]
+Type=simple
+ExecStart=/home/prad/.hermes/hermes-agent/venv/bin/python -m hermes_cli.main gateway run
+WorkingDirectory=/home/prad/.hermes
+Environment="PATH=/home/prad/.hermes/hermes-agent/venv/bin:/home/prad/.hermes/hermes-agent/node_modules/.bin:/home/prad/.local/share/mise/installs/node/latest/bin:/home/prad/.local/bin:/home/prad/.cargo/bin:/home/prad/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
+Environment="VIRTUAL_ENV=/home/prad/.hermes/hermes-agent/venv"
+Environment="HERMES_HOME=/home/prad/.hermes"
+Restart=always
+RestartSec=5
+RestartForceExitStatus=75
+RestartPreventExitStatus=78
+KillMode=mixed
+KillSignal=SIGTERM
+ExecReload=/bin/kill -USR1 $MAINPID
+ExecStopPost=-/home/prad/.hermes/hermes-agent/venv/bin/python -m gateway.cgroup_cleanup
+TimeoutStopSec=210
+StandardOutput=journal
+StandardError=journal
+
+[Install]
+WantedBy=default.target
diff --git a/dot_config/systemd/user/nirinit.service b/dot_config/systemd/user/nirinit.service
new file mode 100644
index 0000000..40e3a55
--- /dev/null
+++ b/dot_config/systemd/user/nirinit.service
@@ -0,0 +1,14 @@
+[Unit]
+Description=nirinit - Niri session save/restore
+PartOf=graphical-session.target
+After=graphical-session.target
+Requisite=graphical-session.target
+
+[Service]
+Type=simple
+ExecStart=%h/.cargo/bin/nirinit --save-interval 300
+Restart=on-failure
+RestartSec=2
+
+[Install]
+WantedBy=graphical-session.target
diff --git a/dot_config/systemd/user/omp-loop@.service b/dot_config/systemd/user/omp-loop@.service
new file mode 100644
index 0000000..cd3e4f1
--- /dev/null
+++ b/dot_config/systemd/user/omp-loop@.service
@@ -0,0 +1,10 @@
+[Unit]
+Description=omp agent loop: %i
+
+[Service]
+Type=oneshot
+ExecStart=%h/.omp/loops/bin/run-loop.sh %i
+# Loops are green (read-only + own state file) but belt-and-braces:
+# no interactive session, hard runtime ceiling above the script's own caps.
+TimeoutStartSec=45min
+Nice=10
diff --git a/dot_config/systemd/user/omp-loop@answer-gap.timer b/dot_config/systemd/user/omp-loop@answer-gap.timer
new file mode 100644
index 0000000..6c8ffa2
--- /dev/null
+++ b/dot_config/systemd/user/omp-loop@answer-gap.timer
@@ -0,0 +1,10 @@
+[Unit]
+Description=Timer for omp loop: answer-gap
+
+[Timer]
+OnCalendar=Thu 07:00
+Persistent=true
+RandomizedDelaySec=10min
+
+[Install]
+WantedBy=timers.target
diff --git a/dot_config/systemd/user/omp-loop@brand-radar.timer b/dot_config/systemd/user/omp-loop@brand-radar.timer
new file mode 100644
index 0000000..708d910
--- /dev/null
+++ b/dot_config/systemd/user/omp-loop@brand-radar.timer
@@ -0,0 +1,10 @@
+[Unit]
+Description=Timer for omp loop: brand-radar
+
+[Timer]
+OnCalendar=Wed 07:00
+Persistent=true
+RandomizedDelaySec=10min
+
+[Install]
+WantedBy=timers.target
diff --git a/dot_config/systemd/user/omp-loop@competitor-watch.timer b/dot_config/systemd/user/omp-loop@competitor-watch.timer
new file mode 100644
index 0000000..d2a1596
--- /dev/null
+++ b/dot_config/systemd/user/omp-loop@competitor-watch.timer
@@ -0,0 +1,10 @@
+[Unit]
+Description=Timer for omp loop: competitor-watch
+
+[Timer]
+OnCalendar=Fri 07:00
+Persistent=true
+RandomizedDelaySec=10min
+
+[Install]
+WantedBy=timers.target
diff --git a/dot_config/systemd/user/omp-loop@intel-refresh.timer b/dot_config/systemd/user/omp-loop@intel-refresh.timer
new file mode 100644
index 0000000..1a0fefb
--- /dev/null
+++ b/dot_config/systemd/user/omp-loop@intel-refresh.timer
@@ -0,0 +1,10 @@
+[Unit]
+Description=Timer for omp loop: intel-refresh
+
+[Timer]
+OnCalendar=Mon 06:00
+Persistent=true
+RandomizedDelaySec=10min
+
+[Install]
+WantedBy=timers.target
diff --git a/dot_config/systemd/user/omp-loop@regulatory-digest.timer b/dot_config/systemd/user/omp-loop@regulatory-digest.timer
new file mode 100644
index 0000000..71f57d6
--- /dev/null
+++ b/dot_config/systemd/user/omp-loop@regulatory-digest.timer
@@ -0,0 +1,10 @@
+[Unit]
+Description=Timer for omp loop: regulatory-digest
+
+[Timer]
+OnCalendar=Tue 07:00
+Persistent=true
+RandomizedDelaySec=10min
+
+[Install]
+WantedBy=timers.target
diff --git a/dot_config/systemd/user/omp-loop@repeat-offender.timer b/dot_config/systemd/user/omp-loop@repeat-offender.timer
new file mode 100644
index 0000000..ac93091
--- /dev/null
+++ b/dot_config/systemd/user/omp-loop@repeat-offender.timer
@@ -0,0 +1,10 @@
+[Unit]
+Description=Timer for omp loop: repeat-offender
+
+[Timer]
+OnCalendar=Sun 18:00
+Persistent=true
+RandomizedDelaySec=10min
+
+[Install]
+WantedBy=timers.target
diff --git a/dot_config/systemd/user/omp-loop@share-of-model.timer b/dot_config/systemd/user/omp-loop@share-of-model.timer
new file mode 100644
index 0000000..0b14ba5
--- /dev/null
+++ b/dot_config/systemd/user/omp-loop@share-of-model.timer
@@ -0,0 +1,10 @@
+[Unit]
+Description=Timer for omp loop: share-of-model
+
+[Timer]
+OnCalendar=Mon 07:00
+Persistent=true
+RandomizedDelaySec=10min
+
+[Install]
+WantedBy=timers.target
diff --git a/dot_config/systemd/user/openwebui-hermes.service b/dot_config/systemd/user/openwebui-hermes.service
new file mode 100644
index 0000000..935b0f8
--- /dev/null
+++ b/dot_config/systemd/user/openwebui-hermes.service
@@ -0,0 +1,15 @@
+[Unit]
+Description=Open WebUI connected to Hermes Agent
+After=default.target
+
+[Service]
+Type=simple
+ExecStart=/bin/bash %h/.local/bin/start-open-webui-hermes.sh
+Restart=always
+RestartSec=3
+WorkingDirectory=%h
+StandardOutput=append:%h/.hermes/logs/openwebui.log
+StandardError=append:%h/.hermes/logs/openwebui.error.log
+
+[Install]
+WantedBy=default.target
diff --git a/dot_config/systemd/user/rclone-gdrive-hyperauth.service b/dot_config/systemd/user/rclone-gdrive-hyperauth.service
new file mode 100644
index 0000000..850c6cb
--- /dev/null
+++ b/dot_config/systemd/user/rclone-gdrive-hyperauth.service
@@ -0,0 +1,7 @@
+[Unit]
+Description=Rclone SFTP Service for gdrive-hyperauth
+Requires=rclone-gdrive-hyperauth.socket
+
+[Service]
+Type=simple
+ExecStart=/usr/bin/rclone serve sftp gdrive-hyperauth: --vfs-cache-mode full --vfs-fast-fingerprint --user yazi --pass yazi
diff --git a/dot_config/systemd/user/rclone-gdrive-hyperauth.socket b/dot_config/systemd/user/rclone-gdrive-hyperauth.socket
new file mode 100644
index 0000000..ea0dad5
--- /dev/null
+++ b/dot_config/systemd/user/rclone-gdrive-hyperauth.socket
@@ -0,0 +1,8 @@
+[Unit]
+Description=Rclone SFTP Socket for gdrive-hyperauth
+
+[Socket]
+ListenStream=127.0.0.1:2223
+
+[Install]
+WantedBy=sockets.target
diff --git a/dot_config/systemd/user/rclone-gdrive-personal.service b/dot_config/systemd/user/rclone-gdrive-personal.service
new file mode 100644
index 0000000..f67ef17
--- /dev/null
+++ b/dot_config/systemd/user/rclone-gdrive-personal.service
@@ -0,0 +1,7 @@
+[Unit]
+Description=Rclone SFTP Service for gdrive-personal
+Requires=rclone-gdrive-personal.socket
+
+[Service]
+Type=simple
+ExecStart=/usr/bin/rclone serve sftp gdrive-personal: --vfs-cache-mode full --vfs-fast-fingerprint --user yazi --pass yazi
diff --git a/dot_config/systemd/user/rclone-gdrive-personal.socket b/dot_config/systemd/user/rclone-gdrive-personal.socket
new file mode 100644
index 0000000..76819f1
--- /dev/null
+++ b/dot_config/systemd/user/rclone-gdrive-personal.socket
@@ -0,0 +1,8 @@
+[Unit]
+Description=Rclone SFTP Socket for gdrive-personal
+
+[Socket]
+ListenStream=127.0.0.1:2221
+
+[Install]
+WantedBy=sockets.target
diff --git a/dot_config/systemd/user/rclone-gdrive-sonr.service b/dot_config/systemd/user/rclone-gdrive-sonr.service
new file mode 100644
index 0000000..2264f7a
--- /dev/null
+++ b/dot_config/systemd/user/rclone-gdrive-sonr.service
@@ -0,0 +1,7 @@
+[Unit]
+Description=Rclone SFTP Service for gdrive-sonr
+Requires=rclone-gdrive-sonr.socket
+
+[Service]
+Type=simple
+ExecStart=/usr/bin/rclone serve sftp gdrive-sonr: --vfs-cache-mode full --vfs-fast-fingerprint --user yazi --pass yazi
diff --git a/dot_config/systemd/user/rclone-gdrive-sonr.socket b/dot_config/systemd/user/rclone-gdrive-sonr.socket
new file mode 100644
index 0000000..c790ba4
--- /dev/null
+++ b/dot_config/systemd/user/rclone-gdrive-sonr.socket
@@ -0,0 +1,8 @@
+[Unit]
+Description=Rclone SFTP Socket for gdrive-sonr
+
+[Socket]
+ListenStream=127.0.0.1:2222
+
+[Install]
+WantedBy=sockets.target
diff --git a/dot_config/systemd/user/shelly-notifications.service b/dot_config/systemd/user/shelly-notifications.service
new file mode 100644
index 0000000..b86e5ad
--- /dev/null
+++ b/dot_config/systemd/user/shelly-notifications.service
@@ -0,0 +1,12 @@
+[Unit]
+Description=Shelly Notifications tray service
+After=graphical-session.target
+
+[Service]
+Type=simple
+ExecStart=/usr/bin/shelly-notifications
+Restart=on-failure
+RestartSec=5s
+
+[Install]
+WantedBy=graphical-session.target
\ No newline at end of file
diff --git a/dot_config/systemd/user/voxtype.service b/dot_config/systemd/user/voxtype.service
new file mode 100644
index 0000000..0e22007
--- /dev/null
+++ b/dot_config/systemd/user/voxtype.service
@@ -0,0 +1,17 @@
+[Unit]
+Description=Voxtype push-to-talk voice-to-text daemon
+Documentation=https://voxtype.io
+PartOf=graphical-session.target
+After=graphical-session.target
+
+[Service]
+Type=simple
+ExecStart=/usr/bin/voxtype daemon
+Restart=on-failure
+RestartSec=5
+
+# Ensure we have access to the display
+Environment=XDG_RUNTIME_DIR=%t
+
+[Install]
+WantedBy=graphical-session.target
diff --git a/dot_local/bin/executable_niri-launch b/dot_local/bin/executable_niri-launch
new file mode 100755
index 0000000..a80f214
--- /dev/null
+++ b/dot_local/bin/executable_niri-launch
@@ -0,0 +1,88 @@
+#!/bin/bash
+APP=$1
+declare -a INSTANCES
+
+# Per-class launch commands for kitty-* (class -> command run via `kitty -e`).
+# Unmapped classes just open a plain kitty with that class.
+declare -A KITTY_CMDS=(
+ # [kitty-lazygit]="lazygit"
+ # [kitty-btop]="btop"
+)
+
+# Handle webapp cycling and launching
+if [[ "$APP" == "webapp" ]]; then
+ # Cycle through all WebApps
+ INSTANCES=($(niri msg -j windows | jq -r '.[] | select(.app_id | startswith("WebApp-")) | .id'))
+elif [[ "$APP" == webapp-* ]]; then
+ # Extract the webapp name (e.g., "webapp-claude" -> "Claude")
+ WEBAPP_NAME=$(echo "$APP" | sed 's/webapp-//' | sed 's/.*/\u&/')
+ # Find matching WebApp by prefix (case-insensitive match)
+ APP_ID=$(niri msg -j windows | jq -r ".[] | select(.app_id | test(\"WebApp-${WEBAPP_NAME}\"; \"i\")) | .app_id" | head -1)
+
+ if [ -z "$APP_ID" ]; then
+ # No instance running, launch via gtk-launch
+ DESKTOP_FILE=$(find ~/.local/share/applications -name "WebApp-${WEBAPP_NAME}*.desktop" -print -quit 2>/dev/null)
+ if [ -n "$DESKTOP_FILE" ]; then
+ gtk-launch "$(basename "$DESKTOP_FILE")"
+ else
+ echo "No desktop file found for WebApp-${WEBAPP_NAME}"
+ fi
+ exit 0
+ fi
+
+ INSTANCES=($(niri msg -j windows | jq -r ".[] | select(.app_id | test(\"WebApp-${WEBAPP_NAME}\"; \"i\")) | .id"))
+elif [[ "$APP" == "kitty" ]]; then
+ # Cycle through ALL kitty windows (any class: kitty, kitty-nvim, ...)
+ INSTANCES=($(niri msg -j windows | jq -r '.[] | select((.app_id // "") | ascii_downcase | startswith("kitty")) | .id'))
+elif [[ "$APP" == kitty-* ]]; then
+ # Specific kitty class, e.g. kitty-nvim -> app_id "kitty-nvim"
+ INSTANCES=($(niri msg -j windows | jq -r --arg cls "$APP" \
+ '.[] | select((.app_id // "") | ascii_downcase == ($cls | ascii_downcase)) | .id'))
+
+ if [ ${#INSTANCES[@]} -eq 0 ]; then
+ cmd="${KITTY_CMDS[$APP]:-}"
+ if [ -n "$cmd" ]; then
+ niri msg action spawn -- kitty --class "$APP" -e $cmd
+ else
+ niri msg action spawn -- kitty --class "$APP"
+ fi
+ exit 0
+ fi
+elif [[ "$APP" == "ghostty" ]]; then
+ # Cycle through Ghostty terminals (case-insensitive app_id match)
+ INSTANCES=($(niri msg -j windows | jq -r '.[] | select(.app_id | test("ghostty"; "i")) | .id'))
+else
+ INSTANCES=($(niri msg -j windows | jq -r ".[] | select(.app_id==\"${APP}\") | .id"))
+fi
+
+# Launch if no instances
+if [ ${#INSTANCES[@]} -eq 0 ]; then
+ # Removed "kitty" from this block so it falls through to the spawn command
+ if [[ "$APP" == "webapp" || "$APP" == "ghostty" ]]; then
+ echo "No ${APP} windows running"
+ exit 0
+ fi
+ niri msg action spawn -- $APP
+ exit 0
+fi
+
+# Focus logic
+if [ ${#INSTANCES[@]} -eq 1 ]; then
+ niri msg action focus-window --id ${INSTANCES[0]}
+else
+ ISORTED=($(printf "%s\n" "${INSTANCES[@]}" | sort -n))
+ FOCUSED=$(niri msg -j focused-window | jq '.id')
+
+ if [[ ! " ${ISORTED[@]} " =~ ${FOCUSED} ]]; then
+ niri msg action focus-window --id ${ISORTED[0]}
+ else
+ new_index=0
+ for i in "${!ISORTED[@]}"; do
+ if [ "${ISORTED[$i]}" -eq "${FOCUSED}" ]; then
+ new_index=$(( (i + 1) % ${#ISORTED[@]} ))
+ break
+ fi
+ done
+ niri msg action focus-window --id ${ISORTED[$new_index]}
+ fi
+fi