import 'package:flutter/material.dart'; import 'app_colors.dart'; class AppTheme { static ThemeData lightTheme = (() { // Color scheme for light theme const scheme = ColorScheme.light( primary: AppColors.primaryColor, onPrimary: Colors.white, secondary: AppColors.secondaryColor, tertiary: AppColors.infoColor, error: AppColors.errorColor, surface: AppColors.surfaceColor, ); return ThemeData( useMaterial3: true, colorScheme: scheme, // 기본 배경색 scaffoldBackgroundColor: AppColors.backgroundColor, // 카드 스타일 - Material 3 표면 중심 cardTheme: CardThemeData( elevation: 1, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16), ), margin: const EdgeInsets.symmetric(vertical: 8, horizontal: 16), ), // 앱바 스타일 - 기본 M3 사용(투명 배경 유지) appBarTheme: const AppBarTheme( backgroundColor: Colors.transparent, elevation: 0, centerTitle: false, ), // 타이포그래피 - Material 3 + onSurface 정렬 textTheme: ThemeData.light(useMaterial3: true) .textTheme .copyWith( headlineLarge: const TextStyle( fontSize: 32, fontWeight: FontWeight.w700, letterSpacing: -0.5, height: 1.2, ), headlineMedium: const TextStyle( fontSize: 28, fontWeight: FontWeight.w700, letterSpacing: -0.5, height: 1.2, ), headlineSmall: const TextStyle( fontSize: 24, fontWeight: FontWeight.w600, letterSpacing: -0.25, height: 1.3, ), titleLarge: const TextStyle( fontSize: 20, fontWeight: FontWeight.w600, letterSpacing: -0.2, height: 1.4, ), titleMedium: const TextStyle( fontSize: 18, fontWeight: FontWeight.w600, letterSpacing: -0.1, height: 1.4, ), titleSmall: const TextStyle( fontSize: 16, fontWeight: FontWeight.w600, height: 1.4, ), bodyLarge: const TextStyle( fontSize: 16, fontWeight: FontWeight.w400, letterSpacing: 0.1, height: 1.5, ), bodyMedium: const TextStyle( fontSize: 14, fontWeight: FontWeight.w400, letterSpacing: 0.1, height: 1.5, ), bodySmall: const TextStyle( fontSize: 12, fontWeight: FontWeight.w400, letterSpacing: 0.2, height: 1.5, ), labelLarge: const TextStyle( fontSize: 14, fontWeight: FontWeight.w600, letterSpacing: 0.1, height: 1.4, ), labelMedium: const TextStyle( fontSize: 12, fontWeight: FontWeight.w600, letterSpacing: 0.2, height: 1.4, ), labelSmall: const TextStyle( fontSize: 11, fontWeight: FontWeight.w500, letterSpacing: 0.2, height: 1.4, ), ) .apply( // 본문/헤드라인 공통 색상은 onSurface로 적용 bodyColor: scheme.onSurface, displayColor: scheme.onSurface, ), // 입력 필드 스타일 - M3 surface/outline 기반 inputDecorationTheme: InputDecorationTheme( filled: true, fillColor: scheme.surface, 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: scheme.outline, width: 1), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: BorderSide(color: scheme.primary, width: 1.5), ), errorBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: BorderSide(color: scheme.error, width: 1), ), focusedErrorBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: BorderSide(color: scheme.error, width: 1.5), ), labelStyle: TextStyle( color: scheme.onSurfaceVariant, fontSize: 14, fontWeight: FontWeight.w500, ), hintStyle: TextStyle( color: scheme.onSurfaceVariant, fontSize: 14, fontWeight: FontWeight.w400, ), errorStyle: TextStyle( color: scheme.error, fontSize: 12, fontWeight: FontWeight.w400, ), ), // 버튼 스타일 - 프라이머리 버튼 elevatedButtonTheme: ElevatedButtonThemeData( style: ElevatedButton.styleFrom( backgroundColor: scheme.primary, foregroundColor: scheme.onPrimary, minimumSize: const Size(0, 48), padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 12), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), elevation: 0, ), ), // 텍스트 버튼 스타일 textButtonTheme: TextButtonThemeData( style: TextButton.styleFrom( foregroundColor: scheme.primary, minimumSize: const Size(0, 40), padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), // Text style inherits from theme.labelLarge ), ), // 아웃라인 버튼 스타일 outlinedButtonTheme: OutlinedButtonThemeData( style: OutlinedButton.styleFrom( foregroundColor: scheme.primary, minimumSize: const Size(0, 48), padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 12), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), side: BorderSide(color: scheme.outline, width: 1), ), ), // FAB 스타일 floatingActionButtonTheme: FloatingActionButtonThemeData( backgroundColor: scheme.primary, foregroundColor: scheme.onPrimary, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16), ), elevation: 2, extendedPadding: const EdgeInsets.symmetric(horizontal: 24, vertical: 16), extendedTextStyle: const TextStyle( fontSize: 15, fontWeight: FontWeight.w600, letterSpacing: 0.1, ), ), // 스위치 스타일 (공통 테마) switchTheme: SwitchThemeData( thumbColor: WidgetStateProperty.resolveWith((states) { if (states.contains(WidgetState.selected)) { return scheme.primary; } return scheme.onSurfaceVariant; // OFF 썸을 명확하게 }), trackColor: WidgetStateProperty.resolveWith((states) { if (states.contains(WidgetState.selected)) { return scheme.primary.withValues(alpha: 0.5); } // OFF 트랙 대비 강화 return scheme.surfaceContainerHighest.withValues(alpha: 0.5); }), ), // 체크박스 스타일 checkboxTheme: CheckboxThemeData( fillColor: WidgetStateProperty.resolveWith((states) { if (states.contains(WidgetState.selected)) { return scheme.primary; } return Colors.transparent; }), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(4), ), side: BorderSide(color: scheme.outline, width: 1.5), ), // 라디오 버튼 스타일 radioTheme: RadioThemeData( fillColor: WidgetStateProperty.resolveWith((states) { if (states.contains(WidgetState.selected)) { return scheme.primary; } return scheme.onSurfaceVariant; }), ), // 슬라이더 스타일 sliderTheme: SliderThemeData( activeTrackColor: scheme.primary, inactiveTrackColor: scheme.onSurfaceVariant, thumbColor: scheme.primary, overlayColor: scheme.primary.withValues(alpha: 0.3), trackHeight: 4, thumbShape: const RoundSliderThumbShape(enabledThumbRadius: 10), overlayShape: const RoundSliderOverlayShape(overlayRadius: 20), ), // 탭바 스타일 tabBarTheme: TabBarThemeData( labelColor: scheme.primary, unselectedLabelColor: scheme.onSurfaceVariant, indicatorColor: scheme.primary, labelStyle: const TextStyle( fontSize: 14, fontWeight: FontWeight.w600, letterSpacing: 0.1, ), unselectedLabelStyle: const TextStyle( fontSize: 14, fontWeight: FontWeight.w500, letterSpacing: 0.1, ), ), // 디바이더 스타일 dividerTheme: DividerThemeData( color: scheme.outline, thickness: 1, space: 16, ), // 페이지 트랜지션 pageTransitionsTheme: const PageTransitionsTheme( builders: { TargetPlatform.android: ZoomPageTransitionsBuilder(), TargetPlatform.iOS: CupertinoPageTransitionsBuilder(), TargetPlatform.macOS: CupertinoPageTransitionsBuilder(), }, ), // 스낵바 스타일 (기본 유지) snackBarTheme: SnackBarThemeData( backgroundColor: scheme.primary, contentTextStyle: TextStyle( color: scheme.onPrimary, fontSize: 14, fontWeight: FontWeight.w500, ), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), behavior: SnackBarBehavior.floating, ), ); })(); }