diff --git a/docs/superpowers/specs/2026-03-22-design-system-v4-migration.md b/docs/superpowers/specs/2026-03-22-design-system-v4-migration.md new file mode 100644 index 00000000..c438af96 --- /dev/null +++ b/docs/superpowers/specs/2026-03-22-design-system-v4-migration.md @@ -0,0 +1,276 @@ +# Design System v4 Migration — Flat Dark Theme + +> **Goal:** Migrate ResolutionFlow's frontend from glassmorphism/gradient aesthetic to a flat, high-contrast dark theme (Sentry/PostHog-inspired) with an icon rail sidebar, as defined in DESIGN-SYSTEM.md. + +## Scope + +~130 files across 15+ directories use old design patterns (`glass-card`, `bg-gradient-brand`, `text-gradient-brand`, `backdrop-filter: blur()`, ambient orbs). All must be updated to the new flat dark system. + +## Approach + +**Foundation first, then sweep.** Three phases: + +1. **Phase 1: CSS Foundation** — Rewrite `index.css` tokens, remove old utilities, add new variables +2. **Phase 2: Layout Shell** — Icon rail sidebar + app layout restructure +3. **Phase 3: Component Sweep** — Update all 132 files directory-by-directory + +Each phase produces deployable commits. The app will look inconsistent during Phase 3 but will always be functional. + +--- + +## Phase 1: CSS Foundation + +### index.css @theme Block + +Rewrite the `@theme` block with new color tokens matching DESIGN-SYSTEM.md: + +``` +Page background: #0c0d10 → --bg-page +Sidebar background: #0f1118 → --bg-sidebar +Card background: #14161d → --bg-card +Card hover: #191c25 → --bg-card-hover +Input background: #191c25 → --bg-input +Code background: #0e1017 → --bg-code +Elevated surface: #1c1f2a → --bg-elevated + +Text heading: #f0f2f5 → --text-heading +Text primary: #e2e5eb → --text-primary +Text secondary: #848b9b → --text-secondary +Text muted: #4f5666 → --text-muted + +Border default: #1e2130 → --border-default +Border hover: #2a2f3d → --border-hover + +Accent: #22d3ee → --accent +Accent hover: #06b6d4 → --accent-hover +Accent dim (10%): rgba(34,211,238,0.10) → --accent-dim +Accent text: #67e8f9 → --accent-text + +Success: #34d399 + dim at 10% +Warning: #fbbf24 + dim at 10% +Danger: #f87171 + dim at 10% + +Rail label: #6b7280 → --text-rail-label +``` + +### Variables Structure + +All colors in `:root` (dark is default). Light mode values prepared as comments — implementing the toggle is a future follow-up that just adds a `.light` class block. + +### Compatibility Shims (Critical) + +To avoid breaking the entire app while Phase 3 sweeps components, Phase 1 keeps the old utility class names as **deprecated aliases** mapping to the new values: + +```css +/* Deprecated — remove after Phase 3 sweep completes */ +.glass-card, .glass-card-static { @apply bg-[var(--bg-card)] border border-[var(--border-default)] rounded-lg; } +.glass-card:hover { @apply border-[var(--border-hover)]; } +``` + +These shims are removed in a final cleanup commit after Phase 3 is complete. + +### Remove Old Utilities + +Delete from `index.css` (after Phase 3 sweep — shims keep the app functional until then): +- `.glass-card`, `.glass-card-static`, `.glass-stat`, `.glass-card-glow` +- `.active-glow`, `.breatheGlow` keyframes +- `bg-gradient-brand`, `text-gradient-brand`, `bg-gradient-brand-hover` +- `--glass-bg`, `--glass-border`, `--glass-blur` variables +- `--shadow-float`, `--shadow-float-hover`, `--shadow-cyan-glow` shadow variables +- Atmosphere orb styles (`.atmosphere-orb`) +- Orchestrated page-load animation keyframes (slideDown, slideInLeft, fadeInUp, fadeInRight) + +### Rename + +- `--font-label` → `--font-mono` (JetBrains Mono, same font, clearer name) + +### Keep + +- Google Fonts imports (same three fonts) +- React Flow import +- Tailwind v4 `@theme` approach +- Base animation keyframes: `fade-in`, `fade-in-up`, `slide-in-from-left`, `slide-in-from-bottom` — all others removed (no `breatheGlow`, `bellWobble`, `slideDown`, orchestrated page-load sequence) + +### New Base Classes + +Add reusable component classes: + +```css +.card { /* bg-card, 1px border-default, 8px radius, no shadow */ } +.card-interactive { /* extends .card + hover border-hover transition */ } +.stat-card { /* extends .card + 3px left border */ } +.badge { /* 11px, pill shape, dim bg + matching text */ } +.btn-primary { /* solid accent, white text, 5px radius — NOTE: text changes from dark (#101114) to white */ } +.btn-ghost { /* transparent, 1px border, hover bg-elevated */ } +``` + +Implement each class per DESIGN-SYSTEM.md Component Patterns section for exact values. + +--- + +## Phase 2: Icon Rail Sidebar + +### New Component: IconRailSidebar + +Replaces current `Sidebar.tsx`. Two states: + +**Icon Rail (72px, default):** +- `bg-sidebar` background, full viewport height +- Logo mark at top: 30px cyan gradient square with lightning bolt +- Nav items: vertical column, 20px icon + 10px label underneath +- Horizontal dividers between sections (RESOLVE / KNOWLEDGE / INSIGHTS) +- User avatar at bottom +- Pin/expand toggle below avatar +- Active item: `accent-dim` background, `accent-text` on icon + label + +**Hover Flyout (220px panel):** +- Opens to the right of the hovered rail item with 150ms ease-out transition +- Also opens on keyboard focus/Enter for accessibility; closes on Escape or focus-out +- Shows sub-navigation for that section +- If section has many sub-items, flyout scrolls with `max-height: 70vh; overflow-y: auto` +- `bg-card` with `border-default` and `box-shadow: 0 4px 12px rgba(0,0,0,0.3)` +- Stays open while cursor is on rail item OR flyout panel +- Closes on mouse leave from both + +**Pinned State (260px full sidebar):** +- Click pin → expands to traditional sidebar with text labels, section headers, badges +- 3px left accent bar on active item +- Unpin button in sidebar header +- Preference persisted in localStorage / userPreferences store + +**Mobile:** +- Icon rail hidden below `sm` breakpoint +- Hamburger menu opens full overlay sidebar (same as pinned content) + +### Layout Changes + +`AppLayout.tsx` CSS Grid: +- Default: `grid-template-columns: 72px 1fr` +- Pinned: `grid-template-columns: 260px 1fr` +- Mobile: `grid-template-columns: 1fr` +- CSS variable `--sidebar-w` updated accordingly (used by FlowPilotMessageBar, FlowPilotActionBar) +- Ensure `--sidebar-w` transition is coordinated with sidebar width transition to prevent layout jump on pin/unpin + +**Sidebar commits:** Phase 2 produces 2-3 commits (icon rail core, flyout behavior, pinned state + persistence). + +### BrandLogo Update + +Replace current decision-tree icon SVG in `BrandLogo.tsx` with 30px gradient square (cyan, `border-radius: 8px`) + white lightning bolt mark. Wordmark: "ResolutionFlow" in Bricolage Grotesque 700, `text-heading` color (no gradient). + +### Files + +| Action | File | +|--------|------| +| Rewrite | `frontend/src/components/layout/Sidebar.tsx` → icon rail with flyout + pinned state | +| Modify | `frontend/src/components/layout/AppLayout.tsx` → grid columns, mobile handling | +| Modify | `frontend/src/components/layout/TopBar.tsx` → flat styling, remove blur | +| Keep | `FlowPilotMessageBar.tsx`, `FlowPilotActionBar.tsx` — `left: var(--sidebar-w)` still works | + +--- + +## Phase 3: Component Sweep + +### Pattern Replacement Map + +| Old Pattern | New Pattern | +|------------|-------------| +| `glass-card` / `glass-card-static` | `bg-[var(--bg-card)] border border-[var(--border-default)] rounded-lg` (or `.card` class) | +| `bg-gradient-brand` | `bg-[var(--accent)]` (solid cyan) | +| `text-gradient-brand` | `text-[var(--accent-text)]` | +| `bg-gradient-brand-hover` | `hover:brightness-110` | +| `text-foreground` | `text-[var(--text-primary)]` | +| `text-muted-foreground` | `text-[var(--text-secondary)]` | +| `bg-background` | `bg-[var(--bg-page)]` | +| `bg-card` (old token) | `bg-[var(--bg-card)]` | +| `border-border` | `border-[var(--border-default)]` | +| `font-label` (on code/monospace content) | `font-mono` | +| `font-label` (on labels/badges/timestamps) | `font-sans text-xs` — inspect each usage | +| `backdrop-filter: blur(...)` | Remove | +| `shadow-lg shadow-primary/20` on buttons | Remove | +| `rounded-[10px]` / `rounded-[16px]` on cards | `rounded-lg` (8px) | +| `scale(1.02)` hover on cards | Border color transition | +| `.atmosphere-orb` elements | Remove from JSX | +| `style={{ background: 'rgba(...)' }}` glass surfaces | Use CSS variable classes | + +### Sweep Order (one commit per directory group, ~10 commits total) + +Phase 3 covers app components only; landing page is handled in Phase 4. + +1. **`components/layout/`** (3 files) — AppLayout, TopBar, BrandLogo +2. **`components/dashboard/`** (16 files) — highest visibility +3. **`components/flowpilot/`** (12 files) — core product +4. **`pages/`** (25 files) — all page components +5. **`components/session/`** (8 files) +6. **`components/script-builder/`** (4 files) +7. **`components/kb-accelerator/`** (5 files) +8. **`components/account/`** (4 files) +9. **`components/tree-editor/`** (4 files) +10. **All remaining directories** (~51 files: admin, analytics, assistant, common, copilot, library, procedural, public, script-editor, ui) + +### What Stays the Same + +- Component logic, state management, hooks, API calls — untouched +- Lucide icons — same +- `cn()` utility — same +- All non-design Tailwind utilities (flex, grid, padding, margin, etc.) +- React Router, Zustand stores, type definitions + +--- + +## Phase 4: Landing Page + +- Remove ambient glow effects and gradient overlays from `landing.css` +- Hero: subtle radial gradient at 15% accent opacity (replaces heavy glow) +- Section labels: JetBrains Mono, 12px, uppercase, accent-text +- Section titles: Bricolage Grotesque, `clamp(28px, 4vw, 42px)`, weight 800 +- Pricing cards: flat `bg-card` + `border-default`, featured card gets accent border +- Top nav: flat, no blur backdrop +- CTAs: solid accent buttons +- Product mockup: update screenshot to show new flat UI + +**Files:** `landing.css`, `LandingPage.tsx`, landing-specific components + +--- + +## Phase 5: Cleanup & Documentation + +- Remove compatibility shims from `index.css` (deprecated `glass-card` aliases from Phase 1) +- Update CLAUDE.md: verify branding section and design system section reflect the new flat theme (already partially done in the doc-swap commit — verify no stale references remain) +- Update `BrandWordmark.tsx` if it references `text-gradient-brand` +- Verify `npm run build` passes with zero references to removed utilities + +**Light mode note:** All colors use CSS custom properties. Light mode values from DESIGN-SYSTEM.md are stored as comments in `index.css`. Adding light mode later = add `.light` class values + toggle in user settings. Not implemented in this migration. + +--- + +## Out of Scope + +- Light mode toggle (future follow-up — just variable swap + settings toggle) +- React Flow canvas theme updates (separate concern, works with any color scheme) +- Backend changes (none needed) +- New features or functionality (purely visual migration) +- Test changes (no visual tests exist) + +--- + +## Risk Mitigation + +- Each phase produces deployable commits +- The app is functional throughout (just visually inconsistent during Phase 3) +- Old CSS utilities removed in Phase 1 — if a component breaks visually, it's obvious +- `npm run build` verified after each phase +- No logic changes = no new bugs in functionality + +--- + +## Verification + +After each phase: +1. `npm run build` passes +2. Visual spot-check of key pages (Dashboard, FlowPilot session, Script Builder, Landing) + +After all phases: +1. Full app walkthrough — every sidebar nav item +2. Mobile responsive check (icon rail hidden, hamburger menu works) +3. Landing page check +4. FlowPilot session check (message bar, action bar positioning)