import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; import 'app_colors.dart'; // Import Extension enum AppFontStyle { sans, // Noto Sans JP (ゴシック) serif, // Noto Serif JP (明朝) pottaOne, // Potta One (髭文字) digital, // DotGothic16 (ドット) } enum ColorVariant { washiSumiKohaku, // 和紙×墨×琥珀 (Theme A) current, // Current theme (Theme B) } class AppTheme { static const Color posimaiBlue = Color(0xFF376495); // ===== Theme A: 和紙×墨×琥珀 (Washi × Sumi × Kohaku) ===== // 日本酒の世界観を反映した洗練された配色 static const Color washiWhite = Color(0xFFFDFBF7); // 和紙の温かみのある白 static const Color sumiBlack = Color(0xFF4A3B32); // 墨色(温かみのある焦げ茶) static const Color kohakuGold = Color(0xFFD4A574); // 琥珀色(酒の黄金色) static const Color kohakuDeep = Color(0xFFB8860B); // 深い琥珀(アクセント用) // ===== Theme B: Current (Original) ===== // 既存のPosimai Blueベースのテーマ // Padding Constants static const double spacingEmpty = 0.0; static const double spacingTiny = 4.0; static const double spacingSmall = 8.0; static const double spacingMedium = 16.0; static const double spacingLarge = 24.0; static const double spacingXLarge = 32.0; static ThemeData createTheme( AppFontStyle fontStyle, Brightness brightness, ColorVariant colorVariant, ) { /* Why GoogleFonts is safe: 1. Downloads dynamically (no asset size increase). 2. Caches locally (fast 2nd load). 3. Fallback exists during download. */ final TextTheme textTheme; switch (fontStyle) { case AppFontStyle.sans: textTheme = GoogleFonts.notoSansJpTextTheme(); case AppFontStyle.serif: textTheme = GoogleFonts.notoSerifJpTextTheme(); case AppFontStyle.pottaOne: textTheme = GoogleFonts.pottaOneTextTheme(); case AppFontStyle.digital: textTheme = GoogleFonts.dotGothic16TextTheme(); } // Get AppColors for this theme variant final appColors = _getAppColors(colorVariant, brightness); // Color scheme based on variant final ColorScheme colorScheme; if (colorVariant == ColorVariant.washiSumiKohaku) { // Theme A: 和紙×墨×琥珀 colorScheme = ColorScheme.fromSeed( seedColor: kohakuGold, brightness: brightness, ).copyWith( primary: brightness == Brightness.dark ? kohakuGold // 琥珀色 for dark mode : sumiBlack, // 墨色 for light mode surface: brightness == Brightness.dark ? const Color(0xFF1E1E1E) : washiWhite, // 和紙ホワイト secondary: brightness == Brightness.dark ? kohakuDeep // 深い琥珀 for dark mode : kohakuGold, // 琥珀色 for light mode ); } else { // Theme B: Current (Original) colorScheme = ColorScheme.fromSeed( seedColor: posimaiBlue, brightness: brightness, ).copyWith( primary: brightness == Brightness.dark ? const Color(0xFF8AB4F8) // Bright blue for dark mode : posimaiBlue, // Original blue for light mode surface: brightness == Brightness.dark ? const Color(0xFF1E1E1E) : Colors.white, secondary: brightness == Brightness.dark ? const Color(0xFFFFB74D) // Warm orange for dark mode accents : const Color(0xFFFF6F00), // Deep orange for light mode ); } return ThemeData( useMaterial3: true, colorScheme: colorScheme, textTheme: textTheme.apply( bodyColor: (brightness == Brightness.dark) ? Colors.white : Colors.black87, displayColor: (brightness == Brightness.dark) ? Colors.white : Colors.black87, ).copyWith( // Ensure headers/labels are visible titleMedium: TextStyle(color: (brightness == Brightness.dark) ? Colors.white : Colors.black87), titleSmall: TextStyle(color: (brightness == Brightness.dark) ? Colors.white70 : Colors.black54), labelLarge: TextStyle(color: (brightness == Brightness.dark) ? Colors.white : Colors.black87), ), scaffoldBackgroundColor: (brightness == Brightness.dark) ? const Color(0xFF121212) : (colorVariant == ColorVariant.washiSumiKohaku ? washiWhite : const Color(0xFFFAFAFA)), cardTheme: CardThemeData( elevation: 0, margin: EdgeInsets.zero, color: (brightness == Brightness.dark) ? const Color(0xFF1E1E1E) : (colorVariant == ColorVariant.washiSumiKohaku ? Colors.white : Colors.white), ), appBarTheme: AppBarTheme( // UI/UX Consistency: AppBarとNavigationBarの背景色を統一(ダークモードのみ) backgroundColor: (brightness == Brightness.dark) ? const Color(0xFF1E1E1E) : null, foregroundColor: (brightness == Brightness.dark) ? Colors.white : Colors.black87, actionsIconTheme: IconThemeData( color: (brightness == Brightness.dark) ? Colors.white : Colors.black87, ), iconTheme: IconThemeData( color: (brightness == Brightness.dark) ? Colors.white : Colors.black87, ), ), iconTheme: IconThemeData( color: (brightness == Brightness.dark) ? Colors.white : (colorVariant == ColorVariant.washiSumiKohaku ? sumiBlack : posimaiBlue), ), navigationBarTheme: NavigationBarThemeData( backgroundColor: (brightness == Brightness.dark) ? const Color(0xFF1E1E1E) : null, indicatorColor: brightness == Brightness.dark ? appColors.brandPrimary.withValues(alpha: 0.4) : appColors.brandPrimary.withValues(alpha: 0.25), ), extensions: [ _getAppColors(colorVariant, brightness), ], ); } /// AppColorsインスタンスを取得(テーマバリアントとブライトネスに基づく) static AppColors _getAppColors(ColorVariant colorVariant, Brightness brightness) { if (colorVariant == ColorVariant.washiSumiKohaku) { return brightness == Brightness.dark ? AppColors.washiDark() : AppColors.washiLight(); } else { return brightness == Brightness.dark ? AppColors.currentDark() : AppColors.currentLight(); } } }