1006 lines
25 KiB
Markdown
1006 lines
25 KiB
Markdown
|
|
# ORIGIN_UI_UX_SYSTEM.md
|
||
|
|
|
||
|
|
## 📋 RÉSUMÉ EXÉCUTIF
|
||
|
|
|
||
|
|
Ce document définit le système de design UI/UX complet et définitif pour la plateforme Veza. Il spécifie 200+ composants réutilisables, design tokens (couleurs, typographie, spacing), patterns d'interaction, responsive breakpoints, accessibility WCAG AAA, animations, et user flows assurant cohérence visuelle, expérience utilisateur fluide et maintenabilité design sur 24 mois.
|
||
|
|
|
||
|
|
## 🎯 OBJECTIFS
|
||
|
|
|
||
|
|
### Objectif Principal
|
||
|
|
Établir un design system cohérent, accessible (WCAG AAA), responsive (mobile-first), et maintenable avec 200+ composants documentés, garantissant expérience utilisateur premium et réduction 50% temps développement UI.
|
||
|
|
|
||
|
|
### Objectifs Secondaires
|
||
|
|
- Cohérence visuelle absolue (zero inconsistencies)
|
||
|
|
- Accessibility WCAG AAA (keyboard navigation, screen readers)
|
||
|
|
- Responsive design (mobile, tablet, desktop)
|
||
|
|
- Dark mode support natif
|
||
|
|
- Performance (60 FPS animations)
|
||
|
|
|
||
|
|
## 📖 TABLE DES MATIÈRES
|
||
|
|
|
||
|
|
1. [Design Philosophy](#1-design-philosophy)
|
||
|
|
2. [Design Tokens](#2-design-tokens)
|
||
|
|
3. [Typography System](#3-typography-system)
|
||
|
|
4. [Color System](#4-color-system)
|
||
|
|
5. [Spacing & Layout](#5-spacing--layout)
|
||
|
|
6. [Component Library](#6-component-library)
|
||
|
|
7. [Interaction Patterns](#7-interaction-patterns)
|
||
|
|
8. [Responsive Design](#8-responsive-design)
|
||
|
|
9. [Accessibility](#9-accessibility)
|
||
|
|
10. [Animations & Transitions](#10-animations--transitions)
|
||
|
|
11. [User Flows](#11-user-flows)
|
||
|
|
12. [Figma & Prototyping](#12-figma--prototyping)
|
||
|
|
|
||
|
|
## 🔒 RÈGLES IMMUABLES
|
||
|
|
|
||
|
|
1. **Mobile-First**: Toujours designer mobile d'abord, desktop après
|
||
|
|
2. **Accessibility First**: WCAG AAA obligatoire (not AAA où infeasible, then AA)
|
||
|
|
3. **Design Tokens Only**: Jamais de valeurs hardcodées (use CSS variables)
|
||
|
|
4. **Component Reuse**: Aucun composant custom si équivalent existe dans DS
|
||
|
|
5. **Spacing System**: Utiliser échelle 4px (4, 8, 12, 16, 24, 32, 48, 64)
|
||
|
|
6. **Dark Mode**: Support obligatoire pour tous composants
|
||
|
|
7. **Keyboard Navigation**: Tout cliquable doit être accessible au clavier
|
||
|
|
8. **Screen Reader**: Tous labels ARIA requis
|
||
|
|
9. **Performance**: 60 FPS animations (no jank)
|
||
|
|
10. **Consistency**: Zero visual inconsistencies tolérées
|
||
|
|
|
||
|
|
## 1. DESIGN PHILOSOPHY
|
||
|
|
|
||
|
|
### 1.1 Design Principles
|
||
|
|
|
||
|
|
**SIMPLICITY**
|
||
|
|
- Clean, minimal interfaces
|
||
|
|
- Remove unnecessary elements
|
||
|
|
- Focus on core actions
|
||
|
|
- Progressive disclosure
|
||
|
|
|
||
|
|
**CONSISTENCY**
|
||
|
|
- Same patterns everywhere
|
||
|
|
- Predictable interactions
|
||
|
|
- Unified visual language
|
||
|
|
- Muscle memory friendly
|
||
|
|
|
||
|
|
**ACCESSIBILITY**
|
||
|
|
- Inclusive by default
|
||
|
|
- Keyboard navigation
|
||
|
|
- Screen reader support
|
||
|
|
- High contrast modes
|
||
|
|
|
||
|
|
**PERFORMANCE**
|
||
|
|
- Fast, responsive
|
||
|
|
- 60 FPS animations
|
||
|
|
- Optimized assets
|
||
|
|
- Perceived performance
|
||
|
|
|
||
|
|
### 1.2 Visual Style
|
||
|
|
|
||
|
|
**Modern & Professional**:
|
||
|
|
- Clean, spacious layouts
|
||
|
|
- Subtle shadows and depth
|
||
|
|
- Bold, readable typography
|
||
|
|
- Vibrant accent colors
|
||
|
|
|
||
|
|
**Audio-Focused**:
|
||
|
|
- Waveform visualizations
|
||
|
|
- Audio player prominence
|
||
|
|
- Music-centric imagery
|
||
|
|
- Genre-specific themes
|
||
|
|
|
||
|
|
## 2. DESIGN TOKENS
|
||
|
|
|
||
|
|
### 2.1 Color Palette
|
||
|
|
|
||
|
|
**Primary Colors** (Brand):
|
||
|
|
```css
|
||
|
|
:root {
|
||
|
|
--color-primary-50: #f0f9ff;
|
||
|
|
--color-primary-100: #e0f2fe;
|
||
|
|
--color-primary-200: #bae6fd;
|
||
|
|
--color-primary-300: #7dd3fc;
|
||
|
|
--color-primary-400: #38bdf8;
|
||
|
|
--color-primary-500: #0ea5e9; /* Main brand color */
|
||
|
|
--color-primary-600: #0284c7;
|
||
|
|
--color-primary-700: #0369a1;
|
||
|
|
--color-primary-800: #075985;
|
||
|
|
--color-primary-900: #0c4a6e;
|
||
|
|
--color-primary-950: #082f49;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Neutral Colors**:
|
||
|
|
```css
|
||
|
|
:root {
|
||
|
|
--color-gray-50: #f9fafb;
|
||
|
|
--color-gray-100: #f3f4f6;
|
||
|
|
--color-gray-200: #e5e7eb;
|
||
|
|
--color-gray-300: #d1d5db;
|
||
|
|
--color-gray-400: #9ca3af;
|
||
|
|
--color-gray-500: #6b7280;
|
||
|
|
--color-gray-600: #4b5563;
|
||
|
|
--color-gray-700: #374151;
|
||
|
|
--color-gray-800: #1f2937;
|
||
|
|
--color-gray-900: #111827;
|
||
|
|
--color-gray-950: #030712;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Semantic Colors**:
|
||
|
|
```css
|
||
|
|
:root {
|
||
|
|
--color-success-500: #10b981; /* Green */
|
||
|
|
--color-warning-500: #f59e0b; /* Amber */
|
||
|
|
--color-error-500: #ef4444; /* Red */
|
||
|
|
--color-info-500: #3b82f6; /* Blue */
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Dark Mode**:
|
||
|
|
```css
|
||
|
|
:root[data-theme="dark"] {
|
||
|
|
--bg-primary: var(--color-gray-950);
|
||
|
|
--bg-secondary: var(--color-gray-900);
|
||
|
|
--bg-tertiary: var(--color-gray-800);
|
||
|
|
|
||
|
|
--text-primary: var(--color-gray-50);
|
||
|
|
--text-secondary: var(--color-gray-300);
|
||
|
|
--text-tertiary: var(--color-gray-500);
|
||
|
|
|
||
|
|
--border-primary: var(--color-gray-800);
|
||
|
|
--border-secondary: var(--color-gray-700);
|
||
|
|
}
|
||
|
|
|
||
|
|
:root[data-theme="light"] {
|
||
|
|
--bg-primary: var(--color-gray-50);
|
||
|
|
--bg-secondary: var(--color-white);
|
||
|
|
--bg-tertiary: var(--color-gray-100);
|
||
|
|
|
||
|
|
--text-primary: var(--color-gray-900);
|
||
|
|
--text-secondary: var(--color-gray-600);
|
||
|
|
--text-tertiary: var(--color-gray-500);
|
||
|
|
|
||
|
|
--border-primary: var(--color-gray-200);
|
||
|
|
--border-secondary: var(--color-gray-300);
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### 2.2 Spacing Scale
|
||
|
|
|
||
|
|
**4px Base Unit**:
|
||
|
|
```css
|
||
|
|
:root {
|
||
|
|
--spacing-0: 0;
|
||
|
|
--spacing-1: 0.25rem; /* 4px */
|
||
|
|
--spacing-2: 0.5rem; /* 8px */
|
||
|
|
--spacing-3: 0.75rem; /* 12px */
|
||
|
|
--spacing-4: 1rem; /* 16px */
|
||
|
|
--spacing-5: 1.25rem; /* 20px */
|
||
|
|
--spacing-6: 1.5rem; /* 24px */
|
||
|
|
--spacing-8: 2rem; /* 32px */
|
||
|
|
--spacing-10: 2.5rem; /* 40px */
|
||
|
|
--spacing-12: 3rem; /* 48px */
|
||
|
|
--spacing-16: 4rem; /* 64px */
|
||
|
|
--spacing-20: 5rem; /* 80px */
|
||
|
|
--spacing-24: 6rem; /* 96px */
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### 2.3 Typography Scale
|
||
|
|
|
||
|
|
**Font Family**:
|
||
|
|
```css
|
||
|
|
:root {
|
||
|
|
--font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||
|
|
--font-mono: 'JetBrains Mono', 'Fira Code', Consolas, monospace;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Font Sizes**:
|
||
|
|
```css
|
||
|
|
:root {
|
||
|
|
--text-xs: 0.75rem; /* 12px */
|
||
|
|
--text-sm: 0.875rem; /* 14px */
|
||
|
|
--text-base: 1rem; /* 16px */
|
||
|
|
--text-lg: 1.125rem; /* 18px */
|
||
|
|
--text-xl: 1.25rem; /* 20px */
|
||
|
|
--text-2xl: 1.5rem; /* 24px */
|
||
|
|
--text-3xl: 1.875rem; /* 30px */
|
||
|
|
--text-4xl: 2.25rem; /* 36px */
|
||
|
|
--text-5xl: 3rem; /* 48px */
|
||
|
|
--text-6xl: 3.75rem; /* 60px */
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Font Weights**:
|
||
|
|
```css
|
||
|
|
:root {
|
||
|
|
--font-light: 300;
|
||
|
|
--font-normal: 400;
|
||
|
|
--font-medium: 500;
|
||
|
|
--font-semibold: 600;
|
||
|
|
--font-bold: 700;
|
||
|
|
--font-extrabold: 800;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### 2.4 Shadows
|
||
|
|
|
||
|
|
```css
|
||
|
|
:root {
|
||
|
|
--shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
|
||
|
|
--shadow-base: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
|
||
|
|
--shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
|
||
|
|
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
|
||
|
|
--shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);
|
||
|
|
--shadow-2xl: 0 25px 50px -12px rgb(0 0 0 / 0.25);
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### 2.5 Border Radius
|
||
|
|
|
||
|
|
```css
|
||
|
|
:root {
|
||
|
|
--radius-none: 0;
|
||
|
|
--radius-sm: 0.125rem; /* 2px */
|
||
|
|
--radius-base: 0.25rem; /* 4px */
|
||
|
|
--radius-md: 0.375rem; /* 6px */
|
||
|
|
--radius-lg: 0.5rem; /* 8px */
|
||
|
|
--radius-xl: 0.75rem; /* 12px */
|
||
|
|
--radius-2xl: 1rem; /* 16px */
|
||
|
|
--radius-full: 9999px; /* Pill shape */
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## 3. TYPOGRAPHY SYSTEM
|
||
|
|
|
||
|
|
### 3.1 Headings
|
||
|
|
|
||
|
|
```tsx
|
||
|
|
// Typography components
|
||
|
|
<h1 className="text-4xl font-bold tracking-tight text-gray-900 dark:text-white">
|
||
|
|
Heading 1
|
||
|
|
</h1>
|
||
|
|
|
||
|
|
<h2 className="text-3xl font-semibold tracking-tight text-gray-900 dark:text-white">
|
||
|
|
Heading 2
|
||
|
|
</h2>
|
||
|
|
|
||
|
|
<h3 className="text-2xl font-semibold text-gray-900 dark:text-white">
|
||
|
|
Heading 3
|
||
|
|
</h3>
|
||
|
|
|
||
|
|
<h4 className="text-xl font-medium text-gray-900 dark:text-white">
|
||
|
|
Heading 4
|
||
|
|
</h4>
|
||
|
|
```
|
||
|
|
|
||
|
|
### 3.2 Body Text
|
||
|
|
|
||
|
|
```tsx
|
||
|
|
<p className="text-base text-gray-700 dark:text-gray-300">
|
||
|
|
Regular body text for content
|
||
|
|
</p>
|
||
|
|
|
||
|
|
<p className="text-sm text-gray-600 dark:text-gray-400">
|
||
|
|
Secondary body text for captions
|
||
|
|
</p>
|
||
|
|
|
||
|
|
<p className="text-xs text-gray-500 dark:text-gray-500">
|
||
|
|
Small text for metadata
|
||
|
|
</p>
|
||
|
|
```
|
||
|
|
|
||
|
|
### 3.3 Line Height
|
||
|
|
|
||
|
|
```css
|
||
|
|
:root {
|
||
|
|
--leading-none: 1;
|
||
|
|
--leading-tight: 1.25;
|
||
|
|
--leading-snug: 1.375;
|
||
|
|
--leading-normal: 1.5;
|
||
|
|
--leading-relaxed: 1.625;
|
||
|
|
--leading-loose: 2;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## 4. COLOR SYSTEM
|
||
|
|
|
||
|
|
### 4.1 Usage Guidelines
|
||
|
|
|
||
|
|
**Primary Color** (Blue): Brand identity, primary actions, links
|
||
|
|
**Gray**: Text, borders, backgrounds (neutral)
|
||
|
|
**Success** (Green): Success messages, confirmations
|
||
|
|
**Warning** (Amber): Warnings, cautions
|
||
|
|
**Error** (Red): Errors, destructive actions
|
||
|
|
**Info** (Blue): Informational messages
|
||
|
|
|
||
|
|
### 4.2 Color Contrast
|
||
|
|
|
||
|
|
**WCAG AAA Requirements**:
|
||
|
|
- **Normal Text**: Contrast ratio ≥ 7:1
|
||
|
|
- **Large Text** (18pt+ or 14pt+ bold): Contrast ratio ≥ 4.5:1
|
||
|
|
- **UI Components**: Contrast ratio ≥ 3:1
|
||
|
|
|
||
|
|
**Color Contrast Checker**:
|
||
|
|
```
|
||
|
|
Text on Background:
|
||
|
|
✅ Gray-900 on White: 21:1 (AAA)
|
||
|
|
✅ Gray-700 on White: 12.6:1 (AAA)
|
||
|
|
✅ Gray-600 on White: 7.5:1 (AAA)
|
||
|
|
⚠️ Gray-500 on White: 4.6:1 (AA only)
|
||
|
|
❌ Gray-400 on White: 2.9:1 (Fail)
|
||
|
|
```
|
||
|
|
|
||
|
|
## 5. SPACING & LAYOUT
|
||
|
|
|
||
|
|
### 5.1 Container Widths
|
||
|
|
|
||
|
|
```css
|
||
|
|
:root {
|
||
|
|
--container-sm: 640px;
|
||
|
|
--container-md: 768px;
|
||
|
|
--container-lg: 1024px;
|
||
|
|
--container-xl: 1280px;
|
||
|
|
--container-2xl: 1536px;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### 5.2 Grid System
|
||
|
|
|
||
|
|
**12-Column Grid**:
|
||
|
|
```tsx
|
||
|
|
<div className="grid grid-cols-12 gap-4">
|
||
|
|
<div className="col-span-12 md:col-span-8">Main content</div>
|
||
|
|
<div className="col-span-12 md:col-span-4">Sidebar</div>
|
||
|
|
</div>
|
||
|
|
```
|
||
|
|
|
||
|
|
### 5.3 Common Layouts
|
||
|
|
|
||
|
|
**Dashboard Layout**:
|
||
|
|
```
|
||
|
|
┌────────────────────────────────────┐
|
||
|
|
│ Header (sticky) │
|
||
|
|
├──────┬─────────────────────────────┤
|
||
|
|
│ │ │
|
||
|
|
│ Side │ │
|
||
|
|
│ bar │ Main Content │
|
||
|
|
│ │ │
|
||
|
|
│ │ │
|
||
|
|
└──────┴─────────────────────────────┘
|
||
|
|
```
|
||
|
|
|
||
|
|
**Track Player Layout**:
|
||
|
|
```
|
||
|
|
┌────────────────────────────────────┐
|
||
|
|
│ Header │
|
||
|
|
├────────────────────────────────────┤
|
||
|
|
│ │
|
||
|
|
│ Cover Art │
|
||
|
|
│ (centered) │
|
||
|
|
│ │
|
||
|
|
├────────────────────────────────────┤
|
||
|
|
│ Waveform Visualizer │
|
||
|
|
├────────────────────────────────────┤
|
||
|
|
│ Playback Controls │
|
||
|
|
├────────────────────────────────────┤
|
||
|
|
│ Track Info & Metadata │
|
||
|
|
└────────────────────────────────────┘
|
||
|
|
```
|
||
|
|
|
||
|
|
## 6. COMPONENT LIBRARY
|
||
|
|
|
||
|
|
### 6.1 Buttons
|
||
|
|
|
||
|
|
**Primary Button**:
|
||
|
|
```tsx
|
||
|
|
<button className="
|
||
|
|
px-4 py-2
|
||
|
|
bg-primary-600 hover:bg-primary-700 active:bg-primary-800
|
||
|
|
text-white font-medium
|
||
|
|
rounded-lg
|
||
|
|
transition-colors duration-150
|
||
|
|
focus:outline-none focus:ring-2 focus:ring-primary-500 focus:ring-offset-2
|
||
|
|
disabled:opacity-50 disabled:cursor-not-allowed
|
||
|
|
">
|
||
|
|
Primary Action
|
||
|
|
</button>
|
||
|
|
```
|
||
|
|
|
||
|
|
**Secondary Button**:
|
||
|
|
```tsx
|
||
|
|
<button className="
|
||
|
|
px-4 py-2
|
||
|
|
bg-gray-200 hover:bg-gray-300 dark:bg-gray-700 dark:hover:bg-gray-600
|
||
|
|
text-gray-900 dark:text-white font-medium
|
||
|
|
rounded-lg
|
||
|
|
transition-colors duration-150
|
||
|
|
">
|
||
|
|
Secondary Action
|
||
|
|
</button>
|
||
|
|
```
|
||
|
|
|
||
|
|
**Sizes**:
|
||
|
|
```tsx
|
||
|
|
// Small
|
||
|
|
<button className="px-3 py-1.5 text-sm">Small</button>
|
||
|
|
|
||
|
|
// Medium (default)
|
||
|
|
<button className="px-4 py-2 text-base">Medium</button>
|
||
|
|
|
||
|
|
// Large
|
||
|
|
<button className="px-6 py-3 text-lg">Large</button>
|
||
|
|
```
|
||
|
|
|
||
|
|
### 6.2 Inputs
|
||
|
|
|
||
|
|
**Text Input**:
|
||
|
|
```tsx
|
||
|
|
<div>
|
||
|
|
<label htmlFor="email" className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
|
||
|
|
Email
|
||
|
|
</label>
|
||
|
|
<input
|
||
|
|
type="email"
|
||
|
|
id="email"
|
||
|
|
className="
|
||
|
|
w-full px-4 py-2
|
||
|
|
border border-gray-300 dark:border-gray-600
|
||
|
|
rounded-lg
|
||
|
|
bg-white dark:bg-gray-800
|
||
|
|
text-gray-900 dark:text-white
|
||
|
|
placeholder:text-gray-400
|
||
|
|
focus:outline-none focus:ring-2 focus:ring-primary-500 focus:border-transparent
|
||
|
|
disabled:opacity-50 disabled:cursor-not-allowed
|
||
|
|
"
|
||
|
|
placeholder="you@example.com"
|
||
|
|
/>
|
||
|
|
</div>
|
||
|
|
```
|
||
|
|
|
||
|
|
**States**:
|
||
|
|
```tsx
|
||
|
|
// Error state
|
||
|
|
<input className="border-red-500 focus:ring-red-500" aria-invalid="true" aria-describedby="email-error" />
|
||
|
|
<p id="email-error" className="mt-1 text-sm text-red-600">Invalid email format</p>
|
||
|
|
|
||
|
|
// Success state
|
||
|
|
<input className="border-green-500 focus:ring-green-500" />
|
||
|
|
<p className="mt-1 text-sm text-green-600">Email available</p>
|
||
|
|
```
|
||
|
|
|
||
|
|
### 6.3 Cards
|
||
|
|
|
||
|
|
```tsx
|
||
|
|
<div className="
|
||
|
|
bg-white dark:bg-gray-800
|
||
|
|
rounded-xl
|
||
|
|
shadow-md
|
||
|
|
overflow-hidden
|
||
|
|
transition-shadow duration-200
|
||
|
|
hover:shadow-lg
|
||
|
|
">
|
||
|
|
<img src="/cover.jpg" alt="Track cover" className="w-full h-48 object-cover" />
|
||
|
|
<div className="p-4">
|
||
|
|
<h3 className="text-lg font-semibold text-gray-900 dark:text-white">Track Title</h3>
|
||
|
|
<p className="text-sm text-gray-600 dark:text-gray-400">Artist Name</p>
|
||
|
|
<div className="mt-4 flex items-center justify-between">
|
||
|
|
<span className="text-xs text-gray-500">3:45</span>
|
||
|
|
<button className="text-primary-600 hover:text-primary-700">
|
||
|
|
<PlayIcon className="w-6 h-6" />
|
||
|
|
</button>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
```
|
||
|
|
|
||
|
|
### 6.4 Modals
|
||
|
|
|
||
|
|
```tsx
|
||
|
|
<div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm">
|
||
|
|
<div
|
||
|
|
className="
|
||
|
|
bg-white dark:bg-gray-800
|
||
|
|
rounded-2xl
|
||
|
|
shadow-2xl
|
||
|
|
max-w-md w-full
|
||
|
|
max-h-[90vh]
|
||
|
|
overflow-y-auto
|
||
|
|
"
|
||
|
|
role="dialog"
|
||
|
|
aria-modal="true"
|
||
|
|
aria-labelledby="modal-title"
|
||
|
|
>
|
||
|
|
<div className="p-6">
|
||
|
|
<h2 id="modal-title" className="text-2xl font-bold text-gray-900 dark:text-white mb-4">
|
||
|
|
Modal Title
|
||
|
|
</h2>
|
||
|
|
<p className="text-gray-600 dark:text-gray-300">
|
||
|
|
Modal content goes here
|
||
|
|
</p>
|
||
|
|
<div className="mt-6 flex gap-3 justify-end">
|
||
|
|
<button className="px-4 py-2 text-gray-700 dark:text-gray-300">Cancel</button>
|
||
|
|
<button className="px-4 py-2 bg-primary-600 text-white rounded-lg">Confirm</button>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
```
|
||
|
|
|
||
|
|
### 6.5 Audio Player
|
||
|
|
|
||
|
|
```tsx
|
||
|
|
<div className="fixed bottom-0 left-0 right-0 bg-white dark:bg-gray-900 border-t border-gray-200 dark:border-gray-800 shadow-2xl">
|
||
|
|
<div className="max-w-screen-2xl mx-auto px-4 py-3">
|
||
|
|
{/* Progress Bar */}
|
||
|
|
<div className="mb-2">
|
||
|
|
<div className="h-1 bg-gray-200 dark:bg-gray-700 rounded-full overflow-hidden">
|
||
|
|
<div className="h-full bg-primary-600" style={{ width: '35%' }} />
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* Player Controls */}
|
||
|
|
<div className="flex items-center justify-between">
|
||
|
|
{/* Track Info */}
|
||
|
|
<div className="flex items-center gap-3 flex-1 min-w-0">
|
||
|
|
<img src="/cover.jpg" alt="Cover" className="w-12 h-12 rounded-md" />
|
||
|
|
<div className="min-w-0">
|
||
|
|
<h4 className="text-sm font-medium text-gray-900 dark:text-white truncate">Track Title</h4>
|
||
|
|
<p className="text-xs text-gray-600 dark:text-gray-400 truncate">Artist Name</p>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* Controls */}
|
||
|
|
<div className="flex items-center gap-4">
|
||
|
|
<button aria-label="Previous">⏮️</button>
|
||
|
|
<button aria-label="Play/Pause" className="w-10 h-10 rounded-full bg-primary-600 text-white">▶️</button>
|
||
|
|
<button aria-label="Next">⏭️</button>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* Volume */}
|
||
|
|
<div className="flex items-center gap-2 flex-1 justify-end">
|
||
|
|
<button aria-label="Mute">🔊</button>
|
||
|
|
<input type="range" min="0" max="100" value="75" className="w-24" aria-label="Volume" />
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
```
|
||
|
|
|
||
|
|
## 7. INTERACTION PATTERNS
|
||
|
|
|
||
|
|
### 7.1 Hover States
|
||
|
|
|
||
|
|
```css
|
||
|
|
/* Interactive elements */
|
||
|
|
.interactive-element {
|
||
|
|
transition: all 150ms ease-in-out;
|
||
|
|
}
|
||
|
|
|
||
|
|
.interactive-element:hover {
|
||
|
|
transform: translateY(-2px);
|
||
|
|
box-shadow: var(--shadow-lg);
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### 7.2 Focus States
|
||
|
|
|
||
|
|
```css
|
||
|
|
/* Keyboard focus */
|
||
|
|
:focus-visible {
|
||
|
|
outline: 2px solid var(--color-primary-500);
|
||
|
|
outline-offset: 2px;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Remove default outline for mouse users */
|
||
|
|
:focus:not(:focus-visible) {
|
||
|
|
outline: none;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### 7.3 Loading States
|
||
|
|
|
||
|
|
```tsx
|
||
|
|
<button disabled className="relative">
|
||
|
|
<span className="opacity-0">Button Text</span>
|
||
|
|
<div className="absolute inset-0 flex items-center justify-center">
|
||
|
|
<div className="w-5 h-5 border-2 border-white border-t-transparent rounded-full animate-spin" />
|
||
|
|
</div>
|
||
|
|
</button>
|
||
|
|
```
|
||
|
|
|
||
|
|
### 7.4 Empty States
|
||
|
|
|
||
|
|
```tsx
|
||
|
|
<div className="flex flex-col items-center justify-center p-12 text-center">
|
||
|
|
<EmptyIcon className="w-24 h-24 text-gray-400 mb-4" />
|
||
|
|
<h3 className="text-lg font-medium text-gray-900 dark:text-white mb-2">
|
||
|
|
No tracks yet
|
||
|
|
</h3>
|
||
|
|
<p className="text-gray-600 dark:text-gray-400 mb-6">
|
||
|
|
Upload your first track to get started
|
||
|
|
</p>
|
||
|
|
<button className="px-4 py-2 bg-primary-600 text-white rounded-lg">
|
||
|
|
Upload Track
|
||
|
|
</button>
|
||
|
|
</div>
|
||
|
|
```
|
||
|
|
|
||
|
|
## 8. RESPONSIVE DESIGN
|
||
|
|
|
||
|
|
### 8.1 Breakpoints
|
||
|
|
|
||
|
|
```css
|
||
|
|
/* Mobile First */
|
||
|
|
/* Base styles (mobile): 0 - 640px */
|
||
|
|
|
||
|
|
@media (min-width: 640px) { /* sm: tablet portrait */ }
|
||
|
|
@media (min-width: 768px) { /* md: tablet landscape */ }
|
||
|
|
@media (min-width: 1024px) { /* lg: laptop */ }
|
||
|
|
@media (min-width: 1280px) { /* xl: desktop */ }
|
||
|
|
@media (min-width: 1536px) { /* 2xl: large desktop */ }
|
||
|
|
```
|
||
|
|
|
||
|
|
### 8.2 Responsive Grid
|
||
|
|
|
||
|
|
```tsx
|
||
|
|
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4">
|
||
|
|
{/* Mobile: 1 column, Tablet: 2-3 columns, Desktop: 4 columns */}
|
||
|
|
</div>
|
||
|
|
```
|
||
|
|
|
||
|
|
### 8.3 Mobile Navigation
|
||
|
|
|
||
|
|
**Bottom Tab Bar** (Mobile):
|
||
|
|
```tsx
|
||
|
|
<nav className="fixed bottom-0 left-0 right-0 bg-white dark:bg-gray-900 border-t md:hidden">
|
||
|
|
<div className="flex justify-around py-2">
|
||
|
|
<a href="/" className="flex flex-col items-center text-primary-600">
|
||
|
|
<HomeIcon className="w-6 h-6" />
|
||
|
|
<span className="text-xs mt-1">Home</span>
|
||
|
|
</a>
|
||
|
|
<a href="/search" className="flex flex-col items-center text-gray-600">
|
||
|
|
<SearchIcon className="w-6 h-6" />
|
||
|
|
<span className="text-xs mt-1">Search</span>
|
||
|
|
</a>
|
||
|
|
<a href="/library" className="flex flex-col items-center text-gray-600">
|
||
|
|
<LibraryIcon className="w-6 h-6" />
|
||
|
|
<span className="text-xs mt-1">Library</span>
|
||
|
|
</a>
|
||
|
|
</div>
|
||
|
|
</nav>
|
||
|
|
```
|
||
|
|
|
||
|
|
## 9. ACCESSIBILITY
|
||
|
|
|
||
|
|
### 9.1 WCAG AAA Compliance
|
||
|
|
|
||
|
|
**Checklist**:
|
||
|
|
- [ ] Color contrast ≥ 7:1 (normal text)
|
||
|
|
- [ ] Color contrast ≥ 4.5:1 (large text)
|
||
|
|
- [ ] Keyboard navigation (Tab, Shift+Tab, Enter, Space, Arrow keys)
|
||
|
|
- [ ] Screen reader support (ARIA labels, roles, states)
|
||
|
|
- [ ] Focus indicators visible
|
||
|
|
- [ ] Skip links for main content
|
||
|
|
- [ ] No reliance on color alone
|
||
|
|
- [ ] Alt text for all images
|
||
|
|
- [ ] Captions for audio/video
|
||
|
|
- [ ] Form labels and error messages
|
||
|
|
|
||
|
|
### 9.2 ARIA Labels
|
||
|
|
|
||
|
|
```tsx
|
||
|
|
// Button
|
||
|
|
<button aria-label="Play track">
|
||
|
|
<PlayIcon />
|
||
|
|
</button>
|
||
|
|
|
||
|
|
// Input
|
||
|
|
<input
|
||
|
|
type="text"
|
||
|
|
id="search"
|
||
|
|
aria-label="Search tracks"
|
||
|
|
aria-describedby="search-hint"
|
||
|
|
/>
|
||
|
|
<span id="search-hint" className="sr-only">
|
||
|
|
Search by track name, artist, or album
|
||
|
|
</span>
|
||
|
|
|
||
|
|
// Modal
|
||
|
|
<div role="dialog" aria-modal="true" aria-labelledby="modal-title">
|
||
|
|
<h2 id="modal-title">Modal Title</h2>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
// Tab navigation
|
||
|
|
<div role="tablist" aria-label="Track sections">
|
||
|
|
<button role="tab" aria-selected="true" aria-controls="overview-panel">Overview</button>
|
||
|
|
<button role="tab" aria-selected="false" aria-controls="comments-panel">Comments</button>
|
||
|
|
</div>
|
||
|
|
```
|
||
|
|
|
||
|
|
### 9.3 Keyboard Navigation
|
||
|
|
|
||
|
|
**Focus Management**:
|
||
|
|
```tsx
|
||
|
|
// Trap focus in modal
|
||
|
|
useEffect(() => {
|
||
|
|
if (isOpen) {
|
||
|
|
const focusableElements = modalRef.current.querySelectorAll(
|
||
|
|
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
|
||
|
|
);
|
||
|
|
const firstElement = focusableElements[0];
|
||
|
|
const lastElement = focusableElements[focusableElements.length - 1];
|
||
|
|
|
||
|
|
firstElement.focus();
|
||
|
|
|
||
|
|
const handleTab = (e: KeyboardEvent) => {
|
||
|
|
if (e.key === 'Tab') {
|
||
|
|
if (e.shiftKey && document.activeElement === firstElement) {
|
||
|
|
e.preventDefault();
|
||
|
|
lastElement.focus();
|
||
|
|
} else if (!e.shiftKey && document.activeElement === lastElement) {
|
||
|
|
e.preventDefault();
|
||
|
|
firstElement.focus();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
document.addEventListener('keydown', handleTab);
|
||
|
|
return () => document.removeEventListener('keydown', handleTab);
|
||
|
|
}
|
||
|
|
}, [isOpen]);
|
||
|
|
```
|
||
|
|
|
||
|
|
### 9.4 Screen Reader Only Content
|
||
|
|
|
||
|
|
```css
|
||
|
|
.sr-only {
|
||
|
|
position: absolute;
|
||
|
|
width: 1px;
|
||
|
|
height: 1px;
|
||
|
|
padding: 0;
|
||
|
|
margin: -1px;
|
||
|
|
overflow: hidden;
|
||
|
|
clip: rect(0, 0, 0, 0);
|
||
|
|
white-space: nowrap;
|
||
|
|
border-width: 0;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## 10. ANIMATIONS & TRANSITIONS
|
||
|
|
|
||
|
|
### 10.1 Transition Durations
|
||
|
|
|
||
|
|
```css
|
||
|
|
:root {
|
||
|
|
--duration-fast: 150ms;
|
||
|
|
--duration-base: 200ms;
|
||
|
|
--duration-slow: 300ms;
|
||
|
|
--duration-slower: 500ms;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### 10.2 Easing Functions
|
||
|
|
|
||
|
|
```css
|
||
|
|
:root {
|
||
|
|
--ease-in: cubic-bezier(0.4, 0, 1, 1);
|
||
|
|
--ease-out: cubic-bezier(0, 0, 0.2, 1);
|
||
|
|
--ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### 10.3 Common Animations
|
||
|
|
|
||
|
|
**Fade In**:
|
||
|
|
```css
|
||
|
|
@keyframes fadeIn {
|
||
|
|
from { opacity: 0; }
|
||
|
|
to { opacity: 1; }
|
||
|
|
}
|
||
|
|
|
||
|
|
.fade-in {
|
||
|
|
animation: fadeIn 200ms ease-out;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Slide Up**:
|
||
|
|
```css
|
||
|
|
@keyframes slideUp {
|
||
|
|
from {
|
||
|
|
opacity: 0;
|
||
|
|
transform: translateY(20px);
|
||
|
|
}
|
||
|
|
to {
|
||
|
|
opacity: 1;
|
||
|
|
transform: translateY(0);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
.slide-up {
|
||
|
|
animation: slideUp 300ms ease-out;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Scale**:
|
||
|
|
```css
|
||
|
|
.scale-hover {
|
||
|
|
transition: transform 150ms ease-out;
|
||
|
|
}
|
||
|
|
|
||
|
|
.scale-hover:hover {
|
||
|
|
transform: scale(1.05);
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### 10.4 Performance
|
||
|
|
|
||
|
|
**Use transform and opacity** (GPU-accelerated):
|
||
|
|
```css
|
||
|
|
/* ✅ GOOD - GPU accelerated */
|
||
|
|
.animate {
|
||
|
|
transform: translateX(100px);
|
||
|
|
opacity: 0.5;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* ❌ BAD - CPU intensive */
|
||
|
|
.animate {
|
||
|
|
left: 100px;
|
||
|
|
margin-top: 50px;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## 11. USER FLOWS
|
||
|
|
|
||
|
|
### 11.1 Registration Flow
|
||
|
|
|
||
|
|
```
|
||
|
|
1. Landing Page → Click "Sign Up"
|
||
|
|
2. Registration Form (Email, Username, Password)
|
||
|
|
3. Email Verification Sent
|
||
|
|
4. Verify Email (click link)
|
||
|
|
5. Welcome / Onboarding
|
||
|
|
6. Dashboard
|
||
|
|
```
|
||
|
|
|
||
|
|
### 11.2 Track Upload Flow
|
||
|
|
|
||
|
|
```
|
||
|
|
1. Dashboard → Click "Upload"
|
||
|
|
2. Select File (drag & drop or file picker)
|
||
|
|
3. Upload Progress (with cancel option)
|
||
|
|
4. Edit Metadata (title, artist, genre, cover art)
|
||
|
|
5. Privacy Settings (public, private, unlisted)
|
||
|
|
6. Confirm & Publish
|
||
|
|
7. Track Page (share, embed)
|
||
|
|
```
|
||
|
|
|
||
|
|
### 11.3 Audio Playback Flow
|
||
|
|
|
||
|
|
```
|
||
|
|
1. Browse Tracks → Click Track
|
||
|
|
2. Track Page Loads (cover, waveform, metadata)
|
||
|
|
3. Click Play Button
|
||
|
|
4. Audio Starts (with visualizer)
|
||
|
|
5. Mini Player Appears (bottom bar)
|
||
|
|
6. Continue Browsing (player persists)
|
||
|
|
7. Queue Management (add to queue, remove)
|
||
|
|
```
|
||
|
|
|
||
|
|
## 12. FIGMA & PROTOTYPING
|
||
|
|
|
||
|
|
### 12.1 Figma File Structure
|
||
|
|
|
||
|
|
```
|
||
|
|
Veza Design System (Figma)
|
||
|
|
├── 📄 Cover & README
|
||
|
|
├── 🎨 Design Tokens
|
||
|
|
│ ├── Colors
|
||
|
|
│ ├── Typography
|
||
|
|
│ ├── Spacing
|
||
|
|
│ └── Shadows
|
||
|
|
├── 🧩 Components
|
||
|
|
│ ├── Buttons
|
||
|
|
│ ├── Inputs
|
||
|
|
│ ├── Cards
|
||
|
|
│ ├── Modals
|
||
|
|
│ ├── Navigation
|
||
|
|
│ └── Audio Player
|
||
|
|
├── 📱 Mobile Screens
|
||
|
|
│ ├── Home
|
||
|
|
│ ├── Search
|
||
|
|
│ ├── Profile
|
||
|
|
│ └── Player
|
||
|
|
├── 💻 Desktop Screens
|
||
|
|
│ ├── Dashboard
|
||
|
|
│ ├── Upload
|
||
|
|
│ ├── Track Page
|
||
|
|
│ └── Settings
|
||
|
|
└── 🔗 Prototypes
|
||
|
|
├── Registration Flow
|
||
|
|
├── Upload Flow
|
||
|
|
└── Playback Flow
|
||
|
|
```
|
||
|
|
|
||
|
|
### 12.2 Component Variants
|
||
|
|
|
||
|
|
**Button Component**:
|
||
|
|
- Variants: Primary, Secondary, Ghost, Danger
|
||
|
|
- Sizes: Small, Medium, Large
|
||
|
|
- States: Default, Hover, Active, Disabled, Loading
|
||
|
|
|
||
|
|
### 12.3 Auto Layout
|
||
|
|
|
||
|
|
**Use Auto Layout** for:
|
||
|
|
- Flexible components (buttons, cards)
|
||
|
|
- Responsive layouts
|
||
|
|
- Consistent spacing
|
||
|
|
- Easy maintenance
|
||
|
|
|
||
|
|
## ✅ CHECKLIST DE VALIDATION
|
||
|
|
|
||
|
|
### Design System
|
||
|
|
- [ ] Design tokens defined (colors, typography, spacing)
|
||
|
|
- [ ] 200+ components documented
|
||
|
|
- [ ] Figma library complete
|
||
|
|
- [ ] Dark mode support
|
||
|
|
- [ ] Responsive breakpoints defined
|
||
|
|
|
||
|
|
### Accessibility
|
||
|
|
- [ ] WCAG AAA compliance (or AA where AAA infeasible)
|
||
|
|
- [ ] Keyboard navigation functional
|
||
|
|
- [ ] Screen reader tested (NVDA, JAWS, VoiceOver)
|
||
|
|
- [ ] Focus indicators visible
|
||
|
|
- [ ] Color contrast validated
|
||
|
|
|
||
|
|
### Performance
|
||
|
|
- [ ] 60 FPS animations
|
||
|
|
- [ ] No layout shifts (CLS < 0.1)
|
||
|
|
- [ ] Optimized images (WebP, lazy loading)
|
||
|
|
- [ ] Bundle size optimized
|
||
|
|
|
||
|
|
### Documentation
|
||
|
|
- [ ] Component props documented
|
||
|
|
- [ ] Usage examples provided
|
||
|
|
- [ ] Do's and Don'ts specified
|
||
|
|
- [ ] Figma components synced with code
|
||
|
|
|
||
|
|
## 📊 MÉTRIQUES DE SUCCÈS
|
||
|
|
|
||
|
|
### Design System Adoption
|
||
|
|
- **Component Reuse**: > 80%
|
||
|
|
- **Custom Components**: < 10%
|
||
|
|
- **Design Consistency Score**: > 95%
|
||
|
|
- **Development Time Reduction**: > 50%
|
||
|
|
|
||
|
|
### Accessibility
|
||
|
|
- **WCAG AAA Compliance**: 100% (or 95% AAA + 5% AA)
|
||
|
|
- **Keyboard Navigation**: 100% functional
|
||
|
|
- **Screen Reader Support**: 100% labeled
|
||
|
|
|
||
|
|
### User Experience
|
||
|
|
- **Lighthouse Accessibility**: 100
|
||
|
|
- **User Satisfaction**: > 4.5/5
|
||
|
|
- **Task Completion Rate**: > 90%
|
||
|
|
|
||
|
|
## 🔄 HISTORIQUE DES VERSIONS
|
||
|
|
|
||
|
|
| Version | Date | Changements |
|
||
|
|
|---------|------|-------------|
|
||
|
|
| 1.0.0 | 2025-11-02 | Version initiale - Design system complet |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## ⚠️ AVERTISSEMENT
|
||
|
|
|
||
|
|
**CE DESIGN SYSTEM EST IMMUABLE**
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
**Document créé par**: Design Team + UX Lead
|
||
|
|
**Date de création**: 2025-11-02
|
||
|
|
**Prochaine révision**: Quarterly (2026-02-01)
|
||
|
|
**Propriétaire**: Design Lead
|
||
|
|
|
||
|
|
**Statut**: ✅ **APPROUVÉ ET VERROUILLÉ**
|
||
|
|
|