Files
resolutionflow/docs/superpowers/specs/2026-03-22-design-system-v4-migration.md
Michael Chihlas 1de0b50ce4 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>
2026-03-21 23:50:59 -04:00

11 KiB

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:

/* 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:

.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.tsxleft: 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)