import 'package:flutter/material.dart'; import 'app_theme.dart'; /// Design System UnionFlow basé sur le nombre d'or et Material Design 3 class DesignSystem { // === NOMBRE D'OR ET PROPORTIONS === static const double goldenRatio = 1.618; static const double inverseGoldenRatio = 0.618; // === ESPACEMENTS BASÉS SUR LE NOMBRE D'OR === static const double baseUnit = 8.0; // Espacements principaux (progression géométrique basée sur le nombre d'or) static const double spacing2xs = baseUnit * 0.5; // 4px static const double spacingXs = baseUnit; // 8px static const double spacingSm = baseUnit * 1.5; // 12px static const double spacingMd = baseUnit * 2; // 16px static const double spacingLg = baseUnit * 3; // 24px static const double spacingXl = baseUnit * 4; // 32px static const double spacing2xl = baseUnit * 6; // 48px static const double spacing3xl = baseUnit * 8; // 64px // Espacements spéciaux basés sur le nombre d'or static const double spacingGolden = spacingMd * goldenRatio; // ~26px static const double spacingGoldenLarge = spacingLg * goldenRatio; // ~39px // === RAYONS DE BORDURE === static const double radiusXs = 4.0; static const double radiusSm = 8.0; static const double radiusMd = 12.0; static const double radiusLg = 16.0; static const double radiusXl = 20.0; static const double radius2xl = 24.0; // === ÉLÉVATIONS ET OMBRES === static const double elevationCard = 2.0; static const double elevationModal = 8.0; static const double elevationAppBar = 0.0; // Ombres personnalisées static List get shadowCard => [ BoxShadow( color: Colors.black.withOpacity(0.04), blurRadius: 8, offset: const Offset(0, 2), ), BoxShadow( color: Colors.black.withOpacity(0.02), blurRadius: 16, offset: const Offset(0, 4), ), ]; static List get shadowCardHover => [ BoxShadow( color: Colors.black.withOpacity(0.08), blurRadius: 16, offset: const Offset(0, 4), ), BoxShadow( color: Colors.black.withOpacity(0.04), blurRadius: 32, offset: const Offset(0, 8), ), ]; static List get shadowModal => [ BoxShadow( color: Colors.black.withOpacity(0.12), blurRadius: 24, offset: const Offset(0, 8), ), BoxShadow( color: Colors.black.withOpacity(0.08), blurRadius: 48, offset: const Offset(0, 16), ), ]; // === TYPOGRAPHIE AVANCÉE === static const TextStyle displayLarge = TextStyle( fontSize: 40, fontWeight: FontWeight.w800, letterSpacing: -0.5, height: 1.2, color: AppTheme.textPrimary, ); static const TextStyle displayMedium = TextStyle( fontSize: 32, fontWeight: FontWeight.w700, letterSpacing: -0.25, height: 1.25, color: AppTheme.textPrimary, ); static const TextStyle headlineLarge = TextStyle( fontSize: 28, fontWeight: FontWeight.w600, letterSpacing: 0, height: 1.3, color: AppTheme.textPrimary, ); static const TextStyle headlineMedium = TextStyle( fontSize: 24, fontWeight: FontWeight.w600, letterSpacing: 0, height: 1.33, color: AppTheme.textPrimary, ); static const TextStyle titleLarge = TextStyle( fontSize: 20, fontWeight: FontWeight.w600, letterSpacing: 0, height: 1.4, color: AppTheme.textPrimary, ); static const TextStyle titleMedium = TextStyle( fontSize: 16, fontWeight: FontWeight.w500, letterSpacing: 0.1, height: 1.5, color: AppTheme.textPrimary, ); static const TextStyle bodyLarge = TextStyle( fontSize: 16, fontWeight: FontWeight.w400, letterSpacing: 0.15, height: 1.5, color: AppTheme.textPrimary, ); static const TextStyle bodyMedium = TextStyle( fontSize: 14, fontWeight: FontWeight.w400, letterSpacing: 0.25, height: 1.43, color: AppTheme.textPrimary, ); static const TextStyle labelLarge = TextStyle( fontSize: 14, fontWeight: FontWeight.w500, letterSpacing: 0.1, height: 1.43, color: AppTheme.textPrimary, ); static const TextStyle labelMedium = TextStyle( fontSize: 12, fontWeight: FontWeight.w500, letterSpacing: 0.5, height: 1.33, color: AppTheme.textSecondary, ); static const TextStyle labelSmall = TextStyle( fontSize: 10, fontWeight: FontWeight.w500, letterSpacing: 0.5, height: 1.2, color: AppTheme.textHint, ); // === COULEURS ÉTENDUES === // Palette de couleurs pour les graphiques (harmonieuse et accessible) static const List chartColors = [ Color(0xFF2196F3), // Bleu principal Color(0xFF4CAF50), // Vert Color(0xFFFF9800), // Orange Color(0xFF9C27B0), // Violet Color(0xFFF44336), // Rouge Color(0xFF00BCD4), // Cyan Color(0xFFFFEB3B), // Jaune Color(0xFF795548), // Marron Color(0xFF607D8B), // Bleu gris Color(0xFFE91E63), // Rose ]; // Couleurs de gradient static const LinearGradient primaryGradient = LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: [ AppTheme.primaryColor, AppTheme.primaryLight, ], ); static const LinearGradient successGradient = LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: [ AppTheme.successColor, AppTheme.secondaryLight, ], ); static const LinearGradient warningGradient = LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: [ AppTheme.warningColor, Color(0xFFFFB74D), ], ); static const LinearGradient errorGradient = LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: [ AppTheme.errorColor, Color(0xFFEF5350), ], ); // === ANIMATIONS ET TRANSITIONS === static const Duration animationFast = Duration(milliseconds: 150); static const Duration animationMedium = Duration(milliseconds: 300); static const Duration animationSlow = Duration(milliseconds: 500); static const Curve animationCurve = Curves.easeInOutCubic; static const Curve animationCurveEnter = Curves.easeOut; static const Curve animationCurveExit = Curves.easeIn; // === BREAKPOINTS RESPONSIVE === static const double breakpointMobile = 480; static const double breakpointTablet = 768; static const double breakpointDesktop = 1024; // === UTILITAIRES === static bool isMobile(BuildContext context) { return MediaQuery.of(context).size.width < breakpointMobile; } static bool isTablet(BuildContext context) { final width = MediaQuery.of(context).size.width; return width >= breakpointMobile && width < breakpointDesktop; } static bool isDesktop(BuildContext context) { return MediaQuery.of(context).size.width >= breakpointDesktop; } // Calcul de dimensions basées sur le nombre d'or static double goldenWidth(double height) => height * goldenRatio; static double goldenHeight(double width) => width * inverseGoldenRatio; // Espacement adaptatif basé sur la taille d'écran static double adaptiveSpacing(BuildContext context, { double mobile = spacingMd, double tablet = spacingLg, double desktop = spacingXl, }) { if (isMobile(context)) return mobile; if (isTablet(context)) return tablet; return desktop; } }