Made visual changes to the migration wizard

This commit is contained in:
Richard Osborne
2025-12-21 11:27:41 +01:00
parent 03a464f6ff
commit 89c7160de8
10 changed files with 2090 additions and 294 deletions

View File

@@ -2,6 +2,162 @@
## [Unreleased] ## [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 ### Session 11: MigrationWizard AI Integration Complete
#### 2024-12-20 #### 2024-12-20

View File

@@ -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 { .AIConfigPanel {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 24px; gap: $spacing-lg;
max-width: 600px; max-width: 600px;
padding: 24px; padding: $spacing-xl;
animation: fadeInUp 0.4s ease;
} }
// Header Section
.Header { .Header {
display: flex; display: flex;
gap: 16px; gap: $spacing-md;
align-items: flex-start; 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 { svg {
flex-shrink: 0; 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 { .HeaderText {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 8px; gap: $spacing-xs;
flex: 1;
h3 { h3 {
margin: 0; margin: 0;
font-size: 16px; font-size: 18px;
font-weight: 600; font-weight: 600;
color: var(--theme-color-fg-highlight); 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 { .Section {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 12px; gap: $spacing-md;
padding: 16px; padding: $spacing-lg;
background: var(--theme-color-bg-2); 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 { h4 {
margin: 0; margin: 0;
font-size: 14px; font-size: 15px;
font-weight: 600; font-weight: 600;
color: var(--theme-color-fg-highlight); 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 { a {
color: var(--theme-color-primary); color: $ai-primary;
text-decoration: none; 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 { &:hover {
text-decoration: underline; color: $ai-primary-dark;
&::after {
transform: scaleX(1);
}
} }
} }
} }
// Input Group
.InputGroup { .InputGroup {
display: flex; display: flex;
gap: 8px; gap: $spacing-sm;
align-items: center; align-items: flex-start;
> :first-child { > :first-child {
flex: 1; 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 { .ValidationSuccess {
display: flex; display: flex;
gap: 8px; gap: $spacing-sm;
align-items: center; 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-size: 13px;
font-weight: 500;
animation: checkBounce 0.5s ease;
svg { svg {
flex-shrink: 0; flex-shrink: 0;
width: 18px;
height: 18px;
filter: drop-shadow(0 2px 4px rgba(16, 185, 129, 0.3));
} }
} }
.ValidationError { .ValidationError {
display: flex; display: flex;
gap: 8px; gap: $spacing-sm;
align-items: center; 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-size: 13px;
font-weight: 500;
animation: shake 0.5s ease;
svg { svg {
flex-shrink: 0; flex-shrink: 0;
width: 18px;
height: 18px;
} }
} }
// Security Note
.SecurityNote { .SecurityNote {
display: flex; display: flex;
gap: 8px; gap: $spacing-sm;
align-items: flex-start; align-items: flex-start;
padding: 12px; padding: $spacing-md;
background: var(--theme-color-bg-3); background: linear-gradient(135deg, var(--theme-color-bg-3) 0%, var(--theme-color-bg-2) 100%);
border-radius: 4px; border-left: 3px solid $ai-primary;
border-radius: $radius-md;
font-size: 13px; font-size: 13px;
line-height: 1.6;
box-shadow: $shadow-sm;
svg { svg {
flex-shrink: 0; flex-shrink: 0;
width: 20px;
height: 20px;
margin-top: 2px; 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 { .Field {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 8px; gap: $spacing-sm;
> label:first-child { > label:first-child {
font-size: 13px; font-size: 13px;
font-weight: 500; font-weight: 600;
color: var(--theme-color-fg-default); 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 { .BudgetRow {
display: flex; display: flex;
gap: 8px; gap: $spacing-sm;
align-items: center; 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 { span {
color: var(--theme-color-fg-default); 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 { .BudgetInput {
width: 80px; width: 90px;
padding: 6px 10px; padding: 8px 12px;
background: var(--theme-color-bg-1); background: var(--theme-color-bg-1);
border: 1px solid var(--theme-color-bg-3); border: 2px solid var(--theme-color-bg-3);
border-radius: 4px; border-radius: $radius-md;
color: var(--theme-color-fg-highlight); color: var(--theme-color-fg-highlight);
font-size: 14px; font-size: 15px;
font-weight: 600;
text-align: center;
transition: all $transition-base;
&:focus { &:focus {
outline: none; 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 { .Checkbox {
display: flex; display: flex;
gap: 8px; gap: $spacing-sm;
align-items: center; align-items: center;
padding: $spacing-sm;
cursor: pointer; cursor: pointer;
font-size: 13px; font-size: 13px;
border-radius: $radius-md;
transition: all $transition-fast;
user-select: none;
&:hover {
background: var(--theme-color-bg-3);
}
input[type='checkbox'] { input[type='checkbox'] {
cursor: pointer; 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 { span {
color: var(--theme-color-fg-default); color: var(--theme-color-fg-default);
line-height: 1.5;
} }
} }
// Actions
.Actions { .Actions {
display: flex; display: flex;
gap: 12px; gap: $spacing-md;
justify-content: flex-end; 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;
}
}
} }

View File

@@ -2,43 +2,122 @@
* MigrationWizard Styles * MigrationWizard Styles
* *
* Main container for the migration wizard using CoreBaseDialog. * 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 { .WizardContainer {
position: relative; position: relative;
width: 700px; width: 750px;
max-width: 90vw; max-width: 92vw;
max-height: 80vh; max-height: 85vh;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
background-color: var(--theme-color-bg-4); background-color: var(--theme-color-bg-4);
border-radius: 4px; border-radius: var(--wizard-radius-lg);
overflow: hidden; overflow: hidden;
box-shadow: var(--wizard-shadow-lg);
animation: fadeIn var(--wizard-transition-base);
} }
.CloseButton { .CloseButton {
position: absolute; position: absolute;
top: 8px; top: var(--wizard-space-md);
right: 8px; right: var(--wizard-space-md);
z-index: 10; z-index: 10;
transition: transform var(--wizard-transition-fast);
&:hover {
transform: scale(1.1);
}
&:active {
transform: scale(0.95);
}
} }
.WizardHeader { .WizardHeader {
padding: 24px 24px 16px; padding: var(--wizard-space-xl) var(--wizard-space-xl) var(--wizard-space-lg);
padding-right: 48px; // Space for close button padding-right: var(--wizard-space-xxl); // Space for close button
border-bottom: 1px solid var(--theme-color-bg-3);
} }
.WizardContent { .WizardContent {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
padding: 0 24px 24px; padding: 0 var(--wizard-space-xl) var(--wizard-space-xl);
gap: 16px; gap: var(--wizard-space-lg);
flex: 1; flex: 1;
min-height: 0; min-height: 0;
overflow-y: auto; 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 { .StepContainer {
flex: 1; flex: 1;
min-height: 200px; min-height: 300px;
animation: slideIn var(--wizard-transition-base);
} }

View File

@@ -1,78 +1,146 @@
/** /**
* WizardProgress Styles * 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 { .Root {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 8px; gap: 0;
padding: 8px 0; padding: 16px 0 24px;
margin-bottom: 8px;
} }
.Step { .Step {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
gap: 4px; gap: 8px;
flex: 1; flex: 1;
position: relative; position: relative;
z-index: 1;
} }
.StepCircle { .StepCircle {
width: 28px; width: 36px;
height: 28px; height: 36px;
border-radius: 50%; border-radius: 50%;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
font-size: 12px; font-size: 13px;
font-weight: 600; font-weight: 600;
background-color: var(--theme-color-bg-2); background-color: var(--theme-color-bg-2);
color: var(--theme-color-secondary-as-fg); color: var(--theme-color-fg-muted);
transition: background-color 0.2s, color 0.2s; border: 2px solid var(--theme-color-bg-2);
transition: all 300ms ease-in-out;
position: relative;
z-index: 2;
} }
.Step.is-completed .StepCircle { .Step.is-completed .StepCircle {
background-color: var(--theme-color-success); background-color: var(--theme-color-success);
border-color: var(--theme-color-success);
color: white; color: white;
animation: checkmark 400ms ease-out;
} }
.Step.is-active .StepCircle { .Step.is-active .StepCircle {
background-color: var(--theme-color-primary); background-color: var(--theme-color-primary);
border-color: var(--theme-color-primary);
color: white; color: white;
animation: pulse 2s ease-in-out infinite;
box-shadow: 0 0 0 0 rgba(66, 135, 245, 0.7);
} }
.StepLabel { .StepLabel {
font-size: 10px; font-size: 11px;
color: var(--theme-color-secondary-as-fg); font-weight: 500;
color: var(--theme-color-fg-muted);
text-align: center; text-align: center;
max-width: 60px; max-width: 80px;
white-space: nowrap; transition: color 200ms ease-in-out;
overflow: hidden; line-height: 1.3;
text-overflow: ellipsis;
} }
.Step.is-completed .StepLabel, .Step.is-completed .StepLabel,
.Step.is-active .StepLabel { .Step.is-active .StepLabel {
color: var(--theme-color-fg-highlight); color: var(--theme-color-fg-highlight);
font-weight: 600;
} }
.Connector { .Connector {
width: 24px; flex: 1;
height: 2px; height: 2px;
background-color: var(--theme-color-bg-2); background-color: var(--theme-color-bg-2);
margin-bottom: 20px; margin: 0 -4px;
transition: background-color 0.2s; 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 { .Connector.is-completed::after {
background-color: var(--theme-color-success); transform: scaleX(1);
animation: slideProgress 400ms ease-out;
} }
.CheckIcon { .CheckIcon {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
svg {
width: 18px;
height: 18px;
}
} }

View File

@@ -1,161 +1,321 @@
/** /**
* CompleteStep Styles * 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 { .Root {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
height: 100%; height: 100%;
animation: slideInUp 300ms ease-out;
} }
.Header { .Header {
display: flex; display: flex;
flex-direction: column;
align-items: center; align-items: center;
gap: 12px; gap: 16px;
margin-bottom: 8px; margin-bottom: 24px;
padding: 20px;
background: linear-gradient(135deg, rgba(34, 197, 94, 0.1) 0%, transparent 100%);
border-radius: 12px;
.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 { svg {
width: 36px;
height: 36px;
color: var(--theme-color-success); 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 { .Stats {
display: flex; display: grid;
gap: 12px; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
margin-top: 16px; gap: 16px;
margin-bottom: 24px;
} }
.StatCard { .StatCard {
flex: 1;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
gap: 4px; gap: 12px;
padding: 12px; padding: 20px 16px;
background-color: var(--theme-color-bg-3); background: linear-gradient(135deg, var(--theme-color-bg-3) 0%, var(--theme-color-bg-2) 100%);
border-radius: 8px; border-radius: 12px;
text-align: center; 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 { .StatCardIcon {
width: 20px; width: 40px;
height: 20px; height: 40px;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
border-radius: 50%;
transition: all 200ms ease-in-out;
svg {
width: 22px;
height: 22px;
}
} }
.StatCard.is-success .StatCardIcon { .StatCard.is-success .StatCardIcon {
color: var(--theme-color-success); color: var(--theme-color-success);
background-color: rgba(34, 197, 94, 0.15);
} }
.StatCard.is-warning .StatCardIcon { .StatCard.is-warning .StatCardIcon {
color: var(--theme-color-warning); color: var(--theme-color-warning);
background-color: rgba(251, 191, 36, 0.15);
} }
.StatCard.is-error .StatCardIcon { .StatCard.is-error .StatCardIcon {
color: var(--theme-color-danger); color: var(--theme-color-danger);
background-color: rgba(239, 68, 68, 0.15);
}
.StatCard:hover .StatCardIcon {
transform: scale(1.1) rotate(5deg);
} }
.StatCardValue { .StatCardValue {
font-size: 24px; font-size: 32px;
font-weight: 600; font-weight: 700;
color: var(--theme-color-fg-highlight); color: var(--theme-color-fg-highlight);
line-height: 1;
font-variant-numeric: tabular-nums;
animation: countUp 400ms ease-out;
} }
.StatCardLabel { .StatCardLabel {
font-size: 11px; font-size: 11px;
color: var(--theme-color-secondary-as-fg); color: var(--theme-color-fg-default);
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 0.5px; letter-spacing: 0.8px;
font-weight: 600;
} }
.MetaInfo { .MetaInfo {
display: flex; display: flex;
gap: 16px; gap: 20px;
margin-top: 12px; 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 { .MetaItem {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 6px; gap: 8px;
color: var(--theme-color-secondary-as-fg); padding: 8px 16px;
background-color: var(--theme-color-bg-4);
svg { border-radius: 20px;
width: 14px; font-size: 13px;
height: 14px; font-weight: 500;
} color: var(--theme-color-fg-highlight);
} border: 1px solid var(--theme-color-bg-2);
.Paths {
margin-top: 16px;
padding: 16px;
background-color: var(--theme-color-bg-3);
border-radius: 8px;
}
.PathItem {
display: flex;
gap: 12px;
margin-top: 12px;
svg { svg {
width: 16px; width: 16px;
height: 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; flex-shrink: 0;
margin-top: 2px; margin-top: 2px;
} }
&:first-of-type { &:hover {
margin-top: 8px; background-color: var(--theme-color-bg-3);
border-color: var(--theme-color-primary);
} }
} }
.PathContent { .PathContent {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 2px; gap: 6px;
overflow: hidden; 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-family: monospace;
font-size: 12px; font-size: 12px;
color: var(--theme-color-fg-highlight);
word-break: break-all; word-break: break-all;
background-color: var(--theme-color-bg-2);
padding: 8px 12px;
border-radius: 6px;
} }
} }
.NextSteps { .NextSteps {
margin-top: 16px; padding: 20px;
padding: 16px; background: linear-gradient(135deg, var(--theme-color-bg-3) 0%, var(--theme-color-bg-2) 100%);
background-color: var(--theme-color-bg-3); border-radius: 12px;
border-radius: 8px; 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 { .StepsList {
list-style: none; list-style: none;
padding: 0; padding: 0;
margin: 8px 0 0 0; margin: 0;
li { li {
display: flex; display: flex;
gap: 12px; gap: 16px;
padding: 8px 0; padding: 16px;
border-bottom: 1px solid var(--theme-color-bg-2); 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 { &:not(:last-child) {
border-bottom: none; margin-bottom: 10px;
}
&:hover {
background-color: var(--theme-color-bg-3);
transform: translateX(4px);
} }
svg { svg {
width: 16px; width: 20px;
height: 16px; height: 20px;
flex-shrink: 0; flex-shrink: 0;
margin-top: 2px; margin-top: 2px;
color: var(--theme-color-secondary-as-fg); color: var(--theme-color-primary);
} }
} }
} }
@@ -165,4 +325,5 @@
padding-top: 24px; padding-top: 24px;
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;
gap: 12px;
} }

View File

@@ -2,53 +2,124 @@
* ConfirmStep Styles * ConfirmStep Styles
* *
* First step of migration wizard - confirm source and target paths. * 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 { .Root {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
height: 100%; height: 100%;
animation: slideInUp 300ms ease-out;
} }
.Header { .Header {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 12px; gap: 12px;
margin-bottom: 8px; margin-bottom: 20px;
svg { svg {
color: var(--theme-color-primary); 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 { .PathSection {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 8px; gap: 12px;
padding: 16px; padding: 20px;
background-color: var(--theme-color-bg-3); background-color: var(--theme-color-bg-3);
border-radius: 8px; 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 { .PathHeader {
display: flex; display: flex;
align-items: center; 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 { .FolderIcon {
color: var(--theme-color-secondary-as-fg); color: var(--theme-color-primary);
width: 16px;
height: 16px;
} }
.PathFields { .PathFields {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 16px; gap: 20px;
margin-top: 16px; margin-top: 0;
padding: 16px;
background-color: var(--theme-color-bg-3);
border-radius: 8px;
} }
.PathField { .PathField {
@@ -115,24 +186,66 @@
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
gap: 8px; gap: 12px;
padding: 8px 0; padding: 16px 0;
color: var(--theme-color-secondary-as-fg); 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 { .InfoBox {
padding: 16px; padding: 20px;
background-color: var(--theme-color-bg-3); background: linear-gradient(135deg, var(--theme-color-bg-3) 0%, var(--theme-color-bg-2) 100%);
border-radius: 8px; 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 { .StepsList {
margin: 8px 0 0 0; margin: 0;
padding-left: 20px; padding-left: 24px;
color: var(--theme-color-fg-default); color: var(--theme-color-fg-default);
font-size: 13px;
line-height: 1.6;
li { li {
margin-bottom: 4px; margin-bottom: 8px;
padding-left: 4px;
&::marker {
color: var(--theme-color-primary);
font-weight: 600;
}
} }
} }

View File

@@ -1,91 +1,181 @@
/** /**
* FailedStep Styles * 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 { .Root {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
height: 100%; height: 100%;
animation: slideInUp 300ms ease-out;
} }
.Header { .Header {
display: flex; display: flex;
flex-direction: column;
align-items: center; align-items: center;
gap: 12px; gap: 16px;
margin-bottom: 8px; margin-bottom: 24px;
} padding: 20px;
background: linear-gradient(135deg, rgba(239, 68, 68, 0.1) 0%, transparent 100%);
border-radius: 12px;
.ErrorCircleIcon { .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;
svg {
width: 36px;
height: 36px;
color: var(--theme-color-danger); color: var(--theme-color-danger);
} }
}
.DescriptionText { h2 {
color: var(--theme-color-secondary-as-fg); 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 { .ErrorBox {
margin-top: 16px; margin-bottom: 20px;
background-color: rgba(239, 68, 68, 0.1); background: linear-gradient(135deg, rgba(239, 68, 68, 0.08) 0%, rgba(239, 68, 68, 0.05) 100%);
border: 1px solid rgba(239, 68, 68, 0.3); border: 2px solid rgba(239, 68, 68, 0.3);
border-radius: 8px; border-radius: 12px;
overflow: hidden; overflow: hidden;
} }
.ErrorHeader { .ErrorHeader {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 8px; gap: 12px;
padding: 12px 16px; padding: 16px 20px;
background-color: rgba(239, 68, 68, 0.15); background-color: rgba(239, 68, 68, 0.15);
border-bottom: 1px solid rgba(239, 68, 68, 0.2);
svg { svg {
width: 20px;
height: 20px;
color: var(--theme-color-danger); color: var(--theme-color-danger);
} flex-shrink: 0;
} }
.ErrorText { h3 {
font-size: 14px;
font-weight: 600;
color: var(--theme-color-danger); color: var(--theme-color-danger);
font-weight: 500; margin: 0;
}
} }
.ErrorMessage { .ErrorMessage {
padding: 12px 16px; padding: 20px;
font-family: monospace; font-family: monospace;
font-size: 12px; font-size: 13px;
line-height: 1.6;
color: var(--theme-color-fg-highlight); 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 { .Suggestions {
margin-top: 16px; padding: 20px;
padding: 16px; background: linear-gradient(135deg, var(--theme-color-bg-3) 0%, var(--theme-color-bg-2) 100%);
background-color: var(--theme-color-bg-3); border-radius: 12px;
border-radius: 8px; 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 { .SuggestionList {
list-style: none; list-style: none;
padding: 0; padding: 0;
margin: 12px 0 0 0; margin: 0;
li { li {
display: flex; display: flex;
gap: 12px; gap: 16px;
padding: 8px 0; padding: 16px;
border-bottom: 1px solid var(--theme-color-bg-2); 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 { &:not(:last-child) {
border-bottom: none; margin-bottom: 10px;
}
&:hover {
background-color: var(--theme-color-bg-3);
transform: translateX(4px);
} }
svg { svg {
width: 16px; width: 20px;
height: 16px; height: 20px;
flex-shrink: 0; flex-shrink: 0;
margin-top: 2px; margin-top: 2px;
color: var(--theme-color-secondary-as-fg); color: var(--theme-color-primary);
} }
} }
} }
@@ -93,31 +183,47 @@
.Link { .Link {
color: var(--theme-color-primary); color: var(--theme-color-primary);
text-decoration: underline; text-decoration: underline;
font-weight: 500;
transition: opacity 200ms ease-in-out;
&:hover { &:hover {
opacity: 0.8; opacity: 0.7;
} }
} }
.SafetyNotice { .SafetyNotice {
display: flex; display: flex;
gap: 12px; gap: 16px;
margin-top: 16px; padding: 20px;
padding: 12px 16px; background: linear-gradient(135deg, rgba(34, 197, 94, 0.12) 0%, rgba(34, 197, 94, 0.08) 100%);
background-color: rgba(34, 197, 94, 0.1); border: 2px solid rgba(34, 197, 94, 0.3);
border: 1px solid rgba(34, 197, 94, 0.3); border-radius: 12px;
border-radius: 8px; margin-bottom: 20px;
svg { svg {
width: 16px; width: 24px;
height: 16px; height: 24px;
flex-shrink: 0; flex-shrink: 0;
color: var(--theme-color-success); color: var(--theme-color-success);
} }
.SafetyContent {
flex: 1;
h4 {
font-size: 14px;
font-weight: 600;
color: var(--theme-color-success);
margin: 0 0 6px 0;
} }
.SafetyText { p {
color: var(--theme-color-secondary-as-fg); font-size: 13px;
line-height: 1.6;
color: var(--theme-color-fg-default);
margin: 0;
}
}
} }
.Actions { .Actions {
@@ -125,4 +231,5 @@
padding-top: 24px; padding-top: 24px;
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;
gap: 12px;
} }

View File

@@ -1,52 +1,204 @@
/** /**
* MigratingStep Styles * 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 { .Root {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
height: 100%; height: 100%;
gap: 16px; gap: 20px;
animation: slideInUp 300ms ease-out;
} }
.Header { .Header {
display: flex; display: flex;
align-items: center; 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 */ /* Budget Section */
.BudgetSection { .BudgetSection {
padding: 12px 16px; padding: 20px;
background-color: var(--theme-color-bg-3); background: linear-gradient(135deg, var(--theme-color-bg-3) 0%, var(--theme-color-bg-2) 100%);
border-radius: 8px; border-radius: 12px;
border: 1px solid var(--theme-color-bg-2); 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 { .BudgetHeader {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; 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 { .BudgetBar {
height: 6px; height: 10px;
background-color: var(--theme-color-bg-2); background-color: var(--theme-color-bg-1);
border-radius: 3px; border-radius: 5px;
overflow: hidden; 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 { .BudgetFill {
height: 100%; height: 100%;
background-color: var(--theme-color-primary); background: linear-gradient(
border-radius: 3px; 90deg,
transition: width 0.3s ease, background-color 0.3s ease; 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 { &.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;
} }
} }

View File

@@ -1,82 +1,187 @@
/** /**
* ReportStep Styles * 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 { .Root {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
height: 100%; height: 100%;
animation: slideInUp 300ms ease-out;
} }
.Header { .Header {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 12px; gap: 16px;
margin-bottom: 8px; margin-bottom: 20px;
svg { svg {
width: 24px;
height: 24px;
color: var(--theme-color-primary); 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 { .StatsRow {
display: flex; display: grid;
gap: 12px; grid-template-columns: repeat(3, 1fr);
margin-top: 16px; gap: 16px;
margin-bottom: 24px;
} }
.StatCard { .StatCard {
flex: 1;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
gap: 4px; gap: 12px;
padding: 12px; padding: 20px 16px;
background-color: var(--theme-color-bg-3); background: linear-gradient(135deg, var(--theme-color-bg-3) 0%, var(--theme-color-bg-2) 100%);
border-radius: 8px; border-radius: 12px;
text-align: center; 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 { .StatCardIcon {
width: 24px; width: 40px;
height: 24px; height: 40px;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
color: var(--theme-color-secondary-as-fg); 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 { .StatCard.is-automatic .StatCardIcon {
color: var(--theme-color-success); color: var(--theme-color-success);
background-color: rgba(34, 197, 94, 0.15);
} }
.StatCard.is-simpleFixes .StatCardIcon { .StatCard.is-simpleFixes .StatCardIcon {
color: var(--theme-color-warning); color: var(--theme-color-warning);
background-color: rgba(251, 191, 36, 0.15);
} }
.StatCard.is-needsReview .StatCardIcon { .StatCard.is-needsReview .StatCardIcon {
color: var(--theme-color-danger); color: var(--theme-color-danger);
background-color: rgba(239, 68, 68, 0.15);
}
.StatCard:hover .StatCardIcon {
transform: scale(1.1) rotate(5deg);
} }
.StatCardValue { .StatCardValue {
font-size: 24px; font-size: 32px;
font-weight: 600; font-weight: 700;
color: var(--theme-color-fg-highlight); color: var(--theme-color-fg-highlight);
line-height: 1;
font-variant-numeric: tabular-nums;
animation: countUp 400ms ease-out;
} }
.StatCardLabel { .StatCardLabel {
font-size: 11px; font-size: 11px;
color: var(--theme-color-secondary-as-fg); color: var(--theme-color-fg-default);
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 0.5px; letter-spacing: 0.8px;
font-weight: 600;
} }
.Categories { .Categories {
flex: 1; flex: 1;
overflow-y: auto; overflow-y: auto;
margin-top: 16px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 12px; gap: 12px;
@@ -84,127 +189,309 @@
.CategorySection { .CategorySection {
background-color: var(--theme-color-bg-3); background-color: var(--theme-color-bg-3);
border-radius: 8px; border-radius: 10px;
overflow: hidden; 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 { .CategoryHeader {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 8px; gap: 12px;
padding: 12px 16px; padding: 16px 20px;
background-color: var(--theme-color-bg-2); background-color: transparent;
cursor: pointer; cursor: pointer;
transition: all 200ms ease-in-out;
user-select: none;
&:hover { &: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 { .CategoryIcon {
width: 16px; width: 36px;
height: 16px; height: 36px;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: 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 { .CategorySection.is-automatic .CategoryIcon {
color: var(--theme-color-success); color: var(--theme-color-success);
background-color: rgba(34, 197, 94, 0.15);
} }
.CategorySection.is-simpleFixes .CategoryIcon { .CategorySection.is-simpleFixes .CategoryIcon {
color: var(--theme-color-warning); color: var(--theme-color-warning);
background-color: rgba(251, 191, 36, 0.15);
} }
.CategorySection.is-needsReview .CategoryIcon { .CategorySection.is-needsReview .CategoryIcon {
color: var(--theme-color-danger); 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 { .CategoryTitle {
flex: 1; font-size: 15px;
font-weight: 500; font-weight: 600;
color: var(--theme-color-fg-highlight);
}
.CategoryDescription {
font-size: 12px;
color: var(--theme-color-fg-default);
} }
.CategoryCount { .CategoryCount {
background-color: var(--theme-color-bg-1); background-color: var(--theme-color-bg-4);
padding: 2px 8px; padding: 4px 12px;
border-radius: 10px; border-radius: 12px;
font-size: 11px; font-size: 13px;
color: var(--theme-color-secondary-as-fg); font-weight: 600;
color: var(--theme-color-fg-highlight);
border: 1px solid var(--theme-color-bg-1);
} }
.ExpandIcon { .ExpandIcon {
width: 16px; width: 20px;
height: 16px; height: 20px;
color: var(--theme-color-secondary-as-fg); color: var(--theme-color-fg-muted);
transition: transform 0.2s ease; transition: transform 250ms ease-in-out;
flex-shrink: 0;
svg {
width: 100%;
height: 100%;
}
} }
.CategorySection.is-expanded .ExpandIcon { .CategorySection.is-expanded .ExpandIcon {
transform: rotate(180deg); transform: rotate(180deg);
color: var(--theme-color-primary);
} }
.ComponentList { .ComponentList {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 2px; gap: 6px;
padding: 8px; padding: 12px;
max-height: 200px; max-height: 250px;
overflow-y: auto; 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 { .ComponentItem {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
padding: 8px 12px; padding: 12px 16px;
background-color: var(--theme-color-bg-2); background-color: var(--theme-color-bg-4);
border-radius: 4px; border-radius: 8px;
border: 1px solid var(--theme-color-bg-3);
transition: all 200ms ease-in-out;
cursor: pointer;
&:hover { &: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 { .ComponentName {
font-size: 13px; 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 { .ComponentIssueCount {
font-size: 11px; 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 { .AiPromptSection {
margin-top: 16px; margin-top: 20px;
padding: 16px; padding: 24px;
background-color: rgba(139, 92, 246, 0.1); background: linear-gradient(135deg, rgba(139, 92, 246, 0.12) 0%, rgba(139, 92, 246, 0.08) 100%);
border: 1px solid rgba(139, 92, 246, 0.3); border: 2px solid rgba(139, 92, 246, 0.3);
border-radius: 8px; 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 { .AiPromptHeader {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 8px; gap: 12px;
margin-bottom: 8px; margin-bottom: 16px;
svg { svg {
width: 20px; width: 28px;
height: 20px; height: 28px;
color: #8b5cf6; // AI purple 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; 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 { .AiPromptSection.is-disabled {
opacity: 0.6; opacity: 0.5;
pointer-events: none; pointer-events: none;
filter: grayscale(0.5);
} }
.Actions { .Actions {
@@ -212,4 +499,5 @@
padding-top: 24px; padding-top: 24px;
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;
gap: 12px;
} }

View File

@@ -1,27 +1,9 @@
/** /**
* ScanningStep Styles * 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 { @keyframes spin {
from { from {
transform: rotate(0deg); 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 { .ProgressSection {
padding: 16px; padding: 24px;
background-color: var(--theme-color-bg-3); background: linear-gradient(135deg, var(--theme-color-bg-3) 0%, var(--theme-color-bg-2) 100%);
border-radius: 8px; border-radius: 12px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
border: 1px solid var(--theme-color-bg-2);
} }
.ProgressHeader { .ProgressHeader {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; 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 { .ProgressBar {
height: 8px; height: 12px;
background-color: var(--theme-color-bg-2); background-color: var(--theme-color-bg-1);
border-radius: 4px; border-radius: 6px;
overflow: hidden; 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 { .ProgressFill {
height: 100%; height: 100%;
background-color: var(--theme-color-primary); background: linear-gradient(
border-radius: 4px; 90deg,
transition: width 0.3s ease; 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 { .ActivityLog {