mirror of
https://github.com/The-Low-Code-Foundation/OpenNoodl.git
synced 2026-01-11 23:02:56 +01:00
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:
@@ -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);
|
||||
}
|
||||
|
||||
*/
|
||||
@@ -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
|
||||
125
dev-docs/tasks/phase-3/TASK-000-styles-overhaul/INDEX.md
Normal file
125
dev-docs/tasks/phase-3/TASK-000-styles-overhaul/INDEX.md
Normal 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
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user