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:
Michael Chihlas
2026-03-21 23:50:59 -04:00
parent 6ff793bf45
commit 1de0b50ce4

View 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)