--- id: "design-system" title: "🎨 Design System Veza Platform" sidebar_label: "🎨 Design System Veza Platform" --- > NOTE: Cette page décrit la CIBLE (but visé). # 🎨 Design System Veza Platform > **Système de design unifié pour toutes les interfaces Veza (Web, Desktop, Mobile)** ## 🎯 **Vision & Identité** ### **Identité de Veza** Veza Platform est une **plateforme musicale collaborative moderne** qui combine : - **Créativité** - Outils de création musicale avancés - **Collaboration** - Jam sessions temps réel et projets partagés - **Innovation** - IA, streaming adaptatif, marketplace - **Accessibilité** - Interface intuitive pour tous les niveaux ### **Ton Visuel** - **Moderne** - Design épuré et contemporain - **Professionnel** - Interface sérieuse pour créateurs - **Créatif** - Couleurs vibrantes et animations fluides - **Inclusif** - Accessible et adaptatif ### **Inspiration** - **Spotify** - Interface audio moderne et intuitive - **Discord** - Collaboration temps réel et communauté - **SoundCloud** - Découverte et partage musical - **Figma** - Outils créatifs professionnels --- ## 🎨 **Palette de Couleurs** ### **Mode Sombre (Principal)** #### **Couleurs Principales** ```css /* Primary - Bleu/Violet créatif */ --veza-primary-50: #f0f9ff; --veza-primary-100: #e0f2fe; --veza-primary-200: #bae6fd; --veza-primary-300: #7dd3fc; --veza-primary-400: #38bdf8; --veza-primary-500: #0ea5e9; /* Couleur principale */ --veza-primary-600: #0284c7; --veza-primary-700: #0369a1; --veza-primary-800: #075985; --veza-primary-900: #0c4a6e; /* Secondary - Violet/Purple créatif */ --veza-secondary-50: #fdf4ff; --veza-secondary-100: #fae8ff; --veza-secondary-200: #f5d0fe; --veza-secondary-300: #f0abfc; --veza-secondary-400: #e879f9; --veza-secondary-500: #d946ef; /* Couleur secondaire */ --veza-secondary-600: #c026d3; --veza-secondary-700: #a21caf; --veza-secondary-800: #86198f; --veza-secondary-900: #701a75; /* Accent - Orange/Ambre énergique */ --veza-accent-50: #fff7ed; --veza-accent-100: #ffedd5; --veza-accent-200: #fed7aa; --veza-accent-300: #fdba74; --veza-accent-400: #fb923c; --veza-accent-500: #f97316; /* Couleur d'accent */ --veza-accent-600: #ea580c; --veza-accent-700: #c2410c; --veza-accent-800: #9a3412; --veza-accent-900: #7c2d12; ``` #### **Couleurs de Fond** ```css /* Background - Gradients sombres */ --veza-bg-primary: #0f0f23; /* Fond principal */ --veza-bg-secondary: #1a1a2e; /* Fond secondaire */ --veza-bg-tertiary: #16213e; /* Fond tertiaire */ --veza-bg-surface: #1f2937; /* Surfaces (cards) */ --veza-bg-elevated: #374151; /* Surfaces élevées */ --veza-bg-overlay: rgba(0, 0, 0, 0.5); /* Overlays */ /* Gradients de fond */ --veza-gradient-primary: linear-gradient(135deg, #0f0f23 0%, #1a1a2e 50%, #16213e 100%); --veza-gradient-header: linear-gradient(135deg, #667eea 0%, #764ba2 100%); --veza-gradient-card: linear-gradient(135deg, #1f2937 0%, #374151 100%); ``` #### **Couleurs de Texte** ```css /* Text - Hiérarchie claire */ --veza-text-primary: #ffffff; /* Texte principal */ --veza-text-secondary: #e5e7eb; /* Texte secondaire */ --veza-text-tertiary: #9ca3af; /* Texte tertiaire */ --veza-text-muted: #6b7280; /* Texte atténué */ --veza-text-inverse: #111827; /* Texte inversé */ /* Text avec opacité */ --veza-text-primary-87: rgba(255, 255, 255, 0.87); --veza-text-secondary-70: rgba(229, 231, 235, 0.7); ``` #### **Couleurs d'État** ```css /* Success - Vert */ --veza-success-50: #f0fdf4; --veza-success-500: #10b981; --veza-success-600: #059669; --veza-success-700: #047857; /* Warning - Jaune */ --veza-warning-50: #fffbeb; --veza-warning-500: #f59e0b; --veza-warning-600: #d97706; --veza-warning-700: #b45309; /* Error - Rouge */ --veza-error-50: #fef2f2; --veza-error-500: #ef4444; --veza-error-600: #dc2626; --veza-error-700: #b91c1c; /* Info - Bleu */ --veza-info-50: #eff6ff; --veza-info-500: #3b82f6; --veza-info-600: #2563eb; --veza-info-700: #1d4ed8; ``` ### **Mode Clair (Alternative)** #### **Couleurs Principales (Clair)** ```css /* Background - Clair */ --veza-light-bg-primary: #ffffff; --veza-light-bg-secondary: #f9fafb; --veza-light-bg-tertiary: #f3f4f6; --veza-light-bg-surface: #ffffff; --veza-light-bg-elevated: #f9fafb; /* Text - Clair */ --veza-light-text-primary: #111827; --veza-light-text-secondary: #374151; --veza-light-text-tertiary: #6b7280; --veza-light-text-muted: #9ca3af; ``` --- ## 🖋 **Typographie** ### **Police Principale** ```css /* Inter - Police moderne et lisible */ --veza-font-family: 'Inter', system-ui, -apple-system, sans-serif; --veza-font-mono: 'JetBrains Mono', 'Fira Code', monospace; ``` ### **Hiérarchie Typographique** #### **Titres** ```css /* H1 - Titre principal */ --veza-h1-font-size: 3rem; /* 48px */ --veza-h1-font-weight: 700; --veza-h1-line-height: 1.2; --veza-h1-letter-spacing: -0.025em; /* H2 - Titre de section */ --veza-h2-font-size: 2.25rem; /* 36px */ --veza-h2-font-weight: 600; --veza-h2-line-height: 1.3; --veza-h2-letter-spacing: -0.025em; /* H3 - Titre de sous-section */ --veza-h3-font-size: 1.875rem; /* 30px */ --veza-h3-font-weight: 600; --veza-h3-line-height: 1.4; /* H4 - Titre de carte */ --veza-h4-font-size: 1.5rem; /* 24px */ --veza-h4-font-weight: 600; --veza-h4-line-height: 1.4; /* H5 - Titre de composant */ --veza-h5-font-size: 1.25rem; /* 20px */ --veza-h5-font-weight: 600; --veza-h5-line-height: 1.5; /* H6 - Titre de détail */ --veza-h6-font-size: 1.125rem; /* 18px */ --veza-h6-font-weight: 600; --veza-h6-line-height: 1.5; ``` #### **Corps de Texte** ```css /* Body - Texte principal */ --veza-body-font-size: 1rem; /* 16px */ --veza-body-font-weight: 400; --veza-body-line-height: 1.6; /* Body Large - Texte important */ --veza-body-large-font-size: 1.125rem; /* 18px */ --veza-body-large-font-weight: 400; --veza-body-large-line-height: 1.6; /* Body Small - Texte secondaire */ --veza-body-small-font-size: 0.875rem; /* 14px */ --veza-body-small-font-weight: 400; --veza-body-small-line-height: 1.5; /* Caption - Légendes */ --veza-caption-font-size: 0.75rem; /* 12px */ --veza-caption-font-weight: 400; --veza-caption-line-height: 1.4; ``` #### **Interface** ```css /* Button - Boutons */ --veza-button-font-size: 0.875rem; /* 14px */ --veza-button-font-weight: 500; --veza-button-line-height: 1.4; /* Input - Champs de saisie */ --veza-input-font-size: 0.875rem; /* 14px */ --veza-input-font-weight: 400; --veza-input-line-height: 1.4; /* Label - Étiquettes */ --veza-label-font-size: 0.875rem; /* 14px */ --veza-label-font-weight: 500; --veza-label-line-height: 1.4; ``` --- ## 🔲 **Composants UI de Base** ### **Boutons** #### **Variantes de Boutons** ```tsx // Primary Button // Secondary Button // Ghost Button // Danger Button ``` #### **Tailles de Boutons** ```tsx // Small // Medium (default) // Large // Extra Large ``` ### **Inputs** #### **Champs de Texte** ```tsx // Text Input // Password Input // Search Input
``` #### **États des Inputs** ```tsx // Error State // Success State // Disabled State ``` ### **Cards** #### **Card de Base** ```tsx // Basic Card

Titre de la Carte

Contenu de la carte avec description détaillée.

// Interactive Card

Carte Interactive

Cliquez pour plus d'informations.

``` #### **Card avec Gradient** ```tsx // Gradient Card

Carte avec Gradient

Carte avec dégradé de couleurs Veza.

``` ### **Navigation** #### **Sidebar** ```tsx // Sidebar Container ``` #### **Top Navigation** ```tsx // Top Navigation
🎵

Veza Platform

``` ### **États Interactifs** #### **Hover States** ```css /* Hover sur les boutons */ .button:hover { transform: translateY(-1px); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); } /* Hover sur les cards */ .card:hover { transform: translateY(-2px); box-shadow: 0 8px 25px rgba(0, 0, 0, 0.2); } /* Hover sur les liens */ .link:hover { color: var(--veza-primary-400); text-decoration: underline; } ``` #### **Focus States** ```css /* Focus sur les inputs */ .input:focus { outline: none; ring: 2px; ring-color: var(--veza-primary-500); ring-offset: 2px; } /* Focus sur les boutons */ .button:focus { outline: none; ring: 2px; ring-color: var(--veza-primary-500); ring-offset: 2px; } ``` #### **Loading States** ```tsx // Loading Button // Loading Spinner
``` --- ## 🌗 **Modes Clair et Sombre** ### **Variables CSS pour les Thèmes** ```css /* Mode Sombre (Par défaut) */ [data-theme="dark"] { --veza-bg-primary: #0f0f23; --veza-bg-secondary: #1a1a2e; --veza-bg-surface: #1f2937; --veza-text-primary: #ffffff; --veza-text-secondary: #e5e7eb; --veza-border-color: #374151; } /* Mode Clair */ [data-theme="light"] { --veza-bg-primary: #ffffff; --veza-bg-secondary: #f9fafb; --veza-bg-surface: #ffffff; --veza-text-primary: #111827; --veza-text-secondary: #374151; --veza-border-color: #e5e7eb; } ``` ### **Composant de Toggle de Thème** ```tsx // Theme Toggle Component const ThemeToggle: React.FC = () => { const [theme, setTheme] = useState<'light' | 'dark'>('dark'); const toggleTheme = () => { const newTheme = theme === 'dark' ? 'light' : 'dark'; setTheme(newTheme); document.documentElement.setAttribute('data-theme', newTheme); }; return ( ); }; ``` --- ## 🎛 **Micro-interactions et Animations** ### **Animations CSS** ```css /* Fade In */ @keyframes fadeIn { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } .fade-in { animation: fadeIn 0.5s ease-out; } /* Pulse */ @keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } } .pulse { animation: pulse 2s infinite; } /* Wave */ @keyframes wave { 0%, 100% { transform: rotate(0deg); } 25% { transform: rotate(20deg); } 75% { transform: rotate(-20deg); } } .wave { animation: wave 1.5s ease-in-out infinite; } /* Slide In */ @keyframes slideIn { from { opacity: 0; transform: translateX(-20px); } to { opacity: 1; transform: translateX(0); } } .slide-in { animation: slideIn 0.3s ease-out; } ``` ### **Transitions** ```css /* Transitions fluides */ * { transition: all 0.2s ease-in-out; } /* Transitions spécifiques */ .button { transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); } .card { transition: transform 0.2s ease, box-shadow 0.2s ease; } .input { transition: border-color 0.2s ease, box-shadow 0.2s ease; } ``` ### **Feedback Visuel** ```tsx // Success Feedback const SuccessFeedback: React.FC = () => (
Action réussie !
); // Error Feedback const ErrorFeedback: React.FC = () => (
Une erreur s'est produite
); // Loading Feedback const LoadingFeedback: React.FC = () => (
Chargement...
); ``` --- ## 📦 **Kit de Composants React/Tailwind** ### **Composant Button** ```tsx // Button.tsx interface ButtonProps { children: React.ReactNode; variant?: 'primary' | 'secondary' | 'ghost' | 'danger'; size?: 'sm' | 'md' | 'lg' | 'xl'; disabled?: boolean; loading?: boolean; onClick?: () => void; type?: 'button' | 'submit' | 'reset'; className?: string; } const Button: React.FC = ({ children, variant = 'primary', size = 'md', disabled = false, loading = false, onClick, type = 'button', className = '', }) => { const baseClasses = 'inline-flex items-center justify-center font-medium rounded-lg transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2'; const variantClasses = { primary: 'bg-veza-primary-500 hover:bg-veza-primary-600 text-white focus:ring-veza-primary-500 hover:scale-105', secondary: 'bg-veza-secondary-500 hover:bg-veza-secondary-600 text-white focus:ring-veza-secondary-500 hover:scale-105', ghost: 'text-veza-primary-500 hover:text-veza-primary-400 hover:bg-veza-primary-50 focus:ring-veza-primary-500', danger: 'bg-veza-error-500 hover:bg-veza-error-600 text-white focus:ring-veza-error-500 hover:scale-105', }; const sizeClasses = { sm: 'px-3 py-1.5 text-sm', md: 'px-4 py-2 text-sm', lg: 'px-6 py-3 text-base', xl: 'px-8 py-4 text-lg', }; const disabledClasses = disabled ? 'opacity-50 cursor-not-allowed hover:scale-100' : ''; const loadingClasses = loading ? 'cursor-wait' : ''; const classes = `${baseClasses} ${variantClasses[variant]} ${sizeClasses[size]} ${disabledClasses} ${loadingClasses} ${className}`; return ( ); }; export default Button; ``` ### **Composant Input** ```tsx // Input.tsx interface InputProps { type?: 'text' | 'password' | 'email' | 'search' | 'number'; placeholder?: string; value?: string; onChange?: (value: string) => void; error?: string; success?: boolean; disabled?: boolean; className?: string; icon?: React.ReactNode; } const Input: React.FC = ({ type = 'text', placeholder, value, onChange, error, success, disabled = false, className = '', icon, }) => { const baseClasses = 'w-full px-3 py-2 bg-veza-bg-surface border rounded-lg text-veza-text-primary placeholder-veza-text-muted focus:outline-none focus:ring-2 focus:ring-offset-2 transition-colors duration-200'; const stateClasses = error ? 'border-veza-error-500 focus:ring-veza-error-500' : success ? 'border-veza-success-500 focus:ring-veza-success-500' : 'border-veza-bg-elevated focus:ring-veza-primary-500 focus:border-veza-primary-500'; const disabledClasses = disabled ? 'bg-veza-bg-tertiary cursor-not-allowed' : ''; const classes = `${baseClasses} ${stateClasses} ${disabledClasses} ${className}`; return (
{icon && (
{icon}
)} onChange?.(e.target.value)} disabled={disabled} className={classes} style={icon ? { paddingLeft: '2.5rem' } : {}} /> {error && (

{error}

)}
); }; export default Input; ``` ### **Composant Card** ```tsx // Card.tsx interface CardProps { children: React.ReactNode; title?: string; subtitle?: string; interactive?: boolean; gradient?: boolean; className?: string; onClick?: () => void; } const Card: React.FC = ({ children, title, subtitle, interactive = false, gradient = false, className = '', onClick, }) => { const baseClasses = 'rounded-xl p-6 shadow-lg transition-all duration-200'; const styleClasses = gradient ? 'bg-gradient-to-br from-veza-primary-500 to-veza-secondary-500 text-white' : 'bg-veza-bg-surface border border-veza-bg-elevated'; const interactiveClasses = interactive ? 'hover:shadow-xl hover:scale-105 cursor-pointer' : ''; const classes = `${baseClasses} ${styleClasses} ${interactiveClasses} ${className}`; return (
{(title || subtitle) && (
{title && (

{title}

)} {subtitle && (

{subtitle}

)}
)} {children}
); }; export default Card; ``` ### **Composant Modal** ```tsx // Modal.tsx interface ModalProps { isOpen: boolean; onClose: () => void; title?: string; children: React.ReactNode; size?: 'sm' | 'md' | 'lg' | 'xl'; } const Modal: React.FC = ({ isOpen, onClose, title, children, size = 'md', }) => { if (!isOpen) return null; const sizeClasses = { sm: 'max-w-md', md: 'max-w-lg', lg: 'max-w-2xl', xl: 'max-w-4xl', }; return (
{title && (

{title}

)}
{children}
); }; export default Modal; ``` --- ## 🎯 **Guide d'Utilisation** ### **Principes de Design** 1. **Cohérence** - Utilisez toujours les mêmes couleurs, typographies et espacements 2. **Accessibilité** - Respectez les contrastes et les états de focus 3. **Performance** - Optimisez les animations et transitions 4. **Responsive** - Adaptez l'interface à tous les écrans 5. **Feedback** - Donnez toujours un retour visuel aux actions utilisateur ### **Checklist d'Implémentation** - [ ] Variables CSS définies dans le thème - [ ] Composants React créés et documentés - [ ] Animations CSS optimisées - [ ] Tests d'accessibilité passés - [ ] Tests de performance validés - [ ] Documentation des composants mise à jour ### **Prochaines Étapes** 1. **Implémenter** les composants dans les applications existantes 2. **Créer** un Storybook pour documenter tous les composants 3. **Tester** l'accessibilité et la performance 4. **Former** l'équipe sur l'utilisation du design system 5. **Maintenir** et évoluer le design system --- **Dernière mise à jour** : $(date) **Version** : 1.0.0 **Statut** : ✅ Design System Complet