import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; /// shadcn/ui 스타일 테마 시스템 class ShadcnTheme { // shadcn/ui 색상 시스템 static const Color background = Color(0xFFFFFFFF); static const Color foreground = Color(0xFF020817); static const Color card = Color(0xFFFFFFFF); static const Color cardForeground = Color(0xFF020817); static const Color popover = Color(0xFFFFFFFF); static const Color popoverForeground = Color(0xFF020817); static const Color primary = Color(0xFF0F172A); static const Color primaryForeground = Color(0xFFF8FAFC); static const Color secondary = Color(0xFFF1F5F9); static const Color secondaryForeground = Color(0xFF0F172A); static const Color muted = Color(0xFFF1F5F9); static const Color mutedForeground = Color(0xFF64748B); static const Color accent = Color(0xFFF1F5F9); static const Color accentForeground = Color(0xFF0F172A); static const Color destructive = Color(0xFFEF4444); static const Color destructiveForeground = Color(0xFFF8FAFC); static const Color border = Color(0xFFE2E8F0); static const Color input = Color(0xFFE2E8F0); static const Color ring = Color(0xFF020817); static const Color radius = Color(0xFF000000); // 사용하지 않음 // 그라데이션 색상 static const Color gradient1 = Color(0xFF6366F1); static const Color gradient2 = Color(0xFF8B5CF6); static const Color gradient3 = Color(0xFFEC4899); // 상태 색상 static const Color success = Color(0xFF10B981); static const Color warning = Color(0xFFF59E0B); static const Color error = Color(0xFFEF4444); static const Color info = Color(0xFF3B82F6); // 그림자 설정 static List get cardShadow => [ BoxShadow( color: Colors.black.withOpacity(0.05), blurRadius: 6, offset: const Offset(0, 2), ), BoxShadow( color: Colors.black.withOpacity(0.1), blurRadius: 20, offset: const Offset(0, 10), ), ]; static List get buttonShadow => [ BoxShadow( color: Colors.black.withOpacity(0.1), blurRadius: 3, offset: const Offset(0, 1), ), ]; // 간격 시스템 static const double spacing1 = 4.0; static const double spacing2 = 8.0; static const double spacing3 = 12.0; static const double spacing4 = 16.0; static const double spacing5 = 20.0; static const double spacing6 = 24.0; static const double spacing8 = 32.0; static const double spacing10 = 40.0; static const double spacing12 = 48.0; static const double spacing16 = 64.0; static const double spacing20 = 80.0; // 라운드 설정 static const double radiusNone = 0.0; static const double radiusSm = 2.0; static const double radiusMd = 6.0; static const double radiusLg = 8.0; static const double radiusXl = 12.0; static const double radius2xl = 16.0; static const double radius3xl = 24.0; static const double radiusFull = 9999.0; // 타이포그래피 시스템 static TextStyle get headingH1 => GoogleFonts.inter( fontSize: 36, fontWeight: FontWeight.w800, color: foreground, letterSpacing: -0.02, ); static TextStyle get headingH2 => GoogleFonts.inter( fontSize: 30, fontWeight: FontWeight.w700, color: foreground, letterSpacing: -0.02, ); static TextStyle get headingH3 => GoogleFonts.inter( fontSize: 24, fontWeight: FontWeight.w600, color: foreground, letterSpacing: -0.01, ); static TextStyle get headingH4 => GoogleFonts.inter( fontSize: 20, fontWeight: FontWeight.w600, color: foreground, letterSpacing: -0.01, ); static TextStyle get bodyLarge => GoogleFonts.inter( fontSize: 16, fontWeight: FontWeight.w400, color: foreground, letterSpacing: 0, ); static TextStyle get bodyMedium => GoogleFonts.inter( fontSize: 14, fontWeight: FontWeight.w400, color: foreground, letterSpacing: 0, ); static TextStyle get bodySmall => GoogleFonts.inter( fontSize: 12, fontWeight: FontWeight.w400, color: mutedForeground, letterSpacing: 0, ); static TextStyle get bodyMuted => GoogleFonts.inter( fontSize: 14, fontWeight: FontWeight.w400, color: mutedForeground, letterSpacing: 0, ); static TextStyle get labelLarge => GoogleFonts.inter( fontSize: 14, fontWeight: FontWeight.w500, color: foreground, letterSpacing: 0, ); static TextStyle get labelMedium => GoogleFonts.inter( fontSize: 12, fontWeight: FontWeight.w500, color: foreground, letterSpacing: 0, ); static TextStyle get labelSmall => GoogleFonts.inter( fontSize: 10, fontWeight: FontWeight.w500, color: mutedForeground, letterSpacing: 0, ); // Flutter 테마 데이터 static ThemeData get lightTheme { return ThemeData( useMaterial3: true, colorScheme: const ColorScheme.light( primary: primary, secondary: secondary, surface: background, surfaceContainerHighest: card, onSurface: foreground, onPrimary: primaryForeground, onSecondary: secondaryForeground, error: destructive, onError: destructiveForeground, outline: border, outlineVariant: input, ), scaffoldBackgroundColor: background, textTheme: TextTheme( headlineLarge: headingH1, headlineMedium: headingH2, headlineSmall: headingH3, titleLarge: headingH4, bodyLarge: bodyLarge, bodyMedium: bodyMedium, bodySmall: bodySmall, labelLarge: labelLarge, labelMedium: labelMedium, labelSmall: labelSmall, ), appBarTheme: AppBarTheme( backgroundColor: background, foregroundColor: foreground, elevation: 0, scrolledUnderElevation: 1, shadowColor: Colors.black.withOpacity(0.1), surfaceTintColor: Colors.transparent, titleTextStyle: headingH4, iconTheme: const IconThemeData(color: foreground), ), cardTheme: CardThemeData( color: card, elevation: 0, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(radiusLg), side: const BorderSide(color: border, width: 1), ), shadowColor: Colors.black.withOpacity(0.05), ), elevatedButtonTheme: ElevatedButtonThemeData( style: ElevatedButton.styleFrom( backgroundColor: primary, foregroundColor: primaryForeground, elevation: 0, shadowColor: Colors.transparent, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(radiusMd), ), padding: const EdgeInsets.symmetric( horizontal: spacing4, vertical: spacing2, ), textStyle: labelMedium, ), ), outlinedButtonTheme: OutlinedButtonThemeData( style: OutlinedButton.styleFrom( foregroundColor: foreground, side: const BorderSide(color: border), elevation: 0, shadowColor: Colors.transparent, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(radiusMd), ), padding: const EdgeInsets.symmetric( horizontal: spacing4, vertical: spacing2, ), textStyle: labelMedium, ), ), textButtonTheme: TextButtonThemeData( style: TextButton.styleFrom( foregroundColor: foreground, elevation: 0, shadowColor: Colors.transparent, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(radiusMd), ), padding: const EdgeInsets.symmetric( horizontal: spacing4, vertical: spacing2, ), textStyle: labelMedium, ), ), inputDecorationTheme: InputDecorationTheme( filled: true, fillColor: background, contentPadding: const EdgeInsets.symmetric( horizontal: spacing3, vertical: spacing2, ), border: OutlineInputBorder( borderRadius: BorderRadius.circular(radiusMd), borderSide: const BorderSide(color: input), ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(radiusMd), borderSide: const BorderSide(color: input), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(radiusMd), borderSide: const BorderSide(color: ring, width: 2), ), errorBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(radiusMd), borderSide: const BorderSide(color: destructive), ), focusedErrorBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(radiusMd), borderSide: const BorderSide(color: destructive, width: 2), ), hintStyle: bodyMedium.copyWith(color: mutedForeground), labelStyle: labelMedium, ), dividerTheme: const DividerThemeData(color: border, thickness: 1), ); } }