Kill pure-black crust (->Void #070709) and add the figure/ground tokens
focusActive/focusField/emberField. Move active/selection states to violet
(calendar Today, keybinds active tab, battery + power profiles); stop spending
danger-red on non-danger states (mic + audio-default -> cyan); make the notif
bell state-driven (neutral/focus/danger); give critical notifications an ember
ground; bluetooth scanning -> cyan; k8s MEM -> blue (free the special violet).
Migrate the shell palette to the v2 semantic spine and clean up
spec violations:
- Theme.qml: v2 neutrals (#070709 ground), split real blue (#5b8cff)
from info cyan, retire the peach token, add a focus attention violet.
- Weather: severity-driven coloring (cyan/amber/red) from weatherCode;
replaces decorative peach. Forecast highs=text, lows=subtext0.
- SystemPopout: performance profile + Reboot hold -> amber (peach retired).
- Workspaces: active indicator red -> focus violet (selection is
attention, not danger).
- SystemPill: Arch logo lavender -> real blue.
- Bar.qml: gate BluetoothPill instantiation behind hasBluetooth so
BlueZ DBus never spins up when the bluetooth tag is off.
- IdleScreen: route hardcoded hex through Theme tokens.
Gated on a new Config.hasBluetooth (bluetooth tag). Adds a bar pill
showing adapter state + connected count, and a full manager popout:
adapter power toggle, scan/discovery, and per-device pair / connect /
disconnect / trust / forget with battery. Built on Quickshell.Bluetooth
(BlueZ); mirrors the existing Kubernetes/System pill+popout pattern.
Collapse redundant template tags into a cleaner data model:
- drop the desktop tag (use "not laptop"); replace hyprland/niri with
compositor = "hyprland"|"niri"; replace cs2/entertainment with an
apps list (gated via has); drop the dead waybar tag.
- move app->workspace->monitor routing into a portable [[data.placement]]
table keyed by monitor role (left/right/primary), resolved per machine
with fallback to the primary monitor. workspaces.lua.tmpl and
rules.lua.tmpl now generate the workspace/window rules from it, so
single-monitor machines work with no hardcoded monitor names.
Update CLAUDE.md / AGENTS.md / GEMINI.md schema references to match.
While the popout is open, poll both status and metrics at a fast cadence
(kubeRefreshOpenMs, 3s) instead of 2min/15s, and refresh immediately when
it opens — so opening the pill shows fresh data and updates live. Status
reverts to the slow 2min pill cadence once closed.
GamemodePill is instantiated per screen Variant, so it spawned one
long-lived gdbus monitor per monitor (3 on desktop). Move the watcher into
a shared Gamemode singleton so only one runs regardless of screen count.
swaylock broke and the stack already locks with hyprlock everywhere else;
point the desktop lockCommand and power menu at hyprlock and drop the
now-identical laptop/desktop branches.
The metrics poller spawned the heavy k8s-metrics script every 15s all day
even though its data only renders in the popout. Gate it on the popout
being open (triggeredOnStart fetches immediately on open) and slow the
pill's status poll from 30s to 120s.
The pill and popout each picked an active MPRIS player independently, so
with multiple players open they disagreed and flipped. Add a Media
singleton that selects one active player with stickiness and bind both
components to it.
Template Config.qml with chezmoi data for multi-machine support. Surface
gets eDP-1 monitor, battery/power-profile widgets, no discrete GPU or
Kubernetes polling. Desktop behavior unchanged.
- Vertical bar on DP-2 with rounded-square pills throughout
- Per-monitor workspace groups sorted by screen x position, with
Nerd Font icons for named workspaces and apex-neon red active indicator
- Bar layout: datetime+weather top, workspaces centered, gamemode+media+notif+system bottom
- Popouts anchor to triggering icon (top-right for datetime/weather, bottom-right for media/notif/system)
- Lock command switched from hyprlock to swaylock
- Hyprland blur/ignore_alpha layerrules for quickshell namespace
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>