/** * NOTYTEX - Class Dashboard CSS * Animations avancées et comportements responsive pour le dashboard de classe */ /* ======================================== DESIGN TOKENS SPÉCIFIQUES ======================================== */ :root { /* Transitions et timing */ --dashboard-transition-fast: 150ms cubic-bezier(0.4, 0, 0.2, 1); --dashboard-transition-normal: 300ms cubic-bezier(0.4, 0, 0.2, 1); --dashboard-transition-slow: 500ms cubic-bezier(0.4, 0, 0.2, 1); --dashboard-transition-spring: 400ms cubic-bezier(0.34, 1.56, 0.64, 1); /* Animations personnalisées */ --dashboard-bounce: cubic-bezier(0.68, -0.55, 0.265, 1.55); --dashboard-ease-out-back: cubic-bezier(0.175, 0.885, 0.32, 1.275); /* Z-index layers */ --z-dropdown: 1000; --z-sticky: 1020; --z-fixed: 1030; --z-modal: 1040; --z-popover: 1050; --z-tooltip: 1060; } /* ======================================== ANIMATIONS KEYFRAMES ======================================== */ /* Card expansion fluide */ @keyframes cardExpand { from { height: 0; opacity: 0; transform: translateY(-10px); } to { height: auto; opacity: 1; transform: translateY(0); } } @keyframes cardCollapse { from { height: auto; opacity: 1; transform: translateY(0); } to { height: 0; opacity: 0; transform: translateY(-10px); } } /* Slide transitions entre trimestres */ @keyframes slideInFromRight { from { opacity: 0; transform: translateX(20px); } to { opacity: 1; transform: translateX(0); } } @keyframes slideInFromLeft { from { opacity: 0; transform: translateX(-20px); } to { opacity: 1; transform: translateX(0); } } @keyframes slideOutToRight { from { opacity: 1; transform: translateX(0); } to { opacity: 0; transform: translateX(20px); } } @keyframes slideOutToLeft { from { opacity: 1; transform: translateX(0); } to { opacity: 0; transform: translateX(-20px); } } /* Skeleton loading animation */ @keyframes skeletonPulse { 0%, 100% { opacity: 1; background-color: #e5e7eb; } 50% { opacity: 0.7; background-color: #f3f4f6; } } /* Ripple effect pour touch feedback */ @keyframes ripple { from { opacity: 0.6; transform: scale(0); } to { opacity: 0; transform: scale(2); } } /* Micro-bounce pour les interactions */ @keyframes microBounce { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.05); } } /* Apparition progressive des éléments */ @keyframes cascadeFadeIn { from { opacity: 0; transform: translateY(30px) scale(0.9); } to { opacity: 1; transform: translateY(0) scale(1); } } /* ======================================== COMPOSANTS DASHBOARD ======================================== */ /* Conteneur principal */ .class-dashboard { min-height: 100vh; background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%); position: relative; overflow-x: hidden; } /* Navigation par trimestre */ .trimester-nav { position: sticky; top: 0; z-index: var(--z-sticky); background: rgba(255, 255, 255, 0.95); backdrop-filter: blur(10px); border-bottom: 1px solid #e5e7eb; transition: all var(--dashboard-transition-normal); } .trimester-tabs { display: flex; gap: 0.5rem; padding: 1rem; overflow-x: auto; scrollbar-width: none; -ms-overflow-style: none; } .trimester-tabs::-webkit-scrollbar { display: none; } .trimester-tab { flex-shrink: 0; padding: 0.75rem 1.5rem; border-radius: 0.75rem; font-weight: 600; transition: all var(--dashboard-transition-normal); position: relative; overflow: hidden; cursor: pointer; white-space: nowrap; } .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 var(--dashboard-transition-slow); } .trimester-tab:hover::before { left: 100%; } .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); } .trimester-tab:not(.active) { background: white; color: #374151; border: 2px solid #e5e7eb; } .trimester-tab:not(.active):hover { background: #f9fafb; border-color: #d1d5db; transform: translateY(-2px); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); } /* Stats Grid */ .stats-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 1.5rem; } /* Stats Cards */ .stats-card { background: white; border-radius: 1rem; box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1); transition: all var(--dashboard-transition-normal); overflow: hidden; position: relative; } .stats-card::before { content: ''; position: absolute; top: 0; left: 0; right: 0; height: 4px; background: linear-gradient(90deg, #3b82f6, #8b5cf6, #06b6d4); transform: scaleX(0); transform-origin: left; transition: transform var(--dashboard-transition-normal); } .stats-card:hover::before { transform: scaleX(1); } .stats-card:hover { transform: translateY(-4px); box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04); } /* Card Header */ .stats-card-header { padding: 1.5rem; border-bottom: 1px solid #f3f4f6; cursor: pointer; position: relative; overflow: hidden; } .stats-card-header::after { content: ''; position: absolute; top: 50%; left: 50%; width: 0; height: 0; background: radial-gradient(circle, rgba(59, 130, 246, 0.1) 0%, transparent 70%); transform: translate(-50%, -50%); transition: all var(--dashboard-transition-fast); pointer-events: none; } .stats-card-header:active::after { width: 300px; height: 300px; } .stats-card-title { font-size: 1.125rem; font-weight: 700; color: #1f2937; display: flex; align-items: center; gap: 0.5rem; } .stats-card-icon { width: 1.25rem; height: 1.25rem; color: #6b7280; transition: all var(--dashboard-transition-normal); } .stats-card-header:hover .stats-card-icon { color: #3b82f6; transform: rotate(5deg) scale(1.1); } .expand-icon { margin-left: auto; width: 1.25rem; height: 1.25rem; color: #9ca3af; transition: all var(--dashboard-transition-normal); } .stats-card-header[aria-expanded="true"] .expand-icon { transform: rotate(180deg); color: #3b82f6; } /* Card Content */ .stats-card-content { overflow: hidden; transition: all var(--dashboard-transition-normal); } .stats-card-content[aria-hidden="true"] { height: 0 !important; padding: 0 1.5rem; opacity: 0; } .stats-card-content[aria-hidden="false"] { padding: 1.5rem; opacity: 1; } .stats-card-body { display: grid; gap: 1rem; } /* ======================================== RESPONSIVE BEHAVIOR ======================================== */ /* Mobile-first adaptations */ @media (max-width: 768px) { .class-dashboard { padding: 0; } .trimester-nav { position: relative; background: white; border-radius: 0; } .trimester-tabs { padding: 1rem 0.5rem; gap: 0.25rem; } .trimester-tab { padding: 0.5rem 1rem; font-size: 0.875rem; min-width: fit-content; } .stats-grid { grid-template-columns: 1fr; gap: 1rem; padding: 1rem 0.5rem; } .stats-card { border-radius: 0.75rem; } .stats-card-header { padding: 1rem; } .stats-card-content[aria-hidden="false"] { padding: 1rem; } /* Accordéon behavior sur mobile */ .stats-card-content { background: #f9fafb; border-top: 1px solid #f3f4f6; } /* Touch feedback amélioré */ .trimester-tab:active, .stats-card-header:active { transform: scale(0.98); transition: transform 0.1s ease; } } /* Tablet adaptations */ @media (min-width: 769px) and (max-width: 1024px) { .stats-grid { grid-template-columns: repeat(2, 1fr); gap: 1.25rem; } .trimester-tabs { justify-content: center; gap: 0.75rem; } } /* Desktop enhancements */ @media (min-width: 1025px) { .stats-grid { grid-template-columns: repeat(auto-fit, minmax(350px, 1fr)); gap: 2rem; padding: 2rem; } .stats-card:hover { transform: translateY(-6px) scale(1.02); } .trimester-tab:not(.active):hover { transform: translateY(-3px) scale(1.05); } } /* ======================================== SKELETON LOADING ======================================== */ .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; height: 1rem; } .skeleton-item.skeleton-title { height: 1.25rem; width: 60%; margin-bottom: 0.5rem; } .skeleton-item.skeleton-text { width: 80%; margin-bottom: 0.25rem; } .skeleton-item.skeleton-number { width: 40%; height: 1.5rem; } .skeleton-container { padding: 1.5rem; display: grid; gap: 1rem; } /* ======================================== TOUCH GESTURES & ANIMATIONS ======================================== */ /* Ripple effect container */ .ripple-container { position: relative; overflow: hidden; } .ripple { position: absolute; border-radius: 50%; background: rgba(255, 255, 255, 0.6); animation: ripple 0.6s ease-out; pointer-events: none; } /* Swipe indicators */ .swipe-indicator { position: absolute; top: 50%; transform: translateY(-50%); width: 2px; height: 60px; background: linear-gradient(to bottom, transparent, #3b82f6, transparent); opacity: 0; transition: opacity var(--dashboard-transition-fast); } .swipe-indicator.left { left: 10px; animation: slideInFromLeft 0.3s ease-out; } .swipe-indicator.right { right: 10px; animation: slideInFromRight 0.3s ease-out; } .swipe-indicator.visible { opacity: 1; } /* Pull to refresh */ .pull-refresh-container { position: relative; overflow: hidden; } .pull-refresh-indicator { position: absolute; top: -60px; left: 50%; transform: translateX(-50%); width: 40px; height: 40px; border-radius: 50%; background: #3b82f6; color: white; display: flex; align-items: center; justify-content: center; transition: all var(--dashboard-transition-normal); } .pull-refresh-indicator.active { top: 20px; animation: spin 1s linear infinite; } /* ======================================== PERFORMANCE OPTIMIZATIONS ======================================== */ /* GPU acceleration pour les animations critiques */ .stats-card, .trimester-tab, .stats-card-content { will-change: transform, opacity; backface-visibility: hidden; perspective: 1000px; } /* Réduction des animations sur devices lents */ @media (hover: none) and (pointer: coarse) { .stats-card:hover { transform: none; transition-duration: 0.15s; } .trimester-tab::before { display: none; } } /* ======================================== ACCESSIBILITY ENHANCEMENTS ======================================== */ /* Focus visible amélioré */ .trimester-tab:focus-visible, .stats-card-header:focus-visible { outline: 2px solid #3b82f6; outline-offset: 2px; } /* High contrast mode support */ @media (prefers-contrast: high) { .stats-card { border: 2px solid #1f2937; } .trimester-tab.active { background: #1f2937; border-color: #1f2937; } .trimester-tab:not(.active) { background: white; border: 2px solid #6b7280; } } /* Reduced motion support */ @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; } } /* Screen reader optimizations */ .sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; } /* Annonces pour changements dynamiques */ .live-region { position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; } /* ======================================== UTILITY CLASSES ======================================== */ /* Animation delays pour effects cascades */ .animate-delay-1 { animation-delay: 0.1s; } .animate-delay-2 { animation-delay: 0.2s; } .animate-delay-3 { animation-delay: 0.3s; } .animate-delay-4 { animation-delay: 0.4s; } /* Transform utilities */ .scale-up { transform: scale(1.05); } .scale-down { transform: scale(0.95); } /* Loading states */ .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: var(--z-modal); transition: all var(--dashboard-transition-normal); } .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-card { background: linear-gradient(135deg, #fef2f2, #fee2e2); border: 1px solid #fecaca; color: #dc2626; } .error-icon { color: #ef4444; } /* Success states */ .success-card { background: linear-gradient(135deg, #f0fdf4, #dcfce7); border: 1px solid #bbf7d0; color: #16a34a; } .success-icon { color: #22c55e; } /* Dark theme preparation (future implementation) */ @media (prefers-color-scheme: dark) { :root { --dashboard-bg-primary: #1f2937; --dashboard-bg-secondary: #111827; --dashboard-text-primary: #f9fafb; --dashboard-text-secondary: #d1d5db; } /* Note: Full dark theme implementation will be added in a future phase */ }