import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:worker/core/theme/colors.dart'; import 'package:worker/core/theme/typography.dart'; /// App theme configuration for Material 3 design system /// Provides both light and dark theme variants class AppTheme { // Prevent instantiation AppTheme._(); // ==================== Light Theme ==================== /// Light theme configuration static ThemeData lightTheme() { final ColorScheme colorScheme = ColorScheme.fromSeed( seedColor: AppColors.primaryBlue, brightness: Brightness.light, primary: AppColors.primaryBlue, secondary: AppColors.lightBlue, tertiary: AppColors.accentCyan, error: AppColors.danger, surface: AppColors.white, background: AppColors.grey50, ); return ThemeData( useMaterial3: true, colorScheme: colorScheme, fontFamily: AppTypography.fontFamily, // ==================== App Bar Theme ==================== appBarTheme: AppBarTheme( elevation: 0, centerTitle: true, backgroundColor: AppColors.primaryBlue, foregroundColor: AppColors.white, titleTextStyle: AppTypography.titleLarge.copyWith( color: AppColors.white, fontWeight: FontWeight.w600, ), iconTheme: const IconThemeData( color: AppColors.white, size: 24, ), systemOverlayStyle: SystemUiOverlayStyle.light, ), // ==================== Card Theme ==================== cardTheme: const CardThemeData( elevation: 2, shape: RoundedRectangleBorder( borderRadius: BorderRadius.all(Radius.circular(12)), ), clipBehavior: Clip.antiAlias, color: AppColors.white, margin: EdgeInsets.symmetric(horizontal: 16, vertical: 8), ), // ==================== Elevated Button Theme ==================== elevatedButtonTheme: ElevatedButtonThemeData( style: ElevatedButton.styleFrom( backgroundColor: AppColors.primaryBlue, foregroundColor: AppColors.white, elevation: 2, padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), textStyle: AppTypography.buttonText, minimumSize: const Size(64, 48), ), ), // ==================== Text Button Theme ==================== textButtonTheme: TextButtonThemeData( style: TextButton.styleFrom( foregroundColor: AppColors.primaryBlue, padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), textStyle: AppTypography.buttonText, ), ), // ==================== Outlined Button Theme ==================== outlinedButtonTheme: OutlinedButtonThemeData( style: OutlinedButton.styleFrom( foregroundColor: AppColors.primaryBlue, side: const BorderSide(color: AppColors.primaryBlue, width: 1.5), padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), textStyle: AppTypography.buttonText, minimumSize: const Size(64, 48), ), ), // ==================== Input Decoration Theme ==================== inputDecorationTheme: InputDecorationTheme( filled: true, fillColor: AppColors.white, contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 16), border: OutlineInputBorder( borderRadius: BorderRadius.circular(8), borderSide: const BorderSide(color: AppColors.grey100, width: 1), ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(8), borderSide: const BorderSide(color: AppColors.grey100, width: 1), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(8), borderSide: const BorderSide(color: AppColors.primaryBlue, width: 2), ), errorBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(8), borderSide: const BorderSide(color: AppColors.danger, width: 1), ), focusedErrorBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(8), borderSide: const BorderSide(color: AppColors.danger, width: 2), ), labelStyle: AppTypography.bodyMedium.copyWith( color: AppColors.grey500, ), hintStyle: AppTypography.bodyMedium.copyWith( color: AppColors.grey500, ), errorStyle: AppTypography.bodySmall.copyWith( color: AppColors.danger, ), ), // ==================== Bottom Navigation Bar Theme ==================== bottomNavigationBarTheme: const BottomNavigationBarThemeData( backgroundColor: AppColors.white, selectedItemColor: AppColors.primaryBlue, unselectedItemColor: AppColors.grey500, selectedIconTheme: IconThemeData( size: 28, color: AppColors.primaryBlue, ), unselectedIconTheme: IconThemeData( size: 24, color: AppColors.grey500, ), selectedLabelStyle: TextStyle( fontSize: 12, fontWeight: FontWeight.w600, fontFamily: AppTypography.fontFamily, ), unselectedLabelStyle: TextStyle( fontSize: 12, fontWeight: FontWeight.normal, fontFamily: AppTypography.fontFamily, ), type: BottomNavigationBarType.fixed, elevation: 8, ), // ==================== Floating Action Button Theme ==================== floatingActionButtonTheme: const FloatingActionButtonThemeData( backgroundColor: AppColors.accentCyan, foregroundColor: AppColors.white, elevation: 6, shape: CircleBorder(), iconSize: 24, ), // ==================== Chip Theme ==================== chipTheme: ChipThemeData( backgroundColor: AppColors.grey50, selectedColor: AppColors.primaryBlue, disabledColor: AppColors.grey100, secondarySelectedColor: AppColors.lightBlue, labelStyle: AppTypography.labelMedium, secondaryLabelStyle: AppTypography.labelMedium.copyWith( color: AppColors.white, ), padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16), ), ), // ==================== Dialog Theme ==================== dialogTheme: const DialogThemeData( backgroundColor: AppColors.white, elevation: 8, shape: RoundedRectangleBorder( borderRadius: BorderRadius.all(Radius.circular(16)), ), ).copyWith( titleTextStyle: AppTypography.headlineMedium.copyWith( color: AppColors.grey900, ), contentTextStyle: AppTypography.bodyLarge.copyWith( color: AppColors.grey900, ), ), // ==================== Snackbar Theme ==================== snackBarTheme: SnackBarThemeData( backgroundColor: AppColors.grey900, contentTextStyle: AppTypography.bodyMedium.copyWith( color: AppColors.white, ), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), behavior: SnackBarBehavior.floating, elevation: 4, ), // ==================== Divider Theme ==================== dividerTheme: const DividerThemeData( color: AppColors.grey100, thickness: 1, space: 1, ), // ==================== Icon Theme ==================== iconTheme: const IconThemeData( color: AppColors.grey900, size: 24, ), // ==================== List Tile Theme ==================== listTileTheme: ListTileThemeData( contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), titleTextStyle: AppTypography.titleMedium.copyWith( color: AppColors.grey900, ), subtitleTextStyle: AppTypography.bodyMedium.copyWith( color: AppColors.grey500, ), iconColor: AppColors.grey500, ), // ==================== Switch Theme ==================== switchTheme: SwitchThemeData( thumbColor: MaterialStateProperty.resolveWith((states) { if (states.contains(MaterialState.selected)) { return AppColors.primaryBlue; } return AppColors.grey500; }), trackColor: MaterialStateProperty.resolveWith((states) { if (states.contains(MaterialState.selected)) { return AppColors.lightBlue; } return AppColors.grey100; }), ), // ==================== Checkbox Theme ==================== checkboxTheme: CheckboxThemeData( fillColor: MaterialStateProperty.resolveWith((states) { if (states.contains(MaterialState.selected)) { return AppColors.primaryBlue; } return AppColors.white; }), checkColor: MaterialStateProperty.all(AppColors.white), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(4), ), ), // ==================== Radio Theme ==================== radioTheme: RadioThemeData( fillColor: MaterialStateProperty.resolveWith((states) { if (states.contains(MaterialState.selected)) { return AppColors.primaryBlue; } return AppColors.grey500; }), ), // ==================== Progress Indicator Theme ==================== progressIndicatorTheme: const ProgressIndicatorThemeData( color: AppColors.primaryBlue, linearTrackColor: AppColors.grey100, circularTrackColor: AppColors.grey100, ), // ==================== Badge Theme ==================== badgeTheme: const BadgeThemeData( backgroundColor: AppColors.danger, textColor: AppColors.white, smallSize: 6, largeSize: 16, ), // ==================== Tab Bar Theme ==================== tabBarTheme: const TabBarThemeData( labelColor: AppColors.primaryBlue, unselectedLabelColor: AppColors.grey500, indicatorColor: AppColors.primaryBlue, ).copyWith( labelStyle: AppTypography.labelLarge, unselectedLabelStyle: AppTypography.labelLarge, ), ); } // ==================== Dark Theme ==================== /// Dark theme configuration static ThemeData darkTheme() { final ColorScheme colorScheme = ColorScheme.fromSeed( seedColor: AppColors.primaryBlue, brightness: Brightness.dark, primary: AppColors.lightBlue, secondary: AppColors.accentCyan, tertiary: AppColors.primaryBlue, error: AppColors.danger, surface: const Color(0xFF1E1E1E), background: const Color(0xFF121212), ); return ThemeData( useMaterial3: true, colorScheme: colorScheme, fontFamily: AppTypography.fontFamily, // ==================== App Bar Theme ==================== appBarTheme: AppBarTheme( elevation: 0, centerTitle: true, backgroundColor: const Color(0xFF1E1E1E), foregroundColor: AppColors.white, titleTextStyle: AppTypography.titleLarge.copyWith( color: AppColors.white, fontWeight: FontWeight.w600, ), iconTheme: const IconThemeData( color: AppColors.white, size: 24, ), systemOverlayStyle: SystemUiOverlayStyle.light, ), // ==================== Card Theme ==================== cardTheme: const CardThemeData( elevation: 2, shape: RoundedRectangleBorder( borderRadius: BorderRadius.all(Radius.circular(12)), ), clipBehavior: Clip.antiAlias, color: Color(0xFF1E1E1E), margin: EdgeInsets.symmetric(horizontal: 16, vertical: 8), ), // ==================== Elevated Button Theme ==================== elevatedButtonTheme: ElevatedButtonThemeData( style: ElevatedButton.styleFrom( backgroundColor: AppColors.lightBlue, foregroundColor: AppColors.white, elevation: 2, padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), textStyle: AppTypography.buttonText, minimumSize: const Size(64, 48), ), ), // ==================== Input Decoration Theme ==================== inputDecorationTheme: InputDecorationTheme( filled: true, fillColor: const Color(0xFF2A2A2A), contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 16), border: OutlineInputBorder( borderRadius: BorderRadius.circular(8), borderSide: const BorderSide(color: Color(0xFF3A3A3A), width: 1), ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(8), borderSide: const BorderSide(color: Color(0xFF3A3A3A), width: 1), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(8), borderSide: const BorderSide(color: AppColors.lightBlue, width: 2), ), errorBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(8), borderSide: const BorderSide(color: AppColors.danger, width: 1), ), focusedErrorBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(8), borderSide: const BorderSide(color: AppColors.danger, width: 2), ), labelStyle: AppTypography.bodyMedium.copyWith( color: AppColors.grey500, ), hintStyle: AppTypography.bodyMedium.copyWith( color: AppColors.grey500, ), errorStyle: AppTypography.bodySmall.copyWith( color: AppColors.danger, ), ), // ==================== Bottom Navigation Bar Theme ==================== bottomNavigationBarTheme: const BottomNavigationBarThemeData( backgroundColor: Color(0xFF1E1E1E), selectedItemColor: AppColors.lightBlue, unselectedItemColor: AppColors.grey500, selectedIconTheme: IconThemeData( size: 28, color: AppColors.lightBlue, ), unselectedIconTheme: IconThemeData( size: 24, color: AppColors.grey500, ), selectedLabelStyle: TextStyle( fontSize: 12, fontWeight: FontWeight.w600, fontFamily: AppTypography.fontFamily, ), unselectedLabelStyle: TextStyle( fontSize: 12, fontWeight: FontWeight.normal, fontFamily: AppTypography.fontFamily, ), type: BottomNavigationBarType.fixed, elevation: 8, ), // ==================== Floating Action Button Theme ==================== floatingActionButtonTheme: const FloatingActionButtonThemeData( backgroundColor: AppColors.accentCyan, foregroundColor: AppColors.white, elevation: 6, shape: CircleBorder(), iconSize: 24, ), // ==================== Snackbar Theme ==================== snackBarTheme: SnackBarThemeData( backgroundColor: const Color(0xFF2A2A2A), contentTextStyle: AppTypography.bodyMedium.copyWith( color: AppColors.white, ), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), behavior: SnackBarBehavior.floating, elevation: 4, ), ); } }