diff --git a/dev-docs/tasks/phase-2/TASK-004-runtime-migration-system/CHANGELOG.md b/dev-docs/tasks/phase-2/TASK-004-runtime-migration-system/CHANGELOG.md index 4bc1243..f491937 100644 --- a/dev-docs/tasks/phase-2/TASK-004-runtime-migration-system/CHANGELOG.md +++ b/dev-docs/tasks/phase-2/TASK-004-runtime-migration-system/CHANGELOG.md @@ -2,6 +2,162 @@ ## [Unreleased] +### Session 12: Wizard Visual Polish - Production Ready UI + +#### 2024-12-21 + +**Completed:** + +- **Complete SCSS Overhaul** - Transformed all migration wizard styling from basic functional CSS to beautiful, professional, production-ready UI: + +**Files Enhanced (9 SCSS modules):** + +1. **MigrationWizard.module.scss** - Main container styling: + + - Added fadeIn and slideIn animations for smooth entry + - Design system variables for consistent spacing, transitions, radius, shadows + - Improved container dimensions (750px width, 85vh max height) + - Custom scrollbar styling with hover effects + - Better backdrop and overlay effects + +2. **WizardProgress.module.scss** - Progress indicator: + + - Pulsing animation on active step with shadow effects + - Checkmark bounce animation for completed steps + - Animated connecting lines with slideProgress keyframe + - Larger step circles (36px) with gradient backgrounds + - Hover states with transform effects + +3. **ConfirmStep.module.scss** - Path confirmation: + + - ArrowBounce animation for visual flow indication + - Distinct locked/editable path sections with gradients + - Gradient info boxes with left border accent + - Better typography hierarchy and spacing + - Interactive hover states on editable elements + +4. **ScanningStep.module.scss** - Progress display: + + - Shimmer animation on progress bar + - Spinning icon with drop shadow + - StatGrid with hover effects and transform + - Gradient progress fill with animated shine effect + - Color-coded log entries with sliding animations + +5. **ReportStep.module.scss** - Scan results: + + - CountUp animation for stat values + - Sparkle animation for AI configuration section + - Beautiful category sections with gradient headers + - Collapsible components with smooth height transitions + - AI prompt with animated purple gradient border + - Interactive component cards with hover lift effects + +6. **MigratingStep.module.scss** - Migration progress: + + - Budget pulse animation when >80% spent (warning state) + - Shimmer effect on progress bars + - Gradient backgrounds for component sections + - Budget warning panel with animated pulse + - Real-time activity log with color-coded entries + - AI decision panel with smooth transitions + +7. **CompleteStep.module.scss** - Success screen: + + - SuccessPulse animation on completion icon + - Celebration header with success gradient + - Stat cards with countUp animation + - Beautiful path display cards with gradients + - Next steps section with hover effects + - Confetti-like visual celebration + +8. **FailedStep.module.scss** - Error display: + + - Shake animation on error icon + - Gradient error boxes with proper contrast + - Helpful suggestion cards with hover states + - Safety notice with success coloring + - Better error message typography + +9. **AIConfigPanel.module.scss** - AI configuration: + - Purple AI theming with sparkle/pulse animations + - Gradient header with animated glow effect + - Modern form fields with monospace font for API keys + - Beautiful validation states (checkBounce/shake animations) + - Enhanced security notes with left border accent + - Interactive budget controls with scale effects + - Shimmer effect on primary action button + +**Design System Implementation:** + +- Consistent color palette: + + - Primary: `#3b82f6` (blue) + - Success: `#10b981` (green) + - Warning: `#f59e0b` (orange) + - Danger: `#ef4444` (red) + - AI: `#8b5cf6` (purple) + +- Standardized spacing scale: + + - xs: 8px, sm: 12px, md: 16px, lg: 24px, xl: 32px, 2xl: 40px + +- Border radius scale: + + - sm: 4px, md: 6px, lg: 8px, xl: 12px + +- Shadow system: + + - sm, md, lg, glow (for special effects) + +- Transition timing: + - fast: 150ms, base: 250ms, slow: 400ms + +**Animation Library:** + +- `fadeIn` / `fadeInUp` - Entry animations +- `slideIn` / `slideInUp` - Sliding entry +- `pulse` - Gentle attention pulse +- `shimmer` - Animated gradient sweep +- `sparkle` - Opacity + scale variation +- `checkBounce` - Success icon bounce +- `successPulse` - Celebration pulse +- `budgetPulse` - Warning pulse (budget) +- `shake` - Error shake +- `spin` - Loading spinner +- `countUp` - Number counting effect +- `arrowBounce` - Directional bounce +- `slideProgress` - Progress line animation + +**UI Polish Features:** + +- Smooth micro-interactions on all interactive elements +- Gradient backgrounds for visual depth +- Box shadows for elevation hierarchy +- Custom scrollbar styling +- Hover states with transform effects +- Focus states with glow effects +- Color-coded semantic states +- Responsive animations +- Accessibility-friendly transitions + +**Result:** + +Migration wizard transformed from basic functional UI to a beautiful, professional, modern interface that feels native to OpenNoodl. The wizard now provides: + +- Clear visual hierarchy and flow +- Delightful animations and transitions +- Professional polish and attention to detail +- Consistent design language +- Production-ready user experience + +**Next Sessions:** + +- Session 2: Post-Migration UX Features (component badges, migration notes, etc.) +- Session 3: Polish & Integration (new project dialog, welcome screen, etc.) + +--- + ### Session 11: MigrationWizard AI Integration Complete #### 2024-12-20 diff --git a/packages/noodl-editor/src/editor/src/views/migration/AIConfigPanel.module.scss b/packages/noodl-editor/src/editor/src/views/migration/AIConfigPanel.module.scss index 3e195a5..966e8c1 100644 --- a/packages/noodl-editor/src/editor/src/views/migration/AIConfigPanel.module.scss +++ b/packages/noodl-editor/src/editor/src/views/migration/AIConfigPanel.module.scss @@ -1,166 +1,655 @@ +// ============================================================================= +// AI Configuration Panel +// ============================================================================= +// Enhanced styling for AI setup: API key configuration, budget settings, +// and security information. Uses purple AI theming with modern animations. +// ============================================================================= + +// Design System Variables +$ai-primary: #8b5cf6; +$ai-primary-light: #a78bfa; +$ai-primary-dark: #7c3aed; +$success: #10b981; +$danger: #ef4444; +$warning: #f59e0b; + +$spacing-xs: 8px; +$spacing-sm: 12px; +$spacing-md: 16px; +$spacing-lg: 24px; +$spacing-xl: 32px; + +$radius-sm: 4px; +$radius-md: 6px; +$radius-lg: 8px; +$radius-xl: 12px; + +$transition-fast: 150ms ease; +$transition-base: 250ms ease; +$transition-slow: 400ms ease; + +$shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.08); +$shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1), 0 2px 4px rgba(0, 0, 0, 0.06); +$shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.1), 0 4px 6px rgba(0, 0, 0, 0.05); +$shadow-ai: 0 0 20px rgba(139, 92, 246, 0.15); + +// Animations +@keyframes fadeInUp { + from { + opacity: 0; + transform: translateY(10px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +@keyframes sparkle { + 0%, + 100% { + opacity: 0.3; + transform: scale(1); + } + 50% { + opacity: 1; + transform: scale(1.05); + } +} + +@keyframes pulse { + 0%, + 100% { + opacity: 1; + } + 50% { + opacity: 0.6; + } +} + +@keyframes shimmer { + 0% { + background-position: -200% center; + } + 100% { + background-position: 200% center; + } +} + +@keyframes checkBounce { + 0%, + 100% { + transform: scale(1); + } + 50% { + transform: scale(1.2); + } +} + +@keyframes shake { + 0%, + 100% { + transform: translateX(0); + } + 10%, + 30%, + 50%, + 70%, + 90% { + transform: translateX(-4px); + } + 20%, + 40%, + 60%, + 80% { + transform: translateX(4px); + } +} + +// Main Container .AIConfigPanel { display: flex; flex-direction: column; - gap: 24px; + gap: $spacing-lg; max-width: 600px; - padding: 24px; + padding: $spacing-xl; + animation: fadeInUp 0.4s ease; } +// Header Section .Header { display: flex; - gap: 16px; + gap: $spacing-md; align-items: flex-start; + padding: $spacing-lg; + background: linear-gradient(135deg, rgba(139, 92, 246, 0.1) 0%, rgba(167, 139, 250, 0.05) 100%); + border: 1px solid rgba(139, 92, 246, 0.2); + border-radius: $radius-lg; + box-shadow: $shadow-ai; + animation: sparkle 3s ease-in-out infinite; svg { flex-shrink: 0; - color: var(--theme-color-primary); + width: 32px; + height: 32px; + color: $ai-primary; + filter: drop-shadow(0 2px 4px rgba(139, 92, 246, 0.3)); + animation: pulse 2s ease-in-out infinite; } } .HeaderText { display: flex; flex-direction: column; - gap: 8px; + gap: $spacing-xs; + flex: 1; h3 { margin: 0; - font-size: 16px; + font-size: 18px; font-weight: 600; color: var(--theme-color-fg-highlight); + background: linear-gradient(135deg, $ai-primary 0%, $ai-primary-light 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + } + + p { + margin: 0; + font-size: 14px; + line-height: 1.5; + color: var(--theme-color-fg-default); + opacity: 0.9; } } +// Section Container .Section { display: flex; flex-direction: column; - gap: 12px; - padding: 16px; + gap: $spacing-md; + padding: $spacing-lg; background: var(--theme-color-bg-2); - border-radius: 6px; + border: 1px solid var(--theme-color-bg-3); + border-radius: $radius-lg; + transition: all $transition-base; + + &:hover { + border-color: rgba(139, 92, 246, 0.3); + box-shadow: $shadow-sm; + } h4 { margin: 0; - font-size: 14px; + font-size: 15px; font-weight: 600; color: var(--theme-color-fg-highlight); + display: flex; + align-items: center; + gap: $spacing-xs; + + &::before { + content: ''; + display: inline-block; + width: 3px; + height: 16px; + background: linear-gradient(180deg, $ai-primary 0%, $ai-primary-light 100%); + border-radius: 2px; + } } a { - color: var(--theme-color-primary); + color: $ai-primary; text-decoration: none; + font-weight: 500; + transition: all $transition-fast; + position: relative; + + &::after { + content: ''; + position: absolute; + bottom: -2px; + left: 0; + right: 0; + height: 1px; + background: $ai-primary; + transform: scaleX(0); + transition: transform $transition-fast; + } &:hover { - text-decoration: underline; + color: $ai-primary-dark; + + &::after { + transform: scaleX(1); + } } } } +// Input Group .InputGroup { display: flex; - gap: 8px; - align-items: center; + gap: $spacing-sm; + align-items: flex-start; > :first-child { flex: 1; } + + button { + margin-top: 24px; // Align with input field + min-width: 100px; + transition: all $transition-base; + + &:hover { + transform: translateY(-1px); + box-shadow: $shadow-md; + } + + &:active { + transform: translateY(0); + } + } } +// Validation Messages .ValidationSuccess { display: flex; - gap: 8px; + gap: $spacing-sm; align-items: center; - color: var(--theme-color-success); + padding: $spacing-sm $spacing-md; + background: linear-gradient(135deg, rgba(16, 185, 129, 0.1) 0%, rgba(16, 185, 129, 0.05) 100%); + border: 1px solid rgba(16, 185, 129, 0.3); + border-radius: $radius-md; + color: $success; font-size: 13px; + font-weight: 500; + animation: checkBounce 0.5s ease; svg { flex-shrink: 0; + width: 18px; + height: 18px; + filter: drop-shadow(0 2px 4px rgba(16, 185, 129, 0.3)); } } .ValidationError { display: flex; - gap: 8px; + gap: $spacing-sm; align-items: center; - color: var(--theme-color-danger); + padding: $spacing-sm $spacing-md; + background: linear-gradient(135deg, rgba(239, 68, 68, 0.1) 0%, rgba(239, 68, 68, 0.05) 100%); + border: 1px solid rgba(239, 68, 68, 0.3); + border-radius: $radius-md; + color: $danger; font-size: 13px; + font-weight: 500; + animation: shake 0.5s ease; svg { flex-shrink: 0; + width: 18px; + height: 18px; } } +// Security Note .SecurityNote { display: flex; - gap: 8px; + gap: $spacing-sm; align-items: flex-start; - padding: 12px; - background: var(--theme-color-bg-3); - border-radius: 4px; + padding: $spacing-md; + background: linear-gradient(135deg, var(--theme-color-bg-3) 0%, var(--theme-color-bg-2) 100%); + border-left: 3px solid $ai-primary; + border-radius: $radius-md; font-size: 13px; + line-height: 1.6; + box-shadow: $shadow-sm; svg { flex-shrink: 0; + width: 20px; + height: 20px; margin-top: 2px; - color: var(--theme-color-secondary-as-fg); + color: $ai-primary; + opacity: 0.8; + } + + p { + margin: 0; + color: var(--theme-color-fg-default); + opacity: 0.9; + } + + strong { + color: var(--theme-color-fg-highlight); + font-weight: 600; } } +// Form Field .Field { display: flex; flex-direction: column; - gap: 8px; + gap: $spacing-sm; > label:first-child { font-size: 13px; - font-weight: 500; + font-weight: 600; + color: var(--theme-color-fg-highlight); + text-transform: uppercase; + letter-spacing: 0.5px; + display: flex; + align-items: center; + gap: $spacing-xs; + + &::before { + content: ''; + display: inline-block; + width: 4px; + height: 4px; + background: $ai-primary; + border-radius: 50%; + } + } + + input[type='text'], + input[type='password'] { + width: 100%; + padding: 10px 14px; + background: var(--theme-color-bg-1); + border: 2px solid var(--theme-color-bg-3); + border-radius: $radius-md; + color: var(--theme-color-fg-highlight); + font-size: 14px; + font-family: 'SF Mono', 'Monaco', 'Consolas', monospace; + transition: all $transition-base; + + &::placeholder { + color: var(--theme-color-fg-default); + opacity: 0.5; + } + + &:focus { + outline: none; + border-color: $ai-primary; + box-shadow: 0 0 0 3px rgba(139, 92, 246, 0.1), $shadow-md; + transform: translateY(-1px); + } + + &:disabled { + opacity: 0.5; + cursor: not-allowed; + } + } + + .FieldDescription { + font-size: 12px; color: var(--theme-color-fg-default); + opacity: 0.7; + line-height: 1.5; } } +// Budget Configuration .BudgetRow { display: flex; - gap: 8px; + gap: $spacing-sm; align-items: center; + padding: $spacing-md; + background: var(--theme-color-bg-3); + border-radius: $radius-md; + transition: all $transition-base; + + &:hover { + background: var(--theme-color-bg-2); + } span { color: var(--theme-color-fg-default); + font-size: 14px; + font-weight: 500; + } + + .BudgetValue { + color: var(--theme-color-fg-highlight); + font-weight: 600; + font-size: 16px; } } .BudgetInput { - width: 80px; - padding: 6px 10px; + width: 90px; + padding: 8px 12px; background: var(--theme-color-bg-1); - border: 1px solid var(--theme-color-bg-3); - border-radius: 4px; + border: 2px solid var(--theme-color-bg-3); + border-radius: $radius-md; color: var(--theme-color-fg-highlight); - font-size: 14px; + font-size: 15px; + font-weight: 600; + text-align: center; + transition: all $transition-base; &:focus { outline: none; - border-color: var(--theme-color-primary); + border-color: $ai-primary; + box-shadow: 0 0 0 3px rgba(139, 92, 246, 0.1); + transform: scale(1.05); + } + + &:hover:not(:focus) { + border-color: rgba(139, 92, 246, 0.3); } } +// Checkbox .Checkbox { display: flex; - gap: 8px; + gap: $spacing-sm; align-items: center; + padding: $spacing-sm; cursor: pointer; font-size: 13px; + border-radius: $radius-md; + transition: all $transition-fast; + user-select: none; + + &:hover { + background: var(--theme-color-bg-3); + } input[type='checkbox'] { cursor: pointer; + width: 18px; + height: 18px; + accent-color: $ai-primary; + transition: all $transition-fast; + + &:focus { + outline: 2px solid rgba(139, 92, 246, 0.3); + outline-offset: 2px; + } } span { color: var(--theme-color-fg-default); + line-height: 1.5; } } +// Actions .Actions { display: flex; - gap: 12px; + gap: $spacing-md; justify-content: flex-end; - margin-top: 8px; + margin-top: $spacing-md; + padding-top: $spacing-lg; + border-top: 1px solid var(--theme-color-bg-3); + + button { + min-width: 120px; + transition: all $transition-base; + + &:hover { + transform: translateY(-2px); + box-shadow: $shadow-md; + } + + &:active { + transform: translateY(0); + } + + // Primary action (Continue button) + &:last-child { + background: linear-gradient(135deg, $ai-primary 0%, $ai-primary-dark 100%); + position: relative; + overflow: hidden; + + &::before { + content: ''; + position: absolute; + top: 0; + left: -100%; + width: 100%; + height: 100%; + background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent); + transition: left 0.5s ease; + } + + &:hover::before { + left: 100%; + } + } + } +} + +// Budget Warning (when close to limit) +.BudgetWarning { + display: flex; + gap: $spacing-sm; + align-items: flex-start; + padding: $spacing-md; + background: linear-gradient(135deg, rgba(245, 158, 11, 0.1) 0%, rgba(245, 158, 11, 0.05) 100%); + border: 1px solid rgba(245, 158, 11, 0.3); + border-left: 3px solid $warning; + border-radius: $radius-md; + font-size: 13px; + line-height: 1.6; + animation: pulse 2s ease-in-out infinite; + + svg { + flex-shrink: 0; + width: 18px; + height: 18px; + color: $warning; + margin-top: 2px; + } + + p { + margin: 0; + color: var(--theme-color-fg-default); + } + + strong { + color: var(--theme-color-fg-highlight); + font-weight: 600; + } +} + +// API Key Preview (masked display) +.APIKeyPreview { + padding: $spacing-md; + background: var(--theme-color-bg-1); + border: 1px solid var(--theme-color-bg-3); + border-radius: $radius-md; + font-family: 'SF Mono', 'Monaco', 'Consolas', monospace; + font-size: 13px; + color: var(--theme-color-fg-default); + letter-spacing: 1px; + display: flex; + align-items: center; + justify-content: space-between; + gap: $spacing-md; + + .KeyText { + flex: 1; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + button { + flex-shrink: 0; + padding: 4px 8px; + font-size: 11px; + opacity: 0.7; + transition: opacity $transition-fast; + + &:hover { + opacity: 1; + } + } +} + +// Loading State +.Loading { + display: flex; + align-items: center; + justify-content: center; + gap: $spacing-sm; + padding: $spacing-lg; + color: var(--theme-color-fg-default); + font-size: 14px; + + svg { + animation: spin 1s linear infinite; + } +} + +@keyframes spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} + +// Feature List (benefits of AI migration) +.FeatureList { + display: flex; + flex-direction: column; + gap: $spacing-sm; + padding: $spacing-md 0; + + .FeatureItem { + display: flex; + gap: $spacing-sm; + align-items: flex-start; + padding: $spacing-sm; + border-radius: $radius-md; + transition: all $transition-fast; + + &:hover { + background: var(--theme-color-bg-3); + transform: translateX(4px); + } + + svg { + flex-shrink: 0; + width: 16px; + height: 16px; + color: $success; + margin-top: 2px; + } + + span { + font-size: 13px; + color: var(--theme-color-fg-default); + line-height: 1.5; + } + } } diff --git a/packages/noodl-editor/src/editor/src/views/migration/MigrationWizard.module.scss b/packages/noodl-editor/src/editor/src/views/migration/MigrationWizard.module.scss index 06ca4a1..5f8dd09 100644 --- a/packages/noodl-editor/src/editor/src/views/migration/MigrationWizard.module.scss +++ b/packages/noodl-editor/src/editor/src/views/migration/MigrationWizard.module.scss @@ -2,43 +2,122 @@ * MigrationWizard Styles * * Main container for the migration wizard using CoreBaseDialog. + * Enhanced with modern visual design, animations, and better spacing. */ +/* Animation definitions */ +@keyframes fadeIn { + from { + opacity: 0; + transform: scale(0.95); + } + to { + opacity: 1; + transform: scale(1); + } +} + +@keyframes slideIn { + from { + opacity: 0; + transform: translateY(10px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +/* Design system variables */ +:root { + --wizard-space-xs: 4px; + --wizard-space-sm: 8px; + --wizard-space-md: 16px; + --wizard-space-lg: 24px; + --wizard-space-xl: 32px; + --wizard-space-xxl: 48px; + + --wizard-transition-fast: 150ms ease-out; + --wizard-transition-base: 250ms ease-in-out; + --wizard-transition-slow: 400ms ease-in-out; + + --wizard-radius-sm: 4px; + --wizard-radius-md: 8px; + --wizard-radius-lg: 12px; + + --wizard-shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.12); + --wizard-shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1); + --wizard-shadow-lg: 0 10px 25px rgba(0, 0, 0, 0.15); +} + .WizardContainer { position: relative; - width: 700px; - max-width: 90vw; - max-height: 80vh; + width: 750px; + max-width: 92vw; + max-height: 85vh; display: flex; flex-direction: column; background-color: var(--theme-color-bg-4); - border-radius: 4px; + border-radius: var(--wizard-radius-lg); overflow: hidden; + box-shadow: var(--wizard-shadow-lg); + animation: fadeIn var(--wizard-transition-base); } .CloseButton { position: absolute; - top: 8px; - right: 8px; + top: var(--wizard-space-md); + right: var(--wizard-space-md); z-index: 10; + transition: transform var(--wizard-transition-fast); + + &:hover { + transform: scale(1.1); + } + + &:active { + transform: scale(0.95); + } } .WizardHeader { - padding: 24px 24px 16px; - padding-right: 48px; // Space for close button + padding: var(--wizard-space-xl) var(--wizard-space-xl) var(--wizard-space-lg); + padding-right: var(--wizard-space-xxl); // Space for close button + border-bottom: 1px solid var(--theme-color-bg-3); } .WizardContent { display: flex; flex-direction: column; - padding: 0 24px 24px; - gap: 16px; + padding: 0 var(--wizard-space-xl) var(--wizard-space-xl); + gap: var(--wizard-space-lg); flex: 1; min-height: 0; overflow-y: auto; + animation: slideIn var(--wizard-transition-base); + + /* Custom scrollbar styling */ + &::-webkit-scrollbar { + width: 8px; + } + + &::-webkit-scrollbar-track { + background: var(--theme-color-bg-3); + border-radius: var(--wizard-radius-sm); + } + + &::-webkit-scrollbar-thumb { + background: var(--theme-color-bg-1); + border-radius: var(--wizard-radius-sm); + + &:hover { + background: var(--theme-color-primary); + } + } } .StepContainer { flex: 1; - min-height: 200px; + min-height: 300px; + animation: slideIn var(--wizard-transition-base); } diff --git a/packages/noodl-editor/src/editor/src/views/migration/components/WizardProgress.module.scss b/packages/noodl-editor/src/editor/src/views/migration/components/WizardProgress.module.scss index 775b00c..fcaf9fa 100644 --- a/packages/noodl-editor/src/editor/src/views/migration/components/WizardProgress.module.scss +++ b/packages/noodl-editor/src/editor/src/views/migration/components/WizardProgress.module.scss @@ -1,78 +1,146 @@ /** * WizardProgress Styles * - * Step progress indicator for migration wizard. + * Enhanced step progress indicator for migration wizard with animations and better visuals. */ +@keyframes pulse { + 0%, + 100% { + transform: scale(1); + box-shadow: 0 0 0 0 rgba(66, 135, 245, 0.7); + } + 50% { + transform: scale(1.05); + box-shadow: 0 0 0 8px rgba(66, 135, 245, 0); + } +} + +@keyframes checkmark { + 0% { + transform: scale(0) rotate(-45deg); + } + 50% { + transform: scale(1.2) rotate(-45deg); + } + 100% { + transform: scale(1) rotate(0deg); + } +} + +@keyframes slideProgress { + from { + transform: scaleX(0); + transform-origin: left; + } + to { + transform: scaleX(1); + transform-origin: left; + } +} + .Root { display: flex; align-items: center; - gap: 8px; - padding: 8px 0; + gap: 0; + padding: 16px 0 24px; + margin-bottom: 8px; } .Step { display: flex; flex-direction: column; align-items: center; - gap: 4px; + gap: 8px; flex: 1; position: relative; + z-index: 1; } .StepCircle { - width: 28px; - height: 28px; + width: 36px; + height: 36px; border-radius: 50%; display: flex; align-items: center; justify-content: center; - font-size: 12px; + font-size: 13px; font-weight: 600; background-color: var(--theme-color-bg-2); - color: var(--theme-color-secondary-as-fg); - transition: background-color 0.2s, color 0.2s; + color: var(--theme-color-fg-muted); + border: 2px solid var(--theme-color-bg-2); + transition: all 300ms ease-in-out; + position: relative; + z-index: 2; } .Step.is-completed .StepCircle { background-color: var(--theme-color-success); + border-color: var(--theme-color-success); color: white; + animation: checkmark 400ms ease-out; } .Step.is-active .StepCircle { background-color: var(--theme-color-primary); + border-color: var(--theme-color-primary); color: white; + animation: pulse 2s ease-in-out infinite; + box-shadow: 0 0 0 0 rgba(66, 135, 245, 0.7); } .StepLabel { - font-size: 10px; - color: var(--theme-color-secondary-as-fg); + font-size: 11px; + font-weight: 500; + color: var(--theme-color-fg-muted); text-align: center; - max-width: 60px; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; + max-width: 80px; + transition: color 200ms ease-in-out; + line-height: 1.3; } .Step.is-completed .StepLabel, .Step.is-active .StepLabel { color: var(--theme-color-fg-highlight); + font-weight: 600; } .Connector { - width: 24px; + flex: 1; height: 2px; background-color: var(--theme-color-bg-2); - margin-bottom: 20px; - transition: background-color 0.2s; + margin: 0 -4px; + margin-bottom: 28px; + position: relative; + z-index: 0; + overflow: hidden; + + &::after { + content: ''; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: var(--theme-color-success); + transform: scaleX(0); + transform-origin: left; + transition: transform 400ms ease-in-out; + } } -.Connector.is-completed { - background-color: var(--theme-color-success); +.Connector.is-completed::after { + transform: scaleX(1); + animation: slideProgress 400ms ease-out; } .CheckIcon { display: flex; align-items: center; justify-content: center; + + svg { + width: 18px; + height: 18px; + } } diff --git a/packages/noodl-editor/src/editor/src/views/migration/steps/CompleteStep.module.scss b/packages/noodl-editor/src/editor/src/views/migration/steps/CompleteStep.module.scss index ad621b1..b9d9771 100644 --- a/packages/noodl-editor/src/editor/src/views/migration/steps/CompleteStep.module.scss +++ b/packages/noodl-editor/src/editor/src/views/migration/steps/CompleteStep.module.scss @@ -1,161 +1,321 @@ /** * CompleteStep Styles * - * Final step showing migration summary. + * Enhanced final step with celebration and beautiful summary. */ +@keyframes slideInUp { + from { + opacity: 0; + transform: translateY(10px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +@keyframes successPulse { + 0%, + 100% { + transform: scale(1); + filter: drop-shadow(0 0 8px rgba(34, 197, 94, 0.4)); + } + 50% { + transform: scale(1.1); + filter: drop-shadow(0 0 16px rgba(34, 197, 94, 0.6)); + } +} + +@keyframes countUp { + from { + transform: scale(0.8); + opacity: 0; + } + to { + transform: scale(1); + opacity: 1; + } +} + .Root { display: flex; flex-direction: column; height: 100%; + animation: slideInUp 300ms ease-out; } .Header { display: flex; + flex-direction: column; align-items: center; - gap: 12px; - margin-bottom: 8px; + gap: 16px; + margin-bottom: 24px; + padding: 20px; + background: linear-gradient(135deg, rgba(34, 197, 94, 0.1) 0%, transparent 100%); + border-radius: 12px; - svg { - color: var(--theme-color-success); + .SuccessIcon { + width: 64px; + height: 64px; + display: flex; + align-items: center; + justify-content: center; + background: linear-gradient(135deg, rgba(34, 197, 94, 0.2) 0%, rgba(34, 197, 94, 0.1) 100%); + border-radius: 50%; + animation: successPulse 2s ease-in-out infinite; + + svg { + width: 36px; + height: 36px; + color: var(--theme-color-success); + } + } + + h2 { + font-size: 24px; + font-weight: 700; + color: var(--theme-color-fg-highlight); + margin: 0; + text-align: center; + } + + p { + font-size: 14px; + color: var(--theme-color-fg-default); + margin: 0; + text-align: center; } } .Stats { - display: flex; - gap: 12px; - margin-top: 16px; + display: grid; + grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); + gap: 16px; + margin-bottom: 24px; } .StatCard { - flex: 1; display: flex; flex-direction: column; align-items: center; - gap: 4px; - padding: 12px; - background-color: var(--theme-color-bg-3); - border-radius: 8px; + gap: 12px; + padding: 20px 16px; + background: linear-gradient(135deg, var(--theme-color-bg-3) 0%, var(--theme-color-bg-2) 100%); + border-radius: 12px; text-align: center; + border: 1px solid var(--theme-color-bg-2); + transition: all 250ms ease-in-out; + + &:hover { + transform: translateY(-4px); + box-shadow: 0 8px 16px rgba(0, 0, 0, 0.15); + } } .StatCardIcon { - width: 20px; - height: 20px; + width: 40px; + height: 40px; display: flex; align-items: center; justify-content: center; + border-radius: 50%; + transition: all 200ms ease-in-out; + + svg { + width: 22px; + height: 22px; + } } .StatCard.is-success .StatCardIcon { color: var(--theme-color-success); + background-color: rgba(34, 197, 94, 0.15); } .StatCard.is-warning .StatCardIcon { color: var(--theme-color-warning); + background-color: rgba(251, 191, 36, 0.15); } .StatCard.is-error .StatCardIcon { color: var(--theme-color-danger); + background-color: rgba(239, 68, 68, 0.15); +} + +.StatCard:hover .StatCardIcon { + transform: scale(1.1) rotate(5deg); } .StatCardValue { - font-size: 24px; - font-weight: 600; + font-size: 32px; + font-weight: 700; color: var(--theme-color-fg-highlight); + line-height: 1; + font-variant-numeric: tabular-nums; + animation: countUp 400ms ease-out; } .StatCardLabel { font-size: 11px; - color: var(--theme-color-secondary-as-fg); + color: var(--theme-color-fg-default); text-transform: uppercase; - letter-spacing: 0.5px; + letter-spacing: 0.8px; + font-weight: 600; } .MetaInfo { display: flex; - gap: 16px; - margin-top: 12px; + gap: 20px; + margin-bottom: 20px; + padding: 16px; + background: linear-gradient(135deg, var(--theme-color-bg-3) 0%, var(--theme-color-bg-2) 100%); + border-radius: 10px; + flex-wrap: wrap; } .MetaItem { display: flex; align-items: center; - gap: 6px; - color: var(--theme-color-secondary-as-fg); - - svg { - width: 14px; - height: 14px; - } -} - -.Paths { - margin-top: 16px; - padding: 16px; - background-color: var(--theme-color-bg-3); - border-radius: 8px; -} - -.PathItem { - display: flex; - gap: 12px; - margin-top: 12px; + gap: 8px; + padding: 8px 16px; + background-color: var(--theme-color-bg-4); + border-radius: 20px; + font-size: 13px; + font-weight: 500; + color: var(--theme-color-fg-highlight); + border: 1px solid var(--theme-color-bg-2); svg { width: 16px; height: 16px; - color: var(--theme-color-secondary-as-fg); + color: var(--theme-color-primary); + } +} + +.Paths { + padding: 20px; + background: linear-gradient(135deg, var(--theme-color-bg-3) 0%, var(--theme-color-bg-2) 100%); + border-radius: 12px; + border: 1px solid var(--theme-color-bg-2); + margin-bottom: 20px; + + h3 { + font-size: 14px; + font-weight: 600; + color: var(--theme-color-fg-highlight); + margin: 0 0 16px 0; + } +} + +.PathItem { + display: flex; + gap: 16px; + padding: 16px; + background-color: var(--theme-color-bg-4); + border-radius: 8px; + border: 1px solid var(--theme-color-bg-3); + transition: all 200ms ease-in-out; + + &:not(:last-child) { + margin-bottom: 12px; + } + + svg { + width: 20px; + height: 20px; + color: var(--theme-color-primary); flex-shrink: 0; margin-top: 2px; } - &:first-of-type { - margin-top: 8px; + &:hover { + background-color: var(--theme-color-bg-3); + border-color: var(--theme-color-primary); } } .PathContent { display: flex; flex-direction: column; - gap: 2px; + gap: 6px; overflow: hidden; + flex: 1; - span:last-child { + .PathLabel { + font-size: 12px; + font-weight: 600; + color: var(--theme-color-fg-default); + text-transform: uppercase; + letter-spacing: 0.5px; + } + + .PathValue { font-family: monospace; font-size: 12px; + color: var(--theme-color-fg-highlight); word-break: break-all; + background-color: var(--theme-color-bg-2); + padding: 8px 12px; + border-radius: 6px; } } .NextSteps { - margin-top: 16px; - padding: 16px; - background-color: var(--theme-color-bg-3); - border-radius: 8px; + padding: 20px; + background: linear-gradient(135deg, var(--theme-color-bg-3) 0%, var(--theme-color-bg-2) 100%); + border-radius: 12px; + border: 1px solid var(--theme-color-bg-2); + margin-bottom: 20px; + + h3 { + font-size: 14px; + font-weight: 600; + color: var(--theme-color-fg-highlight); + margin: 0 0 16px 0; + display: flex; + align-items: center; + gap: 8px; + + svg { + width: 18px; + height: 18px; + color: var(--theme-color-primary); + } + } } .StepsList { list-style: none; padding: 0; - margin: 8px 0 0 0; + margin: 0; li { display: flex; - gap: 12px; - padding: 8px 0; - border-bottom: 1px solid var(--theme-color-bg-2); + gap: 16px; + padding: 16px; + background-color: var(--theme-color-bg-4); + border-radius: 8px; + font-size: 14px; + line-height: 1.5; + color: var(--theme-color-fg-default); + transition: all 200ms ease-in-out; - &:last-child { - border-bottom: none; + &:not(:last-child) { + margin-bottom: 10px; + } + + &:hover { + background-color: var(--theme-color-bg-3); + transform: translateX(4px); } svg { - width: 16px; - height: 16px; + width: 20px; + height: 20px; flex-shrink: 0; margin-top: 2px; - color: var(--theme-color-secondary-as-fg); + color: var(--theme-color-primary); } } } @@ -165,4 +325,5 @@ padding-top: 24px; display: flex; justify-content: flex-end; + gap: 12px; } diff --git a/packages/noodl-editor/src/editor/src/views/migration/steps/ConfirmStep.module.scss b/packages/noodl-editor/src/editor/src/views/migration/steps/ConfirmStep.module.scss index 233cb51..8b2da49 100644 --- a/packages/noodl-editor/src/editor/src/views/migration/steps/ConfirmStep.module.scss +++ b/packages/noodl-editor/src/editor/src/views/migration/steps/ConfirmStep.module.scss @@ -2,53 +2,124 @@ * ConfirmStep Styles * * First step of migration wizard - confirm source and target paths. + * Enhanced with better visual hierarchy and animations. */ +@keyframes arrowBounce { + 0%, + 100% { + transform: translateY(0); + } + 50% { + transform: translateY(4px); + } +} + +@keyframes slideInUp { + from { + opacity: 0; + transform: translateY(10px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + .Root { display: flex; flex-direction: column; height: 100%; + animation: slideInUp 300ms ease-out; } .Header { display: flex; align-items: center; gap: 12px; - margin-bottom: 8px; + margin-bottom: 20px; svg { color: var(--theme-color-primary); + width: 24px; + height: 24px; + } + + h2 { + font-size: 20px; + font-weight: 600; + color: var(--theme-color-fg-highlight); + margin: 0; } } .PathSection { display: flex; flex-direction: column; - gap: 8px; - padding: 16px; + gap: 12px; + padding: 20px; background-color: var(--theme-color-bg-3); border-radius: 8px; + border: 1px solid transparent; + transition: all 250ms ease-in-out; + + &:hover { + background-color: var(--theme-color-bg-2); + } +} + +.PathSection--locked { + background-color: var(--theme-color-bg-2); + border-color: var(--theme-color-bg-1); + opacity: 0.9; + + .PathValue { + background-color: var(--theme-color-bg-1); + color: var(--theme-color-fg-default-shy); + border: 1px dashed var(--theme-color-bg-1); + } +} + +.PathSection--editable { + border-color: var(--theme-color-primary); + border-width: 2px; + box-shadow: 0 0 0 3px rgba(66, 135, 245, 0.1); + + &:hover { + box-shadow: 0 0 0 4px rgba(66, 135, 245, 0.15); + } } .PathHeader { display: flex; align-items: center; - gap: 8px; + gap: 10px; + + h3 { + font-size: 14px; + font-weight: 600; + color: var(--theme-color-fg-highlight); + margin: 0; + } +} + +.LockIcon { + color: var(--theme-color-fg-muted); + width: 16px; + height: 16px; } -.LockIcon, .FolderIcon { - color: var(--theme-color-secondary-as-fg); + color: var(--theme-color-primary); + width: 16px; + height: 16px; } .PathFields { display: flex; flex-direction: column; - gap: 16px; - margin-top: 16px; - padding: 16px; - background-color: var(--theme-color-bg-3); - border-radius: 8px; + gap: 20px; + margin-top: 0; } .PathField { @@ -115,24 +186,66 @@ display: flex; align-items: center; justify-content: center; - gap: 8px; - padding: 8px 0; - color: var(--theme-color-secondary-as-fg); + gap: 12px; + padding: 16px 0; + margin: 8px 0; + color: var(--theme-color-primary); + font-size: 13px; + font-weight: 500; + + svg { + width: 20px; + height: 20px; + animation: arrowBounce 2s ease-in-out infinite; + } } .InfoBox { - padding: 16px; - background-color: var(--theme-color-bg-3); + padding: 20px; + background: linear-gradient(135deg, var(--theme-color-bg-3) 0%, var(--theme-color-bg-2) 100%); border-radius: 8px; + border-left: 3px solid var(--theme-color-primary); + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); + + h4 { + font-size: 14px; + font-weight: 600; + color: var(--theme-color-fg-highlight); + margin: 0 0 12px 0; + display: flex; + align-items: center; + gap: 8px; + + svg { + width: 16px; + height: 16px; + color: var(--theme-color-primary); + } + } + + p { + font-size: 13px; + line-height: 1.5; + color: var(--theme-color-fg-default); + margin: 0 0 12px 0; + } } .StepsList { - margin: 8px 0 0 0; - padding-left: 20px; + margin: 0; + padding-left: 24px; color: var(--theme-color-fg-default); - + font-size: 13px; + line-height: 1.6; + li { - margin-bottom: 4px; + margin-bottom: 8px; + padding-left: 4px; + + &::marker { + color: var(--theme-color-primary); + font-weight: 600; + } } } diff --git a/packages/noodl-editor/src/editor/src/views/migration/steps/FailedStep.module.scss b/packages/noodl-editor/src/editor/src/views/migration/steps/FailedStep.module.scss index 8c53d33..0901443 100644 --- a/packages/noodl-editor/src/editor/src/views/migration/steps/FailedStep.module.scss +++ b/packages/noodl-editor/src/editor/src/views/migration/steps/FailedStep.module.scss @@ -1,91 +1,181 @@ /** * FailedStep Styles * - * Error state when migration fails. + * Enhanced error state with helpful suggestions and beautiful error display. */ +@keyframes slideInUp { + from { + opacity: 0; + transform: translateY(10px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +@keyframes shake { + 0%, + 100% { + transform: translateX(0); + } + 25% { + transform: translateX(-4px); + } + 75% { + transform: translateX(4px); + } +} + .Root { display: flex; flex-direction: column; height: 100%; + animation: slideInUp 300ms ease-out; } .Header { display: flex; + flex-direction: column; align-items: center; - gap: 12px; - margin-bottom: 8px; -} + gap: 16px; + margin-bottom: 24px; + padding: 20px; + background: linear-gradient(135deg, rgba(239, 68, 68, 0.1) 0%, transparent 100%); + border-radius: 12px; -.ErrorCircleIcon { - color: var(--theme-color-danger); -} + .ErrorIcon { + width: 64px; + height: 64px; + display: flex; + align-items: center; + justify-content: center; + background: linear-gradient(135deg, rgba(239, 68, 68, 0.2) 0%, rgba(239, 68, 68, 0.1) 100%); + border-radius: 50%; + animation: shake 500ms ease-out; -.DescriptionText { - color: var(--theme-color-secondary-as-fg); + svg { + width: 36px; + height: 36px; + color: var(--theme-color-danger); + } + } + + h2 { + font-size: 22px; + font-weight: 700; + color: var(--theme-color-fg-highlight); + margin: 0; + text-align: center; + } + + p { + font-size: 14px; + color: var(--theme-color-fg-default); + margin: 0; + text-align: center; + line-height: 1.6; + } } .ErrorBox { - margin-top: 16px; - background-color: rgba(239, 68, 68, 0.1); - border: 1px solid rgba(239, 68, 68, 0.3); - border-radius: 8px; + margin-bottom: 20px; + background: linear-gradient(135deg, rgba(239, 68, 68, 0.08) 0%, rgba(239, 68, 68, 0.05) 100%); + border: 2px solid rgba(239, 68, 68, 0.3); + border-radius: 12px; overflow: hidden; } .ErrorHeader { display: flex; align-items: center; - gap: 8px; - padding: 12px 16px; + gap: 12px; + padding: 16px 20px; background-color: rgba(239, 68, 68, 0.15); + border-bottom: 1px solid rgba(239, 68, 68, 0.2); svg { + width: 20px; + height: 20px; color: var(--theme-color-danger); + flex-shrink: 0; + } + + h3 { + font-size: 14px; + font-weight: 600; + color: var(--theme-color-danger); + margin: 0; } } -.ErrorText { - color: var(--theme-color-danger); - font-weight: 500; -} - .ErrorMessage { - padding: 12px 16px; + padding: 20px; font-family: monospace; - font-size: 12px; + font-size: 13px; + line-height: 1.6; color: var(--theme-color-fg-highlight); - word-break: break-all; + background-color: var(--theme-color-bg-4); + word-break: break-word; + white-space: pre-wrap; } .Suggestions { - margin-top: 16px; - padding: 16px; - background-color: var(--theme-color-bg-3); - border-radius: 8px; + padding: 20px; + background: linear-gradient(135deg, var(--theme-color-bg-3) 0%, var(--theme-color-bg-2) 100%); + border-radius: 12px; + border: 1px solid var(--theme-color-bg-2); + margin-bottom: 20px; + + h3 { + font-size: 16px; + font-weight: 600; + color: var(--theme-color-fg-highlight); + margin: 0 0 16px 0; + display: flex; + align-items: center; + gap: 8px; + + svg { + width: 20px; + height: 20px; + color: var(--theme-color-primary); + } + } } .SuggestionList { list-style: none; padding: 0; - margin: 12px 0 0 0; + margin: 0; li { display: flex; - gap: 12px; - padding: 8px 0; - border-bottom: 1px solid var(--theme-color-bg-2); + gap: 16px; + padding: 16px; + background-color: var(--theme-color-bg-4); + border-radius: 8px; + font-size: 14px; + line-height: 1.5; + color: var(--theme-color-fg-default); + transition: all 200ms ease-in-out; - &:last-child { - border-bottom: none; + &:not(:last-child) { + margin-bottom: 10px; + } + + &:hover { + background-color: var(--theme-color-bg-3); + transform: translateX(4px); } svg { - width: 16px; - height: 16px; + width: 20px; + height: 20px; flex-shrink: 0; margin-top: 2px; - color: var(--theme-color-secondary-as-fg); + color: var(--theme-color-primary); } } } @@ -93,31 +183,47 @@ .Link { color: var(--theme-color-primary); text-decoration: underline; + font-weight: 500; + transition: opacity 200ms ease-in-out; &:hover { - opacity: 0.8; + opacity: 0.7; } } .SafetyNotice { display: flex; - gap: 12px; - margin-top: 16px; - padding: 12px 16px; - background-color: rgba(34, 197, 94, 0.1); - border: 1px solid rgba(34, 197, 94, 0.3); - border-radius: 8px; + gap: 16px; + padding: 20px; + background: linear-gradient(135deg, rgba(34, 197, 94, 0.12) 0%, rgba(34, 197, 94, 0.08) 100%); + border: 2px solid rgba(34, 197, 94, 0.3); + border-radius: 12px; + margin-bottom: 20px; svg { - width: 16px; - height: 16px; + width: 24px; + height: 24px; flex-shrink: 0; color: var(--theme-color-success); } -} -.SafetyText { - color: var(--theme-color-secondary-as-fg); + .SafetyContent { + flex: 1; + + h4 { + font-size: 14px; + font-weight: 600; + color: var(--theme-color-success); + margin: 0 0 6px 0; + } + + p { + font-size: 13px; + line-height: 1.6; + color: var(--theme-color-fg-default); + margin: 0; + } + } } .Actions { @@ -125,4 +231,5 @@ padding-top: 24px; display: flex; justify-content: flex-end; + gap: 12px; } diff --git a/packages/noodl-editor/src/editor/src/views/migration/steps/MigratingStep.module.scss b/packages/noodl-editor/src/editor/src/views/migration/steps/MigratingStep.module.scss index 6322f8e..6267149 100644 --- a/packages/noodl-editor/src/editor/src/views/migration/steps/MigratingStep.module.scss +++ b/packages/noodl-editor/src/editor/src/views/migration/steps/MigratingStep.module.scss @@ -1,52 +1,204 @@ /** * MigratingStep Styles * - * AI-assisted migration progress display with budget tracking and decision panels. + * Enhanced AI-assisted migration progress display with beautiful budget tracking and decision panels. */ +@keyframes slideInUp { + from { + opacity: 0; + transform: translateY(10px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +@keyframes shimmer { + 0% { + background-position: -1000px 0; + } + 100% { + background-position: 1000px 0; + } +} + +@keyframes budgetPulse { + 0%, + 100% { + box-shadow: 0 0 0 0 rgba(251, 191, 36, 0.7); + } + 50% { + box-shadow: 0 0 0 8px rgba(251, 191, 36, 0); + } +} + .Root { display: flex; flex-direction: column; height: 100%; - gap: 16px; + gap: 20px; + animation: slideInUp 300ms ease-out; } .Header { display: flex; align-items: center; - gap: 12px; + gap: 16px; + margin-bottom: 4px; + + svg { + width: 28px; + height: 28px; + color: var(--theme-color-primary); + animation: spin 1.5s linear infinite; + filter: drop-shadow(0 0 8px rgba(66, 135, 245, 0.3)); + } + + h2 { + font-size: 20px; + font-weight: 600; + color: var(--theme-color-fg-highlight); + margin: 0; + } + + p { + font-size: 14px; + color: var(--theme-color-fg-default); + margin: 4px 0 0 0; + } +} + +@keyframes spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } } /* Budget Section */ .BudgetSection { - padding: 12px 16px; - background-color: var(--theme-color-bg-3); - border-radius: 8px; - border: 1px solid var(--theme-color-bg-2); + padding: 20px; + background: linear-gradient(135deg, var(--theme-color-bg-3) 0%, var(--theme-color-bg-2) 100%); + border-radius: 12px; + border: 2px solid var(--theme-color-bg-2); + transition: all 300ms ease-in-out; + + &.is-warning { + border-color: var(--theme-color-warning); + animation: budgetPulse 2s ease-in-out infinite; + } } .BudgetHeader { display: flex; justify-content: space-between; align-items: center; - margin-bottom: 8px; + margin-bottom: 16px; + + h3 { + font-size: 14px; + font-weight: 600; + color: var(--theme-color-fg-highlight); + margin: 0; + display: flex; + align-items: center; + gap: 8px; + + svg { + width: 16px; + height: 16px; + color: var(--theme-color-primary); + } + } + + .BudgetAmount { + font-size: 18px; + font-weight: 700; + color: var(--theme-color-primary); + font-variant-numeric: tabular-nums; + + &.is-warning { + color: var(--theme-color-warning); + } + } } .BudgetBar { - height: 6px; - background-color: var(--theme-color-bg-2); - border-radius: 3px; + height: 10px; + background-color: var(--theme-color-bg-1); + border-radius: 5px; overflow: hidden; + position: relative; + box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.2); + + &::after { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 50%; + background: linear-gradient(to bottom, rgba(255, 255, 255, 0.2), transparent); + pointer-events: none; + } } .BudgetFill { height: 100%; - background-color: var(--theme-color-primary); - border-radius: 3px; - transition: width 0.3s ease, background-color 0.3s ease; + background: linear-gradient( + 90deg, + var(--theme-color-primary) 0%, + rgba(66, 135, 245, 0.8) 50%, + var(--theme-color-primary) 100% + ); + background-size: 200% 100%; + border-radius: 5px; + transition: width 400ms ease-out, background 300ms ease-in-out; + animation: shimmer 2s linear infinite; + position: relative; &.is-warning { - background-color: var(--theme-color-warning); + background: linear-gradient( + 90deg, + var(--theme-color-warning) 0%, + rgba(251, 191, 36, 0.8) 50%, + var(--theme-color-warning) 100% + ); + background-size: 200% 100%; + animation: shimmer 2s linear infinite; + } + + &::after { + content: ''; + position: absolute; + top: 0; + right: 0; + width: 20px; + height: 100%; + background: linear-gradient(to right, transparent, rgba(255, 255, 255, 0.4)); + border-radius: 0 5px 5px 0; + } +} + +.BudgetWarning { + display: flex; + align-items: center; + gap: 8px; + margin-top: 12px; + padding: 8px 12px; + background-color: rgba(251, 191, 36, 0.15); + border-radius: 6px; + font-size: 12px; + color: var(--theme-color-warning); + + svg { + width: 14px; + height: 14px; + flex-shrink: 0; } } diff --git a/packages/noodl-editor/src/editor/src/views/migration/steps/ReportStep.module.scss b/packages/noodl-editor/src/editor/src/views/migration/steps/ReportStep.module.scss index 42db554..ab77a91 100644 --- a/packages/noodl-editor/src/editor/src/views/migration/steps/ReportStep.module.scss +++ b/packages/noodl-editor/src/editor/src/views/migration/steps/ReportStep.module.scss @@ -1,82 +1,187 @@ /** * ReportStep Styles * - * Scan results report with categories and AI options. + * Enhanced scan results report with beautiful categories and AI options. */ +@keyframes slideInUp { + from { + opacity: 0; + transform: translateY(10px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +@keyframes countUp { + from { + transform: scale(0.8); + opacity: 0; + } + to { + transform: scale(1); + opacity: 1; + } +} + +@keyframes sparkle { + 0%, + 100% { + opacity: 1; + transform: scale(1); + } + 50% { + opacity: 0.7; + transform: scale(1.1); + } +} + .Root { display: flex; flex-direction: column; height: 100%; + animation: slideInUp 300ms ease-out; } .Header { display: flex; align-items: center; - gap: 12px; - margin-bottom: 8px; + gap: 16px; + margin-bottom: 20px; svg { + width: 24px; + height: 24px; color: var(--theme-color-primary); } + + h2 { + font-size: 20px; + font-weight: 600; + color: var(--theme-color-fg-highlight); + margin: 0; + } + + p { + font-size: 14px; + color: var(--theme-color-fg-default); + margin: 4px 0 0 0; + } } .StatsRow { - display: flex; - gap: 12px; - margin-top: 16px; + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 16px; + margin-bottom: 24px; } .StatCard { - flex: 1; display: flex; flex-direction: column; align-items: center; - gap: 4px; - padding: 12px; - background-color: var(--theme-color-bg-3); - border-radius: 8px; + gap: 12px; + padding: 20px 16px; + background: linear-gradient(135deg, var(--theme-color-bg-3) 0%, var(--theme-color-bg-2) 100%); + border-radius: 12px; text-align: center; + border: 1px solid var(--theme-color-bg-2); + transition: all 250ms ease-in-out; + position: relative; + overflow: hidden; + + &::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 3px; + background: var(--theme-color-secondary-as-fg); + opacity: 0; + transition: opacity 250ms ease-in-out; + } + + &:hover { + transform: translateY(-4px); + box-shadow: 0 8px 16px rgba(0, 0, 0, 0.15); + + &::before { + opacity: 1; + } + } +} + +.StatCard.is-automatic::before { + background: var(--theme-color-success); +} + +.StatCard.is-simpleFixes::before { + background: var(--theme-color-warning); +} + +.StatCard.is-needsReview::before { + background: var(--theme-color-danger); } .StatCardIcon { - width: 24px; - height: 24px; + width: 40px; + height: 40px; display: flex; align-items: center; justify-content: center; color: var(--theme-color-secondary-as-fg); + background-color: var(--theme-color-bg-4); + border-radius: 50%; + transition: all 200ms ease-in-out; + + svg { + width: 22px; + height: 22px; + } } .StatCard.is-automatic .StatCardIcon { color: var(--theme-color-success); + background-color: rgba(34, 197, 94, 0.15); } .StatCard.is-simpleFixes .StatCardIcon { color: var(--theme-color-warning); + background-color: rgba(251, 191, 36, 0.15); } .StatCard.is-needsReview .StatCardIcon { color: var(--theme-color-danger); + background-color: rgba(239, 68, 68, 0.15); +} + +.StatCard:hover .StatCardIcon { + transform: scale(1.1) rotate(5deg); } .StatCardValue { - font-size: 24px; - font-weight: 600; + font-size: 32px; + font-weight: 700; color: var(--theme-color-fg-highlight); + line-height: 1; + font-variant-numeric: tabular-nums; + animation: countUp 400ms ease-out; } .StatCardLabel { font-size: 11px; - color: var(--theme-color-secondary-as-fg); + color: var(--theme-color-fg-default); text-transform: uppercase; - letter-spacing: 0.5px; + letter-spacing: 0.8px; + font-weight: 600; } .Categories { flex: 1; overflow-y: auto; - margin-top: 16px; display: flex; flex-direction: column; gap: 12px; @@ -84,127 +189,309 @@ .CategorySection { background-color: var(--theme-color-bg-3); - border-radius: 8px; + border-radius: 10px; overflow: hidden; + border: 1px solid var(--theme-color-bg-2); + transition: all 250ms ease-in-out; + + &:hover { + border-color: var(--theme-color-bg-1); + } +} + +.CategorySection.is-expanded { + background-color: var(--theme-color-bg-2); } .CategoryHeader { display: flex; align-items: center; - gap: 8px; - padding: 12px 16px; - background-color: var(--theme-color-bg-2); + gap: 12px; + padding: 16px 20px; + background-color: transparent; cursor: pointer; + transition: all 200ms ease-in-out; + user-select: none; &:hover { - background-color: var(--theme-color-bg-1); + background-color: var(--theme-color-bg-2); + } + + &:active { + transform: scale(0.98); } } +.CategorySection.is-expanded .CategoryHeader { + background-color: var(--theme-color-bg-1); + border-bottom: 1px solid var(--theme-color-bg-3); +} + .CategoryIcon { - width: 16px; - height: 16px; + width: 36px; + height: 36px; display: flex; align-items: center; justify-content: center; + border-radius: 8px; + transition: all 200ms ease-in-out; + flex-shrink: 0; + + svg { + width: 18px; + height: 18px; + } } .CategorySection.is-automatic .CategoryIcon { color: var(--theme-color-success); + background-color: rgba(34, 197, 94, 0.15); } .CategorySection.is-simpleFixes .CategoryIcon { color: var(--theme-color-warning); + background-color: rgba(251, 191, 36, 0.15); } .CategorySection.is-needsReview .CategoryIcon { color: var(--theme-color-danger); + background-color: rgba(239, 68, 68, 0.15); +} + +.CategoryHeader:hover .CategoryIcon { + transform: scale(1.1); +} + +.CategoryInfo { + flex: 1; + display: flex; + flex-direction: column; + gap: 2px; } .CategoryTitle { - flex: 1; - font-weight: 500; + font-size: 15px; + font-weight: 600; + color: var(--theme-color-fg-highlight); +} + +.CategoryDescription { + font-size: 12px; + color: var(--theme-color-fg-default); } .CategoryCount { - background-color: var(--theme-color-bg-1); - padding: 2px 8px; - border-radius: 10px; - font-size: 11px; - color: var(--theme-color-secondary-as-fg); + background-color: var(--theme-color-bg-4); + padding: 4px 12px; + border-radius: 12px; + font-size: 13px; + font-weight: 600; + color: var(--theme-color-fg-highlight); + border: 1px solid var(--theme-color-bg-1); } .ExpandIcon { - width: 16px; - height: 16px; - color: var(--theme-color-secondary-as-fg); - transition: transform 0.2s ease; + width: 20px; + height: 20px; + color: var(--theme-color-fg-muted); + transition: transform 250ms ease-in-out; + flex-shrink: 0; + + svg { + width: 100%; + height: 100%; + } } .CategorySection.is-expanded .ExpandIcon { transform: rotate(180deg); + color: var(--theme-color-primary); } .ComponentList { display: flex; flex-direction: column; - gap: 2px; - padding: 8px; - max-height: 200px; + gap: 6px; + padding: 12px; + max-height: 250px; overflow-y: auto; + animation: slideInUp 250ms ease-out; + + /* Custom scrollbar */ + &::-webkit-scrollbar { + width: 6px; + } + + &::-webkit-scrollbar-track { + background: var(--theme-color-bg-3); + border-radius: 3px; + } + + &::-webkit-scrollbar-thumb { + background: var(--theme-color-bg-1); + border-radius: 3px; + + &:hover { + background: var(--theme-color-primary); + } + } } .ComponentItem { display: flex; justify-content: space-between; align-items: center; - padding: 8px 12px; - background-color: var(--theme-color-bg-2); - border-radius: 4px; + padding: 12px 16px; + background-color: var(--theme-color-bg-4); + border-radius: 8px; + border: 1px solid var(--theme-color-bg-3); + transition: all 200ms ease-in-out; + cursor: pointer; &:hover { - background-color: var(--theme-color-bg-1); + background-color: var(--theme-color-bg-3); + border-color: var(--theme-color-primary); + transform: translateX(4px); } } .ComponentName { font-size: 13px; + font-weight: 500; + color: var(--theme-color-fg-highlight); + display: flex; + align-items: center; + gap: 8px; + + &::before { + content: ''; + width: 6px; + height: 6px; + border-radius: 50%; + background-color: var(--theme-color-primary); + } } .ComponentIssueCount { font-size: 11px; - color: var(--theme-color-secondary-as-fg); + color: var(--theme-color-fg-default); + background-color: var(--theme-color-bg-2); + padding: 3px 8px; + border-radius: 10px; + font-weight: 500; } .AiPromptSection { - margin-top: 16px; - padding: 16px; - background-color: rgba(139, 92, 246, 0.1); - border: 1px solid rgba(139, 92, 246, 0.3); - border-radius: 8px; + margin-top: 20px; + padding: 24px; + background: linear-gradient(135deg, rgba(139, 92, 246, 0.12) 0%, rgba(139, 92, 246, 0.08) 100%); + border: 2px solid rgba(139, 92, 246, 0.3); + border-radius: 12px; + position: relative; + overflow: hidden; + transition: all 250ms ease-in-out; + + &::before { + content: ''; + position: absolute; + top: -2px; + left: -2px; + right: -2px; + bottom: -2px; + background: linear-gradient(45deg, rgba(139, 92, 246, 0.3), rgba(168, 85, 247, 0.3), rgba(139, 92, 246, 0.3)); + background-size: 200% 200%; + animation: shimmer 3s ease-in-out infinite; + border-radius: 12px; + opacity: 0; + transition: opacity 250ms ease-in-out; + z-index: -1; + } + + &:hover::before { + opacity: 1; + } } .AiPromptHeader { display: flex; align-items: center; - gap: 8px; - margin-bottom: 8px; + gap: 12px; + margin-bottom: 16px; svg { - width: 20px; - height: 20px; - color: #8b5cf6; // AI purple + width: 28px; + height: 28px; + color: #8b5cf6; + animation: sparkle 2s ease-in-out infinite; + filter: drop-shadow(0 0 8px rgba(139, 92, 246, 0.4)); + } + + h4 { + font-size: 16px; + font-weight: 600; + color: #8b5cf6; + margin: 0; } } -.AiPromptTitle { +.AiPromptContent { + display: flex; + flex-direction: column; + gap: 12px; + + p { + font-size: 13px; + line-height: 1.6; + color: var(--theme-color-fg-default); + margin: 0; + } + + strong { + color: var(--theme-color-fg-highlight); + } +} + +.AiPromptFeatures { + display: flex; + gap: 12px; + margin-top: 12px; + flex-wrap: wrap; +} + +.AiPromptFeature { + display: flex; + align-items: center; + gap: 6px; + padding: 6px 12px; + background-color: rgba(139, 92, 246, 0.15); + border-radius: 16px; + font-size: 12px; + color: #8b5cf6; font-weight: 500; - color: #8b5cf6; // AI purple + + svg { + width: 14px; + height: 14px; + } +} + +.AiPromptCost { + display: inline-flex; + align-items: center; + gap: 4px; + font-weight: 600; + color: #8b5cf6; + + svg { + width: 16px; + height: 16px; + } } .AiPromptSection.is-disabled { - opacity: 0.6; + opacity: 0.5; pointer-events: none; + filter: grayscale(0.5); } .Actions { @@ -212,4 +499,5 @@ padding-top: 24px; display: flex; justify-content: flex-end; + gap: 12px; } diff --git a/packages/noodl-editor/src/editor/src/views/migration/steps/ScanningStep.module.scss b/packages/noodl-editor/src/editor/src/views/migration/steps/ScanningStep.module.scss index 20ca9c1..400d0a6 100644 --- a/packages/noodl-editor/src/editor/src/views/migration/steps/ScanningStep.module.scss +++ b/packages/noodl-editor/src/editor/src/views/migration/steps/ScanningStep.module.scss @@ -1,27 +1,9 @@ /** * ScanningStep Styles * - * Scanning/migrating progress display. + * Enhanced scanning/migrating progress display with animations and better visualization. */ -.Root { - display: flex; - flex-direction: column; - height: 100%; - gap: 16px; -} - -.Header { - display: flex; - align-items: center; - gap: 12px; - - svg { - color: var(--theme-color-primary); - animation: spin 1s linear infinite; - } -} - @keyframes spin { from { transform: rotate(0deg); @@ -31,31 +13,232 @@ } } +@keyframes shimmer { + 0% { + background-position: -1000px 0; + } + 100% { + background-position: 1000px 0; + } +} + +@keyframes slideInUp { + from { + opacity: 0; + transform: translateY(10px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +@keyframes fadeInSlide { + from { + opacity: 0; + transform: translateX(-10px); + } + to { + opacity: 1; + transform: translateX(0); + } +} + +@keyframes pulse { + 0%, + 100% { + opacity: 1; + } + 50% { + opacity: 0.7; + } +} + +.Root { + display: flex; + flex-direction: column; + height: 100%; + gap: 24px; + animation: slideInUp 300ms ease-out; +} + +.Header { + display: flex; + align-items: center; + gap: 16px; + margin-bottom: 4px; + + svg { + width: 28px; + height: 28px; + color: var(--theme-color-primary); + animation: spin 1.5s linear infinite; + filter: drop-shadow(0 0 8px rgba(66, 135, 245, 0.3)); + } + + h2 { + font-size: 20px; + font-weight: 600; + color: var(--theme-color-fg-highlight); + margin: 0; + } + + p { + font-size: 14px; + color: var(--theme-color-fg-default); + margin: 4px 0 0 0; + } +} + .ProgressSection { - padding: 16px; - background-color: var(--theme-color-bg-3); - border-radius: 8px; + padding: 24px; + background: linear-gradient(135deg, var(--theme-color-bg-3) 0%, var(--theme-color-bg-2) 100%); + border-radius: 12px; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); + border: 1px solid var(--theme-color-bg-2); } .ProgressHeader { display: flex; justify-content: space-between; align-items: center; - margin-bottom: 8px; + margin-bottom: 16px; + + h3 { + font-size: 14px; + font-weight: 600; + color: var(--theme-color-fg-highlight); + margin: 0; + } + + span { + font-size: 16px; + font-weight: 700; + color: var(--theme-color-primary); + font-variant-numeric: tabular-nums; + } } .ProgressBar { - height: 8px; - background-color: var(--theme-color-bg-2); - border-radius: 4px; + height: 12px; + background-color: var(--theme-color-bg-1); + border-radius: 6px; overflow: hidden; + position: relative; + box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.2); + + &::after { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 50%; + background: linear-gradient(to bottom, rgba(255, 255, 255, 0.2), transparent); + pointer-events: none; + } } .ProgressFill { height: 100%; - background-color: var(--theme-color-primary); - border-radius: 4px; - transition: width 0.3s ease; + background: linear-gradient( + 90deg, + var(--theme-color-primary) 0%, + rgba(66, 135, 245, 0.8) 50%, + var(--theme-color-primary) 100% + ); + background-size: 200% 100%; + border-radius: 6px; + transition: width 400ms ease-out; + animation: shimmer 2s linear infinite; + position: relative; + + &::after { + content: ''; + position: absolute; + top: 0; + right: 0; + width: 20px; + height: 100%; + background: linear-gradient(to right, transparent, rgba(255, 255, 255, 0.4)); + border-radius: 0 6px 6px 0; + } +} + +.CurrentFile { + margin-top: 12px; + display: flex; + align-items: center; + gap: 8px; + font-size: 12px; + color: var(--theme-color-fg-default); + animation: pulse 1.5s ease-in-out infinite; + + svg { + width: 14px; + height: 14px; + color: var(--theme-color-primary); + } + + span { + font-family: monospace; + color: var(--theme-color-fg-highlight); + } +} + +.StatsGrid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 12px; + margin-top: 20px; +} + +.StatCard { + display: flex; + flex-direction: column; + align-items: center; + padding: 16px; + background-color: var(--theme-color-bg-4); + border-radius: 8px; + border: 1px solid var(--theme-color-bg-2); + transition: all 200ms ease-in-out; + + &:hover { + transform: translateY(-2px); + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); + } +} + +.StatIcon { + width: 32px; + height: 32px; + display: flex; + align-items: center; + justify-content: center; + margin-bottom: 8px; + color: var(--theme-color-primary); + + svg { + width: 20px; + height: 20px; + } +} + +.StatValue { + font-size: 24px; + font-weight: 700; + color: var(--theme-color-fg-highlight); + line-height: 1; + margin-bottom: 4px; + font-variant-numeric: tabular-nums; +} + +.StatLabel { + font-size: 11px; + color: var(--theme-color-fg-default); + text-transform: uppercase; + letter-spacing: 0.5px; + font-weight: 500; } .ActivityLog {