diff --git a/agent/BACKLOG.md b/agent/BACKLOG.md index 5998abc..e5fd739 100644 --- a/agent/BACKLOG.md +++ b/agent/BACKLOG.md @@ -28,15 +28,6 @@ in [`docs/ROADMAP.md`](../docs/ROADMAP.md); map in ## NEXT -### 42. Default theme → boreal (`VISION § B` / v1.0 bar) -Ship Boreal as the distro default instead of Tokyo Night: root -`theme-state.json`, `templates/downstream/theme-state.json` (and any -greeter/plymouth fallbacks that hardcode Tokyo Night when state is -missing). Preset already exists under `themes/boreal/`. Capture -`preview.png` if still missing so the picker looks first-class. -Cost: copy/apply palette into seed state files + grep for tokyo-night -defaults; V0 contrast, V1/V2 theme apply, V3 visual on hardware. - ### 43. System › Firmware — fwupd product surface (`VISION § A`) `services.fwupd.enable` is already default-on and never auto-flashes, but users only learn about `fwupdmgr` from a README sentence. Add a @@ -131,10 +122,12 @@ implement. Bernardo moves accepted items into a tier.* ### v1.0 track — see `docs/VISION.md` -Product themes and the release bar live in **VISION**. Promoted to -**NEXT:** #42 boreal default · #43 System › Firmware · #44 doctor -hardware. Remaining candidate promotions: fingerprint menu · -first-boot tips · human rebuild errors · neon-glass quarantine. +Product themes and the release bar live in **VISION**. **NEXT:** +#43 System › Firmware · #44 doctor hardware. #42 boreal default +shipped (seed state + eval fallbacks); still missing +`themes/boreal/preview.png` (picker plain-name until captured). +Remaining candidate promotions: fingerprint menu · first-boot tips · +human rebuild errors · neon-glass quarantine. ### Pre-existing @@ -283,11 +276,12 @@ first-boot tips · human rebuild errors · neon-glass quarantine. ### Theme polish / completeness (codebase exam 2026-07-09) - **Missing theme picker previews + hand btop for identity themes** - `boreal`, `executive-slate`, and `neon-glass` lack `preview.png` - (picker falls back to plain-name rows) and `btop.theme` (generated - btop only). CSS/jsonc for boreal/executive-slate are otherwise - solid. Capture previews after neon-glass is fixed/quarantined. - Cost: asset capture + optional hand btop; V3 visual. + `boreal` (now the default — higher priority), `executive-slate`, and + `neon-glass` lack `preview.png` (picker plain-name rows) and + `btop.theme` (generated btop only). CSS/jsonc for boreal/executive-slate + are solid. Capture boreal preview ASAP for v1.0 bar; others after + neon-glass is fixed/quarantined. Cost: asset capture + optional hand + btop; V3 visual. - **Generated Waybar missing identity-bar affordances** Whole-swap bars ship `custom/powermenu` and a left logo → main menu; diff --git a/agent/JOURNAL.md b/agent/JOURNAL.md index a0ac884..f7bb0a7 100644 --- a/agent/JOURNAL.md +++ b/agent/JOURNAL.md @@ -17,6 +17,13 @@ Template: --- +## 2026-07-09 — Default theme → Boreal (item #42) +- **Task:** NEXT #42 — distro default theme Tokyo Night → Boreal (`VISION § B` / v1.0 bar). +- **Did:** Seeded `theme-state.json` + `templates/downstream/theme-state.json` from `themes/boreal.json` (incl. border + settings). Eval fallbacks: `theme.nix` preset → boreal.json; plymouth + live ISO splash hex fallbacks; theme-shot / theme-sync examples; TESTING/RECOVERY wording. +- **Verified:** V0 — state JSON matches boreal palette/fonts; `check-theme-contrast` 24×7 pass; py_compile theme-sync. Full `nix flake check --no-build` started but not waited (slow ISO eval). No V2 apply / V3 session. +- **Pending:** `themes/boreal/preview.png` still missing (picker name-only) — left in PROPOSED theme polish; V2/V3 visual on hardware. Queue head now #43 Firmware. +- **Next suggestion:** #43 System › Firmware or #44 doctor hardware. + ## 2026-07-09 — Install contracts: swap=0 + unattended LUKS (workflow test run) - **Task:** VISION § v1.0 install golden path — PROPOSED install P0s (NEXT head blocked: item 14 wait-cron, 20 `[human]`, 33 V3 visual, 41 hw). Test of VISION→BACKLOG→verify→commit loop. - **Did:** (1) `nomarchy-install` passes `swapSize=0` when swap disabled (was always `"${SWAP_GB}G"` → `"0G"` still created `@swap`). (2) `disko-config.nix` treats `"0"` and `"0G"` as no-swap. (3) Unattended LUKS fail-closed: require `NOMARCHY_LUKS_PASSPHRASE` or `NOMARCHY_NO_LUKS=1`. diff --git a/docs/RECOVERY.md b/docs/RECOVERY.md index 0574722..28ad9f2 100644 --- a/docs/RECOVERY.md +++ b/docs/RECOVERY.md @@ -25,7 +25,7 @@ The same picker lives in the menu: **System › Rollback** lists the recent desktop generations — pick one and it activates. Or simply apply a theme you know is good: `nomarchy-theme-sync apply -tokyo-night`. If a switch failed halfway, the state file is written +boreal` (or any preset). If a switch failed halfway, the state file is written *before* the rebuild — fix the cause and re-run `home-manager switch --flake ~/.nomarchy` (or `home-update`). diff --git a/docs/TESTING.md b/docs/TESTING.md index e4b4c62..2d5e43b 100644 --- a/docs/TESTING.md +++ b/docs/TESTING.md @@ -65,13 +65,13 @@ Work through these in order; each one exercises a different layer. | # | Check | Verifies | |---|---|---| -| 1 | Boots to Hyprland with Tokyo Night wallpaper visible | greetd autologin, awww, session start | +| 1 | Boots to Hyprland with the default theme wallpaper visible (Boreal) | greetd autologin, awww, session start | | 2 | Waybar shows at top, themed (blue accent on dark) | HM waybar module, palette baking | -| 3 | `SUPER+Return` opens Ghostty with Tokyo Night colors | terminal default, ANSI palette | +| 3 | `SUPER+Return` opens Ghostty with the default theme colors (Boreal) | terminal default, ANSI palette | | 4 | `btop` in the terminal is themed | per-theme asset baking | | 5 | `nomarchy-theme-sync list` prints 21 presets | package, baked themes dir | | 6 | `nomarchy-theme-sync apply gruvbox` → state written, `home-manager switch` runs, desktop re-themes, wallpaper changes | the whole engine: state write, pure eval, HM rebuild, wallpaper hook | -| 7 | `SUPER+SHIFT+T` cycles wallpapers instantly (try `tokyo-night`: 4 of them) | the runtime wallpaper path | +| 7 | `SUPER+SHIFT+T` cycles wallpapers instantly (try `tokyo-night` for 4, or `boreal` for its set) | the runtime wallpaper path | | 8 | `nomarchy-theme-sync apply summer-night` → after the switch the bar has its own identity (light bar, different styling) | whole-swap waybar.css assets | | 9 | Open a GTK app — dark theme matching the palette | Stylix layer | | 10 | `home-manager generations` lists one generation per theme change; activating an older one rolls the theme back | atomicity / rollback story | diff --git a/docs/VISION.md b/docs/VISION.md index 600fad4..d13079f 100644 --- a/docs/VISION.md +++ b/docs/VISION.md @@ -37,7 +37,7 @@ judgment; agents prepare, do not advance `v1`): | Bar | Done looks like | |-----|-----------------| | **Install golden path** | Offline (or documented online) install → first boot themed desktop; swap=0 and unattended LUKS contracts correct | -| **Default identity** | Boreal (or chosen default) is the seed theme; picker has preview | +| **Default identity** | Boreal is the seed theme (shipped 2026-07-09); picker should have `preview.png` | | **Day-2 confidence** | Doctor covers real failure modes; firmware and fingerprint are discoverable without reading the README | | **Hardware story** | `docs/HARDWARE.md` matches code; option-docs green; i2c/ddcci documented | | **Honesty** | No “done” claims past verified tier; HARDWARE-QUEUE cleared or consciously deferred | diff --git a/hosts/live.nix b/hosts/live.nix index 538e091..b66650f 100644 --- a/hosts/live.nix +++ b/hosts/live.nix @@ -6,14 +6,14 @@ let # ISO boot branding: the Nomarchy monogram recolored to the palette accent, # centred on the theme base. Built from the vendored vector logo and the - # live theme-state.json (tokyo-night by default). The same composed image + # live theme-state.json (Boreal by default). The same composed image # backs both the isolinux (BIOS) splash and the GRUB (UEFI) theme below, so # the two boot paths match. state = builtins.fromJSON (builtins.readFile ../theme-state.json); isoColor = key: fallback: lib.removePrefix "#" ((state.colors or { }).${key} or fallback); - accent = isoColor "accent" "7aa2f7"; - base = isoColor "base" "1a1b26"; - subtext = isoColor "subtext" "787c99"; + accent = isoColor "accent" "B79BE8"; + base = isoColor "base" "21272F"; + subtext = isoColor "subtext" "97A3B2"; isoSplash = pkgs.runCommand "nomarchy-iso-splash.png" { nativeBuildInputs = [ pkgs.imagemagick pkgs.librsvg ]; } '' diff --git a/modules/home/theme.nix b/modules/home/theme.nix index 6e154cd..35ee6d4 100644 --- a/modules/home/theme.nix +++ b/modules/home/theme.nix @@ -22,10 +22,10 @@ let # Defaults guarantee evaluation succeeds on a sparse or older state # file (e.g. one written before a schema field was added). The shipped - # Tokyo Night preset provides the color/ansi fallbacks; the path is + # Boreal preset provides the color/ansi fallbacks; the path is # relative to this module, so it resolves inside Nomarchy's own flake # source even when consumed downstream. - preset = builtins.fromJSON (builtins.readFile ../../themes/tokyo-night.json); + preset = builtins.fromJSON (builtins.readFile ../../themes/boreal.json); defaults = preset // { fonts = { @@ -132,7 +132,7 @@ let ${toString cfg.stateFile} is a snapshot of it). The tool prints the same report with per-field fixes: `nomarchy-theme-sync validate`. Re-applying any preset resets all appearance fields: - `nomarchy-theme-sync apply tokyo-night`.''; + `nomarchy-theme-sync apply boreal`.''; # A border value is a palette key (look it up in colors) unless it's # already a literal hex; unknown keys fall through to the raw string. diff --git a/modules/nixos/options.nix b/modules/nixos/options.nix index 5f656c3..0b4ba45 100644 --- a/modules/nixos/options.nix +++ b/modules/nixos/options.nix @@ -33,7 +33,7 @@ description = '' theme-state.json for the system-side consumers (currently the Plymouth splash background). lib.mkFlake wires it automatically - from your flake; null falls back to the Tokyo Night base color. + from your flake; null falls back to the Boreal base color. ''; }; diff --git a/modules/nixos/plymouth.nix b/modules/nixos/plymouth.nix index 91fb4b1..957b50b 100644 --- a/modules/nixos/plymouth.nix +++ b/modules/nixos/plymouth.nix @@ -15,14 +15,15 @@ let then builtins.fromJSON (builtins.readFile cfg.stateFile) else { }; colorOf = key: fallback: lib.removePrefix "#" ((state.colors or { }).${key} or fallback); - base = colorOf "base" "#1a1b26"; + # Fallbacks match the distro default theme (Boreal) when stateFile is null. + base = colorOf "base" "#21272F"; # Splash elements are recolored from the palette so they read on any # base, light or dark: foreground glyphs → text, field/track boxes → # surface (raised from base in both polarities), the progress fill → # accent. The shipped art is a fixed navy that vanished on dark themes. - text = colorOf "text" "#a9b1d6"; - surface = colorOf "surface" "#32344a"; - accent = colorOf "accent" "#7aa2f7"; + text = colorOf "text" "#D3DAE0"; + surface = colorOf "surface" "#303A46"; + accent = colorOf "accent" "#B79BE8"; magick = lib.getExe' pkgs.imagemagick "magick"; # Plymouth's Window.SetBackgroundTopColor takes three floats in diff --git a/pkgs/nomarchy-theme-sync/nomarchy-theme-sync.py b/pkgs/nomarchy-theme-sync/nomarchy-theme-sync.py index 2f2a707..f4807e6 100644 --- a/pkgs/nomarchy-theme-sync/nomarchy-theme-sync.py +++ b/pkgs/nomarchy-theme-sync/nomarchy-theme-sync.py @@ -208,7 +208,7 @@ def validate_state(state) -> tuple: if not isinstance(state, dict): err("top level", "must be a JSON object", - "re-apply a preset: nomarchy-theme-sync apply tokyo-night") + "re-apply a preset: nomarchy-theme-sync apply boreal") return errors, warnings for k in state: @@ -221,7 +221,7 @@ def validate_state(state) -> tuple: ("icons", "an icon theme name (or \"\" for pick-by-mode)")): v = state.get(field) if v is not None and not isinstance(v, str): - err(field, f"must be a string ({want}), got {v!r}", 'quote it, e.g. "tokyo-night"') + err(field, f"must be a string ({want}), got {v!r}", 'quote it, e.g. "boreal"') mode = state.get("mode") if mode is not None and mode not in ("dark", "light"): diff --git a/templates/downstream/theme-state.json b/templates/downstream/theme-state.json index 635e11d..b1ce6bb 100644 --- a/templates/downstream/theme-state.json +++ b/templates/downstream/theme-state.json @@ -1,55 +1,61 @@ { "version": 1, - "name": "Tokyo Night", - "slug": "tokyo-night", + "name": "Boreal", + "slug": "boreal", "mode": "dark", "wallpaper": "", "colors": { - "base": "#1a1b26", - "mantle": "#161720", - "surface": "#32344a", - "overlay": "#444b6a", - "text": "#a9b1d6", - "subtext": "#787c99", - "muted": "#444b6a", - "accent": "#7aa2f7", - "accentAlt": "#ad8ee6", - "good": "#9ece6a", - "warn": "#e0af68", - "bad": "#f7768e" + "base": "#21272F", + "mantle": "#1A1F26", + "surface": "#303A46", + "overlay": "#404D5C", + "text": "#D3DAE0", + "subtext": "#97A3B2", + "muted": "#5E6A78", + "accent": "#B79BE8", + "accentAlt": "#86C7C0", + "good": "#A3CF88", + "warn": "#E6C384", + "bad": "#E2818A" + }, + "border": { + "active": "accent", + "inactive": "overlay" }, "ansi": [ - "#32344a", - "#f7768e", - "#9ece6a", - "#e0af68", - "#7aa2f7", - "#ad8ee6", - "#449dab", - "#787c99", - "#444b6a", - "#ff7a93", - "#b9f27c", - "#ff9e64", - "#7da6ff", - "#bb9af7", - "#0db9d7", - "#acb0d0" + "#2E3742", + "#E2818A", + "#A3CF88", + "#E6C384", + "#86A9E0", + "#B79BE8", + "#86C7C0", + "#D3DAE0", + "#5E6A78", + "#EC98A0", + "#B4DB9C", + "#EFCF98", + "#9DBBEC", + "#C6AEEF", + "#99D6CF", + "#E8EDF2" ], "fonts": { - "mono": "JetBrainsMono Nerd Font", + "mono": "GeistMono Nerd Font", "ui": "Inter", "size": 11 }, "ui": { - "gapsIn": 5, - "gapsOut": 12, - "borderSize": 2, - "rounding": 10, + "gapsIn": 6, + "gapsOut": 14, + "borderSize": 3, + "rounding": 12, + "iconSize": 44, "activeOpacity": 1.0, - "inactiveOpacity": 0.95, - "terminalOpacity": 0.96, + "inactiveOpacity": 0.93, + "terminalOpacity": 0.9, "blur": true, "shadow": true - } + }, + "settings": {} } diff --git a/theme-state.json b/theme-state.json index e6a5bdb..b1ce6bb 100644 --- a/theme-state.json +++ b/theme-state.json @@ -1,58 +1,59 @@ { "version": 1, - "name": "Tokyo Night", - "slug": "tokyo-night", + "name": "Boreal", + "slug": "boreal", "mode": "dark", "wallpaper": "", "colors": { - "base": "#1a1b26", - "mantle": "#161720", - "surface": "#32344a", - "overlay": "#444b6a", - "text": "#a9b1d6", - "subtext": "#787c99", - "muted": "#444b6a", - "accent": "#7aa2f7", - "accentAlt": "#ad8ee6", - "good": "#9ece6a", - "warn": "#e0af68", - "bad": "#f7768e" + "base": "#21272F", + "mantle": "#1A1F26", + "surface": "#303A46", + "overlay": "#404D5C", + "text": "#D3DAE0", + "subtext": "#97A3B2", + "muted": "#5E6A78", + "accent": "#B79BE8", + "accentAlt": "#86C7C0", + "good": "#A3CF88", + "warn": "#E6C384", + "bad": "#E2818A" }, "border": { "active": "accent", "inactive": "overlay" }, "ansi": [ - "#32344a", - "#f7768e", - "#9ece6a", - "#e0af68", - "#7aa2f7", - "#ad8ee6", - "#449dab", - "#787c99", - "#444b6a", - "#ff7a93", - "#b9f27c", - "#ff9e64", - "#7da6ff", - "#bb9af7", - "#0db9d7", - "#acb0d0" + "#2E3742", + "#E2818A", + "#A3CF88", + "#E6C384", + "#86A9E0", + "#B79BE8", + "#86C7C0", + "#D3DAE0", + "#5E6A78", + "#EC98A0", + "#B4DB9C", + "#EFCF98", + "#9DBBEC", + "#C6AEEF", + "#99D6CF", + "#E8EDF2" ], "fonts": { - "mono": "JetBrainsMono Nerd Font", + "mono": "GeistMono Nerd Font", "ui": "Inter", "size": 11 }, "ui": { - "gapsIn": 5, - "gapsOut": 12, - "borderSize": 2, - "rounding": 10, + "gapsIn": 6, + "gapsOut": 14, + "borderSize": 3, + "rounding": 12, + "iconSize": 44, "activeOpacity": 1.0, - "inactiveOpacity": 0.95, - "terminalOpacity": 0.96, + "inactiveOpacity": 0.93, + "terminalOpacity": 0.9, "blur": true, "shadow": true }, diff --git a/tools/theme-shot.nix b/tools/theme-shot.nix index 8d31b03..45cce38 100644 --- a/tools/theme-shot.nix +++ b/tools/theme-shot.nix @@ -17,7 +17,7 @@ let overlays = [ flake.overlays.default ]; config.allowUnfree = true; }; - slug = let s = builtins.getEnv "THEME"; in if s == "" then "tokyo-night" else s; + slug = let s = builtins.getEnv "THEME"; in if s == "" then "boreal" else s; in pkgs.testers.runNixOSTest { name = "theme-shot-${slug}";