---
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
Action Principale
// Secondary Button
Action Secondaire
// Ghost Button
Action Ghost
// Danger Button
Action Dangereuse
```
#### **Tailles de Boutons**
```tsx
// Small
Petit
// Medium (default)
Moyen
// Large
Grand
// Extra Large
Très Grand
```
### **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
```
### **É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
Chargement...
// 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 (
{theme === 'dark' ? '☀️' : '🌙'}
);
};
```
---
## 🎛 **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 = () => (
);
// Error Feedback
const ErrorFeedback: React.FC = () => (
❌
Une erreur s'est produite
);
// Loading Feedback
const LoadingFeedback: React.FC = () => (
);
```
---
## 📦 **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 (
{loading && (
)}
{children}
);
};
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