# 🎨 Design System & Composants Visuels - Notytex Class Dashboard ## Vue d'ensemble Le Class Dashboard de Notytex représente l'excellence en matière d'interface utilisateur moderne, combinant une hiérarchie visuelle claire, des animations fluides et une adaptation responsive parfaite. Ce système de design privilégie l'experience utilisateur avec des interactions naturelles et des feedback visuels immédiats. --- ## 📐 Design System Global ### 🎨 Palette de Couleurs #### **Couleurs Primaires** ```css /* Bleu - Action principale, navigation */ --primary-blue: #3B82F6 --primary-blue-dark: #1D4ED8 --primary-blue-light: #93C5FD /* Gradient hero sections */ --gradient-indigo: from-indigo-600 to-purple-600 --gradient-blue: from-blue-50 to-indigo-100 ``` #### **Couleurs Sémantiques par État** ```css /* Rouge - Urgence, non commencé */ --status-error: #EF4444 --status-error-bg: #FEF2F2 --status-error-border: #FECACA /* Orange - En cours, attention */ --status-warning: #F59E0B --status-warning-bg: #FEF3C7 --status-warning-border: #FDE68A /* Vert - Terminé, succès */ --status-success: #10B981 --status-success-bg: #ECFDF5 --status-success-border: #D1FAE5 /* Gris - Neutre, secondaire */ --neutral-gray: #6B7280 --neutral-gray-light: #F3F4F6 --neutral-gray-border: #E5E7EB ``` #### **Couleurs Métier** ```css /* Domaines d'évaluation */ --domain-green: #059669 --domain-green-bg: #ECFDF5 --domain-green-accent: #10B981 /* Compétences */ --competence-purple: #7C3AED --competence-purple-bg: #F3E8FF --competence-purple-accent: #8B5CF6 /* Résultats et statistiques */ --results-orange: #EA580C --results-orange-bg: #FFF7ED --results-orange-accent: #FB923C ``` ### 📝 Typographie #### **Hiérarchie des Titres** ```css /* H1 - Titre principal (Hero) */ .text-4xl.font-bold { font-size: 2.25rem; /* 36px */ font-weight: 700; line-height: 1.2; letter-spacing: -0.025em; } /* H2 - Titres de sections */ .text-xl.font-bold { font-size: 1.25rem; /* 20px */ font-weight: 700; line-height: 1.3; color: #1F2937; } /* H3 - Titres de cards */ .text-lg.font-semibold { font-size: 1.125rem; /* 18px */ font-weight: 600; line-height: 1.4; color: #374151; } ``` #### **Corps de Texte** ```css /* Texte principal */ .text-base { font-size: 1rem; /* 16px */ line-height: 1.5; color: #374151; } /* Texte secondaire */ .text-sm { font-size: 0.875rem; /* 14px */ line-height: 1.4; color: #6B7280; } /* Texte de métadonnées */ .text-xs { font-size: 0.75rem; /* 12px */ line-height: 1.3; color: #9CA3AF; } ``` #### **Nombres et Statistiques** ```css /* Gros nombres (moyennes) */ .text-3xl.font-bold { font-size: 1.875rem; /* 30px */ font-weight: 700; font-variant-numeric: tabular-nums; letter-spacing: -0.025em; } ``` ### 📏 Système d'Espacement #### **Espacement Interne (Padding)** ```css /* Cards principales */ .p-6 { padding: 1.5rem; } /* 24px */ /* Sections compactes */ .p-4 { padding: 1rem; } /* 16px */ /* Éléments fins */ .p-3 { padding: 0.75rem; } /* 12px */ /* Micro-espacements */ .p-2 { padding: 0.5rem; } /* 8px */ ``` #### **Espacement Externe (Margin)** ```css /* Séparation entre sections */ .space-y-8 > * + * { margin-top: 2rem; } /* 32px */ /* Séparation entre cards */ .space-y-6 > * + * { margin-top: 1.5rem; } /* 24px */ /* Séparation entre éléments */ .space-y-4 > * + * { margin-top: 1rem; } /* 16px */ ``` #### **Grid et Gaps** ```css /* Gap principal (desktop) */ .gap-6 { gap: 1.5rem; } /* 24px */ /* Gap réduit (mobile) */ .gap-4 { gap: 1rem; } /* 16px */ /* Gap micro-interactions */ .gap-2 { gap: 0.5rem; } /* 8px */ ``` ### 🔲 Système de Grilles #### **Grille Principale (Desktop)** ```css /* Grid responsive 4 colonnes */ .grid-cols-1.md:grid-cols-2.lg:grid-cols-4 { grid-template-columns: repeat(1, 1fr); /* Mobile */ repeat(2, 1fr); /* Tablet */ repeat(4, 1fr); /* Desktop */ } /* Statistics grid adaptatif */ .stats-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 1.5rem; } ``` #### **Layout Containers** ```css /* Conteneur principal */ .max-w-7xl.mx-auto { max-width: 80rem; /* 1280px */ margin: 0 auto; } /* Padding container responsive */ .px-8.py-8 { padding: 2rem; /* Desktop */ } .px-4.py-6 { padding: 1.5rem 1rem; /* Mobile */ } ``` --- ## 🧩 Composants Visuels Principaux ### 🏆 Hero Section #### **Structure & Style** ```html

6ème A 🏫

Dashboard de gestion de classe

``` #### **Guidelines d'Usage** - **Gradient**: Toujours utiliser des gradients cohérents (`from-indigo-600 to-purple-600`) - **Contraste**: Assurer un contraste minimum 4.5:1 sur le texte blanc - **Icônes**: SVG inline 16x16px (w-4 h-4) pour les métadonnées - **Responsive**: Masquer les éléments décoratifs sur mobile avec `hidden md:block` ### 🃏 Action Cards #### **Styles par Priorité** ```html ``` #### **Structure Interne** ```html

Titre Action

Description contextuelle

``` #### **Animations & Interactions** - **Transform**: `hover:scale-[1.02]` pour micro-zoom - **Shadow**: Progression `shadow-lg` → `shadow-xl` - **Background**: Gradient transition avec états hover - **Durée**: `transition-all duration-300` pour fluidité ### 🏷️ Navigation par Trimestre (Tabs) #### **Structure HTML** ```html ``` #### **États Visuels** ```css /* État actif */ .trimester-tab.active { background: linear-gradient(135deg, #3b82f6, #1d4ed8); color: white; box-shadow: 0 4px 20px rgba(59, 130, 246, 0.3); transform: scale(1.02); } /* État inactif */ .trimester-tab:not(.active) { background: white; color: #374151; border: 2px solid #e5e7eb; } /* Hover inactif */ .trimester-tab:not(.active):hover { background: #f9fafb; border-color: #d1d5db; transform: translateY(-2px); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); } ``` #### **Animations Avancées** - **Shimmer Effect**: Effet de brillance au hover - **Scale Animation**: Légère augmentation de taille pour l'état actif - **Color Transition**: Progression fluide des couleurs - **Shadow Progression**: Élévation visuelle au hover ### 📊 Statistics Cards #### **Trois Types Principaux** ##### **1. Card Domaines (Vert)** ```html

Domaines

0
domaines évalués
``` ##### **2. Card Compétences (Violet)** ```html
``` ##### **3. Card Résultats (Orange)** ```html
0.0
moyenne générale
0 évaluation(s)
Min: 0.0
``` #### **Animations des Nombres** ```javascript // Animation fluide des statistiques avec easing animateNumber(element, targetValue, duration = 1000) { const startValue = parseFloat(element.textContent) || 0; const easeOut = 1 - Math.pow(1 - progress, 3); // Cubic easing // Animation avec requestAnimationFrame } ``` ### 🎯 Progress Indicators #### **Trois États Principaux** ##### **Complété (Vert)** ```html
Correction 100%
``` ##### **En Cours (Orange avec Cercle)** ```html
Correction {{ percentage }}%
``` ##### **Non Commencé (Rouge)** ```html
Correction 0%
``` #### **Calcul des Dashoffset** ```css /* Cercle de progression SVG */ circle { stroke-dasharray: 37.7; /* 2π × 6 (rayon) */ stroke-dashoffset: calc(37.7 - (37.7 * var(--percentage) / 100)); transition: stroke-dashoffset 1s ease-in-out; } ``` --- ## 🎭 États Visuels et Feedback ### 📱 Loading States #### **Skeleton Loading** ```css @keyframes skeletonPulse { 0%, 100% { opacity: 1; background-color: #e5e7eb; } 50% { opacity: 0.7; background-color: #f3f4f6; } } .skeleton-item { background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%); background-size: 200% 100%; animation: skeletonPulse 1.5s ease-in-out infinite; border-radius: 0.375rem; } ``` #### **Loading Overlay** ```html
``` ```css .loading-overlay { position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: rgba(255, 255, 255, 0.8); backdrop-filter: blur(4px); display: flex; align-items: center; justify-content: center; z-index: 1040; } .loading-spinner { width: 32px; height: 32px; border: 3px solid #e5e7eb; border-top: 3px solid #3b82f6; border-radius: 50%; animation: spin 1s linear infinite; } ``` ### ❌ Error States #### **Error Cards** ```html

Message d'erreur

``` ### 🎉 Success States #### **Toast Notifications** ```javascript // Notification de succès avec auto-dismiss Notytex.utils.showToast('Trimestre 1 chargé', 'success', 1500); ``` ### 🔄 Empty States #### **Pas d'Évaluations** ```html

Aucune évaluation pour cette classe

Créez votre première évaluation pour cette classe

Créer une évaluation
``` --- ## 📱 Adaptation Responsive ### 🖥️ Breakpoints ```css /* Mobile First Approach */ /* xs: 0px - 639px */ /* Mobile */ /* sm: 640px - 767px */ /* Mobile large */ /* md: 768px - 1023px */ /* Tablette */ /* lg: 1024px - 1279px */ /* Desktop */ /* xl: 1280px+ */ /* Large desktop */ ``` ### 📱 Mobile (< 768px) #### **Layout Changes** - **Grid**: `grid-cols-1` (stack vertical) - **Cards**: Pleine largeur avec `rounded-lg` (bordures réduites) - **Padding**: Réduit à `p-4` au lieu de `p-6` - **Navigation**: Tabs en scroll horizontal - **Actions**: Stack vertical des action cards #### **Touch Optimizations** ```css /* Zones de touch plus grandes */ .trimester-tab { min-height: 44px; /* Apple guidelines */ min-width: 44px; } /* Feedback tactile */ .trimester-tab:active { transform: scale(0.98); transition: transform 0.1s ease; } /* Disable hover effects */ @media (hover: none) and (pointer: coarse) { .stats-card:hover { transform: none; transition-duration: 0.15s; } } ``` ### 📱 Tablette (768px - 1023px) #### **Layout Adaptatif** - **Grid**: `md:grid-cols-2` (2 colonnes) - **Statistics**: Grid 2x2 pour les cards principales - **Navigation**: Tabs centrés avec plus d'espacement - **Hover**: Effets réduits mais présents ### 🖥️ Desktop (1024px+) #### **Enhancements** ```css /* Effets avancés activés */ .stats-card:hover { transform: translateY(-6px) scale(1.02); } /* Grilles optimisées */ .stats-grid { grid-template-columns: repeat(auto-fit, minmax(350px, 1fr)); gap: 2rem; } /* Animations plus prononcées */ .trimester-tab:not(.active):hover { transform: translateY(-3px) scale(1.05); } ``` --- ## ⚡ Animations et Micro-interactions ### 🌊 Système de Transitions #### **Design Tokens** ```css :root { --transition-fast: 150ms cubic-bezier(0.4, 0, 0.2, 1); --transition-normal: 300ms cubic-bezier(0.4, 0, 0.2, 1); --transition-slow: 500ms cubic-bezier(0.4, 0, 0.2, 1); --transition-spring: 400ms cubic-bezier(0.34, 1.56, 0.64, 1); --transition-bounce: cubic-bezier(0.68, -0.55, 0.265, 1.55); } ``` #### **Usage Pattern** ```css /* Standard pour la plupart des interactions */ .transition-all.duration-300 { transition: all var(--transition-normal); } /* Rapide pour les feedbacks immédiats */ .transition-colors.duration-150 { transition: color var(--transition-fast), background-color var(--transition-fast); } ``` ### 🎯 Animations de Chargement #### **Cascade d'Apparition** ```javascript animateInitialLoad() { const elements = [...this.elements.trimesterTabs, ...this.elements.statsCards]; elements.forEach((element, index) => { element.style.opacity = '0'; element.style.transform = 'translateY(30px)'; setTimeout(() => { element.style.transition = 'opacity 300ms ease-out, transform 300ms ease-out'; element.style.opacity = '1'; element.style.transform = 'translateY(0)'; }, index * 50); // 50ms de délai entre chaque élément }); } ``` #### **Animation des Nombres** ```javascript // Compteur animé avec easing animateNumber(element, targetValue, duration = 1000) { const startValue = parseFloat(element.textContent) || 0; const startTime = Date.now(); const animate = () => { const elapsed = Date.now() - startTime; const progress = Math.min(elapsed / duration, 1); // Cubic ease-out: 1 - (1-t)³ const easeOut = 1 - Math.pow(1 - progress, 3); const currentValue = startValue + (targetValue - startValue) * easeOut; element.textContent = isInteger ? Math.round(currentValue) : currentValue.toFixed(1); if (progress < 1) requestAnimationFrame(animate); }; requestAnimationFrame(animate); } ``` ### 🔄 Transitions entre États #### **Changement de Trimestre** ```javascript async animateTrimesterTransition() { const content = this.elements.statsContent; // Animation de sortie content.style.opacity = '0.6'; content.style.transform = 'translateY(10px)'; content.style.transition = 'opacity 300ms ease-out, transform 300ms ease-out'; await new Promise(resolve => setTimeout(resolve, 150)); // Animation d'entrée content.style.opacity = '1'; content.style.transform = 'translateY(0)'; } ``` #### **Expansion de Cards** ```css @keyframes cardExpand { from { height: 0; opacity: 0; transform: translateY(-10px); } to { height: auto; opacity: 1; transform: translateY(0); } } ``` ### 💫 Effets Avancés #### **Shimmer Effect (Tabs)** ```css .trimester-tab::before { content: ''; position: absolute; top: 0; left: -100%; width: 100%; height: 100%; background: linear-gradient(90deg, transparent, rgba(255,255,255,0.6), transparent); transition: left 500ms ease; } .trimester-tab:hover::before { left: 100%; } ``` #### **Ripple Effect (Mobile)** ```javascript addRippleEffect(element, touch) { const ripple = document.createElement('span'); const rect = element.getBoundingClientRect(); const size = Math.max(rect.width, rect.height); ripple.style.width = ripple.style.height = size + 'px'; ripple.style.left = (touch.clientX - rect.left - size/2) + 'px'; ripple.style.top = (touch.clientY - rect.top - size/2) + 'px'; ripple.className = 'ripple'; element.appendChild(ripple); setTimeout(() => ripple.remove(), 600); } ``` ```css .ripple { position: absolute; border-radius: 50%; background: rgba(255, 255, 255, 0.6); animation: ripple 0.6s ease-out; pointer-events: none; } @keyframes ripple { from { opacity: 0.6; transform: scale(0); } to { opacity: 0; transform: scale(2); } } ``` --- ## ♿ Accessibilité Visuelle ### 🎯 Principes WCAG 2.1 #### **Contraste des Couleurs** - **AA Standard**: Minimum 4.5:1 pour le texte normal - **AAA Enhanced**: Minimum 7:1 pour le texte important - **Large Text**: Minimum 3:1 pour texte ≥18pt ou gras ≥14pt #### **Vérifications Automatiques** ```css /* Vérification des contrastes */ .text-green-900 /* #14532d sur #ffffff = 13.64:1 ✅ AAA */ .text-orange-800 /* #9a3412 sur #ffffff = 6.94:1 ✅ AAA */ .text-purple-800 /* #6b21a8 sur #ffffff = 8.33:1 ✅ AAA */ .text-gray-600 /* #4b5563 sur #ffffff = 7.23:1 ✅ AAA */ ``` ### 🎨 Support High Contrast ```css @media (prefers-contrast: high) { .stats-card { border: 2px solid #1f2937; background: #ffffff; } .trimester-tab.active { background: #1f2937; color: #ffffff; border: 2px solid #1f2937; } .trimester-tab:not(.active) { background: #ffffff; color: #1f2937; border: 2px solid #6b7280; } } ``` ### ♿ Navigation Clavier #### **Focus Visible Amélioré** ```css .trimester-tab:focus-visible, .stats-card-header:focus-visible { outline: 2px solid #3b82f6; outline-offset: 2px; border-radius: 0.75rem; } ``` #### **Navigation Logique** ```javascript handleKeyboardNavigation(event) { if (event.target.matches('[data-trimester-tab]')) { switch (event.key) { case 'ArrowLeft': // Naviguer vers l'onglet précédent break; case 'ArrowRight': // Naviguer vers l'onglet suivant break; case 'Enter': case ' ': event.target.click(); break; } } } ``` ### 📢 ARIA et Screen Readers #### **Tabs Navigation** ```html ``` #### **Live Regions pour Updates** ```html
``` ```javascript // Annoncer les changements announceChange(message) { const liveRegion = document.querySelector('[data-live-region]'); liveRegion.textContent = message; // Auto-clear after announcement setTimeout(() => liveRegion.textContent = '', 1000); } ``` ### 🎭 Reduced Motion Support ```css @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; } .stats-card:hover, .trimester-tab:hover { transform: none; } } ``` --- ## 🛠️ Guidelines d'Implémentation ### 📋 Checklist de Qualité #### **Visual Consistency** - [ ] Utilisation cohérente des couleurs sémantiques - [ ] Espacement basé sur le système (multiples de 4px/0.25rem) - [ ] Typographie respectant la hiérarchie définie - [ ] Border-radius cohérents (`rounded-xl` = 12px pour cards) #### **Interaction Design** - [ ] Hover states définis pour tous les éléments interactifs - [ ] Focus states visibles et accessibles - [ ] Loading states pour toutes les actions asynchrones - [ ] Feedback visuel immédiat sur les interactions #### **Responsive Behavior** - [ ] Test sur mobile (320px min-width) - [ ] Test sur tablette (768px - 1023px) - [ ] Test sur desktop (1024px+) - [ ] Touch targets ≥44px sur mobile #### **Performance** - [ ] Animations utilisant `transform` et `opacity` uniquement - [ ] `will-change` défini pour les animations critiques - [ ] GPU acceleration avec `backface-visibility: hidden` - [ ] Debouncing sur les événements fréquents (resize, scroll) ### 🎨 Styleguide d'Utilisation #### **Do's** ✅ Utiliser les gradients définis (`from-blue-500 to-blue-600`) ✅ Maintenir des transitions cohérentes (300ms par défaut) ✅ Grouper les éléments liés avec `space-y-*` ✅ Utiliser `group` + `group-hover:` pour les effets de groupe ✅ Préfixer les data attributes (`data-stats-card`) #### **Don'ts** ❌ Créer de nouveaux gradients sans justification ❌ Utiliser des animations CSS pures pour les transitions complexes ❌ Omettre les états loading/error ❌ Négliger les tests sur appareils tactiles ❌ Ignorer les préférences utilisateur (reduced-motion) ### 📊 Métriques de Performance #### **Core Web Vitals Targets** - **LCP**: < 2.5s (Largest Contentful Paint) - **FID**: < 100ms (First Input Delay) - **CLS**: < 0.1 (Cumulative Layout Shift) #### **Animation Performance** - **60 FPS**: Toutes les animations maintienues à 60fps - **Transform Only**: Éviter les animations de propriétés layout - **RAF**: Utiliser `requestAnimationFrame` pour les animations JS --- ## 🔮 Évolutions Futures ### 🌙 Dark Theme Support ```css /* Préparation du thème sombre */ @media (prefers-color-scheme: dark) { :root { --bg-primary: #1f2937; --bg-secondary: #111827; --text-primary: #f9fafb; --text-secondary: #d1d5db; } .stats-card { background: var(--bg-primary); border: 1px solid #374151; } } ``` ### 📱 Progressive Web App - **Gestures Avancés**: Swipe, pinch-to-zoom, long-press - **Offline Support**: Cache des données critiques - **Native Animations**: Integration avec les APIs mobiles