docs: add Design System v4 migration spec
Flat dark theme migration plan: CSS foundation, icon rail sidebar, ~130 file component sweep, landing page updates. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
276
docs/superpowers/specs/2026-03-22-design-system-v4-migration.md
Normal file
276
docs/superpowers/specs/2026-03-22-design-system-v4-migration.md
Normal file
@@ -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)
|
||||
Reference in New Issue
Block a user