import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import '../tokens/app_colors.dart'; import '../tokens/app_typography.dart'; /// UnionFlow Mobile App — Thème Global /// /// Palette WCAG 2.1 validée : /// Primary : #2563EB [5.7:1 ✅ WCAG AA] /// Dark mode: #0A0D1A [Navy profond] class AppTheme { // ─── THÈME CLAIR ────────────────────────────────────────────────────────── static final ThemeData lightTheme = ThemeData( useMaterial3: true, brightness: Brightness.light, primaryColor: AppColors.primary, scaffoldBackgroundColor: AppColors.background, colorScheme: const ColorScheme.light( primary: AppColors.primary, onPrimary: Colors.white, primaryContainer: AppColors.primaryContainer, onPrimaryContainer: Color(0xFF1E3A8A), secondary: AppColors.accent, onSecondary: Colors.white, tertiary: Color(0xFF5297FF), surface: AppColors.surface, onSurface: AppColors.textPrimary, error: AppColors.error, onError: Colors.white, outline: AppColors.border, ), textTheme: const TextTheme( titleMedium: AppTypography.headerSmall, bodyMedium: AppTypography.bodyTextSmall, bodySmall: AppTypography.subtitleSmall, labelLarge: AppTypography.actionText, labelSmall: AppTypography.badgeText, ).apply( bodyColor: AppColors.textPrimary, displayColor: AppColors.textPrimary, ).copyWith( // .apply() ne propage pas bodyColor aux styles label* (comportement Flutter documenté) // → on les force explicitement ici pour le light mode titleMedium: AppTypography.headerSmall.copyWith(color: AppColors.textTitle), labelLarge: AppTypography.actionText.copyWith(color: AppColors.textTitle), labelSmall: AppTypography.badgeText.copyWith(color: AppColors.textPrimary), ), appBarTheme: AppBarTheme( backgroundColor: AppColors.surface, foregroundColor: AppColors.textPrimary, elevation: 0, scrolledUnderElevation: 0, centerTitle: true, surfaceTintColor: Colors.transparent, systemOverlayStyle: const SystemUiOverlayStyle( statusBarColor: Colors.transparent, statusBarIconBrightness: Brightness.dark, ), iconTheme: const IconThemeData( color: AppColors.textPrimary, size: 20, ), titleTextStyle: AppTypography.headerSmall.copyWith( color: AppColors.textPrimary, ), ), elevatedButtonTheme: ElevatedButtonThemeData( style: ElevatedButton.styleFrom( backgroundColor: AppColors.primary, foregroundColor: Colors.white, elevation: 0, textStyle: AppTypography.actionText, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(20), ), minimumSize: const Size(64, 40), padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10), ), ), outlinedButtonTheme: OutlinedButtonThemeData( style: OutlinedButton.styleFrom( foregroundColor: AppColors.primary, side: const BorderSide(color: AppColors.primary), textStyle: AppTypography.actionText, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(20), ), minimumSize: const Size(64, 40), padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10), ), ), textButtonTheme: TextButtonThemeData( style: TextButton.styleFrom( foregroundColor: AppColors.primary, textStyle: AppTypography.actionText, ), ), inputDecorationTheme: InputDecorationTheme( filled: true, fillColor: AppColors.surface, border: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: const BorderSide(color: AppColors.border), ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: const BorderSide(color: AppColors.border), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: const BorderSide(color: AppColors.primary, width: 2), ), errorBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: const BorderSide(color: AppColors.error), ), labelStyle: const TextStyle(color: AppColors.textSecondary), hintStyle: const TextStyle(color: AppColors.textTertiary), ), bottomNavigationBarTheme: const BottomNavigationBarThemeData( backgroundColor: AppColors.surface, selectedItemColor: AppColors.primary, unselectedItemColor: AppColors.textSecondary, showSelectedLabels: false, showUnselectedLabels: false, elevation: 8, type: BottomNavigationBarType.fixed, ), chipTheme: ChipThemeData( backgroundColor: AppColors.primaryContainer, selectedColor: AppColors.primary, labelStyle: AppTypography.labelMedium, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), ), dividerTheme: const DividerThemeData( color: AppColors.border, thickness: 1, space: 1, ), cardTheme: CardThemeData( color: AppColors.surface, elevation: 0, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), side: const BorderSide(color: AppColors.border), ), margin: EdgeInsets.zero, ), snackBarTheme: SnackBarThemeData( backgroundColor: AppColors.textPrimary, contentTextStyle: AppTypography.bodyTextSmall.copyWith( color: Colors.white, ), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), behavior: SnackBarBehavior.fixed, ), ); // ─── THÈME SOMBRE (Navy Profond) ────────────────────────────────────────── static final ThemeData darkTheme = ThemeData( useMaterial3: true, brightness: Brightness.dark, primaryColor: AppColors.primaryLight, scaffoldBackgroundColor: AppColors.backgroundDark, colorScheme: const ColorScheme.dark( primary: AppColors.primaryLight, onPrimary: Color(0xFF1E3A8A), primaryContainer: Color(0xFF1A2350), onPrimaryContainer: Color(0xFFD6E8FF), secondary: AppColors.accentLight, onSecondary: Color(0xFF2A006F), surface: AppColors.surfaceDark, onSurface: AppColors.textPrimaryDark, error: AppColors.error, onError: Colors.white, outline: AppColors.borderDark, ), textTheme: const TextTheme( titleMedium: AppTypography.headerSmall, bodyMedium: AppTypography.bodyTextSmall, bodySmall: AppTypography.subtitleSmall, labelLarge: AppTypography.actionText, labelSmall: AppTypography.badgeText, ).apply( bodyColor: AppColors.textPrimaryDark, displayColor: AppColors.textPrimaryDark, ).copyWith( // .apply() ne propage pas bodyColor aux styles label* (comportement Flutter documenté) // → on les force explicitement ici pour le dark mode titleMedium: AppTypography.headerSmall.copyWith(color: AppColors.textTitleDark), labelLarge: AppTypography.actionText.copyWith(color: AppColors.textTitleDark), labelSmall: AppTypography.badgeText.copyWith(color: AppColors.textPrimaryDark), ), appBarTheme: AppBarTheme( backgroundColor: AppColors.backgroundDark, foregroundColor: AppColors.textPrimaryDark, elevation: 0, scrolledUnderElevation: 0, centerTitle: true, surfaceTintColor: Colors.transparent, systemOverlayStyle: const SystemUiOverlayStyle( statusBarColor: Colors.transparent, statusBarIconBrightness: Brightness.light, ), iconTheme: const IconThemeData( color: AppColors.textPrimaryDark, size: 20, ), titleTextStyle: AppTypography.headerSmall.copyWith( color: AppColors.textPrimaryDark, ), ), elevatedButtonTheme: ElevatedButtonThemeData( style: ElevatedButton.styleFrom( backgroundColor: AppColors.primary, foregroundColor: Colors.white, elevation: 0, textStyle: AppTypography.actionText, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(20), ), minimumSize: const Size(64, 40), padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10), ), ), outlinedButtonTheme: OutlinedButtonThemeData( style: OutlinedButton.styleFrom( foregroundColor: AppColors.primaryLight, side: const BorderSide(color: AppColors.primaryLight), textStyle: AppTypography.actionText, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(20), ), minimumSize: const Size(64, 40), padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10), ), ), textButtonTheme: TextButtonThemeData( style: TextButton.styleFrom( foregroundColor: AppColors.primaryLight, textStyle: AppTypography.actionText, ), ), inputDecorationTheme: InputDecorationTheme( filled: true, fillColor: AppColors.surfaceDark, border: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: const BorderSide(color: AppColors.borderDark), ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: const BorderSide(color: AppColors.borderDark), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: const BorderSide(color: AppColors.primaryLight, width: 2), ), errorBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: const BorderSide(color: AppColors.error), ), labelStyle: const TextStyle(color: AppColors.textSecondaryDark), hintStyle: TextStyle(color: AppColors.textSecondaryDark.withOpacity(0.6)), ), bottomNavigationBarTheme: const BottomNavigationBarThemeData( backgroundColor: AppColors.backgroundDark, selectedItemColor: AppColors.primaryLight, unselectedItemColor: AppColors.textSecondaryDark, showSelectedLabels: false, showUnselectedLabels: false, elevation: 8, type: BottomNavigationBarType.fixed, ), dividerTheme: const DividerThemeData( color: AppColors.borderDark, thickness: 1, space: 1, ), cardTheme: CardThemeData( color: AppColors.surfaceDark, elevation: 0, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), side: const BorderSide(color: AppColors.borderDark), ), margin: EdgeInsets.zero, ), snackBarTheme: SnackBarThemeData( backgroundColor: AppColors.surfaceDark, contentTextStyle: AppTypography.bodyTextSmall.copyWith( color: AppColors.textPrimaryDark, ), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), behavior: SnackBarBehavior.fixed, ), ); }