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]
### 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

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 {
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;
}
}
}

View File

@@ -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);
}

View File

@@ -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;
}
}

View File

@@ -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;
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}

View File

@@ -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;
}
}

View File

@@ -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;
}

View File

@@ -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 {