fix(preview): add missing font MIME types to web server

- Added MIME type mappings for .otf, .woff, and .woff2 font formats
- Fixed missing break statement after .wav case (was falling through to .mp4)
- Fonts now load correctly in editor preview without 404 errors
- Resolves OTS parsing error messages in console

The web server was already serving project directory files correctly,
but browsers were rejecting font files due to missing/incorrect MIME types.

Related to TASK-006
This commit is contained in:
Richard Osborne
2025-12-15 22:57:48 +01:00
parent 0b47d19776
commit ea45e8b3a3
22 changed files with 5510 additions and 364 deletions

View File

@@ -0,0 +1,343 @@
/* =============================================================================
NOODL DESIGN SYSTEM - COLORS
Minimal palette: Red + Black + White
============================================================================= */
:root {
/* ---------------------------------------------------------------------------
BASE COLORS
A deliberately minimal palette - one accent, pure neutrals
--------------------------------------------------------------------------- */
/* Primary - Noodl Red */
--base-color-red-100: #fef2f3;
--base-color-red-200: #fde3e5;
--base-color-red-300: #fbc5c9;
--base-color-red-400: #f7969e;
--base-color-red-500: #ef5662;
--base-color-red-600: #d21f3c;
--base-color-red-700: #b91830;
--base-color-red-800: #9a1729;
--base-color-red-900: #801827;
--base-color-red-950: #460a11;
/* Neutrals - Pure black to white, no color tint */
--base-color-neutral-0: #000000;
--base-color-neutral-50: #0a0a0a;
--base-color-neutral-100: #121212;
--base-color-neutral-200: #1a1a1a;
--base-color-neutral-300: #262626;
--base-color-neutral-400: #333333;
--base-color-neutral-500: #525252;
--base-color-neutral-600: #737373;
--base-color-neutral-700: #a3a3a3;
--base-color-neutral-800: #d4d4d4;
--base-color-neutral-900: #e5e5e5;
--base-color-neutral-950: #f5f5f5;
--base-color-neutral-1000: #ffffff;
/* Transparent variants */
--base-color-black-transparent-90: rgba(0, 0, 0, 0.9);
--base-color-black-transparent-80: rgba(0, 0, 0, 0.8);
--base-color-black-transparent-50: rgba(0, 0, 0, 0.5);
--base-color-white-transparent-10: rgba(255, 255, 255, 0.1);
--base-color-white-transparent-15: rgba(255, 255, 255, 0.15);
--base-color-white-transparent-50: rgba(255, 255, 255, 0.5);
/* ---------------------------------------------------------------------------
SEMANTIC COLORS (Status indicators)
--------------------------------------------------------------------------- */
/* Success - Keeping a green for semantic meaning */
--base-color-success-100: #ecfdf5;
--base-color-success-200: #a7f3d0;
--base-color-success-300: #6ee7b7;
--base-color-success-400: #34d399;
--base-color-success-500: #10b981;
--base-color-success-600: #059669;
--base-color-success-700: #047857;
--base-color-success-800: #065f46;
--base-color-success-900: #064e3b;
--base-color-success-1000: #022c22;
/* Error - Uses the brand red */
--base-color-error-100: var(--base-color-red-100);
--base-color-error-200: var(--base-color-red-200);
--base-color-error-300: var(--base-color-red-300);
--base-color-error-400: var(--base-color-red-400);
--base-color-error-500: var(--base-color-red-500);
--base-color-error-600: var(--base-color-red-600);
--base-color-error-700: var(--base-color-red-700);
--base-color-error-800: var(--base-color-red-800);
--base-color-error-900: var(--base-color-red-900);
--base-color-error-1000: var(--base-color-red-950);
/* ---------------------------------------------------------------------------
NODE TYPE COLORS
Subtle variations to distinguish node types on canvas
Using desaturated colors so they don't compete with the red accent
--------------------------------------------------------------------------- */
/* Node-Pink - For Custom/User nodes */
--base-color-node-pink-100: #fdf2f8;
--base-color-node-pink-200: #f5d0e5;
--base-color-node-pink-300: #e8a8ca;
--base-color-node-pink-400: #d87caa;
--base-color-node-pink-500: #c2578a;
--base-color-node-pink-600: #a63d6f;
--base-color-node-pink-700: #862d56;
--base-color-node-pink-800: #6b2445;
--base-color-node-pink-900: #521c35;
--base-color-node-pink-1000: #2d0e1c;
/* Node-Purple - For Component nodes */
--base-color-node-purple-100: #f8f5fa;
--base-color-node-purple-200: #e8dff0;
--base-color-node-purple-300: #d4c4e3;
--base-color-node-purple-400: #b8a0cf;
--base-color-node-purple-500: #9a7bb8;
--base-color-node-purple-600: #7d5a9e;
--base-color-node-purple-700: #624382;
--base-color-node-purple-800: #4b3366;
--base-color-node-purple-900: #37264b;
--base-color-node-purple-1000: #1e1429;
/* Node-Green - For Data nodes */
--base-color-node-green-100: #f4f7f4;
--base-color-node-green-200: #d8e5d8;
--base-color-node-green-300: #b5cfb5;
--base-color-node-green-400: #8eb58e;
--base-color-node-green-500: #6a996a;
--base-color-node-green-600: #4d7d4d;
--base-color-node-green-700: #3a613a;
--base-color-node-green-800: #2c4a2c;
--base-color-node-green-900: #203520;
--base-color-node-green-1000: #111c11;
/* Node-Gray - For Logic nodes */
--base-color-node-grey-100: #f5f5f5;
--base-color-node-grey-200: #e0e0e0;
--base-color-node-grey-300: #c2c2c2;
--base-color-node-grey-400: #9e9e9e;
--base-color-node-grey-500: #757575;
--base-color-node-grey-600: #5c5c5c;
--base-color-node-grey-700: #454545;
--base-color-node-grey-800: #333333;
--base-color-node-grey-900: #212121;
--base-color-node-grey-1000: #0d0d0d;
/* Node-Blue - For Visual nodes */
--base-color-node-blue-100: #f4f6f8;
--base-color-node-blue-200: #dce3eb;
--base-color-node-blue-300: #bccad9;
--base-color-node-blue-400: #96adc2;
--base-color-node-blue-500: #7090a9;
--base-color-node-blue-600: #53758f;
--base-color-node-blue-700: #3e5a72;
--base-color-node-blue-800: #2f4557;
--base-color-node-blue-900: #22323f;
--base-color-node-blue-1000: #121b22;
/* ---------------------------------------------------------------------------
LEGACY ALIASES - For backwards compatibility
--------------------------------------------------------------------------- */
/* Grey -> Neutral */
--base-color-grey-100: var(--base-color-neutral-950);
--base-color-grey-100-transparent: var(--base-color-white-transparent-10);
--base-color-grey-200: var(--base-color-neutral-800);
--base-color-grey-300: var(--base-color-neutral-700);
--base-color-grey-400: var(--base-color-neutral-600);
--base-color-grey-500: var(--base-color-neutral-500);
--base-color-grey-600: var(--base-color-neutral-400);
--base-color-grey-700: var(--base-color-neutral-300);
--base-color-grey-800: var(--base-color-neutral-200);
--base-color-grey-900: var(--base-color-neutral-100);
--base-color-grey-1000: var(--base-color-neutral-50);
--base-color-grey-1000-transparent: var(--base-color-black-transparent-80);
--base-color-grey-1000-transparent-2: var(--base-color-black-transparent-50);
/* Teal -> Neutral (secondary is now white/gray) */
--base-color-teal-100: var(--base-color-neutral-1000);
--base-color-teal-200: var(--base-color-neutral-900);
--base-color-teal-300: var(--base-color-neutral-800);
--base-color-teal-400: var(--base-color-neutral-700);
--base-color-teal-500: var(--base-color-neutral-600);
--base-color-teal-600: var(--base-color-neutral-500);
--base-color-teal-700: var(--base-color-neutral-400);
--base-color-teal-800: var(--base-color-neutral-300);
--base-color-teal-900: var(--base-color-neutral-200);
--base-color-teal-1000: var(--base-color-neutral-100);
/* Yellow -> Red (primary is now red) */
--base-color-yellow-100: var(--base-color-red-100);
--base-color-yellow-200: var(--base-color-red-200);
--base-color-yellow-300: var(--base-color-red-400);
--base-color-yellow-400: var(--base-color-red-500);
--base-color-yellow-500: var(--base-color-red-600);
--base-color-yellow-600: var(--base-color-red-700);
--base-color-yellow-700: var(--base-color-red-800);
--base-color-yellow-800: var(--base-color-red-900);
--base-color-yellow-900: var(--base-color-red-950);
--base-color-yellow-1000: var(--base-color-red-950);
}
/* =============================================================================
THEME COLOR TOKENS - USE THESE IN COMPONENTS
============================================================================= */
:root {
/* ---------------------------------------------------------------------------
BACKGROUNDS
Pure blacks with subtle elevation through lightness
--------------------------------------------------------------------------- */
--theme-color-bg-0: #000000;
--theme-color-bg-1: var(--base-color-neutral-50);
--theme-color-bg-1-transparent: var(--base-color-black-transparent-80);
--theme-color-bg-1-transparent-2: var(--base-color-black-transparent-50);
--theme-color-bg-2: var(--base-color-neutral-100);
--theme-color-bg-3: var(--base-color-neutral-200);
--theme-color-bg-4: var(--base-color-neutral-300);
--theme-color-bg-5: var(--base-color-neutral-400);
--theme-color-bg-hover: var(--base-color-white-transparent-10);
/* ---------------------------------------------------------------------------
FOREGROUNDS
Pure whites with subtle hierarchy
--------------------------------------------------------------------------- */
--theme-color-fg-highlight: #ffffff;
--theme-color-fg-default-contrast: var(--base-color-neutral-900);
--theme-color-fg-default: var(--base-color-neutral-800);
--theme-color-fg-default-shy: var(--base-color-neutral-700);
--theme-color-fg-muted: var(--base-color-neutral-600);
--theme-color-fg-transparent: var(--base-color-white-transparent-15);
/* ---------------------------------------------------------------------------
PRIMARY - Noodl Red
The one accent color - used sparingly for maximum impact
--------------------------------------------------------------------------- */
--theme-color-primary: #d21f3c;
--theme-color-primary-highlight: var(--base-color-red-500);
--theme-color-primary-dim: var(--base-color-red-800);
--theme-color-on-primary: #ffffff;
/* ---------------------------------------------------------------------------
SECONDARY - White/Light
For secondary actions, using white as the complement to red
--------------------------------------------------------------------------- */
--theme-color-secondary: #ffffff;
--theme-color-secondary-dim: var(--base-color-neutral-700);
--theme-color-secondary-highlight: #ffffff;
--theme-color-secondary-bright: #ffffff;
--theme-color-secondary-as-fg: var(--base-color-neutral-800);
--theme-color-on-secondary: var(--base-color-neutral-100);
/* ---------------------------------------------------------------------------
NODE COLORS
Muted, desaturated to not compete with the red accent
--------------------------------------------------------------------------- */
/* Data nodes - Muted Green */
--theme-color-node-data-1: var(--base-color-node-green-700);
--theme-color-node-data-2: var(--base-color-node-green-600);
--theme-color-node-data-3: var(--base-color-node-green-500);
--theme-color-node-data-dim: var(--base-color-node-green-900);
/* Visual nodes - Muted Blue */
--theme-color-node-visual-1: var(--base-color-node-blue-700);
--theme-color-node-visual-2: var(--base-color-node-blue-600);
--theme-color-node-visual-2-highlight: var(--base-color-node-blue-500);
--theme-color-node-visual-highlight: var(--base-color-node-blue-200);
--theme-color-node-visual-default: var(--base-color-node-blue-300);
--theme-color-node-visual-shy: var(--base-color-node-blue-400);
--theme-color-node-visual-dim: var(--base-color-node-blue-900);
/* Custom nodes - Muted Pink */
--theme-color-node-custom-1: var(--base-color-node-pink-700);
--theme-color-node-custom-2: var(--base-color-node-pink-600);
--theme-color-node-custom-dim: var(--base-color-node-pink-900);
/* Logic nodes - Gray */
--theme-color-node-logic-1: var(--base-color-node-grey-700);
--theme-color-node-logic-2: var(--base-color-node-grey-600);
--theme-color-node-logic-dim: var(--base-color-node-grey-900);
/* Component nodes - Muted Purple */
--theme-color-node-component-1: var(--base-color-node-purple-700);
--theme-color-node-component-2: var(--base-color-node-purple-600);
--theme-color-node-component-dim: var(--base-color-node-purple-900);
/* ---------------------------------------------------------------------------
STATUS COLORS
Success stays green, everything else maps to the palette
--------------------------------------------------------------------------- */
--theme-color-success: var(--base-color-success-400);
--theme-color-success-dim: var(--base-color-success-600);
--theme-color-success-bg: var(--base-color-success-900);
--theme-color-notice: var(--base-color-red-400);
--theme-color-notice-dim: var(--base-color-red-600);
--theme-color-notice-bg: var(--base-color-red-950);
--theme-color-danger: var(--base-color-red-500);
--theme-color-danger-light: var(--base-color-red-400);
--theme-color-danger-dim: var(--base-color-red-700);
--theme-color-danger-bg: var(--base-color-red-950);
/* ---------------------------------------------------------------------------
CONNECTION COLORS
--------------------------------------------------------------------------- */
--theme-color-signal: var(--base-color-red-500);
--theme-color-data: var(--base-color-neutral-700);
/* ---------------------------------------------------------------------------
BORDERS
Subtle white borders for dark backgrounds
--------------------------------------------------------------------------- */
--theme-color-border-default: var(--base-color-neutral-300);
--theme-color-border-subtle: var(--base-color-neutral-200);
--theme-color-border-strong: var(--base-color-neutral-400);
/* ---------------------------------------------------------------------------
FOCUS
Red focus ring for accessibility
--------------------------------------------------------------------------- */
--theme-color-focus-ring: #d21f3c;
--theme-color-focus-ring-offset: var(--base-color-neutral-50);
}
/* =============================================================================
FUTURE: LIGHT THEME
=============================================================================
.theme-light {
--theme-color-bg-0: #ffffff;
--theme-color-bg-1: var(--base-color-neutral-950);
--theme-color-bg-1-transparent: rgba(255, 255, 255, 0.9);
--theme-color-bg-1-transparent-2: rgba(255, 255, 255, 0.5);
--theme-color-bg-2: #ffffff;
--theme-color-bg-3: var(--base-color-neutral-900);
--theme-color-bg-4: var(--base-color-neutral-800);
--theme-color-bg-5: var(--base-color-neutral-700);
--theme-color-bg-hover: rgba(0, 0, 0, 0.04);
--theme-color-fg-highlight: #000000;
--theme-color-fg-default-contrast: var(--base-color-neutral-100);
--theme-color-fg-default: var(--base-color-neutral-200);
--theme-color-fg-default-shy: var(--base-color-neutral-400);
--theme-color-fg-muted: var(--base-color-neutral-500);
--theme-color-primary: #d21f3c;
--theme-color-on-primary: #ffffff;
--theme-color-secondary: var(--base-color-neutral-100);
--theme-color-on-secondary: #ffffff;
--theme-color-border-default: var(--base-color-neutral-800);
--theme-color-border-subtle: var(--base-color-neutral-900);
--theme-color-border-strong: var(--base-color-neutral-700);
}
*/

View File

@@ -0,0 +1,866 @@
# Task: Noodl Design System Modernization
## Overview
Comprehensive overhaul of Noodl's visual design system to create a modern, clean, professional appearance. Moving from the dated 2015-era dark gray aesthetic to a contemporary design language inspired by tools like Linear, Raycast, and Figma.
**Primary Goals:**
- Clean, modern color palette (Rose + Violet with Zinc neutrals)
- Consistent token usage throughout the codebase
- Foundation for future light/dark theme switching
- Better visual hierarchy and spacing
- Improved component aesthetics
**Brand Direction:**
- Primary: Rose (`#f43f5e`) - Modern, bold, distinctive
- Secondary: Violet (`#a78bfa`) - Complementary, contemporary
- Neutrals: Zinc palette (clean grays, no brown/warm tints)
---
## Phase 1: Token Consolidation & Color Refresh
**Priority: CRITICAL**
**Effort: 1-2 hours**
**Risk: Low**
### Problem
The editor has duplicate color token files. The core-ui tokens are commented out and the editor uses its own copy:
```typescript
// packages/noodl-editor/src/editor/index.ts
//Design tokens for later
// import '../../../noodl-core-ui/src/styles/custom-properties/animations.css';
// import '../../../noodl-core-ui/src/styles/custom-properties/fonts.css';
// import '../../../noodl-core-ui/src/styles/custom-properties/colors.css';
import '../editor/src/styles/custom-properties/animations.css';
import '../editor/src/styles/custom-properties/fonts.css';
import '../editor/src/styles/custom-properties/colors.css';
```
### Tasks
#### 1.1 Consolidate to Single Source of Truth
1. Replace the contents of `packages/noodl-editor/src/editor/src/styles/custom-properties/colors.css` with the new modern palette (see Appendix A)
2. Also update `packages/noodl-core-ui/src/styles/custom-properties/colors.css` with the same content
3. Verify the viewer frame also uses the correct colors:
- Check `packages/noodl-editor/src/frames/viewer-frame/index.js`
#### 1.2 Verify Token Application
After replacing, verify these key tokens are working:
| Token | Expected Value | Where to Check |
|-------|---------------|----------------|
| `--theme-color-bg-1` | `#09090b` (near black) | Main app background |
| `--theme-color-bg-2` | `#18181b` | Panel backgrounds |
| `--theme-color-bg-3` | `#27272a` | Card/input backgrounds |
| `--theme-color-primary` | `#f43f5e` (rose) | CTA buttons |
| `--theme-color-secondary` | `#a78bfa` (violet) | Secondary elements |
### Testing Checklist
- [ ] App background is clean dark (not brownish)
- [ ] Primary buttons are rose colored
- [ ] Text is readable with good contrast
- [ ] Node colors on canvas still distinguishable
- [ ] Success/error/warning states still visible
- [ ] No console errors related to missing CSS variables
---
## Phase 2: Hardcoded Color Audit & Cleanup
**Priority: HIGH**
**Effort: 3-4 hours**
**Risk: Low-Medium**
### Problem
Many components have hardcoded hex colors instead of using design tokens. This breaks consistency and prevents theming.
### Tasks
#### 2.1 Find All Hardcoded Colors
Search the codebase for hardcoded hex colors in these locations:
```
packages/noodl-editor/src/editor/src/styles/
packages/noodl-editor/src/editor/src/views/
packages/noodl-core-ui/src/components/
```
Common patterns to find:
```css
/* Bad - hardcoded */
background-color: #383838;
background: #444444;
border: 1px solid #2a2a2a;
color: #b9b9b9;
/* Good - tokenized */
background-color: var(--theme-color-bg-3);
```
#### 2.2 Create Mapping Reference
Map discovered hardcoded colors to appropriate tokens:
| Hardcoded | Replace With |
|-----------|--------------|
| `#000000` | `var(--theme-color-bg-0)` |
| `#151414`, `#151515` | `var(--theme-color-bg-1)` |
| `#292828`, `#2a2a2a` | `var(--theme-color-bg-2)` |
| `#383838`, `#3c3c3c` | `var(--theme-color-bg-3)` |
| `#444444`, `#4a4a4a` | `var(--theme-color-bg-4)` |
| `#666666`, `#6a6a6a` | `var(--theme-color-fg-muted)` |
| `#999999`, `#9a9a9a` | `var(--theme-color-fg-default-shy)` |
| `#b8b8b8`, `#b9b9b9` | `var(--theme-color-fg-default)` |
| `#d4d4d4` | `var(--theme-color-fg-default-contrast)` |
| `#f5f5f5`, `#ffffff` | `var(--theme-color-fg-highlight)` |
#### 2.3 Priority Files to Fix
Start with these high-impact files:
1. **Popup Layer Styles**
- `packages/noodl-editor/src/editor/src/styles/popuplayer.css`
2. **Property Editor**
- `packages/noodl-editor/src/editor/src/styles/propertyeditor.css`
3. **Node Graph Editor**
- `packages/noodl-editor/src/editor/src/views/nodegrapheditor/` (all .css/.scss files)
4. **Inspect Popup**
- `packages/noodl-editor/src/editor/src/views/nodegrapheditor/InspectJSONView/InspectPopup.module.scss`
5. **Connection Popup**
- `packages/noodl-editor/src/editor/src/views/ConnectionPopup/ConnectionPopup.module.scss`
### Testing Checklist
- [ ] All replaced colors render correctly
- [ ] Hover states still work
- [ ] Focus states visible
- [ ] No visual regressions in property panel
- [ ] Popups/modals look correct
- [ ] Node graph colors unaffected
---
## Phase 3: Typography & Spacing Refresh
**Priority: MEDIUM**
**Effort: 2-3 hours**
**Risk: Low**
### Problem
Current typography feels cramped and dated. Font sizes are small and spacing is inconsistent.
### Tasks
#### 3.1 Update Font Tokens
File: `packages/noodl-core-ui/src/styles/custom-properties/fonts.css`
```css
:root {
--font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
--font-family-code: 'JetBrains Mono', Menlo, Monaco, 'Courier New', monospace;
--font-weight-light: 300;
--font-weight-regular: 400;
--font-weight-medium: 500;
--font-weight-semibold: 600;
--font-weight-bold: 700;
/* New: Font size scale */
--font-size-xs: 10px;
--font-size-sm: 12px;
--font-size-base: 13px;
--font-size-md: 14px;
--font-size-lg: 16px;
--font-size-xl: 18px;
--font-size-2xl: 24px;
/* New: Line height scale */
--line-height-tight: 1.2;
--line-height-normal: 1.5;
--line-height-relaxed: 1.625;
/* New: Letter spacing */
--letter-spacing-tight: -0.02em;
--letter-spacing-normal: 0;
--letter-spacing-wide: 0.02em;
}
```
#### 3.2 Add Spacing Tokens
Create new file: `packages/noodl-core-ui/src/styles/custom-properties/spacing.css`
```css
:root {
--spacing-0: 0;
--spacing-1: 4px;
--spacing-2: 8px;
--spacing-3: 12px;
--spacing-4: 16px;
--spacing-5: 20px;
--spacing-6: 24px;
--spacing-8: 32px;
--spacing-10: 40px;
--spacing-12: 48px;
--spacing-16: 64px;
/* Component-specific spacing */
--spacing-panel-padding: var(--spacing-4);
--spacing-card-padding: var(--spacing-3);
--spacing-input-padding-x: var(--spacing-2);
--spacing-input-padding-y: var(--spacing-1);
--spacing-button-padding-x: var(--spacing-3);
--spacing-button-padding-y: var(--spacing-2);
/* Border radius */
--radius-sm: 2px;
--radius-default: 4px;
--radius-md: 6px;
--radius-lg: 8px;
--radius-xl: 12px;
--radius-full: 9999px;
}
```
#### 3.3 Import New Token Files
Update imports in:
- `packages/noodl-editor/src/editor/index.ts`
- `packages/noodl-core-ui/.storybook/preview.ts`
### Testing Checklist
- [ ] Text is readable at all sizes
- [ ] Spacing feels balanced
- [ ] Components don't overflow
- [ ] Modal/dialog layouts intact
---
## Phase 4: Component Visual Updates
**Priority: MEDIUM**
**Effort: 4-6 hours**
**Risk: Medium**
### Problem
Individual components need visual refinement beyond just color tokens.
### Tasks
#### 4.1 Button Refinements
File: `packages/noodl-core-ui/src/components/inputs/PrimaryButton/PrimaryButton.module.scss`
Updates needed:
- Slightly rounded corners (`border-radius: 6px`)
- Subtle shadow on hover
- Better disabled state (not just opacity)
- Smooth transitions
```scss
.Root {
border-radius: var(--radius-md);
transition: all 150ms ease;
&.is-variant-cta {
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
&:hover {
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
transform: translateY(-1px);
}
}
&:disabled {
opacity: 0.5;
cursor: not-allowed;
transform: none;
box-shadow: none;
}
}
```
#### 4.2 Input Field Refinements
File: `packages/noodl-core-ui/src/components/inputs/TextInput/TextInput.module.scss`
Updates needed:
- Subtle border (not just background change)
- Focus ring using new token
- Better placeholder styling
```scss
.InputArea {
border: 1px solid var(--theme-color-border-subtle);
border-radius: var(--radius-default);
transition: border-color 150ms ease, box-shadow 150ms ease;
&.is-focused {
border-color: var(--theme-color-focus-ring);
box-shadow: 0 0 0 2px rgba(244, 63, 94, 0.15);
}
}
```
#### 4.3 Dialog/Modal Refinements
File: `packages/noodl-core-ui/src/components/layout/BaseDialog/BaseDialog.module.scss`
Updates needed:
- Subtle border
- Refined shadow
- Better backdrop blur (if supported)
```scss
.VisibleDialog {
border: 1px solid var(--theme-color-border-subtle);
border-radius: var(--radius-lg);
box-shadow:
0 4px 6px -1px rgba(0, 0, 0, 0.1),
0 10px 15px -3px rgba(0, 0, 0, 0.2),
0 20px 25px -5px rgba(0, 0, 0, 0.15);
}
.Root.has-backdrop {
backdrop-filter: blur(4px);
-webkit-backdrop-filter: blur(4px);
}
```
#### 4.4 Panel/Section Refinements
Files:
- `packages/noodl-core-ui/src/components/sidebar/BasePanel/`
- `packages/noodl-core-ui/src/components/sidebar/Section/`
Updates needed:
- Consistent padding using spacing tokens
- Subtle dividers between sections
- Better header styling
### Testing Checklist
- [ ] Buttons look polished and modern
- [ ] Inputs have clear focus states
- [ ] Dialogs/modals feel elevated
- [ ] Panels have clear visual hierarchy
- [ ] All interactive states (hover, focus, active, disabled) work
---
## Phase 5: Migration Dialog Specific Fixes
**Priority: HIGH** (User-facing feature)
**Effort: 2-3 hours**
**Risk: Low**
### Problem
The React 19 migration dialog needs specific attention beyond global token changes.
### Tasks
#### 5.1 Identify Migration Dialog Files
Search for migration-related components:
```bash
find . -name "*.tsx" -o -name "*.jsx" | xargs grep -l -i "migrat"
```
#### 5.2 Dialog Structure Improvements
The migration wizard should have:
- Clear step indicator (not just numbered text list)
- Progress visualization
- Distinct sections with proper spacing
- Better icon usage
- Clear primary/secondary actions
#### 5.3 Suggested Component Structure
```tsx
<DialogContainer>
<DialogHeader>
<Title>Migrate Project to React 19</Title>
<Subtitle>Migration Complete</Subtitle>
</DialogHeader>
<StepIndicator
steps={['Confirm', 'Scan', 'Report', 'Migrate', 'Complete']}
currentStep={4}
/>
<DialogBody>
<SuccessBanner>
<Icon name="checkmark-circle" />
<Text>Your project has been migrated successfully</Text>
</SuccessBanner>
<StatsCard>
<Stat value={62} label="Migrated" status="success" />
</StatsCard>
<Section title="Project Locations">
<LocationItem icon="lock" label="Original" path="..." />
<LocationItem icon="folder" label="Migrated" path="..." />
</Section>
<Section title="What's Next?">
<ChecklistItem>Test your app thoroughly</ChecklistItem>
<ChecklistItem>Archive or delete original when ready</ChecklistItem>
</Section>
</DialogBody>
<DialogFooter>
<PrimaryButton label="Open Migrated Project" />
</DialogFooter>
</DialogContainer>
```
### Testing Checklist
- [ ] All wizard steps render correctly
- [ ] Progress is clear
- [ ] Success/error states are obvious
- [ ] Actions are clear
- [ ] Dialog is responsive to content length
---
## Phase 6: Light Theme Foundation
**Priority: LOW** (Future enhancement)
**Effort: 3-4 hours**
**Risk: Medium**
### Problem
Currently no infrastructure for theme switching.
### Tasks
#### 6.1 Theme Provider Setup
Create theme context and provider for React components.
#### 6.2 CSS Theme Classes
The colors.css file already includes a commented `.theme-light` block. Uncomment and refine.
#### 6.3 Theme Toggle
Add settings option to switch between light/dark.
#### 6.4 Persist Preference
Store theme preference in localStorage.
### Testing Checklist
- [ ] Theme toggle works
- [ ] All components respect theme
- [ ] No hardcoded colors breaking theme
- [ ] Preference persists across sessions
---
## Appendix A: Complete colors.css File
See the Rose + Violet palette file provided separately. Key values:
```css
/* Primary - Rose */
--theme-color-primary: #f43f5e;
--theme-color-primary-highlight: #fb7185;
--theme-color-primary-dim: #be123c;
--theme-color-on-primary: #ffffff;
/* Secondary - Violet */
--theme-color-secondary: #a78bfa;
--theme-color-secondary-dim: #7c3aed;
--theme-color-secondary-highlight: #c4b5fd;
--theme-color-on-secondary: #ffffff;
/* Backgrounds - Zinc */
--theme-color-bg-0: #000000;
--theme-color-bg-1: #09090b;
--theme-color-bg-2: #18181b;
--theme-color-bg-3: #27272a;
--theme-color-bg-4: #3f3f46;
/* Foregrounds */
--theme-color-fg-highlight: #ffffff;
--theme-color-fg-default-contrast: #f4f4f5;
--theme-color-fg-default: #d4d4d8;
--theme-color-fg-default-shy: #a1a1aa;
--theme-color-fg-muted: #71717a;
```
---
## Appendix B: File Locations Quick Reference
### Token Files
- `packages/noodl-core-ui/src/styles/custom-properties/colors.css`
- `packages/noodl-core-ui/src/styles/custom-properties/fonts.css`
- `packages/noodl-core-ui/src/styles/custom-properties/animations.css`
- `packages/noodl-editor/src/editor/src/styles/custom-properties/colors.css` (duplicate - primary)
### Entry Points
- `packages/noodl-editor/src/editor/index.ts` (main editor)
- `packages/noodl-editor/src/frames/viewer-frame/index.js` (viewer)
- `packages/noodl-core-ui/.storybook/preview.ts` (storybook)
### Key Component Directories
- `packages/noodl-core-ui/src/components/inputs/` (buttons, inputs)
- `packages/noodl-core-ui/src/components/layout/` (dialogs, containers)
- `packages/noodl-core-ui/src/components/sidebar/` (panels, sections)
- `packages/noodl-core-ui/src/components/typography/` (text, labels)
### Legacy Style Files (need hardcoded color audit)
- `packages/noodl-editor/src/editor/src/styles/`
- `packages/noodl-editor/src/editor/src/views/`
---
## Appendix C: Full colors.css Replacement
```css
/* =============================================================================
NOODL DESIGN SYSTEM - COLORS
Modern refresh: Rose + Violet palette
============================================================================= */
/* =============================================================================
BASE COLORS
These are the raw palette values. DO NOT use directly in components.
Use the THEME COLOR TOKENS below instead.
============================================================================= */
:root {
/* ---------------------------------------------------------------------------
SEMANTIC COLORS
--------------------------------------------------------------------------- */
/* Success - Modern Emerald */
--base-color-success-100: #ecfdf5;
--base-color-success-200: #a7f3d0;
--base-color-success-300: #6ee7b7;
--base-color-success-400: #34d399;
--base-color-success-500: #10b981;
--base-color-success-600: #059669;
--base-color-success-700: #047857;
--base-color-success-800: #065f46;
--base-color-success-900: #064e3b;
--base-color-success-1000: #022c22;
/* Error - Red (distinct from primary rose) */
--base-color-error-100: #fef2f2;
--base-color-error-200: #fecaca;
--base-color-error-300: #fca5a5;
--base-color-error-400: #f87171;
--base-color-error-500: #ef4444;
--base-color-error-600: #dc2626;
--base-color-error-700: #b91c1c;
--base-color-error-800: #991b1b;
--base-color-error-900: #7f1d1d;
--base-color-error-1000: #450a0a;
/* ---------------------------------------------------------------------------
NODE TYPE COLORS
--------------------------------------------------------------------------- */
/* Node-Pink - For Custom/User nodes */
--base-color-node-pink-100: #fdf2f8;
--base-color-node-pink-200: #fbcfe8;
--base-color-node-pink-300: #f9a8d4;
--base-color-node-pink-400: #f472b6;
--base-color-node-pink-500: #ec4899;
--base-color-node-pink-600: #db2777;
--base-color-node-pink-700: #be185d;
--base-color-node-pink-800: #9d174d;
--base-color-node-pink-900: #831843;
--base-color-node-pink-1000: #500724;
/* Node-Purple - For Component nodes */
--base-color-node-purple-100: #faf5ff;
--base-color-node-purple-200: #e9d5ff;
--base-color-node-purple-300: #d8b4fe;
--base-color-node-purple-400: #c084fc;
--base-color-node-purple-500: #a855f7;
--base-color-node-purple-600: #9333ea;
--base-color-node-purple-700: #7c3aed;
--base-color-node-purple-800: #6d28d9;
--base-color-node-purple-900: #5b21b6;
--base-color-node-purple-1000: #2e1065;
/* Node-Green - For Data nodes */
--base-color-node-green-100: #f0fdf4;
--base-color-node-green-200: #bbf7d0;
--base-color-node-green-300: #86efac;
--base-color-node-green-400: #4ade80;
--base-color-node-green-500: #22c55e;
--base-color-node-green-600: #16a34a;
--base-color-node-green-700: #15803d;
--base-color-node-green-800: #166534;
--base-color-node-green-900: #14532d;
--base-color-node-green-1000: #052e16;
/* Node-Gray - For Logic nodes */
--base-color-node-grey-100: #f4f4f5;
--base-color-node-grey-200: #e4e4e7;
--base-color-node-grey-300: #d4d4d8;
--base-color-node-grey-400: #a1a1aa;
--base-color-node-grey-500: #71717a;
--base-color-node-grey-600: #52525b;
--base-color-node-grey-700: #3f3f46;
--base-color-node-grey-800: #27272a;
--base-color-node-grey-900: #18181b;
--base-color-node-grey-1000: #09090b;
/* Node-Blue - For Visual nodes */
--base-color-node-blue-100: #eff6ff;
--base-color-node-blue-200: #dbeafe;
--base-color-node-blue-300: #bfdbfe;
--base-color-node-blue-400: #93c5fd;
--base-color-node-blue-500: #60a5fa;
--base-color-node-blue-600: #3b82f6;
--base-color-node-blue-700: #2563eb;
--base-color-node-blue-800: #1d4ed8;
--base-color-node-blue-900: #1e40af;
--base-color-node-blue-1000: #172554;
/* ---------------------------------------------------------------------------
BRAND COLORS
--------------------------------------------------------------------------- */
/* Primary - Rose (Modern pink-red) */
--base-color-rose-100: #fff1f2;
--base-color-rose-200: #fecdd3;
--base-color-rose-300: #fda4af;
--base-color-rose-400: #fb7185;
--base-color-rose-500: #f43f5e;
--base-color-rose-600: #e11d48;
--base-color-rose-700: #be123c;
--base-color-rose-800: #9f1239;
--base-color-rose-900: #881337;
--base-color-rose-1000: #4c0519;
/* Secondary - Violet */
--base-color-violet-100: #f5f3ff;
--base-color-violet-200: #ede9fe;
--base-color-violet-300: #ddd6fe;
--base-color-violet-400: #c4b5fd;
--base-color-violet-500: #a78bfa;
--base-color-violet-600: #8b5cf6;
--base-color-violet-700: #7c3aed;
--base-color-violet-800: #6d28d9;
--base-color-violet-900: #5b21b6;
--base-color-violet-1000: #2e1065;
/* Amber - For warnings/notices */
--base-color-amber-100: #fffbeb;
--base-color-amber-200: #fef3c7;
--base-color-amber-300: #fcd34d;
--base-color-amber-400: #fbbf24;
--base-color-amber-500: #f59e0b;
--base-color-amber-600: #d97706;
--base-color-amber-700: #b45309;
--base-color-amber-800: #92400e;
--base-color-amber-900: #78350f;
--base-color-amber-1000: #451a03;
/* ---------------------------------------------------------------------------
UI NEUTRALS - Clean Zinc palette
--------------------------------------------------------------------------- */
--base-color-zinc-50: #fafafa;
--base-color-zinc-100: #f4f4f5;
--base-color-zinc-200: #e4e4e7;
--base-color-zinc-300: #d4d4d8;
--base-color-zinc-400: #a1a1aa;
--base-color-zinc-500: #71717a;
--base-color-zinc-600: #52525b;
--base-color-zinc-700: #3f3f46;
--base-color-zinc-800: #27272a;
--base-color-zinc-900: #18181b;
--base-color-zinc-950: #09090b;
/* Transparent variants */
--base-color-zinc-950-transparent: rgba(9, 9, 11, 0.85);
--base-color-zinc-950-transparent-light: rgba(9, 9, 11, 0.5);
--base-color-white-transparent: rgba(255, 255, 255, 0.08);
/* ---------------------------------------------------------------------------
LEGACY ALIASES - For backwards compatibility
--------------------------------------------------------------------------- */
--base-color-grey-100: var(--base-color-zinc-100);
--base-color-grey-100-transparent: rgba(244, 244, 245, 0.13);
--base-color-grey-200: var(--base-color-zinc-200);
--base-color-grey-300: var(--base-color-zinc-300);
--base-color-grey-400: var(--base-color-zinc-400);
--base-color-grey-500: var(--base-color-zinc-500);
--base-color-grey-600: var(--base-color-zinc-600);
--base-color-grey-700: var(--base-color-zinc-700);
--base-color-grey-800: var(--base-color-zinc-800);
--base-color-grey-900: var(--base-color-zinc-900);
--base-color-grey-1000: var(--base-color-zinc-950);
--base-color-grey-1000-transparent: var(--base-color-zinc-950-transparent);
--base-color-grey-1000-transparent-2: var(--base-color-zinc-950-transparent-light);
--base-color-teal-100: var(--base-color-violet-100);
--base-color-teal-200: var(--base-color-violet-200);
--base-color-teal-300: var(--base-color-violet-300);
--base-color-teal-400: var(--base-color-violet-400);
--base-color-teal-500: var(--base-color-violet-500);
--base-color-teal-600: var(--base-color-violet-600);
--base-color-teal-700: var(--base-color-violet-700);
--base-color-teal-800: var(--base-color-violet-800);
--base-color-teal-900: var(--base-color-violet-900);
--base-color-teal-1000: var(--base-color-violet-1000);
--base-color-yellow-100: var(--base-color-rose-100);
--base-color-yellow-200: var(--base-color-rose-200);
--base-color-yellow-300: var(--base-color-rose-300);
--base-color-yellow-400: var(--base-color-rose-400);
--base-color-yellow-500: var(--base-color-rose-500);
--base-color-yellow-600: var(--base-color-rose-600);
--base-color-yellow-700: var(--base-color-rose-700);
--base-color-yellow-800: var(--base-color-rose-800);
--base-color-yellow-900: var(--base-color-rose-900);
--base-color-yellow-1000: var(--base-color-rose-1000);
}
/* =============================================================================
THEME COLOR TOKENS - USE THESE IN COMPONENTS
============================================================================= */
:root {
/* Backgrounds */
--theme-color-bg-0: #000000;
--theme-color-bg-1: var(--base-color-zinc-950);
--theme-color-bg-1-transparent: var(--base-color-zinc-950-transparent);
--theme-color-bg-1-transparent-2: var(--base-color-zinc-950-transparent-light);
--theme-color-bg-2: var(--base-color-zinc-900);
--theme-color-bg-3: var(--base-color-zinc-800);
--theme-color-bg-4: var(--base-color-zinc-700);
--theme-color-bg-5: var(--base-color-zinc-600);
--theme-color-bg-hover: var(--base-color-white-transparent);
/* Foregrounds */
--theme-color-fg-highlight: #ffffff;
--theme-color-fg-default-contrast: var(--base-color-zinc-100);
--theme-color-fg-default: var(--base-color-zinc-300);
--theme-color-fg-default-shy: var(--base-color-zinc-400);
--theme-color-fg-muted: var(--base-color-zinc-500);
--theme-color-fg-transparent: var(--base-color-grey-100-transparent);
/* Primary - Rose */
--theme-color-primary: var(--base-color-rose-500);
--theme-color-primary-highlight: var(--base-color-rose-400);
--theme-color-primary-dim: var(--base-color-rose-700);
--theme-color-on-primary: #ffffff;
/* Secondary - Violet */
--theme-color-secondary: var(--base-color-violet-500);
--theme-color-secondary-dim: var(--base-color-violet-700);
--theme-color-secondary-highlight: var(--base-color-violet-400);
--theme-color-secondary-bright: var(--base-color-violet-300);
--theme-color-secondary-as-fg: var(--base-color-violet-400);
--theme-color-on-secondary: #ffffff;
/* Node Colors */
--theme-color-node-data-1: var(--base-color-node-green-700);
--theme-color-node-data-2: var(--base-color-node-green-600);
--theme-color-node-data-3: var(--base-color-node-green-500);
--theme-color-node-data-dim: var(--base-color-node-green-900);
--theme-color-node-visual-1: var(--base-color-node-blue-700);
--theme-color-node-visual-2: var(--base-color-node-blue-600);
--theme-color-node-visual-2-highlight: var(--base-color-node-blue-500);
--theme-color-node-visual-highlight: var(--base-color-node-blue-200);
--theme-color-node-visual-default: var(--base-color-node-blue-300);
--theme-color-node-visual-shy: var(--base-color-node-blue-400);
--theme-color-node-visual-dim: var(--base-color-node-blue-900);
--theme-color-node-custom-1: var(--base-color-node-pink-700);
--theme-color-node-custom-2: var(--base-color-node-pink-600);
--theme-color-node-custom-dim: var(--base-color-node-pink-900);
--theme-color-node-logic-1: var(--base-color-node-grey-700);
--theme-color-node-logic-2: var(--base-color-node-grey-600);
--theme-color-node-logic-dim: var(--base-color-node-grey-900);
--theme-color-node-component-1: var(--base-color-node-purple-700);
--theme-color-node-component-2: var(--base-color-node-purple-600);
--theme-color-node-component-dim: var(--base-color-node-purple-900);
/* Status Colors */
--theme-color-success: var(--base-color-success-400);
--theme-color-success-dim: var(--base-color-success-600);
--theme-color-success-bg: var(--base-color-success-900);
--theme-color-notice: var(--base-color-amber-400);
--theme-color-notice-dim: var(--base-color-amber-600);
--theme-color-notice-bg: var(--base-color-amber-900);
--theme-color-danger: var(--base-color-error-400);
--theme-color-danger-light: var(--base-color-error-300);
--theme-color-danger-dim: var(--base-color-error-600);
--theme-color-danger-bg: var(--base-color-error-900);
/* Connection Colors */
--theme-color-signal: var(--base-color-rose-400);
--theme-color-data: var(--base-color-violet-500);
/* Border Colors */
--theme-color-border-default: var(--base-color-zinc-700);
--theme-color-border-subtle: var(--base-color-zinc-800);
--theme-color-border-strong: var(--base-color-zinc-600);
/* Focus Ring */
--theme-color-focus-ring: var(--base-color-rose-500);
--theme-color-focus-ring-offset: var(--base-color-zinc-950);
}
```
---
## Success Criteria
### Visual
- [ ] App feels modern and professional
- [ ] Colors are consistent throughout
- [ ] Good contrast and readability
- [ ] Visual hierarchy is clear
### Technical
- [ ] All colors use design tokens
- [ ] No hardcoded hex colors in component styles
- [ ] Token system supports future theming
- [ ] No visual regressions
### User Experience
- [ ] Migration dialog is clear and professional
- [ ] Interactive states (hover, focus) are obvious
- [ ] Success/error feedback is clear
- [ ] Overall polish matches modern dev tools

View File

@@ -0,0 +1,125 @@
# TASK-000: Design System Modernization - Task Index
## Overview
This is the master task for OpenNoodl's UI overhaul, broken down into 8 sub-tasks for incremental implementation.
**Color Scheme**: RED-MINIMAL palette
- **Primary**: Noodl Red (`#d21f3c`)
- **Secondary**: White (`#ffffff`)
- **Neutrals**: Pure black/gray (no color tint)
---
## Sub-Task Summary
| Task | Name | Priority | Effort | Dependencies |
|------|------|----------|--------|--------------|
| **000A** | Token Consolidation & Color Refresh | CRITICAL | 30 min | None |
| **000B** | Hardcoded Colors - Legacy Styles | HIGH | 1-2 hrs | 000A |
| **000C** | Hardcoded Colors - Node Graph | HIGH | 1-2 hrs | 000A |
| **000D** | Hardcoded Colors - Core UI | HIGH | 1-2 hrs | 000A |
| **000E** | Typography & Spacing Tokens | MEDIUM | 1 hr | 000A |
| **000F** | Component Updates - Buttons/Inputs | MEDIUM | 1-2 hrs | 000A, 000D, 000E |
| **000G** | Component Updates - Dialogs/Panels | MEDIUM | 1-2 hrs | 000A, 000D, 000E |
| **000H** | Migration Wizard Polish | HIGH | 1-2 hrs | 000A-000G |
**Total Estimated Effort**: 8-14 hours
---
## Recommended Execution Order
### Phase 1: Foundation (Do First)
1. **TASK-000A** - Token Consolidation & Color Refresh
- This is the foundation - everything else depends on it
- Location: `../TASK-000A-token-consolidation/OVERVIEW.md`
### Phase 2: Color Audit (Can Parallelize)
These can be done in any order after 000A:
2. **TASK-000B** - Hardcoded Colors - Legacy Styles
- Location: `../TASK-000B-hardcoded-colors-legacy/OVERVIEW.md`
3. **TASK-000C** - Hardcoded Colors - Node Graph
- Location: `../TASK-000C-hardcoded-colors-nodegraph/OVERVIEW.md`
4. **TASK-000D** - Hardcoded Colors - Core UI
- Location: `../TASK-000D-hardcoded-colors-coreui/OVERVIEW.md`
5. **TASK-000E** - Typography & Spacing Tokens
- Can be done independently
- Location: `../TASK-000E-typography-spacing/OVERVIEW.md`
### Phase 3: Visual Polish (After Color Audit)
6. **TASK-000F** - Component Updates - Buttons/Inputs
- Location: `../TASK-000F-component-buttons-inputs/OVERVIEW.md`
7. **TASK-000G** - Component Updates - Dialogs/Panels
- Location: `../TASK-000G-component-dialogs-panels/OVERVIEW.md`
### Phase 4: Final Polish
8. **TASK-000H** - Migration Wizard Polish
- Should be last as it benefits from all prior work
- Location: `../TASK-000H-migration-wizard-polish/OVERVIEW.md`
---
## Key Files Reference
### Color Token Files
- `packages/noodl-editor/src/editor/src/styles/custom-properties/colors.css` (primary)
- `packages/noodl-core-ui/src/styles/custom-properties/colors.css` (secondary)
### Color Source
- `dev-docs/tasks/phase-3/TASK-000-styles-overhaul/COLORS-RED-MINIMAL.md`
### Entry Points to Verify
- `packages/noodl-editor/src/editor/index.ts`
- `packages/noodl-core-ui/.storybook/preview.ts`
---
## Success Criteria (All Tasks Complete)
### Technical
- [ ] All colors use CSS variables (no hardcoded hex in styles)
- [ ] Token system supports future light theme
- [ ] Typography and spacing tokens available
### Visual
- [ ] App uses consistent RED-MINIMAL palette
- [ ] Pure dark backgrounds (no warm/brown tint)
- [ ] Primary accent is red (`#d21f3c`)
- [ ] Good contrast and readability
### User Experience
- [ ] Migration wizard looks polished
- [ ] Interactive states are obvious
- [ ] Overall feel matches modern dev tools
---
## Verification Commands
After all tasks complete:
```bash
# Check for remaining hardcoded colors in styles
grep -rn "#[0-9a-fA-F]\{6\}" packages/noodl-editor/src/editor/src/styles/ --include="*.css" --include="*.scss" | wc -l
# Check views directory
grep -rn "#[0-9a-fA-F]\{6\}" packages/noodl-editor/src/editor/src/views/ --include="*.css" --include="*.scss" | wc -l
# Check core-ui components
grep -rn "#[0-9a-fA-F]\{6\}" packages/noodl-core-ui/src/components/ --include="*.css" --include="*.scss" | wc -l
```
**Target: Near-zero hardcoded colors** (some node-specific colors may remain intentionally)
---
## Related Documents
- `DESIGN-SYSTEM-MODERNISATION.md` - Original detailed planning document
- `COLORS-RED-MINIMAL.md` - Complete CSS palette to use

View File

@@ -0,0 +1,131 @@
# TASK-000A: Token Consolidation & Color Refresh
## Overview
Replace the color token files with the new RED-MINIMAL palette. This is the foundation task - all other style tasks depend on this being completed first.
**Priority:** CRITICAL
**Effort:** 30 minutes
**Risk:** Low
**Dependencies:** None
---
## Objective
Consolidate color definitions to a single source of truth using the RED-MINIMAL palette:
- **Primary**: Noodl Red (`#d21f3c`)
- **Secondary**: White (`#ffffff`)
- **Neutrals**: Pure black/gray (no color tint)
---
## Files to Modify
### Primary Target
```
packages/noodl-editor/src/editor/src/styles/custom-properties/colors.css
```
This is the file actually imported by the editor.
### Secondary Target
```
packages/noodl-core-ui/src/styles/custom-properties/colors.css
```
Should contain identical content for Storybook and component development.
### Verify These Entry Points
- `packages/noodl-editor/src/editor/index.ts` - Confirm which colors.css is imported
- `packages/noodl-editor/src/frames/viewer-frame/index.js` - Verify viewer uses same tokens
- `packages/noodl-core-ui/.storybook/preview.ts` - Verify Storybook imports
---
## Implementation Steps
### Step 1: Backup Current Colors
Before making changes, note what the current colors look like for visual comparison.
### Step 2: Replace Editor colors.css
Copy the contents from `dev-docs/tasks/phase-3/TASK-000-styles-overhaul/COLORS-RED-MINIMAL.md` to:
```
packages/noodl-editor/src/editor/src/styles/custom-properties/colors.css
```
Note: The COLORS-RED-MINIMAL.md file contains CSS in markdown format. Copy the CSS content only.
### Step 3: Update Core UI colors.css
Copy the same content to:
```
packages/noodl-core-ui/src/styles/custom-properties/colors.css
```
### Step 4: Verify Imports
Confirm in `packages/noodl-editor/src/editor/index.ts`:
```typescript
// Should be using the editor's copy (not core-ui)
import '../editor/src/styles/custom-properties/colors.css';
```
### Step 5: Build & Test
```bash
npm run build:editor
npm run dev
```
---
## Key Color Mappings
| Token | Value | Usage |
|-------|-------|-------|
| `--theme-color-primary` | `#d21f3c` | Primary buttons, CTAs, focus rings |
| `--theme-color-secondary` | `#ffffff` | Secondary actions |
| `--theme-color-bg-1` | `#0a0a0a` | Main app background |
| `--theme-color-bg-2` | `#121212` | Panel backgrounds |
| `--theme-color-bg-3` | `#1a1a1a` | Card/input backgrounds |
| `--theme-color-fg-default` | `#d4d4d4` | Default text color |
| `--theme-color-fg-muted` | `#737373` | Secondary text |
---
## Testing Checklist
- [ ] App compiles without errors
- [ ] App background is pure dark (not brownish/warm)
- [ ] Primary buttons show red color (`#d21f3c`)
- [ ] Text is readable with good contrast
- [ ] Node colors on canvas still distinguishable
- [ ] Success states show green
- [ ] Error states show red
- [ ] No console errors about missing CSS variables
- [ ] Storybook still works
---
## Expected Visual Changes
After applying:
- **Backgrounds**: Will shift from warm/brownish grays to pure neutral blacks
- **Primary Color**: Yellow/teal accent → Red accent
- **Secondary Color**: Teal → White/neutral
- **Overall Feel**: Cleaner, more modern, higher contrast
---
## Rollback Plan
If something breaks, the original color file can be restored from git:
```bash
git checkout HEAD -- packages/noodl-editor/src/editor/src/styles/custom-properties/colors.css
git checkout HEAD -- packages/noodl-core-ui/src/styles/custom-properties/colors.css
```
---
## Success Criteria
- [ ] Both color files contain identical RED-MINIMAL palette
- [ ] Editor runs without visual regressions
- [ ] All existing functionality unchanged
- [ ] Ready for hardcoded color audit (next tasks)

View File

@@ -0,0 +1,197 @@
# TASK-000B: Hardcoded Color Audit - Legacy Styles
## Overview
Find and replace all hardcoded hex colors in the legacy styles directory. This eliminates inconsistencies and ensures all colors can be changed via design tokens.
**Priority:** HIGH
**Effort:** 1-2 hours
**Risk:** Low-Medium
**Dependencies:** TASK-000A (Token Consolidation)
---
## Objective
Replace all hardcoded hex color values with CSS variable references in the legacy styles directory, ensuring centralized color control.
---
## Target Directory
```
packages/noodl-editor/src/editor/src/styles/
```
---
## Step 1: Find All Hardcoded Colors
Run this search to identify all hardcoded hex colors:
```bash
# Find all hex colors in CSS/SCSS files
grep -rn "#[0-9a-fA-F]\{3,8\}" packages/noodl-editor/src/editor/src/styles/ --include="*.css" --include="*.scss"
```
Or use VSCode search with regex:
```
#[0-9a-fA-F]{3,8}
```
---
## Step 2: Color Mapping Reference
Use this mapping to convert hardcoded colors to tokens:
### Background Colors
| Hardcoded | Token | Notes |
|-----------|-------|-------|
| `#000000`, `#000` | `var(--theme-color-bg-0)` | Pure black |
| `#0a0a0a`, `#0d0d0d`, `#111`, `#111111` | `var(--theme-color-bg-1)` | Near black |
| `#121212`, `#151515`, `#141414` | `var(--theme-color-bg-2)` | Dark panels |
| `#1a1a1a`, `#191919`, `#1c1c1c` | `var(--theme-color-bg-3)` | Elevated panels |
| `#262626`, `#252525`, `#282828` | `var(--theme-color-bg-4)` | Cards |
| `#333333`, `#303030`, `#363636` | `var(--theme-color-bg-5)` | Highest elevation |
### Text/Foreground Colors
| Hardcoded | Token | Notes |
|-----------|-------|-------|
| `#ffffff`, `#fff` | `var(--theme-color-fg-highlight)` | Bright white |
| `#e5e5e5`, `#eaeaea`, `#eeeeee` | `var(--theme-color-fg-default-contrast)` | High contrast text |
| `#d4d4d4`, `#cccccc`, `#c8c8c8` | `var(--theme-color-fg-default)` | Default text |
| `#a3a3a3`, `#aaaaaa`, `#9e9e9e` | `var(--theme-color-fg-default-shy)` | Secondary text |
| `#737373`, `#666666`, `#707070` | `var(--theme-color-fg-muted)` | Muted/disabled text |
### Border Colors
| Hardcoded | Token | Notes |
|-----------|-------|-------|
| `#262626`, `#2a2a2a` | `var(--theme-color-border-subtle)` | Subtle borders |
| `#333333`, `#363636` | `var(--theme-color-border-default)` | Default borders |
| `#444444`, `#4a4a4a` | `var(--theme-color-border-strong)` | Strong borders |
### Accent Colors
| Hardcoded | Token | Notes |
|-----------|-------|-------|
| `#d21f3c`, `#e11d48`, `#dc2626` | `var(--theme-color-primary)` | Primary red |
| Any teal/cyan colors | `var(--theme-color-secondary)` | Now white |
### Status Colors
| Hardcoded | Token | Notes |
|-----------|-------|-------|
| `#10b981`, `#22c55e` (green) | `var(--theme-color-success)` | Success |
| `#ef4444`, `#dc2626` (red) | `var(--theme-color-danger)` | Danger/Error |
| `#f59e0b`, `#fbbf24` (yellow) | `var(--theme-color-notice)` | Warning |
---
## Step 3: Priority Files to Fix
Process these files in order of importance:
### Critical (High Impact)
1. **`popuplayer.css`** - All popup/dropdown backgrounds
2. **`propertyeditor.css`** - Property panel styling
3. **`common.css`** / `base.css` - Global styles
### Important
4. **`projectsview.css`** - Dashboard/projects list
5. **`sidepanel.css`** - Side panel backgrounds
6. **`menubar.css`** - Top menu styling
### Secondary
7. All remaining `.css` and `.scss` files in the directory
---
## Step 4: Implementation Pattern
For each hardcoded color found:
```css
/* BEFORE - Hardcoded */
.popup {
background: #1a1a1a;
border: 1px solid #333333;
color: #d4d4d4;
}
/* AFTER - Tokenized */
.popup {
background: var(--theme-color-bg-3);
border: 1px solid var(--theme-color-border-default);
color: var(--theme-color-fg-default);
}
```
---
## Step 5: Handle Edge Cases
### Colors Not in Token System
If you find a color that doesn't map to any token:
1. Check if it's close enough to an existing token
2. If unique and necessary, add it to colors.css
3. Document why the new token was needed
### RGBA Colors
Convert rgba values too:
```css
/* BEFORE */
background: rgba(0, 0, 0, 0.8);
/* AFTER */
background: var(--base-color-black-transparent-80);
```
### Gradient Colors
For gradients, replace each color in the gradient:
```css
/* BEFORE */
background: linear-gradient(#1a1a1a, #121212);
/* AFTER */
background: linear-gradient(var(--theme-color-bg-3), var(--theme-color-bg-2));
```
---
## Testing Checklist
After each file is updated:
- [ ] No CSS compilation errors
- [ ] Visual appearance matches original (or is intentionally improved)
- [ ] Hover states still work
- [ ] Focus states visible
- [ ] No missing backgrounds (transparent where should be solid)
- [ ] Text contrast is acceptable
### Full Test After All Changes
- [ ] Open/close all popup types
- [ ] Property editor functions correctly
- [ ] Menus display correctly
- [ ] No visual regressions in editor
---
## Verification Command
After completing, run this to ensure no hardcoded colors remain:
```bash
# Should return minimal results (only node-specific colors are acceptable)
grep -rn "#[0-9a-fA-F]\{6\}" packages/noodl-editor/src/editor/src/styles/ --include="*.css" --include="*.scss" | grep -v "node-" | wc -l
```
**Target: 0 hardcoded UI colors remaining**
---
## Success Criteria
- [ ] All UI colors in `packages/noodl-editor/src/editor/src/styles/` use CSS variables
- [ ] No visual regressions
- [ ] Grep search returns no hardcoded hex colors (except node-specific)
- [ ] Ready for component-level audit (TASK-000C, 000D)

View File

@@ -0,0 +1,202 @@
# TASK-000C: Hardcoded Color Audit - Node Graph Editor
## Overview
Find and replace all hardcoded hex colors in the node graph editor views directory. This is a high-visibility area where users spend most of their time.
**Priority:** HIGH
**Effort:** 1-2 hours
**Risk:** Low-Medium
**Dependencies:** TASK-000A (Token Consolidation)
---
## Objective
Replace all hardcoded hex color values in the node graph editor views with CSS variable references.
---
## Target Directory
```
packages/noodl-editor/src/editor/src/views/
```
Focus especially on:
```
packages/noodl-editor/src/editor/src/views/nodegrapheditor/
packages/noodl-editor/src/editor/src/views/ConnectionPopup/
```
---
## Step 1: Find All Hardcoded Colors
```bash
# Find all hex colors in views directory
grep -rn "#[0-9a-fA-F]\{3,8\}" packages/noodl-editor/src/editor/src/views/ --include="*.css" --include="*.scss"
```
---
## Step 2: Priority Files
### Critical Files
1. **`InspectPopup.module.scss`**
- `packages/noodl-editor/src/editor/src/views/nodegrapheditor/InspectJSONView/InspectPopup.module.scss`
- Used for debugging/inspecting node values
2. **`ConnectionPopup.module.scss`**
- `packages/noodl-editor/src/editor/src/views/ConnectionPopup/ConnectionPopup.module.scss`
- Shown when creating connections between nodes
3. **Node Graph Editor Styles**
- Any `.css` or `.scss` files in `nodegrapheditor/` directory
### Other View Files
4. **Migration Wizard files** (if any remain hardcoded)
- `packages/noodl-editor/src/editor/src/views/migration/`
5. **Project views**
- `packages/noodl-editor/src/editor/src/views/projectsview.ts` (check inline styles)
---
## Step 3: Node-Specific Color Handling
**IMPORTANT**: Some colors in node graph views are intentionally distinct for different node types. These should use the node-specific tokens, not general UI tokens:
### Node Type Color Tokens
```css
/* Data nodes - Green */
var(--theme-color-node-data-1)
var(--theme-color-node-data-2)
var(--theme-color-node-data-3)
/* Visual nodes - Blue */
var(--theme-color-node-visual-1)
var(--theme-color-node-visual-2)
/* Custom nodes - Pink */
var(--theme-color-node-custom-1)
var(--theme-color-node-custom-2)
/* Logic nodes - Gray */
var(--theme-color-node-logic-1)
var(--theme-color-node-logic-2)
/* Component nodes - Purple */
var(--theme-color-node-component-1)
var(--theme-color-node-component-2)
```
### Connection Color Tokens
```css
/* Signal connections (events) */
var(--theme-color-signal) /* Red */
/* Data connections (values) */
var(--theme-color-data) /* Gray/neutral */
```
---
## Step 4: Color Mapping for Views
### Background Colors (same as TASK-000B)
| Hardcoded | Token |
|-----------|-------|
| `#0a0a0a`, `#111111` | `var(--theme-color-bg-1)` |
| `#121212`, `#151515` | `var(--theme-color-bg-2)` |
| `#1a1a1a`, `#191919` | `var(--theme-color-bg-3)` |
| `#262626`, `#282828` | `var(--theme-color-bg-4)` |
| `#333333`, `#363636` | `var(--theme-color-bg-5)` |
### Foreground Colors
| Hardcoded | Token |
|-----------|-------|
| `#ffffff`, `#fff` | `var(--theme-color-fg-highlight)` |
| `#d4d4d4`, `#cccccc` | `var(--theme-color-fg-default)` |
| `#a3a3a3`, `#999999` | `var(--theme-color-fg-default-shy)` |
| `#737373`, `#666666` | `var(--theme-color-fg-muted)` |
### Popup/Dialog Colors
| Hardcoded | Token |
|-----------|-------|
| Dark backgrounds | `var(--theme-color-bg-3)` |
| Borders | `var(--theme-color-border-default)` |
| Hover states | `var(--theme-color-bg-hover)` |
---
## Step 5: Check for Inline Styles in TSX/JSX
Some TypeScript/React files may have inline styles with hardcoded colors:
```bash
# Find hardcoded colors in TypeScript files
grep -rn "['\"](#[0-9a-fA-F]\{3,8\})['\"]" packages/noodl-editor/src/editor/src/views/ --include="*.tsx" --include="*.ts"
```
If found, convert to CSS class or use CSS variables:
```tsx
// BEFORE - Inline hardcoded
<div style={{ background: '#1a1a1a' }}>
// AFTER - Use CSS variable
<div style={{ background: 'var(--theme-color-bg-3)' }}>
// BEST - Use CSS class
<div className={styles.container}>
```
---
## Testing Checklist
### InspectPopup
- [ ] Opens correctly when debugging nodes
- [ ] Text is readable
- [ ] JSON syntax highlighting still works (if applicable)
- [ ] Scrollable content works
### ConnectionPopup
- [ ] Opens when dragging connections
- [ ] List items readable and clickable
- [ ] Hover states visible
- [ ] Search/filter works (if applicable)
### Node Graph Editor
- [ ] Node colors are distinguishable by type
- [ ] Connection lines render correctly
- [ ] Selection highlights visible
- [ ] Canvas background correct
- [ ] Zoom/pan doesn't break colors
### General
- [ ] No CSS errors in console
- [ ] No visual regressions
- [ ] All interactive states work
---
## Verification Command
```bash
# Check for remaining hardcoded colors in views
grep -rn "#[0-9a-fA-F]\{6\}" packages/noodl-editor/src/editor/src/views/ --include="*.css" --include="*.scss" | grep -v "node-color" | wc -l
```
**Target: 0 hardcoded UI colors (only intentional node-specific colors allowed)**
---
## Success Criteria
- [ ] All UI colors in views directory use CSS variables
- [ ] Node-specific colors use appropriate node tokens
- [ ] Connection colors use signal/data tokens
- [ ] Popups look consistent with rest of UI
- [ ] No visual regressions in node editor

View File

@@ -0,0 +1,262 @@
# TASK-000D: Hardcoded Color Audit - Core UI Components
## Overview
Find and replace all hardcoded hex colors in the shared Core UI component library. These components are used throughout the editor, so fixing them has wide impact.
**Priority:** HIGH
**Effort:** 1-2 hours
**Risk:** Low-Medium
**Dependencies:** TASK-000A (Token Consolidation)
---
## Objective
Replace all hardcoded hex color values in `noodl-core-ui` components with CSS variable references, ensuring consistent theming across all shared components.
---
## Target Directory
```
packages/noodl-core-ui/src/components/
```
---
## Step 1: Find All Hardcoded Colors
```bash
# Find all hex colors in core-ui components
grep -rn "#[0-9a-fA-F]\{3,8\}" packages/noodl-core-ui/src/components/ --include="*.css" --include="*.scss"
```
List total files to fix:
```bash
grep -rl "#[0-9a-fA-F]\{3,8\}" packages/noodl-core-ui/src/components/ --include="*.css" --include="*.scss"
```
---
## Step 2: Component Categories to Audit
### Input Components (`inputs/`)
Priority files:
- `PrimaryButton/PrimaryButton.module.scss`
- `TextInput/TextInput.module.scss`
- `Select/Select.module.scss`
- `Checkbox/Checkbox.module.scss`
- `Slider/Slider.module.scss`
### Layout Components (`layout/`)
Priority files:
- `BaseDialog/BaseDialog.module.scss`
- `DialogRenderRoot/DialogRenderRoot.module.scss`
- `Container/Container.module.scss`
### Sidebar Components (`sidebar/`)
Priority files:
- `BasePanel/BasePanel.module.scss`
- `Section/Section.module.scss`
- `SidebarItem/SidebarItem.module.scss`
### Typography Components (`typography/`)
- `Text/Text.module.scss`
- `Label/Label.module.scss`
- `Title/Title.module.scss`
### Common Components (`common/`)
- `Icon/Icon.module.scss`
- `Tooltip/Tooltip.module.scss`
- Any other shared components
---
## Step 3: Color Mapping Reference
### Background Colors
| Hardcoded | Token | Usage |
|-----------|-------|-------|
| `#000000` | `var(--theme-color-bg-0)` | Darkest backgrounds |
| `#0a0a0a` | `var(--theme-color-bg-1)` | App background |
| `#121212` | `var(--theme-color-bg-2)` | Panel backgrounds |
| `#1a1a1a` | `var(--theme-color-bg-3)` | Input/card backgrounds |
| `#262626` | `var(--theme-color-bg-4)` | Elevated elements |
| `#333333` | `var(--theme-color-bg-5)` | Highest elevation |
### Foreground Colors
| Hardcoded | Token | Usage |
|-----------|-------|-------|
| `#ffffff` | `var(--theme-color-fg-highlight)` | Bright text |
| `#e5e5e5` | `var(--theme-color-fg-default-contrast)` | High contrast |
| `#d4d4d4` | `var(--theme-color-fg-default)` | Default text |
| `#a3a3a3` | `var(--theme-color-fg-default-shy)` | Secondary text |
| `#737373` | `var(--theme-color-fg-muted)` | Muted/disabled |
### Primary/Accent Colors
| Hardcoded | Token | Usage |
|-----------|-------|-------|
| Old yellow/teal | `var(--theme-color-primary)` | Now red primary |
| `#d21f3c` | `var(--theme-color-primary)` | Primary buttons |
| Any purple/violet | `var(--theme-color-secondary)` | Now white |
### Button-Specific
| State | Token |
|-------|-------|
| Default BG | `var(--theme-color-bg-4)` or `var(--theme-color-primary)` |
| Hover BG | `var(--theme-color-bg-5)` or `var(--theme-color-primary-highlight)` |
| Active BG | `var(--theme-color-bg-3)` or `var(--theme-color-primary-dim)` |
| Disabled | Use opacity or `var(--theme-color-fg-muted)` |
### Input-Specific
| Element | Token |
|---------|-------|
| Background | `var(--theme-color-bg-3)` |
| Border | `var(--theme-color-border-default)` |
| Border focused | `var(--theme-color-focus-ring)` |
| Placeholder | `var(--theme-color-fg-muted)` |
---
## Step 4: Examples
### Button Before/After
```scss
// BEFORE
.button {
background: #363636;
color: #ffffff;
&:hover {
background: #444444;
}
}
// AFTER
.button {
background: var(--theme-color-bg-5);
color: var(--theme-color-fg-highlight);
&:hover {
background: var(--theme-color-bg-hover);
}
}
```
### Input Before/After
```scss
// BEFORE
.input {
background: #1a1a1a;
border: 1px solid #333333;
color: #d4d4d4;
&::placeholder {
color: #666666;
}
&:focus {
border-color: #d21f3c;
}
}
// AFTER
.input {
background: var(--theme-color-bg-3);
border: 1px solid var(--theme-color-border-default);
color: var(--theme-color-fg-default);
&::placeholder {
color: var(--theme-color-fg-muted);
}
&:focus {
border-color: var(--theme-color-focus-ring);
}
}
```
---
## Step 5: Check Storybook
After updating components, verify in Storybook:
```bash
npm run storybook
```
Navigate to each updated component and check:
- Default state renders correctly
- All variants look correct
- Interactive states work (hover, focus, active, disabled)
- Dark theme shows proper contrast
---
## Testing Checklist
### Per Component Type
#### Buttons
- [ ] Primary button is red (`#d21f3c`)
- [ ] Secondary button is neutral/white
- [ ] Hover states visible
- [ ] Focus ring visible
- [ ] Disabled state clear
#### Inputs
- [ ] Input background visible
- [ ] Border visible
- [ ] Focus state shows red ring
- [ ] Placeholder text visible but muted
- [ ] Error state shows red
#### Dialogs
- [ ] Dialog background distinct from page
- [ ] Backdrop visible
- [ ] Header/body/footer sections clear
- [ ] Close button visible
#### Panels/Sidebar
- [ ] Panel backgrounds correct
- [ ] Section headers readable
- [ ] Hover states on items
- [ ] Active/selected state visible
### Global Tests
- [ ] Storybook renders without errors
- [ ] All component stories pass visual check
- [ ] No broken contrast (text unreadable)
---
## Verification Command
```bash
# Check for remaining hardcoded colors
grep -rn "#[0-9a-fA-F]\{6\}" packages/noodl-core-ui/src/components/ --include="*.css" --include="*.scss" | wc -l
```
**Target: 0 hardcoded colors**
---
## Documentation
If you need to add any new tokens to handle edge cases, document them:
1. Add token to `colors.css`
2. Update this task's notes
3. Add comment explaining the token's purpose
---
## Success Criteria
- [ ] All components in `noodl-core-ui` use CSS variables
- [ ] Storybook shows all components correctly
- [ ] No hardcoded hex colors in component styles
- [ ] Consistent appearance across all components
- [ ] Ready for visual refinements (TASK-000F, 000G)

View File

@@ -0,0 +1,337 @@
# TASK-000E: Typography & Spacing Tokens
## Overview
Add comprehensive typography and spacing token systems to enable consistent sizing across the application. This lays the foundation for future UI refinements.
**Priority:** MEDIUM
**Effort:** 1 hour
**Risk:** Low
**Dependencies:** TASK-000A (Token Consolidation)
---
## Objective
Create a robust system of typography and spacing tokens that components can use for consistent sizing, spacing, and visual rhythm throughout the editor.
---
## Part 1: Update Font Tokens
### File to Modify
```
packages/noodl-core-ui/src/styles/custom-properties/fonts.css
```
### New Font Token System
Replace contents with:
```css
/* =============================================================================
NOODL DESIGN SYSTEM - TYPOGRAPHY
============================================================================= */
:root {
/* ---------------------------------------------------------------------------
FONT FAMILIES
--------------------------------------------------------------------------- */
--font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
--font-family-code: 'JetBrains Mono', 'Fira Code', Menlo, Monaco, 'Courier New', monospace;
/* ---------------------------------------------------------------------------
FONT WEIGHTS
--------------------------------------------------------------------------- */
--font-weight-light: 300;
--font-weight-regular: 400;
--font-weight-medium: 500;
--font-weight-semibold: 600;
--font-weight-bold: 700;
/* ---------------------------------------------------------------------------
FONT SIZES
Fluid scale from 10px to 24px
--------------------------------------------------------------------------- */
--font-size-xs: 10px; /* Small labels, hints */
--font-size-sm: 11px; /* Secondary text, captions */
--font-size-base: 12px; /* Default body text */
--font-size-md: 13px; /* Emphasized body text */
--font-size-lg: 14px; /* Section titles, important */
--font-size-xl: 16px; /* Panel titles */
--font-size-2xl: 18px; /* Dialog titles */
--font-size-3xl: 24px; /* Page titles, hero text */
/* ---------------------------------------------------------------------------
LINE HEIGHTS
--------------------------------------------------------------------------- */
--line-height-none: 1;
--line-height-tight: 1.2;
--line-height-snug: 1.375;
--line-height-normal: 1.5;
--line-height-relaxed: 1.625;
--line-height-loose: 2;
/* ---------------------------------------------------------------------------
LETTER SPACING
--------------------------------------------------------------------------- */
--letter-spacing-tighter: -0.05em;
--letter-spacing-tight: -0.025em;
--letter-spacing-normal: 0;
--letter-spacing-wide: 0.025em;
--letter-spacing-wider: 0.05em;
--letter-spacing-widest: 0.1em;
/* ---------------------------------------------------------------------------
SEMANTIC TEXT STYLES
Pre-composed styles for common use cases
--------------------------------------------------------------------------- */
/* Body text */
--text-body-size: var(--font-size-base);
--text-body-weight: var(--font-weight-regular);
--text-body-line-height: var(--line-height-normal);
/* Small text */
--text-small-size: var(--font-size-sm);
--text-small-weight: var(--font-weight-regular);
--text-small-line-height: var(--line-height-normal);
/* Labels */
--text-label-size: var(--font-size-xs);
--text-label-weight: var(--font-weight-medium);
--text-label-letter-spacing: var(--letter-spacing-wide);
/* Code */
--text-code-size: var(--font-size-sm);
--text-code-family: var(--font-family-code);
}
```
---
## Part 2: Create Spacing Tokens
### File to Create
```
packages/noodl-core-ui/src/styles/custom-properties/spacing.css
```
### Content
```css
/* =============================================================================
NOODL DESIGN SYSTEM - SPACING
============================================================================= */
:root {
/* ---------------------------------------------------------------------------
SPACING SCALE
4px base unit system
--------------------------------------------------------------------------- */
--spacing-0: 0;
--spacing-px: 1px;
--spacing-0-5: 2px;
--spacing-1: 4px;
--spacing-1-5: 6px;
--spacing-2: 8px;
--spacing-2-5: 10px;
--spacing-3: 12px;
--spacing-3-5: 14px;
--spacing-4: 16px;
--spacing-5: 20px;
--spacing-6: 24px;
--spacing-7: 28px;
--spacing-8: 32px;
--spacing-9: 36px;
--spacing-10: 40px;
--spacing-11: 44px;
--spacing-12: 48px;
--spacing-14: 56px;
--spacing-16: 64px;
--spacing-20: 80px;
--spacing-24: 96px;
/* ---------------------------------------------------------------------------
SEMANTIC SPACING
Component-specific spacing aliases
--------------------------------------------------------------------------- */
/* Panel spacing */
--spacing-panel-padding: var(--spacing-4);
--spacing-panel-gap: var(--spacing-3);
/* Card spacing */
--spacing-card-padding: var(--spacing-3);
--spacing-card-gap: var(--spacing-2);
/* Section spacing */
--spacing-section-gap: var(--spacing-6);
--spacing-section-padding: var(--spacing-4);
/* Input spacing */
--spacing-input-padding-x: var(--spacing-2);
--spacing-input-padding-y: var(--spacing-1-5);
--spacing-input-gap: var(--spacing-2);
/* Button spacing */
--spacing-button-padding-x: var(--spacing-3);
--spacing-button-padding-y: var(--spacing-2);
--spacing-button-gap: var(--spacing-2);
/* Icon spacing */
--spacing-icon-gap: var(--spacing-2);
/* ---------------------------------------------------------------------------
BORDER RADIUS
--------------------------------------------------------------------------- */
--radius-none: 0;
--radius-sm: 2px;
--radius-default: 4px;
--radius-md: 6px;
--radius-lg: 8px;
--radius-xl: 12px;
--radius-2xl: 16px;
--radius-3xl: 24px;
--radius-full: 9999px;
/* ---------------------------------------------------------------------------
SHADOWS
--------------------------------------------------------------------------- */
--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
--shadow-default: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px -1px rgba(0, 0, 0, 0.1);
--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1);
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1);
--shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.1);
--shadow-2xl: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
--shadow-inner: inset 0 2px 4px 0 rgba(0, 0, 0, 0.05);
/* Dialog/popup shadow */
--shadow-popup: 0 4px 6px -1px rgba(0, 0, 0, 0.1),
0 10px 15px -3px rgba(0, 0, 0, 0.2),
0 20px 25px -5px rgba(0, 0, 0, 0.15);
/* ---------------------------------------------------------------------------
TRANSITIONS
--------------------------------------------------------------------------- */
--transition-fast: 100ms;
--transition-default: 150ms;
--transition-slow: 300ms;
--transition-ease: cubic-bezier(0.4, 0, 0.2, 1);
--transition-ease-in: cubic-bezier(0.4, 0, 1, 1);
--transition-ease-out: cubic-bezier(0, 0, 0.2, 1);
--transition-ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
/* ---------------------------------------------------------------------------
Z-INDEX SCALE
--------------------------------------------------------------------------- */
--z-base: 0;
--z-dropdown: 100;
--z-sticky: 200;
--z-fixed: 300;
--z-modal-backdrop: 400;
--z-modal: 500;
--z-popover: 600;
--z-tooltip: 700;
}
```
---
## Part 3: Update Import Statements
### Editor Entry Point
File: `packages/noodl-editor/src/editor/index.ts`
Add import:
```typescript
import '../editor/src/styles/custom-properties/spacing.css';
```
### Core UI Entry (if exists)
Check `packages/noodl-core-ui/src/index.ts` or similar and add spacing import.
### Storybook Preview
File: `packages/noodl-core-ui/.storybook/preview.ts`
Ensure spacing.css is imported:
```typescript
import '../src/styles/custom-properties/spacing.css';
```
---
## Part 4: Also Update Editor's Font File
File: `packages/noodl-editor/src/editor/src/styles/custom-properties/fonts.css`
Should contain the same content as the core-ui fonts.css (or be deleted and import from core-ui).
---
## Testing Checklist
### Token Availability
- [ ] All font tokens accessible in CSS (`var(--font-size-base)` works)
- [ ] All spacing tokens accessible (`var(--spacing-4)` works)
- [ ] Shadow tokens work
- [ ] Transition tokens work
### Visual Check
- [ ] Text sizes look appropriate
- [ ] Default body text is readable
- [ ] Code blocks use monospace font
- [ ] Spacing feels balanced
### Build Check
- [ ] No CSS compilation errors
- [ ] No missing variable warnings
- [ ] Storybook loads correctly
- [ ] Editor builds successfully
---
## Usage Examples
### Using Font Tokens
```scss
.title {
font-family: var(--font-family);
font-size: var(--font-size-xl);
font-weight: var(--font-weight-semibold);
line-height: var(--line-height-tight);
}
.code {
font-family: var(--font-family-code);
font-size: var(--font-size-sm);
}
```
### Using Spacing Tokens
```scss
.panel {
padding: var(--spacing-panel-padding);
}
.button {
padding: var(--spacing-button-padding-y) var(--spacing-button-padding-x);
gap: var(--spacing-button-gap);
}
.card {
border-radius: var(--radius-lg);
box-shadow: var(--shadow-md);
}
```
---
## Success Criteria
- [ ] fonts.css contains comprehensive typography tokens
- [ ] spacing.css is created with full spacing system
- [ ] Both files imported in editor and storybook
- [ ] No build errors
- [ ] Tokens are usable in components
- [ ] Ready for component visual updates (TASK-000F, 000G)

View File

@@ -0,0 +1,378 @@
# TASK-000F: Component Visual Updates - Buttons & Inputs
## Overview
Apply visual refinements to button and input components to achieve a modern, polished feel. This builds on the token work done in previous tasks.
**Priority:** MEDIUM
**Effort:** 1-2 hours
**Risk:** Medium
**Dependencies:** TASK-000A, TASK-000D, TASK-000E (Color tokens, Core UI audit, Spacing tokens)
---
## Objective
Make buttons and inputs feel modern and polished with:
- Subtle rounded corners
- Smooth transitions
- Clear hover/focus states
- Better disabled appearances
- Consistent spacing using tokens
---
## Part 1: Button Refinements
### File
```
packages/noodl-core-ui/src/components/inputs/PrimaryButton/PrimaryButton.module.scss
```
### Improvements to Apply
```scss
.Root {
/* Use spacing tokens for padding */
padding: var(--spacing-button-padding-y) var(--spacing-button-padding-x);
gap: var(--spacing-button-gap);
/* Modern rounded corners */
border-radius: var(--radius-md);
/* Smooth transitions for all interactive states */
transition:
background-color var(--transition-default) var(--transition-ease),
border-color var(--transition-default) var(--transition-ease),
box-shadow var(--transition-default) var(--transition-ease),
transform var(--transition-fast) var(--transition-ease);
/* Font styling */
font-weight: var(--font-weight-medium);
font-size: var(--font-size-base);
line-height: var(--line-height-tight);
/* CTA (Primary Red) variant */
&.is-variant-cta {
background-color: var(--theme-color-primary);
color: var(--theme-color-on-primary);
border: 1px solid transparent;
box-shadow: var(--shadow-sm);
&:hover:not(:disabled) {
background-color: var(--theme-color-primary-highlight);
box-shadow: var(--shadow-default);
transform: translateY(-1px);
}
&:active:not(:disabled) {
background-color: var(--theme-color-primary-dim);
box-shadow: none;
transform: translateY(0);
}
}
/* Secondary variant */
&.is-variant-secondary {
background-color: var(--theme-color-bg-4);
color: var(--theme-color-fg-default);
border: 1px solid var(--theme-color-border-default);
&:hover:not(:disabled) {
background-color: var(--theme-color-bg-5);
border-color: var(--theme-color-border-strong);
}
}
/* Ghost variant */
&.is-variant-ghost {
background-color: transparent;
color: var(--theme-color-fg-default);
border: 1px solid transparent;
&:hover:not(:disabled) {
background-color: var(--theme-color-bg-hover);
}
}
/* Disabled state - consistent across all variants */
&:disabled {
opacity: 0.5;
cursor: not-allowed;
transform: none !important;
box-shadow: none !important;
}
/* Focus visible - accessibility */
&:focus-visible {
outline: 2px solid var(--theme-color-focus-ring);
outline-offset: 2px;
}
}
```
### Other Button Components to Check
- `SecondaryButton` (if exists)
- `IconButton` (if exists)
- `TextButton` (if exists)
---
## Part 2: Input Field Refinements
### File
```
packages/noodl-core-ui/src/components/inputs/TextInput/TextInput.module.scss
```
### Improvements to Apply
```scss
.Root {
display: flex;
flex-direction: column;
gap: var(--spacing-1);
}
.InputArea {
/* Use spacing tokens */
padding: var(--spacing-input-padding-y) var(--spacing-input-padding-x);
/* Background and border */
background-color: var(--theme-color-bg-3);
border: 1px solid var(--theme-color-border-default);
border-radius: var(--radius-default);
/* Typography */
font-family: var(--font-family);
font-size: var(--font-size-base);
color: var(--theme-color-fg-default);
/* Transitions */
transition:
border-color var(--transition-default) var(--transition-ease),
box-shadow var(--transition-default) var(--transition-ease);
/* Placeholder styling */
&::placeholder {
color: var(--theme-color-fg-muted);
}
/* Hover state */
&:hover:not(:disabled):not(:focus) {
border-color: var(--theme-color-border-strong);
}
/* Focus state - prominent red ring */
&:focus {
border-color: var(--theme-color-focus-ring);
box-shadow: 0 0 0 2px rgba(210, 31, 60, 0.15);
outline: none;
}
/* Error state */
&.has-error {
border-color: var(--theme-color-danger);
&:focus {
box-shadow: 0 0 0 2px rgba(239, 68, 68, 0.15);
}
}
/* Disabled state */
&:disabled {
background-color: var(--theme-color-bg-2);
color: var(--theme-color-fg-muted);
cursor: not-allowed;
opacity: 0.7;
}
}
/* Label styling */
.Label {
font-size: var(--text-label-size);
font-weight: var(--text-label-weight);
letter-spacing: var(--text-label-letter-spacing);
color: var(--theme-color-fg-default-shy);
text-transform: uppercase;
}
/* Helper/error text */
.HelperText {
font-size: var(--font-size-xs);
color: var(--theme-color-fg-muted);
&.is-error {
color: var(--theme-color-danger);
}
}
```
### Other Input Components to Update
- `Select/Select.module.scss`
- `Checkbox/Checkbox.module.scss`
- `Slider/Slider.module.scss`
- `NumberInput` (if exists)
- `TextArea` (if exists)
---
## Part 3: Select/Dropdown Refinements
### File
```
packages/noodl-core-ui/src/components/inputs/Select/Select.module.scss
```
### Key Styles
```scss
.SelectTrigger {
/* Same base styling as TextInput */
padding: var(--spacing-input-padding-y) var(--spacing-input-padding-x);
background-color: var(--theme-color-bg-3);
border: 1px solid var(--theme-color-border-default);
border-radius: var(--radius-default);
/* Flex layout for icon */
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--spacing-2);
transition: border-color var(--transition-default) var(--transition-ease);
&:hover:not(:disabled) {
border-color: var(--theme-color-border-strong);
}
&.is-open {
border-color: var(--theme-color-focus-ring);
}
}
.DropdownMenu {
background-color: var(--theme-color-bg-3);
border: 1px solid var(--theme-color-border-default);
border-radius: var(--radius-md);
box-shadow: var(--shadow-popup);
/* Ensure dropdown appears above other content */
z-index: var(--z-dropdown);
}
.DropdownItem {
padding: var(--spacing-2) var(--spacing-3);
color: var(--theme-color-fg-default);
&:hover {
background-color: var(--theme-color-bg-hover);
}
&.is-selected {
background-color: var(--theme-color-primary);
color: var(--theme-color-on-primary);
}
}
```
---
## Part 4: Checkbox Refinements
### File
```
packages/noodl-core-ui/src/components/inputs/Checkbox/Checkbox.module.scss
```
### Key Styles
```scss
.CheckboxBox {
width: 16px;
height: 16px;
border: 1px solid var(--theme-color-border-strong);
border-radius: var(--radius-sm);
background-color: var(--theme-color-bg-3);
transition:
background-color var(--transition-default) var(--transition-ease),
border-color var(--transition-default) var(--transition-ease);
&:hover:not(:disabled) {
border-color: var(--theme-color-focus-ring);
}
&.is-checked {
background-color: var(--theme-color-primary);
border-color: var(--theme-color-primary);
/* Checkmark icon should be white */
color: var(--theme-color-on-primary);
}
}
```
---
## Testing Checklist
### Buttons
- [ ] Primary (CTA) button is red with white text
- [ ] Hover state brightens and lifts slightly
- [ ] Active state darkens
- [ ] Disabled state is clearly disabled (50% opacity)
- [ ] Focus ring is visible and red
- [ ] Secondary button has visible border
- [ ] Ghost button has no background until hover
### Text Inputs
- [ ] Input has visible background and border
- [ ] Placeholder text is muted gray
- [ ] Hover state shows stronger border
- [ ] Focus state shows red ring
- [ ] Error state shows red border
- [ ] Disabled state is clearly disabled
### Selects
- [ ] Dropdown trigger looks like input
- [ ] Dropdown menu has shadow and border
- [ ] Items have hover states
- [ ] Selected item is highlighted
### Checkboxes
- [ ] Unchecked box has visible border
- [ ] Checked state shows red background
- [ ] Hover state on unchecked shows border change
### General
- [ ] All components use consistent spacing
- [ ] All components use consistent border radius
- [ ] Transitions are smooth, not jarring
- [ ] Storybook shows all states correctly
---
## Verification in Storybook
```bash
npm run storybook
```
Navigate to:
- Inputs / PrimaryButton
- Inputs / TextInput
- Inputs / Select
- Inputs / Checkbox
Review all stories and variants.
---
## Success Criteria
- [ ] Buttons feel modern and responsive
- [ ] Inputs have clear, accessible focus states
- [ ] All interactive states are smooth
- [ ] Disabled states are obvious
- [ ] Consistent use of tokens throughout
- [ ] No visual regressions from previous functionality

View File

@@ -0,0 +1,437 @@
# TASK-000G: Component Visual Updates - Dialogs & Panels
## Overview
Apply visual refinements to dialog, modal, and panel components to create a modern, elevated UI feel. These are high-visibility components that frame content throughout the editor.
**Priority:** MEDIUM
**Effort:** 1-2 hours
**Risk:** Medium
**Dependencies:** TASK-000A, TASK-000D, TASK-000E (Color tokens, Core UI audit, Spacing tokens)
---
## Objective
Make dialogs and panels feel modern and elevated with:
- Subtle borders for definition
- Refined shadows for depth
- Better backdrop styling
- Consistent header/body/footer structure
- Proper spacing using tokens
---
## Part 1: Dialog/Modal Refinements
### File
```
packages/noodl-core-ui/src/components/layout/BaseDialog/BaseDialog.module.scss
```
### Improvements to Apply
```scss
/* Dialog wrapper - handles backdrop */
.Root {
/* Backdrop styling */
&.has-backdrop {
background-color: var(--base-color-black-transparent-80);
/* Optional: subtle blur for modern feel */
/* Note: may have performance implications */
backdrop-filter: blur(4px);
-webkit-backdrop-filter: blur(4px);
}
}
/* The visible dialog box */
.VisibleDialog {
/* Background */
background-color: var(--theme-color-bg-2);
/* Border for definition against backdrop */
border: 1px solid var(--theme-color-border-subtle);
/* Modern rounded corners */
border-radius: var(--radius-lg);
/* Elevated shadow */
box-shadow: var(--shadow-popup);
/* Overflow handling */
overflow: hidden;
/* Maximum size constraints */
max-height: 90vh;
max-width: 90vw;
}
/* Dialog header */
.DialogHeader {
padding: var(--spacing-4) var(--spacing-5);
border-bottom: 1px solid var(--theme-color-border-subtle);
/* Flex layout for title + close button */
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--spacing-4);
}
.DialogTitle {
font-size: var(--font-size-2xl);
font-weight: var(--font-weight-semibold);
color: var(--theme-color-fg-highlight);
line-height: var(--line-height-tight);
margin: 0;
}
.DialogSubtitle {
font-size: var(--font-size-base);
color: var(--theme-color-fg-default-shy);
margin-top: var(--spacing-1);
}
/* Dialog body */
.DialogBody {
padding: var(--spacing-5);
overflow-y: auto;
/* Smooth scrolling */
scroll-behavior: smooth;
/* Scrollbar styling (webkit) */
&::-webkit-scrollbar {
width: 8px;
}
&::-webkit-scrollbar-track {
background: var(--theme-color-bg-3);
}
&::-webkit-scrollbar-thumb {
background: var(--theme-color-bg-5);
border-radius: var(--radius-full);
&:hover {
background: var(--theme-color-fg-muted);
}
}
}
/* Dialog footer */
.DialogFooter {
padding: var(--spacing-4) var(--spacing-5);
border-top: 1px solid var(--theme-color-border-subtle);
background-color: var(--theme-color-bg-1);
/* Flex layout for buttons */
display: flex;
align-items: center;
justify-content: flex-end;
gap: var(--spacing-3);
}
/* Close button in header */
.CloseButton {
width: 32px;
height: 32px;
display: flex;
align-items: center;
justify-content: center;
border-radius: var(--radius-default);
background: transparent;
border: none;
color: var(--theme-color-fg-muted);
cursor: pointer;
transition:
background-color var(--transition-default) var(--transition-ease),
color var(--transition-default) var(--transition-ease);
&:hover {
background-color: var(--theme-color-bg-hover);
color: var(--theme-color-fg-default);
}
}
```
---
## Part 2: Panel Refinements
### Files
```
packages/noodl-core-ui/src/components/sidebar/BasePanel/BasePanel.module.scss
packages/noodl-core-ui/src/components/sidebar/Section/Section.module.scss
```
### BasePanel Improvements
```scss
.Root {
/* Background */
background-color: var(--theme-color-bg-2);
/* Border for definition */
border: 1px solid var(--theme-color-border-subtle);
border-radius: var(--radius-md);
/* Consistent padding */
padding: var(--spacing-panel-padding);
/* Panel gap between children */
display: flex;
flex-direction: column;
gap: var(--spacing-panel-gap);
}
.PanelHeader {
display: flex;
align-items: center;
justify-content: space-between;
padding-bottom: var(--spacing-3);
border-bottom: 1px solid var(--theme-color-border-subtle);
margin-bottom: var(--spacing-2);
}
.PanelTitle {
font-size: var(--font-size-lg);
font-weight: var(--font-weight-semibold);
color: var(--theme-color-fg-default-contrast);
}
```
### Section Improvements
```scss
.Root {
/* Section spacing */
padding: var(--spacing-section-padding) 0;
/* Border between sections */
&:not(:last-child) {
border-bottom: 1px solid var(--theme-color-border-subtle);
}
}
.SectionHeader {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: var(--spacing-3);
}
.SectionTitle {
font-size: var(--text-label-size);
font-weight: var(--text-label-weight);
letter-spacing: var(--text-label-letter-spacing);
color: var(--theme-color-fg-muted);
text-transform: uppercase;
}
.SectionContent {
display: flex;
flex-direction: column;
gap: var(--spacing-2);
}
/* Collapsible section */
.SectionToggle {
cursor: pointer;
display: flex;
align-items: center;
gap: var(--spacing-2);
&:hover .SectionTitle {
color: var(--theme-color-fg-default-shy);
}
}
.CollapseIcon {
transition: transform var(--transition-default) var(--transition-ease);
&.is-collapsed {
transform: rotate(-90deg);
}
}
```
---
## Part 3: Sidebar Item Refinements
### File
```
packages/noodl-core-ui/src/components/sidebar/SidebarItem/SidebarItem.module.scss
```
### Improvements
```scss
.Root {
padding: var(--spacing-2) var(--spacing-3);
border-radius: var(--radius-default);
display: flex;
align-items: center;
gap: var(--spacing-2);
color: var(--theme-color-fg-default);
transition:
background-color var(--transition-default) var(--transition-ease),
color var(--transition-default) var(--transition-ease);
cursor: pointer;
&:hover {
background-color: var(--theme-color-bg-hover);
}
&.is-active {
background-color: var(--theme-color-primary);
color: var(--theme-color-on-primary);
}
&.is-selected {
background-color: var(--theme-color-bg-4);
color: var(--theme-color-fg-highlight);
}
}
.ItemIcon {
flex-shrink: 0;
width: 16px;
height: 16px;
color: inherit;
opacity: 0.7;
}
.ItemLabel {
flex: 1;
font-size: var(--font-size-base);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.ItemBadge {
flex-shrink: 0;
font-size: var(--font-size-xs);
padding: var(--spacing-0-5) var(--spacing-1);
background-color: var(--theme-color-bg-5);
border-radius: var(--radius-sm);
color: var(--theme-color-fg-default-shy);
}
```
---
## Part 4: Tooltip Refinements
### File
```
packages/noodl-core-ui/src/components/common/Tooltip/Tooltip.module.scss
```
### Improvements
```scss
.Root {
background-color: var(--theme-color-bg-4);
color: var(--theme-color-fg-default);
padding: var(--spacing-1-5) var(--spacing-2);
border-radius: var(--radius-default);
font-size: var(--font-size-sm);
line-height: var(--line-height-normal);
box-shadow: var(--shadow-md);
border: 1px solid var(--theme-color-border-default);
/* Ensure tooltip is above everything */
z-index: var(--z-tooltip);
/* Max width for long content */
max-width: 250px;
}
/* Arrow/pointer if applicable */
.Arrow {
fill: var(--theme-color-bg-4);
stroke: var(--theme-color-border-default);
}
```
---
## Testing Checklist
### Dialogs/Modals
- [ ] Dialog has visible border
- [ ] Shadow creates sense of elevation
- [ ] Backdrop is semi-transparent dark
- [ ] Backdrop blur works (if enabled)
- [ ] Header/body/footer clearly separated
- [ ] Title text is prominent
- [ ] Close button works and has hover state
- [ ] Footer buttons aligned correctly
- [ ] Scrollable body works for long content
- [ ] Focus trapped inside dialog
### Panels
- [ ] Panel has subtle border
- [ ] Header section distinct from content
- [ ] Section titles are uppercase/muted
- [ ] Content areas have proper spacing
- [ ] Collapsible sections animate smoothly
### Sidebar Items
- [ ] Items have hover states
- [ ] Active item clearly highlighted (red)
- [ ] Selected item distinct from hover
- [ ] Icons aligned with text
- [ ] Overflow text truncates with ellipsis
### Tooltips
- [ ] Tooltip has border and shadow
- [ ] Text is readable
- [ ] Position correctly relative to trigger
- [ ] Arrow points to trigger (if applicable)
### General
- [ ] Consistent border radius across all components
- [ ] Consistent border colors
- [ ] Smooth transitions
- [ ] Storybook shows all variations correctly
---
## Verification in Storybook
```bash
npm run storybook
```
Navigate to:
- Layout / BaseDialog
- Sidebar / BasePanel
- Sidebar / Section
- Sidebar / SidebarItem
- Common / Tooltip
Review all stories and variants.
---
## Success Criteria
- [ ] Dialogs feel elevated and professional
- [ ] Panels have clear visual structure
- [ ] Sections organize content clearly
- [ ] Sidebar items are interactive and obvious
- [ ] Tooltips are readable and well-positioned
- [ ] Consistent use of tokens throughout
- [ ] No visual regressions from previous functionality

View File

@@ -0,0 +1,535 @@
# TASK-000H: Migration Wizard Polish
## Overview
Final polish pass on the React 19 Migration Wizard dialog to ensure it looks professional and provides clear user guidance. This is an important user-facing feature.
**Priority:** HIGH (User-facing feature)
**Effort:** 1-2 hours
**Risk:** Low
**Dependencies:** TASK-000A through TASK-000G (All token and component updates)
---
## Objective
Ensure the Migration Wizard:
- Uses the new design tokens consistently
- Has clear visual hierarchy
- Provides obvious progress indication
- Shows success/error states clearly
- Looks polished and professional
---
## Migration Wizard Files
### Main Component
```
packages/noodl-editor/src/editor/src/views/migration/MigrationWizard.tsx
packages/noodl-editor/src/editor/src/views/migration/MigrationWizard.module.scss
```
### Step Components
```
packages/noodl-editor/src/editor/src/views/migration/steps/ConfirmStep.tsx
packages/noodl-editor/src/editor/src/views/migration/steps/ConfirmStep.module.scss
packages/noodl-editor/src/editor/src/views/migration/steps/ScanningStep.tsx
packages/noodl-editor/src/editor/src/views/migration/steps/ScanningStep.module.scss
packages/noodl-editor/src/editor/src/views/migration/steps/ReportStep.tsx
packages/noodl-editor/src/editor/src/views/migration/steps/ReportStep.module.scss
packages/noodl-editor/src/editor/src/views/migration/steps/CompleteStep.tsx
packages/noodl-editor/src/editor/src/views/migration/steps/CompleteStep.module.scss
packages/noodl-editor/src/editor/src/views/migration/steps/FailedStep.tsx
packages/noodl-editor/src/editor/src/views/migration/steps/FailedStep.module.scss
```
### Supporting Components
```
packages/noodl-editor/src/editor/src/views/migration/components/WizardProgress.tsx
packages/noodl-editor/src/editor/src/views/migration/components/WizardProgress.module.scss
```
---
## Part 1: Wizard Progress Indicator
### Ensure Progress Uses Tokens
```scss
/* WizardProgress.module.scss */
.Root {
display: flex;
align-items: center;
gap: var(--spacing-2);
padding: var(--spacing-3) var(--spacing-4);
background-color: var(--theme-color-bg-1);
border-bottom: 1px solid var(--theme-color-border-subtle);
}
.StepItem {
display: flex;
align-items: center;
gap: var(--spacing-2);
}
.StepNumber {
width: 24px;
height: 24px;
display: flex;
align-items: center;
justify-content: center;
border-radius: var(--radius-full);
font-size: var(--font-size-sm);
font-weight: var(--font-weight-medium);
transition:
background-color var(--transition-default) var(--transition-ease),
color var(--transition-default) var(--transition-ease);
/* Default (pending) state */
background-color: var(--theme-color-bg-4);
color: var(--theme-color-fg-muted);
/* Active state */
&.is-active {
background-color: var(--theme-color-primary);
color: var(--theme-color-on-primary);
}
/* Completed state */
&.is-complete {
background-color: var(--theme-color-success);
color: var(--theme-color-fg-highlight);
}
/* Error state */
&.is-error {
background-color: var(--theme-color-danger);
color: var(--theme-color-fg-highlight);
}
}
.StepLabel {
font-size: var(--font-size-sm);
color: var(--theme-color-fg-muted);
&.is-active {
color: var(--theme-color-fg-default);
font-weight: var(--font-weight-medium);
}
&.is-complete {
color: var(--theme-color-success);
}
}
.StepConnector {
flex: 1;
height: 2px;
background-color: var(--theme-color-bg-4);
min-width: 20px;
&.is-complete {
background-color: var(--theme-color-success);
}
}
```
---
## Part 2: Step Containers
### Shared Step Styles
Create a shared pattern for all step containers:
```scss
/* Shared concept for each step's .module.scss */
.StepContainer {
padding: var(--spacing-6);
display: flex;
flex-direction: column;
gap: var(--spacing-4);
}
.StepTitle {
font-size: var(--font-size-xl);
font-weight: var(--font-weight-semibold);
color: var(--theme-color-fg-highlight);
margin: 0;
}
.StepDescription {
font-size: var(--font-size-base);
color: var(--theme-color-fg-default-shy);
line-height: var(--line-height-relaxed);
}
.StepContent {
display: flex;
flex-direction: column;
gap: var(--spacing-4);
}
```
---
## Part 3: Success Banner (CompleteStep)
```scss
/* CompleteStep.module.scss */
.SuccessBanner {
display: flex;
align-items: center;
gap: var(--spacing-3);
padding: var(--spacing-4);
background-color: var(--theme-color-success-bg);
border: 1px solid var(--theme-color-success-dim);
border-radius: var(--radius-md);
}
.SuccessIcon {
width: 24px;
height: 24px;
color: var(--theme-color-success);
flex-shrink: 0;
}
.SuccessText {
font-size: var(--font-size-base);
color: var(--theme-color-success);
font-weight: var(--font-weight-medium);
}
/* Stats display */
.StatsCard {
background-color: var(--theme-color-bg-3);
border: 1px solid var(--theme-color-border-default);
border-radius: var(--radius-md);
padding: var(--spacing-4);
}
.StatItem {
display: flex;
align-items: baseline;
gap: var(--spacing-2);
}
.StatValue {
font-size: var(--font-size-2xl);
font-weight: var(--font-weight-bold);
color: var(--theme-color-fg-highlight);
}
.StatLabel {
font-size: var(--font-size-sm);
color: var(--theme-color-fg-muted);
}
/* What's next section */
.NextStepsSection {
padding-top: var(--spacing-4);
border-top: 1px solid var(--theme-color-border-subtle);
}
.NextStepsTitle {
font-size: var(--text-label-size);
font-weight: var(--text-label-weight);
letter-spacing: var(--text-label-letter-spacing);
color: var(--theme-color-fg-muted);
text-transform: uppercase;
margin-bottom: var(--spacing-3);
}
.ChecklistItem {
display: flex;
align-items: flex-start;
gap: var(--spacing-2);
padding: var(--spacing-1-5) 0;
font-size: var(--font-size-base);
color: var(--theme-color-fg-default);
}
.ChecklistIcon {
width: 16px;
height: 16px;
color: var(--theme-color-fg-muted);
flex-shrink: 0;
margin-top: 2px;
}
```
---
## Part 4: Error/Failed State (FailedStep)
```scss
/* FailedStep.module.scss */
.ErrorBanner {
display: flex;
align-items: flex-start;
gap: var(--spacing-3);
padding: var(--spacing-4);
background-color: var(--theme-color-danger-bg);
border: 1px solid var(--theme-color-danger-dim);
border-radius: var(--radius-md);
}
.ErrorIcon {
width: 24px;
height: 24px;
color: var(--theme-color-danger);
flex-shrink: 0;
}
.ErrorContent {
display: flex;
flex-direction: column;
gap: var(--spacing-2);
}
.ErrorTitle {
font-size: var(--font-size-base);
font-weight: var(--font-weight-semibold);
color: var(--theme-color-danger-light);
}
.ErrorMessage {
font-size: var(--font-size-sm);
color: var(--theme-color-fg-default);
line-height: var(--line-height-normal);
}
/* Error details (collapsible) */
.ErrorDetails {
margin-top: var(--spacing-3);
padding: var(--spacing-3);
background-color: var(--theme-color-bg-1);
border-radius: var(--radius-default);
font-family: var(--font-family-code);
font-size: var(--font-size-sm);
color: var(--theme-color-fg-default-shy);
overflow-x: auto;
white-space: pre-wrap;
word-break: break-word;
}
```
---
## Part 5: Scanning/Loading State (ScanningStep)
```scss
/* ScanningStep.module.scss */
.LoadingContainer {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: var(--spacing-8) var(--spacing-4);
gap: var(--spacing-4);
}
.Spinner {
width: 48px;
height: 48px;
border: 3px solid var(--theme-color-bg-4);
border-top-color: var(--theme-color-primary);
border-radius: var(--radius-full);
animation: spin 1s linear infinite;
}
@keyframes spin {
to {
transform: rotate(360deg);
}
}
.LoadingText {
font-size: var(--font-size-base);
color: var(--theme-color-fg-default-shy);
text-align: center;
}
/* Progress bar (if applicable) */
.ProgressBar {
width: 100%;
max-width: 300px;
height: 4px;
background-color: var(--theme-color-bg-4);
border-radius: var(--radius-full);
overflow: hidden;
}
.ProgressFill {
height: 100%;
background-color: var(--theme-color-primary);
border-radius: var(--radius-full);
transition: width var(--transition-slow) var(--transition-ease);
}
```
---
## Part 6: Report Step
```scss
/* ReportStep.module.scss */
.ReportContainer {
display: flex;
flex-direction: column;
gap: var(--spacing-4);
}
.SummaryCard {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
gap: var(--spacing-3);
}
.SummaryItem {
background-color: var(--theme-color-bg-3);
padding: var(--spacing-3);
border-radius: var(--radius-md);
text-align: center;
}
.SummaryValue {
font-size: var(--font-size-2xl);
font-weight: var(--font-weight-bold);
color: var(--theme-color-fg-highlight);
}
.SummaryLabel {
font-size: var(--font-size-xs);
color: var(--theme-color-fg-muted);
text-transform: uppercase;
letter-spacing: var(--letter-spacing-wide);
}
/* Issue list */
.IssueList {
border: 1px solid var(--theme-color-border-default);
border-radius: var(--radius-md);
overflow: hidden;
}
.IssueItem {
padding: var(--spacing-3);
display: flex;
align-items: flex-start;
gap: var(--spacing-3);
border-bottom: 1px solid var(--theme-color-border-subtle);
&:last-child {
border-bottom: none;
}
}
.IssueIcon {
width: 16px;
height: 16px;
flex-shrink: 0;
&.is-warning {
color: var(--theme-color-notice);
}
&.is-error {
color: var(--theme-color-danger);
}
&.is-info {
color: var(--theme-color-fg-muted);
}
}
.IssueContent {
flex: 1;
}
.IssuePath {
font-family: var(--font-family-code);
font-size: var(--font-size-xs);
color: var(--theme-color-fg-muted);
}
.IssueMessage {
font-size: var(--font-size-sm);
color: var(--theme-color-fg-default);
}
```
---
## Testing Checklist
### Wizard Progress
- [ ] Current step is clearly highlighted (red)
- [ ] Completed steps show green checkmarks
- [ ] Pending steps are muted
- [ ] Connectors show completion state
### Success State (CompleteStep)
- [ ] Green success banner is prominent
- [ ] Stats are easy to read
- [ ] Next steps are clear
- [ ] Primary action button is obvious
### Error State (FailedStep)
- [ ] Red error banner catches attention
- [ ] Error message is readable
- [ ] Technical details are available but not overwhelming
- [ ] Retry/close actions are clear
### Scanning State
- [ ] Spinner animates smoothly
- [ ] Progress indication is clear
- [ ] User knows something is happening
### Report Step
- [ ] Summary is scannable
- [ ] Issues are categorized by severity
- [ ] File paths are readable
- [ ] Continue action is clear
### General
- [ ] All steps use consistent spacing
- [ ] Typography is readable
- [ ] Colors match new palette
- [ ] Transitions are smooth
---
## Visual Audit Process
1. **Start Migration Wizard** from a test project
2. **Walk through each step** observing:
- Progress indicator updates
- Content layout and spacing
- Button prominence
- Color usage
3. **Test error scenarios** if possible
4. **Compare against modern UI** (Linear, Raycast, etc.)
---
## Success Criteria
- [ ] Wizard uses design tokens throughout
- [ ] Progress is obvious at a glance
- [ ] Success state feels rewarding
- [ ] Error state is informative but not alarming
- [ ] Overall experience feels polished and professional
- [ ] No hardcoded colors in migration wizard files