feat(deploy): fix docker deployment and add backend i18n
- Docker Deployment Fixes: - Switch base images to docker.m.daocloud.io to resolve registry 401 errors - Add Postgres and Redis services to docker-compose.traefik.yml - Fix frontend build: replace missing icons (Globe->Location, Chart->TrendCharts) - Fix frontend build: resolve pnpm CI/TTY issues and frozen lockfile errors - Add missing backend dependencies (sqlalchemy, psycopg2, redis-py, celery, docker-py) in pixi.toml - Ensure database tables are created on startup (lifespan event) - Backend Internationalization (i18n): - Add backend/app/core/i18n.py for locale handling - Update API endpoints (jobs, tasks, uploads, results) to return localized messages - Support 'Accept-Language' header (en/zh) - Documentation: - Update DOCKER_DEPLOYMENT.md with new architecture and troubleshooting - Update AGENTS.md with latest stack details and deployment steps - Update @fix_plan.md status Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
664
docs/UI_UX_DESIGN_PLAN.md
Normal file
664
docs/UI_UX_DESIGN_PLAN.md
Normal file
@@ -0,0 +1,664 @@
|
||||
# BtToxin Pipeline UI/UX Design Plan
|
||||
|
||||
## Design Philosophy
|
||||
|
||||
**Apple-Inspired Minimalism with Scientific Precision**
|
||||
|
||||
Our design approach combines Apple's signature clean, uncluttered aesthetic with the precision required for scientific data visualization. The interface should feel elegant and approachable while maintaining the credibility expected from a research tool.
|
||||
|
||||
## Current State Analysis
|
||||
|
||||
### Strengths
|
||||
- ✅ Well-structured component hierarchy
|
||||
- ✅ Good use of Element Plus components
|
||||
- ✅ Consistent spacing patterns (8px, 12px, 16px, 24px)
|
||||
- ✅ Basic responsive design implemented
|
||||
- ✅ Clear visual hierarchy with gradient hero text
|
||||
- ✅ Proper i18n integration
|
||||
|
||||
### Areas for Improvement
|
||||
- ❌ Heavy reliance on Element Plus defaults (no brand identity)
|
||||
- ❌ Limited micro-interactions and animations
|
||||
- ❌ No unified design system or tokens
|
||||
- ❌ Card hover effects are basic
|
||||
- ❌ Missing depth and dimensionality
|
||||
- ❌ Typography could be more refined
|
||||
- ❌ Color palette needs scientific/professional refinement
|
||||
|
||||
## Design System Specification
|
||||
|
||||
### Color Palette
|
||||
|
||||
#### Primary Colors
|
||||
```css
|
||||
/* Primary Brand - Scientific Blue */
|
||||
--color-primary: #007AFF; /* Apple blue, trustworthy */
|
||||
--color-primary-light: #5AC8FA; /* Light blue for accents */
|
||||
--color-primary-dark: #0051D5; /* Dark blue for hover states */
|
||||
|
||||
/* Secondary - Teal Gradient */
|
||||
--color-secondary: #30B0C7; /* Scientific teal */
|
||||
--color-secondary-light: #64D2CC;
|
||||
|
||||
/* Success States */
|
||||
--color-success: #34C759; /* Apple green */
|
||||
|
||||
/* Warning States */
|
||||
--color-warning: #FF9500; /* Apple orange */
|
||||
|
||||
/* Error States */
|
||||
--color-error: #FF3B30; /* Apple red */
|
||||
```
|
||||
|
||||
#### Neutral Colors
|
||||
```css
|
||||
/* Text Colors */
|
||||
--text-primary: #1D1D1F; /* Apple near-black */
|
||||
--text-secondary: #86868B; /* Apple gray */
|
||||
--text-tertiary: #C7C7CC; /* Light gray */
|
||||
|
||||
/* Background Colors */
|
||||
--bg-primary: #FFFFFF;
|
||||
--bg-secondary: #F5F5F7; /* Apple light gray */
|
||||
--bg-tertiary: #E8E8ED; /* darker gray for cards */
|
||||
|
||||
/* Surface Colors */
|
||||
--surface-elevated: #FFFFFF;
|
||||
--surface-base: #FAFAFC;
|
||||
```
|
||||
|
||||
### Typography
|
||||
|
||||
#### Font Families
|
||||
```css
|
||||
/* Primary - System Fonts */
|
||||
--font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
|
||||
"Helvetica Neue", Arial, sans-serif;
|
||||
|
||||
/* Monospace for data/code */
|
||||
--font-mono: "SF Mono", Menlo, Monaco, "Cascadia Code", monospace;
|
||||
```
|
||||
|
||||
#### Type Scale
|
||||
```css
|
||||
/* Display */
|
||||
--text-display: 48px / 1.1 / 600 - 700;
|
||||
|
||||
/* Headings */
|
||||
--text-h1: 36px / 1.2 / 600;
|
||||
--text-h2: 30px / 1.3 / 600;
|
||||
--text-h3: 24px / 1.4 / 600;
|
||||
|
||||
/* Body */
|
||||
--text-large: 18px / 1.5 / 400;
|
||||
--text-body: 16px / 1.6 / 400;
|
||||
--text-small: 14px / 1.5 / 400;
|
||||
|
||||
/* Micro */
|
||||
--text-caption: 12px / 1.4 / 400;
|
||||
```
|
||||
|
||||
### Spacing System
|
||||
|
||||
```css
|
||||
/* Base Unit: 4px */
|
||||
--space-1: 4px;
|
||||
--space-2: 8px;
|
||||
--space-3: 12px;
|
||||
--space-4: 16px;
|
||||
--space-5: 20px;
|
||||
--space-6: 24px;
|
||||
--space-8: 32px;
|
||||
--space-10: 40px;
|
||||
--space-12: 48px;
|
||||
--space-16: 64px;
|
||||
```
|
||||
|
||||
### Border Radius
|
||||
|
||||
```css
|
||||
--radius-sm: 6px; /* Small elements: buttons, inputs */
|
||||
--radius-md: 12px; /* Cards, modal containers */
|
||||
--radius-lg: 18px; /* Large cards, hero sections */
|
||||
--radius-xl: 24px; /* Special containers */
|
||||
--radius-full: 9999px; /* Pills, badges */
|
||||
```
|
||||
|
||||
### Shadows
|
||||
|
||||
```css
|
||||
/* Elevation System */
|
||||
--shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.04);
|
||||
--shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.06);
|
||||
--shadow-md: 0 4px 16px rgba(0, 0, 0, 0.08);
|
||||
--shadow-lg: 0 8px 32px rgba(0, 0, 0, 0.12);
|
||||
--shadow-xl: 0 16px 48px rgba(0, 0, 0, 0.16);
|
||||
|
||||
/* Colored Shadows for Depth */
|
||||
--shadow-primary: 0 8px 32px rgba(0, 122, 255, 0.25);
|
||||
--shadow-success: 0 8px 32px rgba(52, 199, 89, 0.25);
|
||||
```
|
||||
|
||||
### Glassmorphism Effects
|
||||
|
||||
```css
|
||||
/* Frosted Glass Effect */
|
||||
--glass-bg: rgba(255, 255, 255, 0.7);
|
||||
--glass-border: rgba(255, 255, 255, 0.18);
|
||||
--glass-blur: blur(20px);
|
||||
--glass-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
|
||||
```
|
||||
|
||||
## Component-Specific Designs
|
||||
|
||||
### 1. Navigation Bar
|
||||
|
||||
**Design Enhancements:**
|
||||
- Glassmorphism background with subtle blur
|
||||
- Smooth height transition on scroll
|
||||
- Logo with gradient text effect
|
||||
- Language switcher with dropdown animation
|
||||
- Active state with bottom indicator line
|
||||
|
||||
**Spec:**
|
||||
```css
|
||||
.navbar {
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
backdrop-filter: blur(20px);
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.06);
|
||||
height: 60px;
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
.navbar.scrolled {
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
box-shadow: var(--shadow-sm);
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
position: relative;
|
||||
transition: color 0.2s;
|
||||
}
|
||||
|
||||
.nav-item::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: -4px;
|
||||
left: 50%;
|
||||
width: 0;
|
||||
height: 2px;
|
||||
background: var(--color-primary);
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
.nav-item.active::after {
|
||||
width: 100%;
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Hero Section
|
||||
|
||||
**Design Enhancements:**
|
||||
- Animated gradient background
|
||||
- Subtle floating particles or mesh gradient
|
||||
- Staggered animation for text elements
|
||||
- Glassmorphism card for key stats
|
||||
|
||||
**Spec:**
|
||||
```css
|
||||
.hero-section {
|
||||
background: linear-gradient(135deg, #F5F5F7 0%, #E8E8ED 100%);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.hero-section::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -50%;
|
||||
right: -50%;
|
||||
width: 200%;
|
||||
height: 200%;
|
||||
background: radial-gradient(circle, rgba(0, 122, 255, 0.1) 0%, transparent 70%);
|
||||
animation: hero-float 20s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes hero-float {
|
||||
0%, 100% { transform: translate(0, 0); }
|
||||
50% { transform: translate(-50px, 50px); }
|
||||
}
|
||||
|
||||
.hero-title {
|
||||
animation: fadeInUp 0.8s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
.hero-subtitle {
|
||||
animation: fadeInUp 0.8s cubic-bezier(0.4, 0, 0.2, 1) 0.1s backwards;
|
||||
}
|
||||
|
||||
@keyframes fadeInUp {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(20px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Feature Cards
|
||||
|
||||
**Design Enhancements:**
|
||||
- Glassmorphism effect with subtle border
|
||||
- Smooth scale and lift on hover
|
||||
- Icon container with gradient background
|
||||
- Glow effect on hover
|
||||
|
||||
**Spec:**
|
||||
```css
|
||||
.feature-card {
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
backdrop-filter: blur(10px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
border-radius: var(--radius-md);
|
||||
padding: var(--space-6);
|
||||
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.feature-card::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 4px;
|
||||
background: linear-gradient(90deg, var(--color-primary), var(--color-secondary));
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s;
|
||||
}
|
||||
|
||||
.feature-card:hover {
|
||||
transform: translateY(-8px) scale(1.02);
|
||||
box-shadow: var(--shadow-lg);
|
||||
}
|
||||
|
||||
.feature-card:hover::before {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.feature-icon-container {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
background: linear-gradient(135deg, rgba(0, 122, 255, 0.1), rgba(48, 176, 199, 0.1));
|
||||
border-radius: var(--radius-lg);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin: 0 auto var(--space-4);
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.feature-card:hover .feature-icon-container {
|
||||
background: linear-gradient(135deg, rgba(0, 122, 255, 0.2), rgba(48, 176, 199, 0.2));
|
||||
box-shadow: 0 8px 24px rgba(0, 122, 255, 0.2);
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Upload Form (TaskSubmitForm)
|
||||
|
||||
**Design Enhancements:**
|
||||
- Drag-and-drop zone with animated border
|
||||
- File type icons with color coding
|
||||
- Progress stepper with smooth animations
|
||||
- Parameter sliders with custom styling
|
||||
- Real-time validation feedback
|
||||
|
||||
**Spec:**
|
||||
```css
|
||||
.upload-zone {
|
||||
border: 2px dashed rgba(0, 122, 255, 0.3);
|
||||
border-radius: var(--radius-lg);
|
||||
background: rgba(0, 122, 255, 0.02);
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.upload-zone.dragover {
|
||||
border-color: var(--color-primary);
|
||||
background: rgba(0, 122, 255, 0.08);
|
||||
transform: scale(1.01);
|
||||
}
|
||||
|
||||
.upload-zone::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: radial-gradient(circle at center, rgba(0, 122, 255, 0.1), transparent 70%);
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s;
|
||||
}
|
||||
|
||||
.upload-zone.dragover::before {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* Custom Slider */
|
||||
.el-slider__runway {
|
||||
background: var(--bg-tertiary);
|
||||
border-radius: var(--radius-full);
|
||||
}
|
||||
|
||||
.el-slider__bar {
|
||||
background: linear-gradient(90deg, var(--color-primary), var(--color-secondary));
|
||||
border-radius: var(--radius-full);
|
||||
}
|
||||
|
||||
.el-slider__button {
|
||||
border: 2px solid var(--color-primary);
|
||||
background: white;
|
||||
box-shadow: 0 2px 8px rgba(0, 122, 255, 0.3);
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.el-slider__button:hover {
|
||||
transform: scale(1.2);
|
||||
box-shadow: 0 4px 16px rgba(0, 122, 255, 0.4);
|
||||
}
|
||||
```
|
||||
|
||||
### 5. Task Monitor (TaskMonitorView)
|
||||
|
||||
**Design Enhancements:**
|
||||
- Status badges with smooth animations
|
||||
- Progress bar with gradient and glow
|
||||
- Task cards with status-based borders
|
||||
- Queue position with animated counter
|
||||
- Smooth transitions between states
|
||||
|
||||
**Spec:**
|
||||
```css
|
||||
/* Status Badges */
|
||||
.status-badge {
|
||||
padding: var(--space-1) var(--space-3);
|
||||
border-radius: var(--radius-full);
|
||||
font-size: var(--text-small);
|
||||
font-weight: 500;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: var(--space-1);
|
||||
}
|
||||
|
||||
.status-badge.pending {
|
||||
background: rgba(255, 149, 0, 0.1);
|
||||
color: var(--color-warning);
|
||||
}
|
||||
|
||||
.status-badge.running {
|
||||
background: rgba(0, 122, 255, 0.1);
|
||||
color: var(--color-primary);
|
||||
}
|
||||
|
||||
.status-badge.completed {
|
||||
background: rgba(52, 199, 89, 0.1);
|
||||
color: var(--color-success);
|
||||
}
|
||||
|
||||
/* Progress Bar */
|
||||
.task-progress {
|
||||
height: 6px;
|
||||
background: var(--bg-tertiary);
|
||||
border-radius: var(--radius-full);
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.task-progress-bar {
|
||||
height: 100%;
|
||||
background: linear-gradient(90deg, var(--color-primary), var(--color-secondary));
|
||||
border-radius: var(--radius-full);
|
||||
transition: width 0.5s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.task-progress-bar::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent);
|
||||
animation: progress-shine 1.5s infinite;
|
||||
}
|
||||
|
||||
@keyframes progress-shine {
|
||||
0% { transform: translateX(-100%); }
|
||||
100% { transform: translateX(100%); }
|
||||
}
|
||||
|
||||
/* Task Card */
|
||||
.task-card {
|
||||
background: var(--surface-elevated);
|
||||
border-radius: var(--radius-md);
|
||||
padding: var(--space-5);
|
||||
border-left: 4px solid transparent;
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
.task-card.status-running {
|
||||
border-left-color: var(--color-primary);
|
||||
box-shadow: var(--shadow-primary);
|
||||
}
|
||||
|
||||
.task-card.status-completed {
|
||||
border-left-color: var(--color-success);
|
||||
}
|
||||
|
||||
.task-card:hover {
|
||||
transform: translateX(4px);
|
||||
box-shadow: var(--shadow-md);
|
||||
}
|
||||
```
|
||||
|
||||
### 6. Buttons
|
||||
|
||||
**Design Enhancements:**
|
||||
- Smooth scale and color transitions
|
||||
- Subtle inner shadow on press
|
||||
- Gradient option for primary actions
|
||||
- Icon animations
|
||||
|
||||
**Spec:**
|
||||
```css
|
||||
.btn-primary {
|
||||
background: linear-gradient(135deg, var(--color-primary), var(--color-secondary));
|
||||
border: none;
|
||||
border-radius: var(--radius-sm);
|
||||
padding: var(--space-3) var(--space-5);
|
||||
color: white;
|
||||
font-weight: 500;
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.btn-primary::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: linear-gradient(135deg, rgba(255, 255, 255, 0.2), transparent);
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: var(--shadow-primary);
|
||||
}
|
||||
|
||||
.btn-primary:hover::before {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.btn-primary:active {
|
||||
transform: translateY(0);
|
||||
box-shadow: var(--shadow-sm);
|
||||
}
|
||||
```
|
||||
|
||||
## Animation Standards
|
||||
|
||||
### Timing Functions
|
||||
```css
|
||||
/* Easing Curves */
|
||||
--ease-out: cubic-bezier(0.4, 0, 0.2, 1); /* Standard, smooth */
|
||||
--ease-in-out: cubic-bezier(0.4, 0, 0.6, 1); /* Symmetrical */
|
||||
--ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1); /* Bouncy */
|
||||
--ease-sharp: cubic-bezier(0.19, 1, 0.22, 1); /* Fast */
|
||||
```
|
||||
|
||||
### Duration Scale
|
||||
```css
|
||||
--duration-instant: 150ms;
|
||||
--duration-fast: 250ms;
|
||||
--duration-base: 350ms;
|
||||
--duration-slow: 500ms;
|
||||
--duration-slower: 750ms;
|
||||
```
|
||||
|
||||
### Common Animations
|
||||
|
||||
```css
|
||||
/* Fade In */
|
||||
@keyframes fadeIn {
|
||||
from { opacity: 0; }
|
||||
to { opacity: 1; }
|
||||
}
|
||||
|
||||
/* Slide Up */
|
||||
@keyframes slideUp {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(20px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Scale In */
|
||||
@keyframes scaleIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: scale(0.95);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Pulse Glow */
|
||||
@keyframes pulseGlow {
|
||||
0%, 100% { box-shadow: 0 0 0 0 rgba(0, 122, 255, 0.4); }
|
||||
50% { box-shadow: 0 0 0 10px rgba(0, 122, 255, 0); }
|
||||
}
|
||||
```
|
||||
|
||||
## Responsive Design
|
||||
|
||||
### Breakpoints
|
||||
```css
|
||||
--breakpoint-xs: 480px;
|
||||
--breakpoint-sm: 640px;
|
||||
--breakpoint-md: 768px;
|
||||
--breakpoint-lg: 1024px;
|
||||
--breakpoint-xl: 1280px;
|
||||
--breakpoint-2xl: 1536px;
|
||||
```
|
||||
|
||||
### Mobile Adaptations
|
||||
- Navigation becomes bottom tab bar on mobile
|
||||
- Hero section stacks vertically
|
||||
- Cards use full width with reduced padding
|
||||
- Touch targets minimum 44px × 44px
|
||||
- Font sizes scale down proportionally
|
||||
|
||||
## Accessibility
|
||||
|
||||
### WCAG 2.1 AA Compliance
|
||||
- Color contrast ratio: 4.5:1 for text, 3:1 for large text
|
||||
- Focus indicators: 2px solid outline with offset
|
||||
- Touch targets: minimum 44px × 44px
|
||||
- Keyboard navigation: visible focus states
|
||||
- Screen reader: proper ARIA labels and semantic HTML
|
||||
|
||||
### Focus States
|
||||
```css
|
||||
:focus-visible {
|
||||
outline: 2px solid var(--color-primary);
|
||||
outline-offset: 2px;
|
||||
border-radius: var(--radius-sm);
|
||||
}
|
||||
```
|
||||
|
||||
## Implementation Priority
|
||||
|
||||
### Phase 1: Foundation (High Impact)
|
||||
1. ✅ Create design tokens file with all variables
|
||||
2. ✅ Update App.vue with glassmorphism navbar
|
||||
3. ✅ Enhance HomeView with hero animations
|
||||
4. ✅ Improve feature cards with hover effects
|
||||
|
||||
### Phase 2: Components (Medium Impact)
|
||||
5. ✅ Redesign TaskSubmitForm upload zone
|
||||
6. ✅ Enhance TaskMonitorView with status animations
|
||||
7. ✅ Update buttons with gradient and micro-interactions
|
||||
8. ✅ Add smooth page transitions
|
||||
|
||||
### Phase 3: Polish (Low Impact)
|
||||
9. ✅ Optimize responsive layouts
|
||||
10. ✅ Add loading states and skeletons
|
||||
11. ✅ Refine typography and spacing
|
||||
12. ✅ Test accessibility improvements
|
||||
|
||||
## Testing Checklist
|
||||
|
||||
- [ ] Visual regression testing across breakpoints
|
||||
- [ ] Animation performance (60fps target)
|
||||
- [ ] Color contrast validation
|
||||
- [ ] Keyboard navigation flow
|
||||
- [ ] Screen reader compatibility
|
||||
- [ ] Touch interaction on mobile devices
|
||||
- [ ] Cross-browser compatibility (Chrome, Safari, Firefox)
|
||||
|
||||
## Design Assets
|
||||
|
||||
### Icons
|
||||
- Use Element Plus icons with custom sizing
|
||||
- Add subtle gradient overlays
|
||||
- Animate on hover with scale/rotate
|
||||
|
||||
### Illustrations
|
||||
- Keep minimal and abstract
|
||||
- Use scientific motifs (DNA helix, molecules, data waves)
|
||||
- Maintain consistent line weight (2px)
|
||||
- Color with brand gradient
|
||||
|
||||
### Gradients
|
||||
- Primary: `linear-gradient(135deg, #007AFF, #30B0C7)`
|
||||
- Success: `linear-gradient(135deg, #34C759, #30B0C7)`
|
||||
- Hero: `linear-gradient(135deg, #F5F5F7, #E8E8ED)`
|
||||
|
||||
---
|
||||
|
||||
**Last Updated:** 2025-01-14
|
||||
**Design System Version:** 1.0
|
||||
**Status:** Ready for Implementation
|
||||
Reference in New Issue
Block a user