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