docs(nexus): layout overhaul spec
Adds docs/specs/2026-04-11-nexus-layout-overhaul.md defining the complete layout and information architecture redesign: - 4-destination primary nav (Assistant, Studio, Projects, Settings) - 56px left icon rail + 48px top strip as global frame - Assistant as default landing (full-bleed chat, no side panels) - Studio as 8-card workshop grid (Convert folded in as 8th workshop) - Projects with per-project Builder tabs replacing global routes (Issues, Agents, Gates, Costs, Activity, Org become per-project; Routines moves to Settings; Goals folds into Overview; Inbox killed-replaced by assistant dot + cmdK) - Promote-to-project transition (chat compresses to 30%, brainstormer rises into 70%, inset shadow ripple, 700ms) - Voice and Cmd-K as global affordances; ChatPanel/PropertiesPanel killed as global rails - Implementation phases 8-16 with parallel subagent dispatch pattern Also promotes the previously untracked MIGRATION-PLAN.md into the repo, and extends it with section 8b (structural overhaul summary table linking to the spec) and section 11 (binding subagent dispatch pattern for phases 8-16). Approved 2026-04-11 in brainstorming session; all 25 decisions from the discussion are captured in spec section 11. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
22e14545d4
commit
43ca8d3047
2 changed files with 1276 additions and 0 deletions
496
MIGRATION-PLAN.md
Normal file
496
MIGRATION-PLAN.md
Normal file
|
|
@ -0,0 +1,496 @@
|
|||
# Design System Migration Plan — Nexus UI → DESIGN.md (ClickHouse-inspired)
|
||||
|
||||
Status: **DRAFT, awaiting review**. Do not touch UI files until this is approved.
|
||||
|
||||
---
|
||||
|
||||
## 1. Executive summary
|
||||
|
||||
Migrate the Nexus UI from its current Tailwind v4 + Catppuccin (Mocha/Latte) + Tokyo Night setup to the new DESIGN.md aesthetic: **pure black canvas, Neon Volt (`#faff69`) as the sole chromatic accent, Forest Green (`#166534`) as secondary CTA, Inter/Basier/Inconsolata typography, sharp geometry, border-based depth**.
|
||||
|
||||
**Scope in numbers (from codebase scan):**
|
||||
|
||||
| Category | Count | How it migrates |
|
||||
|---|---|---|
|
||||
| CSS variables in `index.css` | 29 × 3 selectors | Rewrite `@theme inline` block (single file edit) |
|
||||
| Tailwind theme-token classes (`bg-background`, `text-muted-foreground`, `border-border`, …) | ~1,250 instances | Auto-migrate when CSS vars change — zero source edits |
|
||||
| Raw palette utilities (`bg-red-500`, `text-amber-600`, …) | ~274 instances across ~60 files | Manual remap to semantic tokens — per-file work |
|
||||
| Hardcoded hex fallbacks in TSX (e.g., `#6366f1`, `#64748b`) | ~65 files | Find-and-replace with token refs |
|
||||
| Status / priority / agent-role color maps (`lib/status-colors.ts`, `lib/agent-role-colors.ts`) | ~45 definitions | Rewrite against new palette |
|
||||
| hljs syntax highlighting blocks in `index.css` | 3 theme blocks (Mocha, Tokyo, Latte) | Delete, write one block matching DESIGN.md |
|
||||
| Theme switching machinery (`ThemeContext.tsx`, `Layout.tsx` toggle) | 2 files | Simplify — drop Catppuccin/Tokyo cycle, keep light/dark binary |
|
||||
| Font loading (Inter/Basier/Inconsolata) | 0 currently | Add font-face declarations (or CDN) — new work |
|
||||
|
||||
**Effort estimate:** One careful pass, with the bulk of the mechanical work concentrated in ~3 files (`index.css`, `lib/status-colors.ts`, `lib/agent-role-colors.ts`) and a long tail in the ~60 files using raw palette utilities. The hardcoded hex cleanup is mostly in fallback expressions and is trivial once the token semantics are agreed.
|
||||
|
||||
**Key design decisions the user must make before Phase 1:**
|
||||
|
||||
1. **Light mode strategy.** DESIGN.md explicitly says "no light/white backgrounds anywhere." I've drafted a light mode anyway (Section 5), but I'd like confirmation on the direction — or explicit permission to drop light mode entirely.
|
||||
2. **Neon Volt on white is unreadable.** In light mode, volt either gets reserved for border/active states (primary chromatic accent rotates to Forest Green) or we pick a darker neon-adjacent hue. See Section 5.
|
||||
3. **Tokyo Night removal.** The `.theme-tokyo-night.dark` selector is defined in CSS but never applied by the current ThemeContext (dead code). I propose deleting it — confirm.
|
||||
4. **Font pipeline.** Inter/Basier/Inconsolata are not currently loaded. Options: Google Fonts CDN, self-hosted woff2, or `@fontsource` npm packages. I'd suggest self-hosted woff2 for LAN/offline reliability, but that's 6–10 MB of fonts in `public/`. Confirm preference.
|
||||
5. **Font weight 900 for display.** DESIGN.md calls this out as core to the identity. Current Nexus has no 96px+ display type. Adopt for hero/landing moments or skip?
|
||||
|
||||
---
|
||||
|
||||
## 2. Current state vs. DESIGN.md (side by side)
|
||||
|
||||
### Color philosophy
|
||||
|
||||
| Dimension | Current (Catppuccin Mocha) | Current (Tokyo Night) | DESIGN.md (ClickHouse) |
|
||||
|---|---|---|---|
|
||||
| Background | `#1e1e2e` (dark purple-gray) | `#1a1b26` (dark blue-gray) | `#000000` (pure black) |
|
||||
| Card | `#181825` | `#16161e` | `#141414` or transparent |
|
||||
| Primary | `#89b4fa` (blue) | `#7aa2f7` (blue) | `#faff69` (acid yellow-green) |
|
||||
| Destructive | `#f38ba8` (pink) | `#f7768e` (pink) | TBD — DESIGN.md omits red |
|
||||
| Border | `#313244` | `#24283b` | `rgba(65,65,65,0.8)` (charcoal) |
|
||||
| Accent scale | Smooth pastels | Smooth blues | Binary: volt or green, nothing else |
|
||||
| Overall vibe | Cozy, muted, rounded | Cozy, muted, rounded | Cockpit, sharp, maximum contrast |
|
||||
|
||||
### Typography
|
||||
|
||||
| Role | Current | DESIGN.md |
|
||||
|---|---|---|
|
||||
| Font family | System stack (no explicit loads — Tailwind default) | Inter + Basier + Inconsolata |
|
||||
| Display weight | Up to 700 at 24–36px | **900 at 72–96px** |
|
||||
| Body weight | 400 / 500 | 400 / 500 / 600 / 700 |
|
||||
| Labels | Mixed case | **Uppercase + 1.4px tracking** |
|
||||
| Code | Monospace (system) | Inconsolata 600 |
|
||||
|
||||
### Geometry
|
||||
|
||||
| | Current | DESIGN.md |
|
||||
|---|---|---|
|
||||
| Radius scale | `sm:2px md:4px lg:0 xl:0` (already sharpish) | Sharp 4px / comfortable 8px / pill 9999px — nothing else |
|
||||
| Border style | Solid 1px | Solid 1px, charcoal `rgba(65,65,65,0.8)` — single workhorse color |
|
||||
| Shadow | Subtle layered shadows | Border-based depth + inset "pressed" effect |
|
||||
|
||||
### Interaction
|
||||
|
||||
| | Current | DESIGN.md |
|
||||
|---|---|---|
|
||||
| Link hover | Muted highlight | **Volt (`#faff69`) — universal** |
|
||||
| Active text | Opacity change | **Pale Yellow (`#f4f692`)** |
|
||||
| Button hover | Subtle bg shift | BG shifts to `#3a3a3a`, text to volt/pale |
|
||||
|
||||
---
|
||||
|
||||
## 3. Token mapping — old vars → new vars (DARK mode)
|
||||
|
||||
The migration is primarily a rewrite of the `@theme inline` block in `/opt/nexus/ui/src/index.css`. Token **names** stay the same (so the ~1,250 Tailwind utility classes auto-migrate); only values change.
|
||||
|
||||
| Token | Current (Mocha) | New (DESIGN.md dark) | Notes |
|
||||
|---|---|---|---|
|
||||
| `--background` | `#1e1e2e` | `#000000` | Pure black, no compromise |
|
||||
| `--foreground` | `#cdd6f4` | `#ffffff` | Pure white |
|
||||
| `--card` | `#181825` | `#141414` | "Near Black" from DESIGN.md §2 |
|
||||
| `--card-foreground` | `#cdd6f4` | `#ffffff` | — |
|
||||
| `--popover` | `#181825` | `#141414` | Match card |
|
||||
| `--popover-foreground` | `#cdd6f4` | `#ffffff` | — |
|
||||
| `--primary` | `#89b4fa` (blue) | `#faff69` (**volt**) | The brand inversion — single biggest visual change |
|
||||
| `--primary-foreground` | `#1e1e2e` | `#151515` | Near-black text on volt |
|
||||
| `--secondary` | `#313244` | `#166534` (**forest**) | Secondary CTA becomes green |
|
||||
| `--secondary-foreground` | `#cdd6f4` | `#ffffff` | — |
|
||||
| `--muted` | `#313244` | `#141414` | Muted surfaces stay near-black |
|
||||
| `--muted-foreground` | `#a6adc8` | `#a0a0a0` (**silver**) | DESIGN.md §2 "Silver" |
|
||||
| `--accent` | `#45475a` | `#141414` | Accent surface = muted surface in this system |
|
||||
| `--accent-foreground` | `#cdd6f4` | `#faff69` | Text on accent surfaces lights up volt |
|
||||
| `--destructive` | `#f38ba8` (pink) | `#ef4444` (muted red) | DESIGN.md doesn't specify — I picked a restrained red that doesn't compete with volt. Confirm. |
|
||||
| `--destructive-foreground` | `#1e1e2e` | `#ffffff` | — |
|
||||
| `--border` | `#313244` | `rgba(65,65,65,0.8)` (**charcoal**) | Workhorse — DESIGN.md §2 |
|
||||
| `--input` | `#313244` | `#141414` | Input fields use near-black fill, charcoal border |
|
||||
| `--ring` | `#89b4fa` | `#faff69` | Focus ring is volt |
|
||||
| `--chart-1` | `#89b4fa` | `#faff69` | Primary chart series = volt |
|
||||
| `--chart-2` | `#a6e3a1` | `#166534` | Secondary = forest |
|
||||
| `--chart-3` | `#cba6f7` | `#a0a0a0` | Tertiary = silver |
|
||||
| `--chart-4` | `#f9e2af` | `#f4f692` (pale yellow) | Active/pressed accent |
|
||||
| `--chart-5` | `#f38ba8` | `#ef4444` | Destructive (if needed for alerts) |
|
||||
| `--sidebar` | `#181825` | `#000000` | Sidebar = pure black, no surface differentiation |
|
||||
| `--sidebar-foreground` | `#cdd6f4` | `#a0a0a0` | Secondary silver — nav items dim, active is volt |
|
||||
| `--sidebar-primary` | `#89b4fa` | `#faff69` | — |
|
||||
| `--sidebar-primary-foreground` | `#1e1e2e` | `#151515` | — |
|
||||
| `--sidebar-accent` | `#313244` | `#141414` | — |
|
||||
| `--sidebar-accent-foreground` | `#cdd6f4` | `#ffffff` | — |
|
||||
| `--sidebar-border` | `#313244` | `rgba(65,65,65,0.8)` | — |
|
||||
| `--sidebar-ring` | `#89b4fa` | `#faff69` | — |
|
||||
|
||||
**New tokens to add** (not in current system but needed for DESIGN.md fidelity):
|
||||
|
||||
| New token | Value | Purpose |
|
||||
|---|---|---|
|
||||
| `--volt` | `#faff69` | Direct brand-accent reference (for code that needs the literal brand color, e.g. logo, chart emphasis) |
|
||||
| `--volt-pale` | `#f4f692` | Active/pressed text color per DESIGN.md §2 |
|
||||
| `--volt-border` | `#4f5100` | Dark olive ghost-button borders per DESIGN.md §2 |
|
||||
| `--forest` | `#166534` | Direct secondary-CTA reference |
|
||||
| `--forest-dark` | `#14572f` | Darker forest for border variant |
|
||||
| `--near-black` | `#141414` | Button backgrounds, elevated dark surfaces |
|
||||
| `--hover-gray` | `#3a3a3a` | Button hover background |
|
||||
| `--silver` | `#a0a0a0` | Secondary/muted text |
|
||||
| `--charcoal-border` | `rgba(65,65,65,0.8)` | Signature border |
|
||||
| `--charcoal-divider` | `#343434` | Subtler division |
|
||||
|
||||
### Radius
|
||||
|
||||
DESIGN.md is strict: 4px, 8px, 9999px. Current `--radius-*` tokens are already close — audit and lock:
|
||||
|
||||
| Token | Current | New | Notes |
|
||||
|---|---|---|---|
|
||||
| `--radius-sm` | `2px` | `4px` | Bump to 4 (DESIGN.md "sharp") |
|
||||
| `--radius-md` | `4px` | `4px` | Keep |
|
||||
| `--radius-lg` | `0px` | `8px` | DESIGN.md "comfortable" for cards |
|
||||
| `--radius-xl` | `0px` | `8px` | Alias to lg; audit xl usage and collapse |
|
||||
| `--radius-full` | `9999px` | `9999px` | Pill unchanged |
|
||||
|
||||
**Audit task:** grep for `rounded-xl`, `rounded-2xl`, `rounded-3xl` — these violate the DESIGN.md scale and need to come down.
|
||||
|
||||
---
|
||||
|
||||
## 4. Typography migration
|
||||
|
||||
### Font loading
|
||||
|
||||
Currently: no explicit font loads — Tailwind falls back to system stack.
|
||||
|
||||
Proposed: self-hosted woff2 via `@font-face` in `index.css`, dropped into `ui/public/fonts/`. Rationale: LAN testing without internet; Nexus is meant to run offline-capable.
|
||||
|
||||
```css
|
||||
@font-face {
|
||||
font-family: "Inter";
|
||||
src: url("/fonts/Inter-VariableFont_slnt,wght.woff2") format("woff2-variations");
|
||||
font-weight: 100 900;
|
||||
font-display: swap;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Inconsolata";
|
||||
src: url("/fonts/Inconsolata-VariableFont_wdth,wght.woff2") format("woff2-variations");
|
||||
font-weight: 100 900;
|
||||
font-display: swap;
|
||||
}
|
||||
/* Basier: not free — likely fallback to Inter for feature headings, or purchase license */
|
||||
```
|
||||
|
||||
**Decision needed:** Basier is a paid font. Either:
|
||||
- (A) License Basier (one-time cost) — true to DESIGN.md
|
||||
- (B) Use Inter for both display and feature headings (skip Basier entirely) — simpler, free
|
||||
- (C) Sub in a free alternative (Manrope, Space Grotesk, Archivo) with similar character
|
||||
|
||||
I recommend **(B)** for the migration — DESIGN.md's Inter/Basier split is subtle and the rest of the aesthetic carries the identity. Can upgrade to real Basier later.
|
||||
|
||||
### @theme additions
|
||||
|
||||
```css
|
||||
@theme inline {
|
||||
--font-sans: "Inter", ui-sans-serif, system-ui, sans-serif;
|
||||
--font-mono: "Inconsolata", ui-monospace, "Courier New", monospace;
|
||||
--font-display: "Inter", ui-sans-serif, system-ui, sans-serif; /* weight 900 usage */
|
||||
}
|
||||
```
|
||||
|
||||
### Tracking / weights
|
||||
|
||||
Audit component library (shadcn-like `components/ui/`) for heading weights and letter-spacing. Specifically:
|
||||
- Button text: 600–700 weight
|
||||
- Section overlines: uppercase + `tracking-[0.1em]` (≈ 1.4px at 14px font)
|
||||
- Display heading: `text-6xl md:text-8xl font-black` (96px at weight 900)
|
||||
|
||||
---
|
||||
|
||||
## 5. Light mode derivation
|
||||
|
||||
DESIGN.md is dark-only by policy ("Don't use light/white backgrounds anywhere"). But the user explicitly asked for a light mode. I propose treating light mode as a **legibility alternative**, not a brand statement — it preserves accessibility without claiming design parity with the dark mode.
|
||||
|
||||
### Design principles for the light variant
|
||||
|
||||
1. **Neon Volt is downranked.** On white, `#faff69` is invisible. In light mode, volt is reserved for **border highlights and active states** — never backgrounds, never text. The primary chromatic accent rotates to **Forest Green (`#166534`)**, which DESIGN.md already treats as a primary CTA color.
|
||||
2. **Canvas is near-white, not pure white.** Pure `#ffffff` is harsh; `#fafafa` gives the eye something to hold. Matches "paper on desk" affordance.
|
||||
3. **Charcoal inverts to silver.** Border/divider workhorse becomes `rgba(20,20,20,0.12)` — faint, functional, same role.
|
||||
4. **Text hierarchy inverts.** Primary text `#0a0a0a`, secondary `#6b6b6b` (a light-mode counterpart to DESIGN.md's Silver `#a0a0a0`).
|
||||
5. **Sharp geometry stays.** Radius, fonts, weights, borders — identical. Only hue flips.
|
||||
|
||||
### Light mode token values
|
||||
|
||||
| Token | Value | Rationale |
|
||||
|---|---|---|
|
||||
| `--background` | `#fafafa` | Near-white canvas |
|
||||
| `--foreground` | `#0a0a0a` | Near-black text |
|
||||
| `--card` | `#ffffff` | Pure white cards sit above canvas |
|
||||
| `--card-foreground` | `#0a0a0a` | — |
|
||||
| `--popover` | `#ffffff` | — |
|
||||
| `--popover-foreground` | `#0a0a0a` | — |
|
||||
| `--primary` | `#166534` (**forest**) | In light mode, the CTA accent is forest green — volt is too unreadable |
|
||||
| `--primary-foreground` | `#ffffff` | White on forest |
|
||||
| `--secondary` | `#f1f5f1` | Very pale forest tint for secondary surfaces |
|
||||
| `--secondary-foreground` | `#0a0a0a` | — |
|
||||
| `--muted` | `#f4f4f5` | Pale gray for muted surfaces |
|
||||
| `--muted-foreground` | `#6b6b6b` | "Light silver" — readable but clearly subordinate |
|
||||
| `--accent` | `#fafff0` | Very faint volt tint for highlighted surfaces |
|
||||
| `--accent-foreground` | `#4f5100` | Dark olive text (volt-family) on the pale volt surface |
|
||||
| `--destructive` | `#dc2626` | Readable red on white |
|
||||
| `--destructive-foreground` | `#ffffff` | — |
|
||||
| `--border` | `rgba(20,20,20,0.12)` | Inverted charcoal — workhorse |
|
||||
| `--input` | `#ffffff` | — |
|
||||
| `--ring` | `#166534` | Focus ring matches primary (forest) |
|
||||
| `--volt` | `#4f5100` | **In light mode, `--volt` resolves to the dark olive** (DESIGN.md's "Border Olive") so any component that references it directly stays readable |
|
||||
| `--volt-pale` | `#8a8c00` | Mid-tone olive for active states |
|
||||
| `--volt-border` | `#4f5100` | Same as current DESIGN.md spec |
|
||||
| `--forest` | `#166534` | Unchanged — forest reads on both backgrounds |
|
||||
| `--forest-dark` | `#14572f` | Unchanged |
|
||||
| `--near-black` | `#0a0a0a` | Repurposed as the darkest text color |
|
||||
| `--hover-gray` | `#e4e4e7` | Light hover background |
|
||||
| `--silver` | `#6b6b6b` | Darker silver for light-mode legibility |
|
||||
| `--charcoal-border` | `rgba(20,20,20,0.12)` | Inverted |
|
||||
| `--charcoal-divider` | `rgba(20,20,20,0.08)` | Even fainter |
|
||||
| `--sidebar` | `#ffffff` | — |
|
||||
| `--sidebar-foreground` | `#6b6b6b` | Muted nav labels |
|
||||
| `--sidebar-primary` | `#166534` | Active nav = forest |
|
||||
| `--sidebar-primary-foreground` | `#ffffff` | — |
|
||||
| `--sidebar-accent` | `#f4f4f5` | Hover bg |
|
||||
| `--sidebar-accent-foreground` | `#0a0a0a` | — |
|
||||
| `--sidebar-border` | `rgba(20,20,20,0.12)` | — |
|
||||
| `--sidebar-ring` | `#166534` | — |
|
||||
|
||||
### Trade-offs of this approach
|
||||
|
||||
- **Pro:** Preserves DESIGN.md's dual-accent system (volt + forest) by promoting forest when volt can't perform.
|
||||
- **Pro:** Sharp geometry and charcoal border identity carry across modes.
|
||||
- **Con:** Light mode is objectively weaker brand-wise than dark — the neon-on-black drama is gone.
|
||||
- **Con:** Components that rely on volt as their primary affordance (e.g., "click me, I'm the CTA") look different in light mode.
|
||||
- **Con:** If Nexus is meant to be a cockpit, a light mode fundamentally undermines the atmosphere. The honest answer might be: don't ship a light mode.
|
||||
|
||||
**User decision required:** do I ship this light mode, drop light mode entirely, or iterate on the palette?
|
||||
|
||||
---
|
||||
|
||||
## 6. Raw Tailwind color utility remapping
|
||||
|
||||
The scan found **~274 instances** of raw color utilities (`bg-red-500`, `text-amber-600`, etc.) that bypass the theme-token system. These need manual remapping.
|
||||
|
||||
### Semantic categories and their new homes
|
||||
|
||||
| Use case | Current classes | New strategy |
|
||||
|---|---|---|
|
||||
| **Error / destructive** (`bg-red-*`, `text-red-*`) | 74 instances | → `bg-destructive`, `text-destructive` (theme tokens) |
|
||||
| **Warning / pending** (`bg-amber-*`, `text-amber-*`, `bg-yellow-*`) | 70 instances | → New token `--warning` (proposed: `#f59e0b` dark, `#b45309` light), then `bg-warning`, `text-warning` |
|
||||
| **Success / completed** (`bg-green-*`, `text-green-*`, `bg-emerald-*`) | 34 instances | → New token `--success` = `#166534` (matches forest); `bg-success` |
|
||||
| **Info / in-progress** (`bg-blue-*`, `text-blue-*`, `bg-cyan-*`, `bg-sky-*`) | 63 instances | → `text-muted-foreground` or a new `--info` token = `#a0a0a0` (silver) in dark mode |
|
||||
| **Role / agent hues** (violet, pink, teal, orange, indigo, rose) | ~14 instances | **These are the hardest**. In DESIGN.md's palette, everything non-volt/non-forest is neutral. Options: (a) collapse all role colors into silver/volt/forest variations, losing per-role distinction; (b) introduce a small "chart palette" of low-saturation grays and use pattern/icon differentiation instead of hue; (c) keep a small named-role palette as an exception. I lean toward **(a)** — use volt for the primary role, silver for the rest, rely on labels/icons for identity. |
|
||||
| **Status/neutral** (`bg-neutral-*`, `bg-zinc-*`, `bg-slate-*`, `bg-gray-*`) | 24 instances | → `bg-muted`, `text-muted-foreground` |
|
||||
|
||||
**Impact on `lib/status-colors.ts` and `lib/agent-role-colors.ts`:**
|
||||
|
||||
These files are the primary home for the ~100 palette mappings. They define the source-of-truth dictionaries that most raw-utility usage pulls from. Rewriting these two files gets us ~60% of the raw-utility work done.
|
||||
|
||||
I'll draft the replacement dictionaries in Phase 2 (see Section 8) — that rewrite is the single biggest file-level change in the migration.
|
||||
|
||||
---
|
||||
|
||||
## 7. File-by-file scope
|
||||
|
||||
### Must change (foundation — Phase 1)
|
||||
|
||||
| File | Lines of change | Why |
|
||||
|---|---|---|
|
||||
| `ui/src/index.css` | ~300 → ~250 (rewrite theme blocks, hljs, scrollbars) | All token values, all three theme variants → two modes, new hljs palette |
|
||||
| `ui/src/lib/status-colors.ts` | Full rewrite | ~30 status → color mappings need new palette |
|
||||
| `ui/src/lib/agent-role-colors.ts` | Full rewrite | ~15 role → color mappings |
|
||||
| `ui/src/context/ThemeContext.tsx` | Simplify | Drop `"custom"` theme type, drop Catppuccin/Tokyo cycle, keep light/dark binary |
|
||||
| `ui/src/components/Layout.tsx` | ~10 lines | Drop theme cycle map (lines 66–72), simplify toggle |
|
||||
|
||||
### Should change (sweep — Phase 2)
|
||||
|
||||
Files with raw palette utilities, ordered by instance count (high-impact first). From the scan I'd need to enumerate these precisely in the execution phase, but the top offenders are predictable:
|
||||
|
||||
- Any "status pill" / "priority badge" / "agent role avatar" component — where most of the 274 raw utilities live
|
||||
- `pages/OrgChart.tsx` — 6 hardcoded hex status colors + raw palette usage
|
||||
- `pages/Inbox.tsx` — `#64748b` fallback + raw classes
|
||||
- `pages/Routines.tsx` — `#64748b` fallback × 3
|
||||
- `pages/CompanySettings.tsx`, `pages/ContentStudio.tsx` — brand color defaults
|
||||
- `components/NewIssueDialog.tsx` — `#6366f1` project color fallback × 2
|
||||
- `components/MarkdownEditor.tsx` — `#64748b` fallback
|
||||
- `components/VoiceWaveform.tsx` — hardcoded `#89b4fa` (needs to become `var(--primary)` or `--volt`)
|
||||
- `components/ThemePreviewPanel.tsx` — 12 hardcoded hexes (this file IS the theme preview; needs full rewrite against new palette)
|
||||
- `components/ThemePaletteGrid.tsx` — Catppuccin green references
|
||||
|
||||
**Complete file list to be produced during Phase 2 execution** via a precise `rg '(bg|text|border|ring)-(red|blue|green|amber|yellow|cyan|violet|pink|slate|zinc|neutral|sky|teal|emerald|indigo|rose|orange)-' ui/src` with per-file counts.
|
||||
|
||||
### May change (audit — Phase 3)
|
||||
|
||||
- Typography usages: any `text-*xl`, `font-bold` etc. needing bump to `font-black` for display moments
|
||||
- Radius audits: `rounded-2xl`, `rounded-3xl` need to come down to `rounded-lg` (8px) or `rounded-sm` (4px)
|
||||
- Shadow audits: replace soft shadows with border-based elevation or inset "pressed" effects for active states
|
||||
|
||||
### Do NOT change
|
||||
|
||||
- `.planning/`, `doc/`, `docs/`, test fixtures, snapshots
|
||||
- `packages/branding/` — has no colors, just vocabulary
|
||||
- Test files that assert current palette (note: `ThemePreviewPanel.test.tsx` has snapshot tests that will need updating, but snapshot updates are mechanical, not design work)
|
||||
|
||||
---
|
||||
|
||||
## 8. Migration sequence
|
||||
|
||||
Ordered phases. Each phase is independently committable and reviewable.
|
||||
|
||||
### Phase 1 — Foundation (single commit)
|
||||
**What:** Rewrite `ui/src/index.css` `@theme` block and all three theme selectors. Load new fonts. Simplify `ThemeContext.tsx` + `Layout.tsx` theme cycle.
|
||||
|
||||
**Goal:** After this phase, the app's ~1,250 theme-token class usages visually switch to the new palette with zero per-file edits. Raw utilities and hardcoded hexes will still look wrong — that's Phase 2.
|
||||
|
||||
**Deliverables:**
|
||||
- New `ui/src/index.css` (rewritten theme blocks + font-face declarations)
|
||||
- Fonts in `ui/public/fonts/` (woff2 Inter + Inconsolata)
|
||||
- Simplified `ThemeContext.tsx` (binary light/dark, no Catppuccin/Tokyo)
|
||||
- Simplified `Layout.tsx` theme toggle button
|
||||
|
||||
**Verification:** load any authenticated page, visually confirm black canvas + volt accents on borders and CTAs. Expect ugly patches where raw utilities still show their old colors — that's expected at this phase.
|
||||
|
||||
### Phase 2 — Status / role color rewrite (single commit)
|
||||
**What:** Rewrite `lib/status-colors.ts` and `lib/agent-role-colors.ts` against the new palette. This cleans up ~60% of the raw-utility usage because those two files are the source of truth for most status/priority/role dictionaries.
|
||||
|
||||
**Deliverables:**
|
||||
- New color dictionaries
|
||||
- Any components that import from these files get their "wrongness" fixed automatically
|
||||
|
||||
**Verification:** inbox, org chart, agent cards all show volt/forest/silver status indicators instead of red/blue/green.
|
||||
|
||||
### Phase 3 — Raw utility sweep (one commit per logical component group)
|
||||
**What:** Per-file cleanup of the remaining raw palette utilities and hardcoded hex fallbacks. Group by feature (dashboard, org chart, inbox, settings) so each commit is reviewable.
|
||||
|
||||
**Deliverables:**
|
||||
- ~60 files touched, 274 utility instances replaced with theme tokens or new semantic tokens (`bg-warning`, `bg-success`, etc.)
|
||||
- ~65 hardcoded hex fallbacks replaced with `var(--token)` refs or `text-muted-foreground` equivalents
|
||||
|
||||
**Verification:** grep for raw palette utilities — should be zero matches (or only well-justified exceptions). Visual regression via manual QA of each touched page.
|
||||
|
||||
### Phase 4 — Typography + radius audit (single commit)
|
||||
**What:** Bump heading weights to 900 for display moments, enforce radius scale (4px/8px/9999px only), replace soft shadows with border-based depth.
|
||||
|
||||
**Deliverables:**
|
||||
- Hero/landing pages use display typography
|
||||
- `rounded-2xl`/`rounded-3xl` collapsed to `rounded-lg` or `rounded-sm`
|
||||
- Soft `shadow-md`/`shadow-lg` replaced with `border` + inset shadows for active states
|
||||
|
||||
**Verification:** visual compliance with DESIGN.md §3-§6 on representative pages.
|
||||
|
||||
### Phase 5 — ThemePreviewPanel rewrite (single commit)
|
||||
**What:** The theme preview / palette grid components currently showcase Catppuccin. They need a complete rewrite to preview the new system.
|
||||
|
||||
**Deliverables:**
|
||||
- `ThemePreviewPanel.tsx` showing new palette
|
||||
- `ThemePaletteGrid.tsx` or deprecation (if the grid no longer makes sense in a binary-mode system)
|
||||
|
||||
### Phase 6 — hljs syntax highlighting (single commit)
|
||||
**What:** Replace the three Catppuccin/Tokyo hljs rule sets in `index.css` with a single DESIGN.md-compliant rule set: neon and white on dark, terminal aesthetic per §4.
|
||||
|
||||
**Deliverables:**
|
||||
- `.hljs-*` rules rewritten in `index.css`
|
||||
- Light mode hljs variant derived
|
||||
|
||||
### Phase 7 — Visual QA pass
|
||||
**What:** Walk every top-level route, compare against DESIGN.md principles, capture screenshots for before/after, file any remaining issues. No code changes unless issues found.
|
||||
|
||||
---
|
||||
|
||||
## 8b. Structural overhaul phases (8–16) — see layout spec
|
||||
|
||||
Phases 1–7 above are a **visual repaint** of the existing structure. They do not change layout, navigation, information architecture, or what each page does.
|
||||
|
||||
A separate, larger overhaul to the layout and IA was approved 2026-04-11 and is captured in **`docs/specs/2026-04-11-nexus-layout-overhaul.md`**. That spec defines phases 8–16, summarized here:
|
||||
|
||||
| Phase | Title | Wave |
|
||||
|---|---|---|
|
||||
| 8 | Frame skeleton (56px icon rail, 48px top strip, kill ChatPanel/PropertiesPanel/sidebar) | 1 (alone, foundational) |
|
||||
| 9 | Assistant mode (full-bleed chat at `/assistant`, History/Memory slide-overs, conversational home state) | 2 (parallel) |
|
||||
| 10 | Studio mode (8-card workshop grid, fold ConvertPage in, freeform prompt) | 2 (parallel) |
|
||||
| 11 | Projects + Builder mode (hero-stat cards, 7-tab Builder strip, demote 9 global routes to per-project tabs) | 2 (parallel) |
|
||||
| 12 | Promote-to-project transition (700ms compress + rise animation with inset shadow ripple) | 3 (parallel) |
|
||||
| 13 | Settings consolidation (single-column, Skills + Routines sections, drop nested settings routes) | 3 (parallel) |
|
||||
| 14 | Voice + ⌘K globalization (mic in top header, voice queues to Assistant inbox, universal command palette) | 3 (parallel) |
|
||||
| 15 | Mobile parity (bottom tab bar, project sub-tab strip, mobile takeovers for slide-overs) | 3 (parallel) |
|
||||
| 16 | Cleanup pass (vocabulary sweep, dead-code removal, visual QA) | 4 (alone, sequential) |
|
||||
|
||||
The dispatch pattern for phases 8–16 is documented in §11 below.
|
||||
|
||||
**Phases 1–7 are independent of phases 8–16 and can ship first.** The overhaul does not block visual QA — and conversely, the visual repaint produces tokens that the overhaul phases consume. Phases 8–16 should not begin until phase 4 (typography + radius audit) is at minimum committed, because the new frame relies on the locked-in radius scale and font weights.
|
||||
|
||||
---
|
||||
|
||||
## 9. Risks and decisions
|
||||
|
||||
### Decisions required from you before Phase 1
|
||||
|
||||
1. **Light mode**: ship the derived palette (Section 5), drop it entirely, or iterate on my draft?
|
||||
2. **Basier font**: license it, use Inter everywhere, or pick a free alternative?
|
||||
3. **Destructive color**: DESIGN.md doesn't specify a red. I propose `#ef4444` (muted). Confirm or pick.
|
||||
4. **Role hue collapse vs. preserve**: for agent roles / chart series, do we accept a silver-only palette with pattern differentiation, or keep a small named-role palette as a controlled exception?
|
||||
5. **Display weight 900**: adopt for hero/landing moments, or skip the 96px Inter Black treatment?
|
||||
6. **Theme toggle UX**: if we drop Tokyo Night, is the toggle still light ↔ dark, or do we simplify further (e.g., single dark mode, light is an accessibility fallback only)?
|
||||
7. **Tokyo Night removal**: the `.theme-tokyo-night.dark` block in `index.css` is dead code (never applied by ThemeContext). Confirm I should delete it.
|
||||
|
||||
### Risks
|
||||
|
||||
- **Visual regression**: ~1,250 token-using elements will all shift on Phase 1. Expect surprise — Catppuccin is cozy and Nexus users may not be ready for cockpit-level contrast. Worth previewing on a throwaway branch.
|
||||
- **Accessibility**: volt on black (`#faff69` on `#000000`) passes WCAG AAA for normal text, but volt on white fails for anything smaller than 18pt. That's why light mode downranks volt.
|
||||
- **Chart/viz readability**: with only 5 semantic chart colors (volt, forest, silver, pale, red), multi-series visualizations get crowded. Consider using the same hue with pattern/opacity differentiation, or accepting the "chart palette" as a documented exception.
|
||||
- **Catppuccin Mocha nostalgia**: if anyone on the team is attached to the Mocha look, DESIGN.md's aesthetic is going to feel jarring. Socialize early.
|
||||
- **Component-library components** (`components/ui/*`): these are shadcn-ish primitives. They use theme tokens heavily, which is good — they'll auto-migrate. But any that hardcode radius or shadow styles need individual audit.
|
||||
- **Onboarding wizard + InviteLanding**: just-touched files using the current palette. They'll shift visually in Phase 1 — worth a dedicated visual review since they're the first thing a new user sees.
|
||||
- **Font loading flash**: adding web fonts for the first time introduces FOUT/FOIT. Use `font-display: swap` and preload the most critical weights (Inter 400, 700, 900).
|
||||
|
||||
### Out of scope (for this migration)
|
||||
|
||||
- Custom user themes (the current `"custom"` theme type is seldom used; I propose dropping it)
|
||||
- Per-company branding overrides (covered by separate `worktree-branding.ts` system — untouched)
|
||||
- Print styles
|
||||
- High-contrast accessibility mode beyond normal WCAG
|
||||
|
||||
---
|
||||
|
||||
## 10. Open questions for the user
|
||||
|
||||
Answer these and I'll kick off Phase 1:
|
||||
|
||||
1. Light mode: **ship / drop / iterate**?
|
||||
2. Fonts: **license Basier / Inter only / free alternative (name one)**?
|
||||
3. Destructive red: **`#ef4444` / other (specify)**?
|
||||
4. Role hues: **collapse to silver / keep small named palette / something else**?
|
||||
5. Display 900: **adopt / skip**?
|
||||
6. Theme toggle: **binary light/dark / dark only**?
|
||||
7. Tokyo Night dead code: **delete / keep as future option**?
|
||||
|
||||
Once answered, I'll update this file with the resolved decisions and begin Phase 1 on a separate branch.
|
||||
|
||||
---
|
||||
|
||||
## 11. Subagent dispatch pattern (binding for phases 8–16)
|
||||
|
||||
**Directive from user 2026-04-11:** structural overhaul phases (8–16) MUST be implemented by dispatching subagents in parallel for any work that does not share files. Sequential implementation is wrong for work of this size. The implementation plan derived from `docs/specs/2026-04-11-nexus-layout-overhaul.md` will spell out the dispatch waves; this section is the standing rule.
|
||||
|
||||
**Pattern:**
|
||||
|
||||
1. **Read the spec** before each wave. The spec (`docs/specs/2026-04-11-nexus-layout-overhaul.md`) is the source of truth for what to build. Don't infer from the code.
|
||||
2. **Group phases into waves** based on file overlap. Phases that touch disjoint files run in parallel. Phases that share files (or where one builds on another's output) run sequentially.
|
||||
3. **Dispatch one subagent per phase per wave**, in a single message with multiple Agent tool calls. Each subagent gets:
|
||||
- The phase number and title
|
||||
- The relevant section(s) of the spec verbatim
|
||||
- The specific files it owns (so two subagents in the same wave never touch the same file)
|
||||
- The atomic-commit requirement (one phase = one commit)
|
||||
4. **After each wave**, verify all subagents committed cleanly before dispatching the next wave. If a wave produces conflicts on any file outside its declared ownership, stop and re-plan.
|
||||
5. **Use the `superpowers:dispatching-parallel-agents` skill** for the actual dispatch. The skill enforces the message structure for parallel tool calls.
|
||||
|
||||
**Anti-patterns explicitly forbidden by the user:**
|
||||
- Doing phases 8–16 sequentially in the main session
|
||||
- Doing one phase yourself "to get started" and then dispatching the rest
|
||||
- Dispatching subagents for phases that share files (will produce merge chaos)
|
||||
- Using subagents for phase 16 cleanup (sequential by design — touches everything)
|
||||
|
||||
**Wave structure for the layout overhaul:**
|
||||
|
||||
```
|
||||
Wave 1: [ Phase 8 ] # foundational, alone
|
||||
Wave 2: [ Phase 9 | Phase 10 | Phase 11 ] # 3 subagents, parallel
|
||||
Wave 3: [ Phase 12 | Phase 13 | Phase 14 | Phase 15 ] # 4 subagents, parallel
|
||||
Wave 4: [ Phase 16 ] # sequential cleanup, alone
|
||||
```
|
||||
|
||||
This is captured here in MIGRATION-PLAN.md (rather than only in the spec) so that any future session opening this branch finds the directive even if it doesn't read the spec.
|
||||
780
docs/specs/2026-04-11-nexus-layout-overhaul.md
Normal file
780
docs/specs/2026-04-11-nexus-layout-overhaul.md
Normal file
|
|
@ -0,0 +1,780 @@
|
|||
# Nexus Layout & Information Architecture Overhaul
|
||||
|
||||
**Status:** Approved 2026-04-11 — ready for implementation planning
|
||||
**Branch:** `nexus/design-system-migration`
|
||||
**Companion docs:** `DESIGN.md` (visual language), `MIGRATION-PLAN.md` (visual migration phases 1–7 — this spec defines phases 8–16)
|
||||
|
||||
---
|
||||
|
||||
## 1. Thesis
|
||||
|
||||
**Nexus is not a SaaS dashboard with a chat panel bolted on. Nexus is a chat with a workshop attached.**
|
||||
|
||||
The current frame inverts this: a Paperclip-derived corporate dashboard occupies the center, and chat is a 380px slide-in panel on the right that competes with a `PropertiesPanel` for shared real estate. This is exactly backwards for a single-user, self-hosted personal AI tool whose tagline is "Your personal AI. That also builds things."
|
||||
|
||||
In the new frame, **the Assistant is the canvas.** Everything else — Studio, Projects, Settings — is a destination you visit and return *from*, not a peer that competes with chat for screen real estate. The Project Builder backend (issues, agents, gates, costs, activity, org) is **demoted from global navigation to per-project tabs.** You only see it when you've drilled into a specific project. There is no global "Issues" route, no global "Agents" route, no global "Costs" route — those concepts only exist scoped to a project.
|
||||
|
||||
---
|
||||
|
||||
## 2. Information architecture
|
||||
|
||||
### Primary destinations (in the global icon rail, always visible)
|
||||
|
||||
| Slot | Destination | Route | Mental model |
|
||||
|---|---|---|---|
|
||||
| 1 | **Assistant** | `/assistant` | The home screen. Voice in, voice out. The chat IS the app. |
|
||||
| 2 | **Studio** | `/studio` | Workshop selector for content generation (8 workshops). |
|
||||
| 3 | **Projects** | `/projects` | List of all projects with health stats. |
|
||||
| 4 | **Settings** | `/settings` | Workspace, Local AI, Cloud, Voice, Skills, Routines, Telegram, About. |
|
||||
|
||||
Four destinations. Period. No "Dashboard", no "Inbox", no "Recipes" slot, no "add company" button.
|
||||
|
||||
### Secondary destinations (only inside Project Detail)
|
||||
|
||||
When you drill into `/projects/:id`, you enter **Builder mode** and a project tab strip appears under the header:
|
||||
|
||||
`OVERVIEW · ISSUES · AGENTS · GATES · COSTS · ACTIVITY · ORG`
|
||||
|
||||
These are scoped to one project. They are not addressable globally. Routes: `/projects/:id/overview`, `/projects/:id/issues`, etc.
|
||||
|
||||
### Tertiary surfaces (live inside Settings)
|
||||
|
||||
- **Skills** — Skill Aggregator browse/install/assign UI
|
||||
- **Routines** — workspace-level cron jobs (currently a top-level route, demoted)
|
||||
- **Telegram bridge** — config, not nav
|
||||
- **Cloud providers / API keys** — config
|
||||
- **Voice** — STT/TTS config
|
||||
|
||||
### Killed (removed from the app entirely)
|
||||
|
||||
| What | Why |
|
||||
|---|---|
|
||||
| Company switcher / "add company" / "manage companies" / multi-tenant UI | Nexus is single-workspace by design |
|
||||
| Global Dashboard route as landing page | Assistant is the landing page; the dashboard concept becomes the Assistant's conversational greeting |
|
||||
| Global Issues / Agents / Approvals / Costs / Activity / Inbox / Org / Goals routes | Demoted to per-project tabs (or fold into Overview) |
|
||||
| Global Routines route | Moved to Settings (cron jobs are workspace config, not a workflow) |
|
||||
| `ChatPanel.tsx` as a slide-in right rail | Killed entirely; chat becomes the Assistant route |
|
||||
| `PropertiesPanel` as a standing right-rail fixture | Pages that need it render it inline themselves |
|
||||
| 280px left sidebar with company switcher / sidebar projects / sidebar agents | Replaced by 56px icon rail |
|
||||
| `MobileBottomNav` (company-aware) | Replaced by 4-icon bottom bar matching the desktop rail |
|
||||
| Theme cycle button (Catppuccin/Tokyo/etc.) | Binary light/dark only, configured in Settings, no toggle in chrome |
|
||||
| `ConvertPage` as a top-level route | Folds into Studio as the 8th workshop |
|
||||
| `InboxRootRedirect`, `LegacySettingsRedirect`, `OnboardingRoutePage` URL machinery | Simpler routing |
|
||||
| `PluginPage` as a top-level route slot | Plugin pages render inside Settings or inside a project |
|
||||
| Any UI string containing "company", "companies", "tenant", "workspace member" | Vocabulary cleanup; replace with "workspace" or remove |
|
||||
|
||||
---
|
||||
|
||||
## 3. Visual language (DESIGN.md inheritance)
|
||||
|
||||
The overhaul does **not** introduce a new visual language. It uses DESIGN.md verbatim. Recap of the binding rules for this spec:
|
||||
|
||||
- **Canvas:** pure black `#000000`. No surface differentiation between rail/header/canvas — they all bleed into the same black.
|
||||
- **Sole chromatic accent:** Neon Volt `#faff69`. Used for active states, borders on selected items, hover targets, hero performance numbers, link hover. Never as a fill background outside CTA buttons.
|
||||
- **Secondary CTA:** Forest Green `#166534` for "Create project", "New", "Run" buttons.
|
||||
- **Pressed/active text:** Pale Yellow `#f4f692`.
|
||||
- **Workhorse border:** Charcoal `rgba(65,65,65,0.8)`. The single border color for cards, dividers, inputs.
|
||||
- **Typography:** Inter (variable, weight 400–900). Inconsolata for code/numbers. **Inter Black 900** for hero performance numbers (project %, milestone count). Uppercase + 1.4px tracking for section labels and breadcrumbs.
|
||||
- **Radius scale:** 4px (sharp), 8px (comfortable), 9999px (pill). Nothing else.
|
||||
- **Depth:** border-based, not shadow-based. Inset shadow Level 4 for "pressed into the surface" active states. Volt border highlight (Level 5) for featured/selected.
|
||||
- **Mode:** dark default. Light mode is an accessibility alternative per MIGRATION-PLAN.md §5; this spec assumes dark mode for all wireframes.
|
||||
|
||||
Anything in this spec that conflicts with DESIGN.md, **DESIGN.md wins.** Update this spec, not DESIGN.md.
|
||||
|
||||
---
|
||||
|
||||
## 4. Global frame
|
||||
|
||||
Constant chrome that appears on every page. Two pieces: left icon rail and top strip.
|
||||
|
||||
### 4.1 Left icon rail
|
||||
|
||||
```
|
||||
┌──┐
|
||||
│ │ ← 8px top padding
|
||||
│ ⬢│ ← Nexus mark (volt), 24×24, click → Assistant
|
||||
│ │
|
||||
│ ◆│ ← MessageCircle (Lucide) — Assistant
|
||||
│ │
|
||||
│ ▲│ ← Sparkles (Lucide) — Studio
|
||||
│ │
|
||||
│ ◇│ ← FolderKanban (Lucide) — Projects
|
||||
│ │
|
||||
│ │ ← (gap, flex-1)
|
||||
│ │
|
||||
│ ⚙│ ← Settings (Lucide) — Settings
|
||||
│ │ ← 8px bottom padding
|
||||
└──┘
|
||||
56px wide, 100vh tall, pure black background, no border
|
||||
```
|
||||
|
||||
**Specs:**
|
||||
- **Width:** 56px, locked. No collapse, no expand, no hover-grow.
|
||||
- **Background:** `#000000`, no border, no shadow.
|
||||
- **Position:** `position: fixed; left: 0; top: 0; bottom: 0;` — independent of page scroll.
|
||||
- **Icons:** Lucide icons at 20×20. Default state: silver `#a0a0a0`, stroke 1.5. Hover: volt `#faff69`. Active (current route): volt + 2px volt vertical bar on the right edge of the rail aligned with the icon. **Never a fill background behind the icon** — DESIGN.md forbids volt as background.
|
||||
- **Tooltips:** on hover, render a tooltip 12px to the right of the rail with the destination name in uppercase, 11px Inter 600, 1.4px tracking, silver text on near-black `#141414` with a 1px charcoal border. Sharp 4px radius. Delay 300ms.
|
||||
- **Click:** navigates immediately. No transitions on the rail itself; the canvas content fades.
|
||||
- **Nexus mark at top:** small geometric logo in volt. Click → `/assistant`. This is the only volt-filled element in the rail.
|
||||
- **Settings pinned at bottom:** flex layout (`flex-direction: column`, `Settings` slot has `margin-top: auto`).
|
||||
|
||||
**Accessibility:**
|
||||
- `<nav aria-label="Primary">` with each icon as `<a>` element.
|
||||
- Each link has `aria-label` matching the tooltip text.
|
||||
- `aria-current="page"` on the active link.
|
||||
- Focus ring uses volt at 2px offset.
|
||||
|
||||
### 4.2 Top strip
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────────────────────────┐
|
||||
│ ASSISTANT ⌘K ◉ MIC │
|
||||
└──────────────────────────────────────────────────────────────────┘
|
||||
▲ ▲ ▲
|
||||
│ │ │
|
||||
mode label search voice
|
||||
```
|
||||
|
||||
**Specs:**
|
||||
- **Height:** 48px. **Background:** `#000000`, **bottom border:** 1px charcoal.
|
||||
- **Position:** `position: sticky; top: 0;` within the canvas column (not over the rail).
|
||||
- **Left:** mode label / breadcrumb. Inter 600, 14px, uppercase, 1.4px tracking. Silver for non-active segments, volt for the leaf segment (current location). Slash-separated when nested: `PROJECTS / NEXUS-DESIGN-MIGRATION`. Click any non-leaf segment to navigate up.
|
||||
- **Right cluster (right-aligned, 16px gap):**
|
||||
- **⌘K** — palette trigger button. Renders the kbd glyph in Inconsolata 12px, charcoal background, pale silver border, 4px radius. Click or `Cmd+K` opens the global command palette.
|
||||
- **◉ MIC** — global voice mic button. 32×32 round button (8px radius — *not* pill, per DESIGN.md "no pill except for toggles"). States:
|
||||
- **Idle:** forest green dot (8×8) centered. No animation.
|
||||
- **Listening:** volt fill, 1.5s pulse loop, expanding volt ring at 60% opacity.
|
||||
- **Speaking** (TTS playback): silver fill, no pulse.
|
||||
- Tap-to-talk from any page. See §5.5 for what voice does in each mode.
|
||||
- **No theme toggle, no notifications icon, no user avatar, no sleep button.** Single-user self-hosted; these are all noise.
|
||||
|
||||
### 4.3 The "killed" right rail
|
||||
|
||||
The current `ChatPanel.tsx` (380px slide-in chat) and `PropertiesPanel` (slide-in property inspector) **do not exist as global elements** in the new frame. There is no right rail in the chrome. Pages that need contextual side content render it inline within their own layout (e.g., `IssueDetail` may render an issue-properties column at >1280px; that's a page-level decision, not chrome).
|
||||
|
||||
---
|
||||
|
||||
## 5. Mode 1 — Assistant (`/assistant`)
|
||||
|
||||
The default landing screen and the gravitational center of the app.
|
||||
|
||||
### 5.1 Layout
|
||||
|
||||
```
|
||||
┌──┬───────────────────────────────────────────────────────────────┐
|
||||
│ │ ASSISTANT ⌘K ◉ MIC │
|
||||
│ │───────────────────────────────────────────────────────────────│
|
||||
│ │ │
|
||||
│ ⬢│ │
|
||||
│ │ TODAY · 10:42 │
|
||||
│ ◆│ ───────────────── │
|
||||
│ │ │
|
||||
│ ▲│ ┌──────────────────────────────────────────┐ │
|
||||
│ │ │ user message bubble (right-aligned) │ │
|
||||
│ ◇│ └──────────────────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ │ ┌──────────────────────────────────────────────┐ │
|
||||
│ │ │ assistant message bubble (left-aligned) │ │
|
||||
│ │ └──────────────────────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ ⚙│ ╭────────────────────────────────────────────────────────╮ │
|
||||
│ │ │ ░░ ▆▆ ▂▂ ░░ voice waveform │ │
|
||||
│ │ ├────────────────────────────────────────────────────────┤ │
|
||||
│ │ │ Type a message or hold space to talk… ↗ ◉ │ │
|
||||
│ │ ╰────────────────────────────────────────────────────────╯ │
|
||||
│ │ │
|
||||
│ │ ⊕ Promote to project 📎 Attach 🧠 Memory 📁 History │
|
||||
└──┴───────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 5.2 Components
|
||||
|
||||
| Component | Purpose | Implementation note |
|
||||
|---|---|---|
|
||||
| **Conversation thread** | Full-bleed, no inner scroll columns. Max-width 760px centered in canvas. Messages alternate left/right with 16px gap. | Reuses message-rendering primitives from `ChatMessageList.tsx` but in a new container layout. |
|
||||
| **Day pip** | `TODAY · 10:42` between message groups. Inter 500, 11px, 1.4px tracking, silver. | Render between message clusters when day or hour changes. |
|
||||
| **Voice waveform** | Always visible above text input. Idle = flat baseline. Listening = volt bars. | Reuses `VoiceWaveform.tsx`; lift it from inside ChatPanel into the Assistant page. |
|
||||
| **Text input** | Below waveform, same surface, hairline divider between. Sharp 8px radius, charcoal border, near-black `#141414` fill, generous 24px vertical padding. | New component `AssistantInputBar.tsx`. |
|
||||
| **Send / mic inline button** | Right edge of input row. Mirrors the global mic in state. | Shared mic state via existing voice context. |
|
||||
| **Action strip** | Below input bar. 4 contextual actions in an 8px-gap row. | New component. See below. |
|
||||
|
||||
### 5.3 The action strip
|
||||
|
||||
| Action | Visibility | Behavior |
|
||||
|---|---|---|
|
||||
| **⊕ Promote to project** | Only when the active conversation is brainstormable (existing brainstormer pattern decides eligibility) | Triggers the promote-to-project transition (§5.6). Volt outline button. |
|
||||
| **📎 Attach** | Always | File picker. Reuses existing upload backend. |
|
||||
| **🧠 Memory** | Always | Opens memory slide-over from the right (340px wide). Shows what the assistant remembers about you, editable. |
|
||||
| **📁 History** | Always | Opens conversation list slide-over from the **left** (320px wide), butted against the icon rail. Lists conversations grouped by today/yesterday/this-week/older. |
|
||||
|
||||
The 160px conversation-list column inside the current ChatPanel **moves to the History slide-over.** No persistent column eats horizontal space.
|
||||
|
||||
### 5.4 The conversational home state
|
||||
|
||||
When you open Assistant with **no active conversation**, you do not see an empty thread. You see a status greeting from the assistant itself:
|
||||
|
||||
```
|
||||
|
||||
┌──────────────────────────────────────────────────────────┐
|
||||
│ Good morning, Mikkel. │
|
||||
│ │
|
||||
│ Since we last talked: │
|
||||
│ • nexus-design-migration: 4 commits, Phase 4 ready │
|
||||
│ • personal-finance-dashboard: idle 3 days │
|
||||
│ • 1 gate awaiting approval (nexus, Phase 4 audit) │
|
||||
│ │
|
||||
│ What do you want to do? │
|
||||
└──────────────────────────────────────────────────────────┘
|
||||
|
||||
[voice waveform + input bar]
|
||||
```
|
||||
|
||||
This **replaces the global Dashboard.** The dashboard is a conversational greeting from your assistant, not a grid of widgets. The data behind it (active agents, pending gates, recent completions, stale projects) comes from the same backend that the old Dashboard route used; the rendering is a single assistant message instead of a layout of cards.
|
||||
|
||||
**Implementation:** the home greeting is a synthesized assistant turn that the server generates on Assistant page load when no active conversation is selected. It's not a real chat message stored in the DB — it's a transient render.
|
||||
|
||||
### 5.5 Voice from anywhere
|
||||
|
||||
The mic in the top header is **global.** Tap it from any mode. Voice goes to the **Assistant inbox**, queued for next time you open Assistant.
|
||||
|
||||
- **In Assistant mode:** voice becomes a chat message in the active conversation (existing v1.6 behavior).
|
||||
- **In Studio / Projects / Settings:** voice is captured and held as a pending Assistant message. A small volt indicator dot appears on the Assistant icon in the rail, indicating "you have queued voice waiting." Click Assistant → the queued voice is appended as the next user message and the assistant responds.
|
||||
|
||||
We deliberately do **not** parse voice as UI commands ("close issue 42") in this spec. Single inbox path; simpler; no failure modes around mode-specific intent parsing. If we ever want command-mode voice, that's a separate feature behind an explicit toggle.
|
||||
|
||||
### 5.6 The promote-to-project transition
|
||||
|
||||
The most important visual moment in the app. This is when a chat becomes a project.
|
||||
|
||||
**Trigger:** user clicks `⊕ Promote to project` in the action strip.
|
||||
|
||||
**Animation sequence (700ms total):**
|
||||
|
||||
1. **0–200ms:** the conversation thread compresses from 100% canvas height to a 30% ribbon at the top. Easing: cubic-bezier(0.22, 1, 0.36, 1). Inset shadow Level 4 (DESIGN.md "pressed") fades in along the bottom edge of the compressed thread.
|
||||
2. **200–500ms:** the brainstormer panel rises from the bottom of the canvas, occupying the bottom 70%. It contains the brainstormer flow: goal, acceptance criteria, gates, agent assignments (PM auto-assigned, Engineer template selected from skill aggregator).
|
||||
3. **500–700ms:** a small `SOURCE CONVERSATION` label fades in above the compressed thread.
|
||||
|
||||
```
|
||||
BEFORE AFTER (animation complete)
|
||||
┌──────────────────────────┐ ┌──────────────────────────┐
|
||||
│ ASSISTANT │ │ ASSISTANT │
|
||||
│──────────────────────────│ │──────────────────────────│
|
||||
│ │ │ SOURCE CONVERSATION │
|
||||
│ full chat thread │ │ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ │
|
||||
│ │ │ ▓ chat thread (30% ht) │
|
||||
│ │ ───► │ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ │
|
||||
│ │ │──────────────────────────│
|
||||
│ │ │ BRAINSTORMER │
|
||||
│ ┌─────────────────────┐ │ │ ────────── │
|
||||
│ │ input + ⊕ promote │ │ │ Goal: ____________ │
|
||||
│ └─────────────────────┘ │ │ Acceptance: _________ │
|
||||
│ │ │ [ Create project ] │
|
||||
└──────────────────────────┘ └──────────────────────────┘
|
||||
```
|
||||
|
||||
**On `Create project`:**
|
||||
- A new project row is created (existing project create endpoint).
|
||||
- The brainstormer panel collapses.
|
||||
- The compressed chat thread restores to full height.
|
||||
- A small permanent banner at the top of the chat reads `→ Project: NEXUS-DESIGN-MIGRATION` (link to project detail).
|
||||
- The user is **not** auto-navigated to the project. They stay in Assistant. The project appears in the Projects list and is also linked from the chat itself.
|
||||
|
||||
### 5.7 Origin chat preservation
|
||||
|
||||
The chat that births a project is **preserved as a living conversation,** not frozen as a spec snapshot. Decisions:
|
||||
|
||||
- The chat stays editable and continuable after promotion.
|
||||
- The chat is permanently linked to the project (small banner at the top of the chat: `→ Project: PROJECT-NAME`).
|
||||
- The project's `OVERVIEW` tab has an `ORIGIN CHAT` card linking back to the conversation.
|
||||
- New messages added to the chat after promotion **do not** automatically modify the project. The chat is the assistant's relationship; the project is the implementation contract.
|
||||
- If the user wants to update the project from a later chat message, they explicitly use a `→ Update project` action (out of scope for this spec; a future affordance).
|
||||
|
||||
---
|
||||
|
||||
## 6. Mode 2 — Studio (`/studio`)
|
||||
|
||||
Workshop selector for content generation. Replaces the current 7-tab `ContentStudio.tsx` and folds in `ConvertPage`.
|
||||
|
||||
### 6.1 Layout
|
||||
|
||||
```
|
||||
┌──┬───────────────────────────────────────────────────────────────┐
|
||||
│ │ STUDIO ⌘K ◉ MIC │
|
||||
│ │───────────────────────────────────────────────────────────────│
|
||||
│ │ │
|
||||
│ ⬢│ STUDIO │
|
||||
│ │ ─ ─ ─ ─ ─ │
|
||||
│ ◆│ Eight workshops. Pick one or describe what you need. │
|
||||
│ │ │
|
||||
│ ▲│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
||||
│ │ │ DIAGRAMS │ │ ICONS │ │ THEMES │ │
|
||||
│ ◇│ │ Mermaid → │ │ SVG sets │ │ Color → full │ │
|
||||
│ │ │ rendered │ │ │ │ palette │ │
|
||||
│ │ └──────────────┘ └──────────────┘ └──────────────┘ │
|
||||
│ │ │
|
||||
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
||||
│ ⚙│ │ WALLPAPERS │ │ DOCUMENTS │ │ BRAND KITS │ │
|
||||
│ │ └──────────────┘ └──────────────┘ └──────────────┘ │
|
||||
│ │ │
|
||||
│ │ ┌──────────────┐ ┌──────────────┐ │
|
||||
│ │ │ SOCIAL │ │ CONVERT │ │
|
||||
│ │ └──────────────┘ └──────────────┘ │
|
||||
│ │ │
|
||||
│ │ ───────── │
|
||||
│ │ Or just describe it: "I need a 1920×1080 wallpaper of …" ↗ │
|
||||
└──┴───────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 6.2 Workshop card spec
|
||||
|
||||
- **Layout:** 3-column grid on `>= 1024px`, 2-column on `>= 640px`, 1-column below.
|
||||
- **Card:** 1px charcoal border, 8px radius, transparent fill (canvas black shows through), 24px padding.
|
||||
- **Hover:** background fades to near-black `#141414` over 120ms, border stays charcoal, no transform.
|
||||
- **Title:** Inter 700, 24px, uppercase. Pure white.
|
||||
- **Subtitle:** Inter 400, 14px, silver, single line.
|
||||
- **Icon glyph:** Lucide icon at 32×32 in volt, top-right of card.
|
||||
- **Click:** navigates to `/studio/{workshop-slug}`.
|
||||
|
||||
### 6.3 Eight workshops
|
||||
|
||||
| Slug | Title | Source | Notes |
|
||||
|---|---|---|---|
|
||||
| `diagrams` | DIAGRAMS | Existing diagram-renderer | Mermaid → rendered SVG/PNG |
|
||||
| `icons` | ICONS | Existing icon generator | SVG from description |
|
||||
| `themes` | THEMES | Existing theme generator | Color → full theme with WCAG AA, exports |
|
||||
| `wallpapers` | WALLPAPERS | Existing wallpaper-renderer | Desktop, mobile, social banners |
|
||||
| `documents` | DOCUMENTS | Existing pdf-renderer | PDF reports, invoices, one-pagers |
|
||||
| `brand-kits` | BRAND KITS | Existing brand-renderer | Full brand identity |
|
||||
| `social` | SOCIAL | Existing social generator | Platform-ready posts, carousels |
|
||||
| `convert` | CONVERT | `ConvertPage.tsx` | File format conversion (folded in from `/convert`) |
|
||||
|
||||
**Recipes (v1.8) is not a workshop.** Recipes are intelligence embedded into Assistant suggestions, not a separate generation surface (see §10.2).
|
||||
|
||||
### 6.4 Workshop detail view
|
||||
|
||||
Each workshop, when opened, takes the user into a focused workspace:
|
||||
|
||||
- **Mode label:** `STUDIO / DIAGRAMS`
|
||||
- **Layout:** two-column on desktop. Left column = parameters/prompt input. Right column = live preview.
|
||||
- **Action bar:** bottom of right column. `[Save] [Export] [Send to Assistant]`.
|
||||
- The "Send to Assistant" action queues the generated artifact as an attachment for the next Assistant message — closes the loop between Studio and Assistant.
|
||||
|
||||
### 6.5 Studio freeform prompt
|
||||
|
||||
Bottom of the workshop selector page: a freeform text input that routes to the right workshop based on intent ("I need a 1920×1080 wallpaper of …" → opens Wallpapers workshop with that prompt pre-filled). The routing is a small classifier that maps intent to workshop slug. If routing fails, the prompt becomes an Assistant message.
|
||||
|
||||
---
|
||||
|
||||
## 7. Mode 3 — Projects + Builder mode
|
||||
|
||||
### 7.1 Projects list (`/projects`)
|
||||
|
||||
```
|
||||
┌──┬───────────────────────────────────────────────────────────────┐
|
||||
│ │ PROJECTS ⌘K ◉ MIC │
|
||||
│ │───────────────────────────────────────────────────────────────│
|
||||
│ │ │
|
||||
│ ⬢│ PROJECTS ⊕ NEW PROJECT (forest) │
|
||||
│ │ ─ ─ ─ ─ ─ │
|
||||
│ ◆│ │
|
||||
│ │ ┌─────────────────────────────────────────────────────────┐ │
|
||||
│ ▲│ │ NEXUS-DESIGN-MIGRATION ● 4 agents active │ │
|
||||
│ │ │ ──────────────────────────── │ │
|
||||
│ ◇│ │ 47% Phase 3 of 7 · Next gate: Phase 4 audit │ │
|
||||
│ │ │ ▓▓▓▓▓░░░░░ │ │
|
||||
│ │ │ $14.20 burned · last activity 8m ago │ │
|
||||
│ ⚙│ └─────────────────────────────────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ │ ┌─────────────────────────────────────────────────────────┐ │
|
||||
│ │ │ PERSONAL-FINANCE-DASHBOARD ◉ idle │ │
|
||||
│ │ │ ... │ │
|
||||
│ │ └─────────────────────────────────────────────────────────┘ │
|
||||
└──┴───────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Project card:**
|
||||
|
||||
- **Layout:** full-width on `< 1024px`, 2-up on `>= 1024px`. Stack vertically with 16px gap.
|
||||
- **Card:** 1px charcoal border, 8px radius, transparent fill.
|
||||
- **Title row:** project slug (uppercase) in Inter 700 16px white. Status dot on the right (forest = idle, volt pulse = working, pale yellow = waiting on gate).
|
||||
- **Hero stat:** percentage in **Inter Black 900, 72px, volt.** This is the "performance stat" from DESIGN.md §4 — the visual proof that something is happening. Format: `47%` with no extra label.
|
||||
- **Sub-line:** `Phase 3 of 7 · Next gate: Phase 4 audit` — Inter 500, 14px, silver.
|
||||
- **Progress bar:** 8px tall, charcoal track, volt fill. Sharp 4px corners, no pill.
|
||||
- **Footer line:** `$14.20 burned · last activity 8m ago` — Inter 400, 12px, silver.
|
||||
- **Click:** navigates to `/projects/{slug}/overview`.
|
||||
|
||||
**No table view, no filters, no sort dropdowns.** Search and filter live in ⌘K (`active projects`, `projects with pending gates`, etc.).
|
||||
|
||||
**New project button:** top-right corner, Forest Green per DESIGN.md secondary CTA. Click → opens an empty brainstormer panel inline (same component as the promote-to-project transition, but starting from a blank thread).
|
||||
|
||||
**Empty state:** if no projects exist, the canvas shows a single full-bleed message — `NO PROJECTS YET` in Inter Black 900 96px volt, with a `⊕ START YOUR FIRST PROJECT` Forest Green CTA below.
|
||||
|
||||
### 7.2 Project Detail (`/projects/:slug/...`) — Builder mode
|
||||
|
||||
The header changes when you enter a project:
|
||||
|
||||
- **Mode label** becomes `PROJECTS / PROJECT-NAME` (slash-separated breadcrumb, last segment in volt)
|
||||
- **Project tab strip** appears directly under the header, height 40px, charcoal bottom border:
|
||||
|
||||
```
|
||||
OVERVIEW · ISSUES · AGENTS · GATES · COSTS · ACTIVITY · ORG
|
||||
─────────
|
||||
```
|
||||
|
||||
- Tabs: uppercase, 1.4px tracking, Inter 600 14px, silver default. Active tab: volt text + 2px volt underline. Hover: text shifts to volt.
|
||||
- 24px gap between tabs, 24px left padding to align with mode label.
|
||||
- The tab strip is sticky below the header strip (`position: sticky; top: 48px;`).
|
||||
|
||||
#### 7.2.1 OVERVIEW (default tab)
|
||||
|
||||
```
|
||||
NEXUS-DESIGN-MIGRATION
|
||||
─ ─ ─ ─ ─
|
||||
|
||||
47% 4 AGENTS ACTIVE
|
||||
─── ────────────────
|
||||
72px Inter Black volt Inter 700 14px silver
|
||||
|
||||
┌──────────────────────────────────────────────────────┐
|
||||
│ Current milestone: Phase 4 — typography & radius │
|
||||
│ ───────────────── │
|
||||
│ • [✓] DESIGN.md drafted │
|
||||
│ • [✓] MIGRATION-PLAN.md approved │
|
||||
│ • [✓] Phase 1 — foundation │
|
||||
│ • [✓] Phase 2 — status colors │
|
||||
│ • [✓] Phase 3 — raw utility sweep │
|
||||
│ • [○] Phase 4 — typography + radius ← NEXT GATE │
|
||||
│ • [ ] Phase 5 — theme preview rewrite │
|
||||
│ • [ ] Phase 6 — hljs │
|
||||
│ • [ ] Phase 7 — visual QA │
|
||||
└──────────────────────────────────────────────────────┘
|
||||
|
||||
┌──────────────────┐ ┌──────────────────┐
|
||||
│ ORIGIN CHAT │ │ ACTIVITY (LAST 24H) │
|
||||
│ "Don't just │ │ • 14 commits │
|
||||
│ redesign the │ │ • 3 issues closed │
|
||||
│ right rail …" │ │ • 1 gate awaiting │
|
||||
│ → Open chat │ │ • $4.60 burned │
|
||||
└──────────────────┘ └──────────────────┘
|
||||
```
|
||||
|
||||
- **Hero stat row:** percentage at 72px Inter Black volt + agents-active counter at 14px silver. Two columns. The percent is the visual focal point of the page.
|
||||
- **Milestone checklist card:** the project's milestones as a checklist. Charcoal border, 8px radius, 24px padding. Title in Inter 700 16px uppercase. Items in Inter 500 14px white (completed) or silver (pending). The next gate marker uses pale yellow `#f4f692` for the bullet and a `← NEXT GATE` label.
|
||||
- **Origin chat card:** small card that links back to the conversation that birthed this project. First line of the conversation is rendered as a quote.
|
||||
- **Activity card:** rolling 24h activity feed. Reuses the global `Activity` page data, scoped to this project.
|
||||
|
||||
#### 7.2.2 ISSUES tab
|
||||
|
||||
Project-scoped issue list. Reuses the existing `IssuesList` component but **dropping the company filter** (single workspace) and **scoping by project ID.** No global "Issues" route.
|
||||
|
||||
#### 7.2.3 AGENTS tab
|
||||
|
||||
Project-scoped agent list. Shows agents assigned to this project, their roles (PM, Engineer, Generalist), status (idle/working/blocked), and current task. Reuses existing agent components but scoped.
|
||||
|
||||
#### 7.2.4 GATES tab
|
||||
|
||||
Renamed from "Approvals" to "Gates" because it matches the brainstormer/pipeline mental model (each project has gates that the user approves to advance). Shows all pending and historical gate approvals for this project.
|
||||
|
||||
#### 7.2.5 COSTS tab
|
||||
|
||||
Project-scoped cost burn. Agent-by-agent breakdown. Reuses cost-tracking backend.
|
||||
|
||||
#### 7.2.6 ACTIVITY tab
|
||||
|
||||
Full activity feed for this project. The 24h preview on Overview is a slice of this.
|
||||
|
||||
#### 7.2.7 ORG tab
|
||||
|
||||
Project-specific org chart (which agents report to which, who handles what). Shown as a tab only for projects with multi-agent orchestration; hidden for single-agent projects.
|
||||
|
||||
### 7.3 What's NOT in Builder mode
|
||||
|
||||
| Removed surface | Where it goes |
|
||||
|---|---|
|
||||
| Routines | Settings → Routines section |
|
||||
| Goals | Folded into the milestone checklist on Overview |
|
||||
| Inbox | ⌘K + the global Assistant icon dot indicator |
|
||||
| Approvals (as global) | Becomes per-project Gates tab |
|
||||
| Dashboard | Becomes Assistant conversational greeting |
|
||||
|
||||
---
|
||||
|
||||
## 8. Mode 4 — Settings (`/settings`)
|
||||
|
||||
### 8.1 Layout
|
||||
|
||||
Single-column scroll, no nested settings sub-routes. The current Paperclip nested settings tree (`/instance/settings/general`, `/instance/settings/integrations`, etc.) collapses into one scrollable page with cards.
|
||||
|
||||
```
|
||||
SETTINGS
|
||||
─ ─ ─ ─ ─
|
||||
|
||||
┌──────────────────────────────────────────────────────┐
|
||||
│ WORKSPACE │
|
||||
│ ───────── │
|
||||
│ Root directory /home/mikkel/nexus [edit] │
|
||||
│ Theme ● dark ○ light │
|
||||
│ Re-run onboarding [open wizard] │
|
||||
└──────────────────────────────────────────────────────┘
|
||||
|
||||
┌──────────────────────────────────────────────────────┐
|
||||
│ LOCAL AI │
|
||||
│ ───────── │
|
||||
│ Hermes provider qwen-coder:32b (28GB VRAM) │
|
||||
│ Whisper STT base.en (140MB) ▼ │
|
||||
│ Piper TTS voice en_US-hfc_female-medium ▼ │
|
||||
└──────────────────────────────────────────────────────┘
|
||||
|
||||
┌──────────────────────────────────────────────────────┐
|
||||
│ CLOUD PROVIDERS │
|
||||
│ ──────────────── │
|
||||
│ Anthropic API key ●●●●●●●●●● (set) │
|
||||
│ OpenAI API key (not set) │
|
||||
│ Puter.js (zero-config, enabled) │
|
||||
└──────────────────────────────────────────────────────┘
|
||||
|
||||
┌──────────────────────────────────────────────────────┐
|
||||
│ SKILLS │
|
||||
│ ────── │
|
||||
│ [browse] [installed: 12] [groups: 4] │
|
||||
│ ...skill aggregator UI... │
|
||||
└──────────────────────────────────────────────────────┘
|
||||
|
||||
┌──────────────────────────────────────────────────────┐
|
||||
│ ROUTINES │
|
||||
│ ──────── │
|
||||
│ Daily summary every 09:00 [edit] [pause] │
|
||||
│ Cost report every Mon 08:00 │
|
||||
│ + add routine │
|
||||
└──────────────────────────────────────────────────────┘
|
||||
|
||||
┌──────────────────────────────────────────────────────┐
|
||||
│ TELEGRAM BRIDGE │
|
||||
│ ──────────────── │
|
||||
│ Bot token ●●●●●●●●●● │
|
||||
│ Allowed chat IDs [list] │
|
||||
└──────────────────────────────────────────────────────┘
|
||||
|
||||
┌──────────────────────────────────────────────────────┐
|
||||
│ ABOUT │
|
||||
│ ────── │
|
||||
│ Nexus 1.7-dev · Paperclip fork · MIT │
|
||||
└──────────────────────────────────────────────────────┘
|
||||
|
||||
┌──────────────────────────────────────────────────────┐
|
||||
│ DANGER ZONE │
|
||||
│ ──────────── │
|
||||
│ [Reset workspace] [Delete all conversations] │
|
||||
└──────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 8.2 Section card spec
|
||||
|
||||
- 1px charcoal border, 8px radius, transparent fill.
|
||||
- 24px padding.
|
||||
- Title: uppercase Inter 600 14px, 1.4px tracking, silver. Followed by a hairline rule.
|
||||
- Content: rows of `label / value / action` triples.
|
||||
- Section gap: 24px between cards.
|
||||
|
||||
### 8.3 Skills section
|
||||
|
||||
The Skill Aggregator (browse, install, assign per-agent) lives inside the SKILLS card. Same component, just rendered as a Settings section instead of a top-level page. Browse opens an inline drawer; assignments per-agent are configured here.
|
||||
|
||||
### 8.4 Routines section
|
||||
|
||||
Cron jobs that the workspace runs. Currently a top-level Routines route — demoted here. The current `RoutineDetail` page becomes a slide-over from the Routines section card.
|
||||
|
||||
---
|
||||
|
||||
## 9. Mobile
|
||||
|
||||
```
|
||||
┌──────────────────────┐ ┌──────────────────────┐
|
||||
│ ASSISTANT ◉ ⌘K │ │ STUDIO ◉ ⌘K │
|
||||
│──────────────────────│ │──────────────────────│
|
||||
│ │ │ ┌──────┐ ┌──────┐ │
|
||||
│ chat thread │ │ │ DIAG │ │ ICON │ │
|
||||
│ full bleed │ │ └──────┘ └──────┘ │
|
||||
│ │ │ ┌──────┐ ┌──────┐ │
|
||||
│ │ │ │ THEME│ │ WALL │ │
|
||||
│ ┌──────────────────┐ │ │ └──────┘ └──────┘ │
|
||||
│ │ ▒▒▒▒▒ waveform │ │ │ ┌──────┐ ┌──────┐ │
|
||||
│ │ ──────────────── │ │ │ │ DOC │ │ BRAND│ │
|
||||
│ │ Type or hold ◉ │ │ │ └──────┘ └──────┘ │
|
||||
│ └──────────────────┘ │ │ ┌──────┐ ┌──────┐ │
|
||||
│ │ │ │ SOC │ │ CONV │ │
|
||||
│──────────────────────│ │──────────────────────│
|
||||
│ ◆ ▲ ◇ ⚙ │ │ ◆ ▲ ◇ ⚙ │
|
||||
└──────────────────────┘ └──────────────────────┘
|
||||
```
|
||||
|
||||
### 9.1 Mobile changes from desktop
|
||||
|
||||
- **Bottom tab bar** replaces the left icon rail. Same 4 destinations (MessageCircle, Sparkles, FolderKanban, Settings). 56px tall, charcoal top border. Active tab: volt icon + volt bar above the icon.
|
||||
- **Top header strip** stays. Loses ⌘K text (still tappable as an icon). Mic stays.
|
||||
- **Assistant on mobile is full-bleed.** Reuses existing `MobileChatView.tsx` pattern as the foundation.
|
||||
- **Project sub-tabs** become a horizontally-scrolling strip under the header. No shrinking, no wrapping.
|
||||
- **Studio grid** drops to 2 columns on mobile.
|
||||
- **Promote-to-project transition on mobile** uses a full-screen takeover instead of the split layout — the brainstormer slides up and covers the chat completely.
|
||||
- **History slide-over** on mobile uses a full-screen sheet instead of a left drawer.
|
||||
- **Memory slide-over** same.
|
||||
|
||||
### 9.2 Mobile breakpoint
|
||||
|
||||
Single breakpoint: **`>= 768px`** is desktop frame, `< 768px` is mobile frame. Matches the existing `useMediaQuery("(min-width: 768px)")` in the codebase.
|
||||
|
||||
---
|
||||
|
||||
## 10. Cross-cutting features
|
||||
|
||||
### 10.1 ⌘K command palette
|
||||
|
||||
Single global search and command surface. Opens with `Cmd+K` / `Ctrl+K` or by clicking the ⌘K button in the top strip.
|
||||
|
||||
**Searches:**
|
||||
- Conversations (by title or recent message text)
|
||||
- Projects (by name, status filter, gate filter)
|
||||
- Issues (by title, by project)
|
||||
- Agents (by name, by role)
|
||||
- Recipes (by name, by tag)
|
||||
- Settings (by section name)
|
||||
- Studio workshops (by name)
|
||||
|
||||
**Commands (no search):**
|
||||
- `New project` → opens brainstormer
|
||||
- `New conversation` → starts a fresh Assistant thread
|
||||
- `Open Settings`
|
||||
- `Re-run onboarding`
|
||||
- Recent recipes (`Run "Generate weekly report"`)
|
||||
|
||||
**Layout:** centered modal, 600px wide, charcoal border, near-black fill, 8px radius. Search field at top in Inconsolata 16px. Results below in scrollable list with category headers in uppercase 11px silver. Selected result has a 2px volt left border and pale-yellow text. Keyboard nav: arrow keys + enter.
|
||||
|
||||
### 10.2 Recipes (v1.8) — embedded in Assistant
|
||||
|
||||
Recipes are not a destination. They are intelligence the Assistant uses to make suggestions in chat:
|
||||
|
||||
> _Assistant:_ "I notice you've done this kind of project before — want me to run the **frontend-design + tdd + ship** recipe? It took 3 hours and $4.20 last time."
|
||||
>
|
||||
> [ Yes, run it ] [ Customize ] [ No, do it from scratch ]
|
||||
|
||||
When the user accepts, the recipe executes and the Assistant narrates progress in chat. Recipes are also browsable from ⌘K (`recipes:` prefix) but there is no recipe browser as a destination.
|
||||
|
||||
This means **the icon rail has 4 slots, not 5.** The reserved circle slot from the proposal is removed.
|
||||
|
||||
### 10.3 Voice as a global affordance
|
||||
|
||||
See §5.5. Voice is captured from any mode and queued in the Assistant inbox. Visual indicator: when there is queued voice waiting to be processed, a small volt dot appears next to the Assistant icon in the rail.
|
||||
|
||||
### 10.4 Notifications
|
||||
|
||||
There is no global notifications icon. The single notification surface is the volt dot on the Assistant icon when:
|
||||
- Queued voice is waiting
|
||||
- A pending gate needs approval
|
||||
- A long-running agent task has completed
|
||||
|
||||
Click Assistant → the assistant tells you what's new in chat. No dropdown, no inbox panel. The Assistant's job is to tell you what changed.
|
||||
|
||||
---
|
||||
|
||||
## 11. Decisions log
|
||||
|
||||
Captured from the brainstorming conversation 2026-04-11. These are binding choices the spec is built on.
|
||||
|
||||
| # | Decision | Resolved |
|
||||
|---|---|---|
|
||||
| 1 | "Chat with a workshop attached" thesis | Approved as the product framing |
|
||||
| 2 | Demote Paperclip pages (Issues/Agents/Routines/Goals/Approvals/Costs/Activity/Inbox/Org) from global routes to per-project tabs | Approved |
|
||||
| 3 | Single workspace, no company switcher | Approved |
|
||||
| 4 | Assistant is the default landing route | Approved |
|
||||
| 5 | 56px left icon rail with 4 primary destinations | Approved |
|
||||
| 6 | Voice mic in top header is global, always visible | Approved |
|
||||
| 7 | ⌘K is the universal search; no separate search fields | Approved |
|
||||
| 8 | Origin chat is editable and continuable after promotion (not frozen) | Approved |
|
||||
| 9 | Recipes are embedded in Assistant suggestions, not a destination. Icon rail has 4 slots, not 5. | Approved |
|
||||
| 10 | Assistant home state (no active conversation) is a conversational greeting summarizing project status — replaces the Dashboard | Approved |
|
||||
| 11 | Voice in non-Assistant modes queues to Assistant inbox; no per-mode command parsing | Approved |
|
||||
| 12 | Icon rail uses Lucide icons (MessageCircle, Sparkles, FolderKanban, Settings) in silver outline + volt active. No abstract geometry. | Approved |
|
||||
| 13 | No sleep / lock button | Approved (kill it) |
|
||||
| 14 | Skill Aggregator lives in Settings → Skills section | Approved |
|
||||
| 15 | Promote-to-project transition: chat compresses to 30%, brainstormer rises into bottom 70%, inset shadow ripple | Approved — "ship that exact animation" |
|
||||
| 16 | Studio is a workshop grid (8 cards), not tabs | Approved |
|
||||
| 17 | Convert folds into Studio as a workshop, no separate route | Approved |
|
||||
| 18 | Project list cards use 72px Inter Black volt percentage as hero stat (DESIGN.md "performance stat" pattern) | Approved |
|
||||
| 19 | ChatPanel as a global slide-in right rail is killed entirely | Approved |
|
||||
| 20 | PropertiesPanel as a standing global fixture is killed | Approved |
|
||||
| 21 | Single notification surface = volt dot on Assistant icon | Approved |
|
||||
| 22 | Approvals → Gates rename (matches brainstormer/pipeline mental model) | Approved |
|
||||
| 23 | Routines move to Settings → Routines section | Approved |
|
||||
| 24 | Goals fold into milestone checklist on project Overview | Approved |
|
||||
| 25 | Single mobile breakpoint at 768px; mobile uses bottom tab bar | Approved |
|
||||
|
||||
---
|
||||
|
||||
## 12. Out of scope (for this spec)
|
||||
|
||||
These are explicit non-decisions — we are not designing them in this overhaul, and any future work on them is a separate spec:
|
||||
|
||||
- **Light mode visual treatment beyond what MIGRATION-PLAN.md §5 already specifies.** Light mode is an accessibility alternative. The wireframes here assume dark mode.
|
||||
- **Per-project branding overrides.** The existing `worktree-branding.ts` system is untouched.
|
||||
- **Plugin marketplace UI.** Plugins still install via CLI; in-app browse is future work.
|
||||
- **Voice command parsing in non-Assistant modes** (Star Trek mode). Single inbox path only.
|
||||
- **Update-project-from-chat** affordance. The chat is a relationship; the project is a contract; we don't sync the two except at promotion time.
|
||||
- **Multi-window / tear-off panels.** Single window only.
|
||||
- **Multi-select / batch operations on projects or issues.** Single-target only.
|
||||
- **Custom user themes.** Binary light/dark only.
|
||||
- **High-contrast accessibility mode beyond WCAG AA.** Not in scope.
|
||||
|
||||
---
|
||||
|
||||
## 13. Implementation phases (extends MIGRATION-PLAN.md to phases 8–16)
|
||||
|
||||
The visual migration plan ends at Phase 7 (visual QA of the ClickHouse repaint). This spec defines **structural phases 8–16**, executed in sequence after Phase 7 completes (or in parallel if a worktree is used).
|
||||
|
||||
**Implementation directive (binding):** Each phase below is implemented by **dispatching subagents in parallel** wherever phases or sub-tasks share no files. The user has explicitly requested subagent-driven development for this overhaul because of its size. Sequential implementation is wrong for this work. See `MIGRATION-PLAN.md` §11 (added in this revision) for the dispatch pattern.
|
||||
|
||||
| Phase | Title | Scope | Independence |
|
||||
|---|---|---|---|
|
||||
| **8** | **Frame skeleton** | New 56px icon rail, 48px top strip, killed sidebar/ChatPanel/PropertiesPanel as global elements. Routing simplified (no company prefix as a layout requirement). Old pages render in new frame but look weird — that's expected. | Foundational; blocks phases 9–15 |
|
||||
| **9** | **Assistant mode** | Move PersonalAssistant.tsx to be the canonical Assistant route. Implement History (left) and Memory (right) slide-overs. Implement conversational home state for empty-conversation mode. Replace inline conversation column with slide-over. | Parallelizable with 10, 11 |
|
||||
| **10** | **Studio mode** | Refactor ContentStudio.tsx from 7-tab to 8-card workshop grid. Fold ConvertPage in as 8th workshop. Add freeform Studio prompt with intent routing. Build workshop detail two-column layout. | Parallelizable with 9, 11 |
|
||||
| **11** | **Projects + Builder mode** | Build new Projects list with hero-stat cards. Build Project Detail layout with 7-tab Builder strip. Demote global Issues/Agents/Approvals/Costs/Activity/Org/Goals/Inbox routes to per-project tabs. Rename Approvals → Gates. Reuse existing list components, scope by project ID. | Parallelizable with 9, 10 |
|
||||
| **12** | **Promote-to-project transition** | The 700ms animation: chat compresses to 30%, brainstormer rises into 70%, inset shadow ripple, source-conversation label, post-creation banner linking chat to project. Origin chat preservation logic. | Depends on 9 (Assistant) and 11 (Projects) |
|
||||
| **13** | **Settings consolidation** | Single-column Settings with all sections. Skills section (Skill Aggregator inline). Routines section (demoted from top-level). Re-run onboarding link. Drop nested settings routes. | Parallelizable with 12, 14, 15 |
|
||||
| **14** | **Voice + ⌘K globalization** | Mic in top header with three states (idle/listening/speaking). Voice queues to Assistant inbox from any mode with volt-dot indicator on Assistant icon. ⌘K palette searches conversations, projects, issues, agents, recipes, settings, workshops. Replace any in-page search fields. | Parallelizable with 12, 13, 15 |
|
||||
| **15** | **Mobile parity** | Bottom tab bar matching the desktop rail. Project sub-tabs as horizontal scroll strip. Mobile takeover for promote-to-project. Mobile sheets for History/Memory slide-overs. | Parallelizable with 12, 13, 14 |
|
||||
| **16** | **Cleanup pass** | (a) Vocabulary sweep — remove "company" from all UI text, replace with "workspace" or remove. (b) Removal pass — delete dead code (old Layout sidebar, old ChatPanel global rail, old MobileBottomNav, theme cycle button code, dead route redirects, dead global pages). (c) Visual QA pass for the new frame. | Sequential at the end |
|
||||
|
||||
**Estimated wave structure for parallel dispatch:**
|
||||
|
||||
```
|
||||
Wave 1: [ Phase 8 ] # foundational, alone
|
||||
Wave 2: [ Phase 9 ] [ Phase 10 ] [ Phase 11 ] # parallel — disjoint files
|
||||
Wave 3: [ Phase 12 ] [ Phase 13 ] [ Phase 14 ] [ Phase 15 ] # parallel
|
||||
Wave 4: [ Phase 16 ] # sequential cleanup, alone
|
||||
```
|
||||
|
||||
Each phase produces an independently committable, atomically reviewable change. The implementation plan (separate doc, written next via the writing-plans skill) will detail file-by-file changes per phase.
|
||||
|
||||
---
|
||||
|
||||
## 14. Open items deferred to implementation planning
|
||||
|
||||
These do not need to be answered to start writing the implementation plan, but they will need answers before the corresponding phase ships:
|
||||
|
||||
1. **Animation primitives:** the promote-to-project transition uses 700ms cubic-bezier easing. The codebase currently uses CSS transitions for everything. Decide whether to introduce Motion (`motion/react`) for this single complex sequence or hand-roll with CSS keyframes. Recommendation: hand-roll. One-off animation does not justify a new dependency.
|
||||
|
||||
2. **Workshop intent classifier:** the Studio freeform prompt routes to the right workshop. Decide whether classification runs server-side (LLM call) or client-side (regex/keyword matching). Recommendation: client-side regex first, LLM fallback only if regex fails.
|
||||
|
||||
3. **Conversational home state freshness:** the Assistant greeting on home-state load reads from project status. Decide cache TTL (refresh on every Assistant page open vs. cached for N minutes). Recommendation: refresh on every open, no cache. The data is small.
|
||||
|
||||
4. **⌘K result ranking:** when search returns a mix of conversations, projects, issues, etc., decide the ranking heuristic. Recommendation: recency-weighted, with current-project items boosted if user is currently in a project.
|
||||
|
||||
5. **Project tab strip overflow on narrow desktop:** if 7 tabs don't fit at narrow desktop widths, decide whether to wrap, scroll, or collapse to a `more ▼` menu. Recommendation: horizontal scroll with edge fade, matching mobile.
|
||||
|
||||
---
|
||||
|
||||
## 15. Approval
|
||||
|
||||
Approved by Mikkel 2026-04-11 in conversation. Locked-in items: §1 (thesis), §2 (IA), §4 (frame), §5–§8 (modes), §9 (mobile), §10 (cross-cutting), §11 (decisions log), §13 (phase plan).
|
||||
|
||||
Next step: invoke the writing-plans skill to generate a per-phase implementation plan derived from this spec.
|
||||
Loading…
Add table
Reference in a new issue