Files
Nomarchy/docs/ROADMAP.md
Bernardo Magri fb748c217c feat(services): opt-in Tailscale + Syncthing (nomarchy.services.*)
Start the opt-in services surface: nomarchy.services.{tailscale,syncthing},
off by default, in modules/nixos/services.nix. Tailscale ships the daemon
(authenticate with `sudo tailscale up`); Syncthing runs as the login user
with its GUI on 127.0.0.1:8384 (overrideDevices/Folders off so GUI-managed
folders survive rebuilds). username is read lazily, only when Syncthing is
on. Commented examples in the downstream system.nix template per the opt-in
convention.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 17:08:41 +01:00

28 KiB
Raw Blame History

Roadmap & changelog

Forward-looking plans, plus a running log of shipped fixes (the "Known issues & follow-ups" section). Split out of the README so that stays a focused entry point — what Nomarchy is, how to install it, and how to override it. Items marked ✓ are shipped.

Roadmap

  • Menu system (apps launcher + theme switching + system actions), built on rofi 2.0 (native Wayland on 26.05) — its .rasi theme is baked from theme-state.json like every other app, with rich per-element styling:

    • ✓ shipped: modules/home/rofi.nix (per-element theme generated from the palette, themes/<slug>/rofi.rasi whole-swap) and the nomarchy-menu dispatcher: root picker (no args) · power (lock/logout/suspend/hibernate/reboot/shutdown, SUPER+X) · theme (SUPER+T) · clipboard (cliphist, SUPER+CTRL+V) · calc (rofi-calc, live, SUPER+CTRL+C) · files (fd → xdg-open, SUPER+CTRL+F) · emoji (rofi-emoji, SUPER+CTRL+E) · web (Google). SUPER+D is rofi -show drun.
    • ✓ shipped modules: network (nmtui in $TERMINAL) · bluetooth (blueman-manager) · capture (grim/slurp submenu: region/full → clipboard/file, saved to ~/Pictures/Screenshots) · keybinds (the cheatsheet, see below) · ask (free-text → claude CLI in a terminal; auths via OAuth, no API key; pulled fresh via npx @anthropic-ai/claude-code@latest rather than the nixpkgs package, which lags model releases — nodejs is bundled for npx; REPL stays open)
    • ✓ keybindings cheatsheet: modules/home/keybinds.nix is the single source for both the Hyprland binds and the SUPER+? rofi list, so they can't drift; nomarchy-menu keybinds renders the padded two-column sheet (generated/mouse binds carried in its extra rows)
    • ✓ shipped binds: SUPER+Spacerofi -show drun (quick launch) · SUPER+Mnomarchy-menu (main menu) · SUPER+? → the cheatsheet; SUPER+D stays -show drun
    • launcher icons: ✓ show-icons on, drawing from the theme's icon set (Papirus, via the icon-themes work below)
    • decision record: resolves the old Walker/Lua question — no GTK4 launcher, no second theming pipeline; the dispatcher owns the menu structure, so the renderer stays swappable (we moved fuzzel → rofi 2.0 once mainline gained native Wayland, for its richer theming)
    • Organize the picker into category submenus: the root picker has grown into a long flat list (Apps · Theme · Clipboard · Calculator · Files · Emoji · Web · Network · Bluetooth · Capture · Keybindings · Ask · DND · Snapshots · Power profile · Power · …). Group it into category submenus (e.g. System, Tools, Look & Feel, Power) so the top level stays short and scannable, the dispatcher routing nomarchy-menu <category> → its leaf modules. Keep the direct SUPER+CTRL+<mnemonic> binds as fast paths straight to the leaves (they bypass the menu), and self-gated entries (power-profile, snapshots) still hide when unavailable.
  • Menu modules from rofi plugins: the old calc flow committed the expression blind (result only in the next menu's -mesg) and qalc -t misparsed common phrasings (15% of 200rem(15, 1 B), the natural- language "of" tripping the CLI). Resolved by adopting purpose-built rofi modi (programs.rofi.plugins), all themed through the same .rasi:

    • calcrofi-calc: live results as you type via libqalculate directly (dodging the qalc-CLI "of" bug), Enter copies, menu persists to chain calculations.
    • emojirofi-emoji (new module, SUPER+CTRL+E): glyph picker, copies via the plugin's Wayland clipboard adapter.
    • files stays the hand-rolled fdrofi -dmenu → xdg-open fuzzy search: rofi-file-browser-extended was tried and dropped — its navigate-a-tree model felt worse than flat fuzzy-find for a quick launcher, and yazi (SUPER+E) already covers real browsing.
  • More menu modules from rofi tools: the script-based counterparts (run via rofi -dmenu, like the hand-rolled modules), each a deliberate replacement of an existing flow: rofi-network-manager (a keyboard wifi/VPN picker vs today's nmtui-in-terminal network), rofi-rbw / rofi-pass (a secrets module — Bitwarden via rbw, or pass — pairs with keys.nix), and rofi-pulse-select (an audio sink/source switcher). Decide per-module whether it earns replacing the current path.

  • Theme parity with legacy: summer-day/night now carry their legacy bar layouts as waybar.jsonc whole-swaps (adapted: dead legacy script modules dropped, Nerd-Fonts-v2 codepoints remapped to FontAwesome/v3, logo button opens nomarchy-menu); the other four identity themes are palette recolors and already match. Remaining: a visual pass over all six on the live ISO

  • Per-theme rofi identity: the themes/<slug>/rofi.rasi whole-swap ships, and summer-day/night carry their legacy designs (inverted window, green inputbar, yellow bottom-border). Remaining: author .rasi identities for the other four ported themes if/when they want one (the generated palette theme is the default and looks fine)

  • Faster switches: move backgrounds/ out of the flake source (the 86 MB re-copy on every state write is the main eval tax), then pre-built theme variants if still needed

  • Greeter (tuigreet/SDDM) theming from the same JSON (Plymouth ships since v1: nomarchy.system.plymouth.*, background tinted from the state file)

  • Installer round 2: multi-disk BTRFS RAID, impermanence, BIOS/legacy boot (v1 nomarchy-install is single-disk UEFI — see pkgs/nomarchy-install)

  • launch-or-focus UX scripts (swayosd volume/brightness OSD ships since v1: nomarchy.osd.*, media keys drive swayosd-client, themed from the JSON)

  • Distro branding, round 2: distroName = "Nomarchy" ships (os-release PRETTY_NAME, systemd-boot entries, ISO menu label). ✓ tuigreet greeting (Welcome to <distroName>) and a branded users.motd (doubling as a helper cheat sheet), both keyed off distroName. ✓ isoImage.splashImage — the vendored vector logo (modules/nixos/branding/logo.svg, from legacy) recolored to the palette accent on the theme base, built at ISO-build time (hosts/live.nix). Remaining: isoImage.grubTheme so UEFI boot matches the isolinux splash (needs a full grub theme dir), and the distroId question (it changes DEFAULT_HOSTNAME and upstream isNixos checks — needs a test pass; nixos-* CLI names stay regardless)

  • fastfetch branding: modules/home/fastfetch.nix (nomarchy.fastfetch.enable) — the vendored vector logo, recolored to the palette accent and rendered to compact block-art via chafa at build time (tracks the theme), fronting a curated module list. Replaces the oversized legacy ASCII with a themed, sized logo.

  • Nomarchy logo font in Waybar: vendored Nomarchy.ttf (modules/nixos/branding/), installed via fonts.packages, and the summer-day/night menu buttons now use its U+F000 glyph with font-family: Nomarchy pinned in their CSS (Nerd Fonts also occupy U+F000, so the pin is required). The other themes have no logo button.

  • Quality-of-life command aliases: assemble a curated collection of shell aliases/abbreviations for common operations (git, nix, navigation, the nomarchy helpers, …), themed into the zsh shell experience (modules/home/shell.nix). Decide scope and which to ship on by default.

  • Theme-switch feedback: ✓ the "rebuilding…" notification is now persistent (timeout 0) and replaced in place by "applied ✓" / failure via a synchronous tag, so a multi-minute switch never reads as a failed selection. (An honest indeterminate indicator — HM gives no % — a literal progress widget would be cosmetic; revisit only if wanted.)

  • Icon themes: ✓ ships papirus-icon-theme; the resolved name lives on nomarchy.theme.iconTheme (the JSON's optional icons field, else Papirus-Dark/Light by mode) and feeds both Stylix's gtk.iconTheme (Thunar/GTK apps) and rofi's show-icons. Remaining (optional): per-theme icons overrides for the presets, or shipping more icon packs.

  • Nicer shell out of the box: ✓ zsh is the default login shell, with a starship prompt themed from the JSON, autosuggestions + syntax highlighting, and modern-CLI ergonomics — cat→bat (theme "ansi", so it tracks the palette), ls→eza, cd→zoxide, plus lt/tree. nomarchy.shell.enable. (Deliberately did NOT alias grep→rg / find→fd: their flags differ enough to surprise; rg/fd ship as themselves.)

  • Default application suite: install a complete-workstation set (vscode, libreoffice, gimp, inkscape, texlive-full, …) behind a nomarchy.apps.* option surface so each is individually opt-out for users who want a leaner machine. Watch closure size (texlive-full is multi-GB — likely default-off or a lighter scheme).

  • Plymouth logo contrast: the shipped art was a fixed navy that vanished on dark bases. modules/nixos/plymouth.nix now recolors every element from the palette at build time (flat fill, alpha kept): logo/lock/bullet → text, entry/progress-box → surface, progress-bar → accent. Reads on light and dark; follows the theme as of the last system rebuild (like the background tint).

  • Hibernate double-unlock: on resume from hibernate the LUKS passphrase already gates the machine, but locking hyprlock before sleep meant a second password. Fixed by not locking before an encrypted hibernate: a nomarchy-lock-before-sleep systemd unit (modules/nixos/default.nix) takes over from hypridle's before_sleep_cmd and locks on the RAM-resume sleeps (suspend / hybrid-sleep / suspend-then- hibernate) always, but skips hibernate.target when the disk is LUKS- encrypted. (A first attempt that dismissed hyprlock after resume was wrong — killing a Wayland session-lock client trips its "go to a tty" crash failsafe instead of unlocking, which is the error screen it caused.)

  • Key agents & pinentry: ships modules/home/keys.nix (nomarchy.keys.enable): one agent — services.gpg-agent with enableSshSupport fronts SSH, so a single pinentry-qt (native-Wayland, Stylix-themed Qt) handles GPG and SSH passphrases alike. SSH_AUTH_SOCK comes from the agent's zsh integration; cache TTLs (30 min / 2 h) govern re-prompting. gnome-keyring stays the Secret Service (modern versions run no SSH agent, so no socket contention); screen lock doesn't flush the cache. Remaining (optional): a session-level SSH_AUTH_SOCK export so GUI clients launched outside a shell also see the agent.

  • Sanitize & organize the repo: a housekeeping pass for consistency and clarity.

    • ✓ pruned now-redundant config: the installer no longer writes console.useXkbConfig / boot.initrd.systemd.enable into system.nix (distro-wide defaults since the LUKS-keymap fix), nor the offline-pin test fixture in flake.nix.
    • ✓ reconciled the README option tables with the live nomarchy.* surface (added keys/fastfetch/snapper/greeter.autoLogin).
    • ✓ untracked .claude/settings.local.json (machine-local) + gitignored.
    • branch/release model: main is the development default; v1 is the release pointer downstreams pin (?ref=v1), advanced to main once a batch is tested — rolling, no tags. Brought main current (it was a stale legacy-merge), and deleted the dead refactor / wave/nixos-26.05 branches (kept legacy for history). See the comment in flake.nix.
    • Remaining (optional): re-check that every file still earns its place under the modules/hosts/themes/pkgs/tools rule of thumb.
  • Full docs review & restructure: a dedicated pass over all the prose, not just the code-adjacent cleanup the repo-sanitize item covers. The README has grown to ~540 lines with a ~200-line roadmap inline — the biggest single move is likely splitting the roadmap out (e.g. ROADMAP.md / docs/) so the README stays a focused "what it is / how to install / how to override" entry point. Also: reconcile every option table against the live nomarchy.* surface (snapper and others are missing); a pass over docs/OVERRIDES.md + docs/TESTING.md and the templates/downstream/README.md for drift; check the install/first-run story reads cleanly end to end; and decide whether anything wants a real docs site vs. staying Markdown-in-repo. Pairs with the first-boot welcome and control-center items (shared "how do I…" surface).

  • Laptop power / battery management: a real power story behind a nomarchy.system.power.* surface (modules/nixos/power.nix), replacing the old "only services.upower for Waybar reporting" baseline:

    • profiles: power-profiles-daemon ships by default (the upstream- aligned choice — power-saver/balanced/performance via powerprofilesctl, switched through polkit so no root prompt). A power-profile menu module (in the SUPER+M picker) and the first Waybar custom/* indicator (click to cycle) both self-gate on a battery being present + PPD running, so they hide on desktops and under TLP — no system→home wiring. TLP is the opt-in (backend = "tlp") for deeper battery tuning; the two are mutually exclusive (asserted).
    • thermal: thermald behind power.thermal.enable; the installer turns it on for a GenuineIntel CPU.
    • longevity: power.batteryChargeLimit (e.g. 80) — a backend- independent sysfs oneshot writes charge_control_end_threshold. Off by default; the installer scaffolds it commented-out on laptops.
    • installer: writes power.laptop = true (battery probe) and power.thermal.enable (Intel) into the generated system.nix.
    • idle cohesion: modules/home/idle.nix now suspends only on battery (and sooner — 15 min vs the old fixed 30), gating the hypridle suspend listener on a nomarchy-on-ac probe so a plugged-in machine stays up mid-idle; lock/screen-off are unchanged on both sources. logind's lid handling is left at its defaults (suspend on lid close, ignore when docked) — an explicit "I'm done" that coheres with the idle behaviour.
    • Remaining: a boot-only→event-driven charge-limit re-apply (udev) if a firmware resets the threshold on unplug.
    • Waybar parity: the custom/powerprofile indicator now shows in the summer-day/night whole-swap themes too. powerProfileStatus/Cycle are named writeShellScriptBins on PATH (waybar.nix home.packages), so the generated config and the static waybar.jsonc both exec them by bare name (the same parity the DND bell has). General pattern: any new generated-config module needs adding to the whole-swap themes too.
  • Full hardware enablement (beyond nixos-hardware): nixos-hardware profiles cover basic per-model functionality (quirks, drivers), but the advanced features of a machine — keyed more on the CPU/GPU generation than the model — are left for the user to wire up by hand. Close that gap without making it finnicky: extend the installer's existing autodetection (DMI → nixos-hardware profile today; add CPU vendor/arch, GPU, NPU, fingerprint reader, SSD) to switch on the safe, broadly-beneficial features automatically, and expose a small nomarchy.hardware.* surface (per-vendor where it helps, e.g. nomarchy.hardware.amd.*) for the heavy or experimental bits. Goal: full utilisation out of the box — opt-out for the safe defaults, opt-in for the multi-GB / experimental extras. Complements nixos-hardware (model quirks) rather than replacing it; keep the detection in the installer's hardware-db so an installed machine bakes the right defaults, all overridable through nomarchy.hardware.*. Worked example — ThinkPad T14s (Ryzen 7 PRO 7840U + Radeon 780M):

    • GPU compute — ROCm: the 780M is an RDNA3 iGPU (gfx1103) ROCm doesn't officially list, so it needs HSA_OVERRIDE_GFX_VERSION=11.0.0. Multi-GB closure → opt-in (nomarchy.hardware.amd.rocm.enable); unlocks GPU PyTorch / Ollama.
    • Ryzen AI NPU (XDNA): the amdxdna kernel driver (mainline 6.14+) + the XRT/xdna userspace runtime + firmware. Niche/experimental → opt-in.
    • AMD P-State EPP (Zen 4 power): amd_pstate=active for the EPP governor, which power-profiles-daemon (already shipped, power.nix) drives per profile. Broadly beneficial on Zen 2+ → default on when the installer sees an AMD CPU.
    • Hardware video acceleration (VA-API): mesa's radeonsi exposes VA-API on AMD (LIBVA_DRIVER_NAME=radeonsi, libva + drivers in hardware.graphics.extraPackages); Intel uses intel-media-driver. Broadly beneficial → default on, vendor-detected.
    • LVFS firmware & biometrics: fwupd already ships (✓, services.fwupd). Add fingerprint: services.fprintd when a reader is detected, with opt-in PAM integration for login/sudo (password-only stays the default for the cautious).
    • SSD periodic TRIM: services.fstrim.enable (weekly) — safe and beneficial, so default on (trivial enough it may warrant being distro-wide regardless). Sub-items here can graduate into their own roadmap entries as they're scoped; the unifying work is the detection + nomarchy.hardware.* surface.
  • Opt-in services & integrations: the counterpart to the opt-out application suite above — heavier or more personal integrations shipped off by default, each a nomarchy.services.<name>.enable toggle a downstream flips on in one line. Keeps the base lean while making common additions trivial. ✓ First two shippednomarchy.services.tailscale and nomarchy.services.syncthing (modules/nixos/services.nix, system-side; Syncthing runs as the login user with its GUI on 127.0.0.1:8384), with commented examples in the downstream system.nix template. More candidates by area:

    • cloud/sync: Syncthing (services.syncthing); Nextcloud client (todo)
    • local AI: LM Studio (lmstudio); Ollama (services.ollama, optional GPU accel) — pairs with the menu's Ask-Claude philosophy
    • containers/VMs: Docker/Podman; libvirt + virt-manager
    • networking: Tailscale (services.tailscale); WireGuard (todo)
    • gaming/media: Steam (programs.steam); OBS Studio
    • devices: printing (CUPS + Avahi); KDE Connect / phone integration; OpenRGB
    • backup: restic/borg (services.restic)
    • escape hatch: Flatpak (services.flatpak) for apps outside nixpkgs

    Surface decided: nomarchy.services.*, system-side for system services (home-side ones can extend the same prefix later). Remaining: curate the rest (Ollama, containers, Steam/OBS, printing, backups, Flatpak …) and decide how it relates to nomarchy.apps.* (opt-out suite). Unfree entries are already covered (allowUnfree = true).

  • Display / monitor management: declarative nomarchy.monitors (a per-output schema — name/resolution/position/scale/transform/mirror/ bitdepth/vrr/disable) generates Hyprland monitor rules, keeping the ,preferred,auto,1 wildcard as the fallback; Hyprland applies them on hotplug, so a declared external/dock output arranges itself on connect (no kanshi — it fights Hyprland's own output management). nwg-displays ships behind nomarchy.displays.enable as an interactive arranger (a helper to find values; the declarative config stays the source of truth — its output file isn't sourced). Remaining: true docked/undocked profile switching of the same outputs (Hyprland's per-output rules cover the common "external connects → arrange" case, not multi-layout toggles), and optionally workspace-to-monitor binding.

  • Night light / blue-light filter: nomarchy.nightlight (opt-in) — a scheduled colour-temperature shift via hyprsunset (Hyprland-native), warm at night, identity (no shift) by day. modules/home/nightlight.nix drives the HM services.hyprsunset with two time-based profiles (sunrise → identity, sunsettemperature), so hyprsunset handles the schedule and the on-login state. Needs an on-hardware check that hyprsunset applies the active profile at session start. Remaining (optional): a menu + Waybar toggle to force it on/off, and geo (lat/long) auto sunset/sunrise (would mean wlsunset, which schedules by location).

  • Keyboard layouts (per-device + switching):

    • Per-device declarative layout: nomarchy.keyboard.devices ({ "<hyprctl-device-name>" = { layout; variant; }; }) generates Hyprland device blocks that override the session nomarchy.keyboard.layout for a named keyboard — e.g. an external board that's physically a different layout than the laptop's. Hyprland applies it whenever that device connects (the "external keyboard remembers its layout" case, done the declarative way). A Waybar hyprland/language indicator shows the active layout, gated on more than one layout being in play (comma in the session layout, or any per-device override) so single-layout bars stay clean.
    • Interactive new-keyboard prompt (runtime + persist): set nomarchy.keyboard.layouts (candidate layouts) and a nomarchy-keyboard- watch daemon runs (exec-once): it polls hyprctl devices, and when a keyboard connects after login that isn't in keyboard.devices and hasn't been chosen before, it pops a rofi layout picker, applies the choice with hyprctl switchxkblayout (an index into the candidate set, which input.kb_layout carries), and remembers it per-device in ~/.local/state/nomarchy/keyboard-layouts — re-applied silently on later reconnects. The boot-time set (incl. the built-in keyboard) is never prompted. The runtime-remember complement to the declarative keyboard.devices; a stateful runtime piece by design. Pending an on-hardware test (hotplug isn't verifiable in CI). Remaining (bonus): offer to write a choice into keyboard.devices so it graduates to the reproducible config.
    • Remaining: a multi-layout cycle bind (hyprctl switchxkblayout / xkb grp: options) for switching layouts on one keyboard; add the hyprland/language module to the summer whole-swap themes for parity (the gating doesn't translate to their static JSON). Keep the system (console/initrd) and session layouts in sync (the LUKS-keymap work).
  • Do-Not-Disturb: swaync DND toggle wired into the menu (nomarchy-menu dnd, in the picker, SUPER+CTRL+D) and a Waybar bell indicator (custom/notification via swaync-client -swb: shows the notification count + DND state, left-click toggles the panel, right-click toggles DND). Turning DND off confirms with a toast; turning it on is silent (notifications are suppressed — the bell-off glyph is the cue).

  • Snapshot browse/restore UX: nomarchy-menu snapshot (in the SUPER+M picker, self-gated on snapper) launches btrfs-assistant — the desktop browse/diff/restore/rollback UI, elevating via polkit (the safe choice for a destructive, root-only op vs a fat-fingerable rofi rollback). Shipped system-side gated on nomarchy.system.snapper. Also extended snapper to snapshot /home by default (hourly 5 / daily 7 / weekly 4) when it's its own BTRFS subvolume; a boot oneshot creates the required /home/.snapshots subvolume if missing (covers existing installs, no disko change). The backend is VM-verified (a full BTRFS+LUKS install: both root+home configs, a /home timeline snapshot taken, /home/.snapshots a real subvolume, the oneshot Result=success).

    • Known bug — btrfs-assistant 2.2 segfaults on launch in nixpkgs 26.05: it crashes inside libbtrfsutil.so.1.4.0 (a library ABI mismatch, confirmed in the VM regardless of GL/Qt platform — so it's not a VM/GL artifact and will crash on hardware too). The menu wiring is correct and the app is installed, but the GUI doesn't open. The snapshot backend (the actual snapshots) is unaffected. Fix path: a nixpkgs override aligning its libbtrfsutil, or wait for an upstream bump; meanwhile the menu entry is a no-op when the binary crashes. Fallback if it lingers: a rofi-based snapshot menu (no btrfs-assistant dependency).
    • Remaining (optional): a keyboard-driven rofi browse for quick glances; boot-from-snapshot needs a systemd-boot equivalent of grub-btrfs.
  • Update awareness: updates are manual today (sys-update/home-update); add a Waybar indicator / notification when flake inputs are stale or a new nixpkgs rev is available (optionally with a pending-change count). Augments, never replaces, the explicit rebuild flow.

  • "nomarchy" control center: a single TUI/GUI front-end over the common toggles — theme, power profile, opt-in services, display, DND — built on the same nomarchy-theme-sync / nomarchy.* surface the menu already uses. Plus a first-boot welcome that lands new installs in a guided "pick your theme / essentials" flow (ties into the branding work).

Known issues & follow-ups

  • Yazi TOML parse error on startup: yazi 26.x made fetchers' group field required, so [[plugin.prepend_fetchers]] failed to parse and yazi fell back to presets. Fixed by adding group = "git" to both git fetcher entries in modules/home/yazi.nix (the git plugin's setup() only renders the linemode; the fetcher still needs registering).
  • Starship prompt styling: dropped the powerline look (the [] separator glyph + bg: fills) for a flat prompt — bold-accent directory, warn git branch, subtext status/duration, character, all plain colored text (modules/home/shell.nix). Also wired in cmd_duration, which was configured but never referenced in format.
  • xfce deprecation warnings: moved xfce.exopkgs.xfce4-exo and the three Thunar plugins to their new top-level names in modules/nixos/file-manager.nix; the eval warnings are gone.
  • Rofi function keybindings: direct SUPER+CTRL+<mnemonic> binds jump straight to each nomarchy-menu module — V clipboard · C calc · W web · F files · N network · B bluetooth · S capture · A ask — added to modules/home/keybinds.nix, so they also show in the SUPER+? cheatsheet.
  • Enable nix-ld by default: programs.nix-ld.enable is on distro-wide (modules/nixos/default.nix), so prebuilt/foreign dynamically-linked binaries run out of the box.
  • Hyprland border colors off for some themes: the cause was v1 forcing an accent→accentAlt gradient on every theme; legacy used a solid border (accent for nord/retro-82/lumon, the text tone for kanagawa/summer-day/summer-night). Added a palette-resolved border field ({active, inactive}) to the theme schema (theme.nix), consumed solid in hyprland.nix, and declared it in every preset so a switch always replaces it. All six identity themes now match legacy exactly.
  • Waybar shows non-existent workspaces: the v1 summer port "fixed" legacy's deprecated persistent_workspaces (underscore — silently ignored by current Waybar, so legacy only ever showed existing workspaces) into the modern persistent-workspaces (hyphen), which Waybar honours → all 10 rendered as phantoms. Dropped the block from themes/summer-{day,night}/waybar.jsonc; the other themes use the generated waybar.nix, which never had it, so they already match.
  • GTK/Qt ignore the theme's light/dark mode: Stylix set polarity but not the org.freedesktop.appearance color-scheme that GTK4/libadwaita and Qt6 read via the portal, so a light theme could still render apps dark. stylix.nix now sets dconf org/gnome/desktop/interface color-scheme = prefer-light/prefer-dark from t.mode (xdg-desktop-portal-gtk already ships, and programs.dconf is on system-side), so libadwaita/Qt follow the palette. Confirmed in a live session (headless QEMU): the portal's org.freedesktop.appearance color-scheme reads 1 on a dark theme and flips to 2 after switching to a light one (catppuccin-latte) — so xdg-desktop-portal-gtk does relay the dconf value GTK4/Qt apps read.