import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'app_colors.dart'; import 'app_theme.dart'; /// 적응형 테마 관리 클래스 class AdaptiveTheme { /// 라이트 테마 static ThemeData get lightTheme => AppTheme.lightTheme; /// 다크 테마 static ThemeData get darkTheme { return ThemeData( useMaterial3: true, brightness: Brightness.dark, colorScheme: const ColorScheme.dark( primary: AppColors.primaryColor, onPrimary: Colors.white, secondary: AppColors.secondaryColor, tertiary: AppColors.infoColor, error: AppColors.dangerColor, background: const Color(0xFF121212), surface: const Color(0xFF1E1E1E), ), scaffoldBackgroundColor: const Color(0xFF121212), cardTheme: CardTheme( color: const Color(0xFF1E1E1E), elevation: 2, shadowColor: Colors.black.withValues(alpha: 0.3), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16), side: BorderSide(color: Colors.white.withValues(alpha: 0.1), width: 0.5), ), clipBehavior: Clip.antiAlias, margin: const EdgeInsets.symmetric(vertical: 8, horizontal: 16), ), appBarTheme: AppBarTheme( backgroundColor: const Color(0xFF1E1E1E), foregroundColor: Colors.white, elevation: 0, centerTitle: false, titleTextStyle: const TextStyle( color: Colors.white, fontSize: 22, fontWeight: FontWeight.w600, letterSpacing: -0.2, ), iconTheme: IconThemeData( color: Colors.white.withValues(alpha: 0.9), size: 24, ), ), textTheme: TextTheme( headlineLarge: const TextStyle( color: Colors.white, fontSize: 32, fontWeight: FontWeight.w700, letterSpacing: -0.5, height: 1.2, ), headlineMedium: const TextStyle( color: Colors.white, fontSize: 28, fontWeight: FontWeight.w700, letterSpacing: -0.5, height: 1.2, ), headlineSmall: const TextStyle( color: Colors.white, fontSize: 24, fontWeight: FontWeight.w600, letterSpacing: -0.25, height: 1.3, ), titleLarge: const TextStyle( color: Colors.white, fontSize: 20, fontWeight: FontWeight.w600, letterSpacing: -0.2, height: 1.4, ), titleMedium: const TextStyle( color: Colors.white, fontSize: 18, fontWeight: FontWeight.w600, letterSpacing: -0.1, height: 1.4, ), titleSmall: const TextStyle( color: Colors.white, fontSize: 16, fontWeight: FontWeight.w600, letterSpacing: 0, height: 1.4, ), bodyLarge: TextStyle( color: Colors.white.withValues(alpha: 0.9), fontSize: 16, fontWeight: FontWeight.w400, letterSpacing: 0.1, height: 1.5, ), bodyMedium: TextStyle( color: Colors.white.withValues(alpha: 0.7), fontSize: 14, fontWeight: FontWeight.w400, letterSpacing: 0.1, height: 1.5, ), bodySmall: TextStyle( color: Colors.white.withValues(alpha: 0.5), fontSize: 12, fontWeight: FontWeight.w400, letterSpacing: 0.2, height: 1.5, ), ), inputDecorationTheme: InputDecorationTheme( filled: true, fillColor: const Color(0xFF2A2A2A), contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 16), border: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: BorderSide.none, ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: BorderSide(color: Colors.white.withValues(alpha: 0.1), width: 1), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: const BorderSide(color: AppColors.primaryColor, width: 1.5), ), errorBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: const BorderSide(color: AppColors.dangerColor, width: 1), ), labelStyle: TextStyle( color: Colors.white.withValues(alpha: 0.7), fontSize: 14, fontWeight: FontWeight.w500, ), hintStyle: TextStyle( color: Colors.white.withValues(alpha: 0.5), fontSize: 14, fontWeight: FontWeight.w400, ), ), elevatedButtonTheme: ElevatedButtonThemeData( style: ElevatedButton.styleFrom( backgroundColor: AppColors.primaryColor, foregroundColor: Colors.white, minimumSize: const Size(0, 48), padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 12), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), elevation: 0, ), ), dividerTheme: DividerThemeData( color: Colors.white.withValues(alpha: 0.1), thickness: 1, space: 16, ), ); } /// OLED 최적화 다크 테마 static ThemeData get oledTheme { return darkTheme.copyWith( scaffoldBackgroundColor: Colors.black, colorScheme: darkTheme.colorScheme.copyWith( background: Colors.black, surface: const Color(0xFF0A0A0A), ), cardTheme: darkTheme.cardTheme.copyWith( color: const Color(0xFF0A0A0A), ), appBarTheme: darkTheme.appBarTheme.copyWith( backgroundColor: Colors.black, ), inputDecorationTheme: darkTheme.inputDecorationTheme.copyWith( fillColor: const Color(0xFF0A0A0A), ), ); } /// 고대비 테마 static ThemeData get highContrastTheme { return ThemeData( useMaterial3: true, brightness: Brightness.light, colorScheme: const ColorScheme.highContrastLight( primary: Colors.black, secondary: Colors.black87, tertiary: Colors.black54, error: Colors.red, background: Colors.white, surface: Colors.white, ), textTheme: const TextTheme( headlineLarge: TextStyle( color: Colors.black, fontSize: 32, fontWeight: FontWeight.w900, ), headlineMedium: TextStyle( color: Colors.black, fontSize: 28, fontWeight: FontWeight.w900, ), headlineSmall: TextStyle( color: Colors.black, fontSize: 24, fontWeight: FontWeight.w800, ), bodyLarge: TextStyle( color: Colors.black, fontSize: 16, fontWeight: FontWeight.w600, ), bodyMedium: TextStyle( color: Colors.black87, fontSize: 14, fontWeight: FontWeight.w500, ), ), cardTheme: CardTheme( elevation: 0, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), side: const BorderSide(color: Colors.black, width: 2), ), ), elevatedButtonTheme: ElevatedButtonThemeData( style: ElevatedButton.styleFrom( backgroundColor: Colors.black, foregroundColor: Colors.white, side: const BorderSide(color: Colors.black, width: 2), textStyle: const TextStyle( fontWeight: FontWeight.w700, ), ), ), ); } /// 시스템 테마에 따른 상태바 스타일 적용 static void applySystemUIOverlay(BuildContext context) { final brightness = Theme.of(context).brightness; final isOled = Theme.of(context).scaffoldBackgroundColor == Colors.black; SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle( statusBarColor: Colors.transparent, statusBarIconBrightness: brightness == Brightness.dark ? Brightness.light : Brightness.dark, statusBarBrightness: brightness == Brightness.dark ? Brightness.light : Brightness.dark, systemNavigationBarColor: isOled ? Colors.black : (brightness == Brightness.dark ? const Color(0xFF121212) : Colors.white), systemNavigationBarIconBrightness: brightness == Brightness.dark ? Brightness.light : Brightness.dark, )); } /// 접근성 설정에 따른 테마 조정 static ThemeData getAccessibleTheme( ThemeData baseTheme, { required bool largeText, required bool reduceMotion, required bool highContrast, }) { if (highContrast) { return highContrastTheme; } ThemeData theme = baseTheme; if (largeText) { theme = theme.copyWith( textTheme: theme.textTheme.apply( fontSizeFactor: 1.2, ), ); } if (reduceMotion) { theme = theme.copyWith( pageTransitionsTheme: const PageTransitionsTheme( builders: { TargetPlatform.android: FadeUpwardsPageTransitionsBuilder(), TargetPlatform.iOS: FadeUpwardsPageTransitionsBuilder(), }, ), ); } return theme; } } /// 테마 모드 열거형 enum AppThemeMode { light, dark, oled, system, } /// 테마 설정 클래스 class ThemeSettings { final AppThemeMode mode; final bool useSystemColors; final bool largeText; final bool reduceMotion; final bool highContrast; const ThemeSettings({ this.mode = AppThemeMode.system, this.useSystemColors = false, this.largeText = false, this.reduceMotion = false, this.highContrast = false, }); ThemeSettings copyWith({ AppThemeMode? mode, bool? useSystemColors, bool? largeText, bool? reduceMotion, bool? highContrast, }) { return ThemeSettings( mode: mode ?? this.mode, useSystemColors: useSystemColors ?? this.useSystemColors, largeText: largeText ?? this.largeText, reduceMotion: reduceMotion ?? this.reduceMotion, highContrast: highContrast ?? this.highContrast, ); } Map toJson() => { 'mode': mode.name, 'useSystemColors': useSystemColors, 'largeText': largeText, 'reduceMotion': reduceMotion, 'highContrast': highContrast, }; factory ThemeSettings.fromJson(Map json) { return ThemeSettings( mode: AppThemeMode.values.firstWhere( (mode) => mode.name == json['mode'], orElse: () => AppThemeMode.system, ), useSystemColors: json['useSystemColors'] ?? false, largeText: json['largeText'] ?? false, reduceMotion: json['reduceMotion'] ?? false, highContrast: json['highContrast'] ?? false, ); } }