import 'package:flutter/material.dart'; class AppTheme { // ───────────────────────────────────────────────────────────────────────── // LEGACY API — field names preserved, values updated to 岩美 brand. // ───────────────────────────────────────────────────────────────────────── static const Color primary = Color(0xFF2563AC); static const Color primaryDark = Color(0xFF154072); static const Color primaryLight = Color(0xFF4F86C6); /// Bordeaux accent — wine context cue. Was warm orange #FF6F00. static const Color accent = Color(0xFF8B2331); static const Color success = Color(0xFF2E8B57); static const Color danger = Color(0xFFD14343); static const Color background = Color(0xFFF5F7FA); static const Color surface = Color(0xFFFFFFFF); static const Color border = Color(0xFFDCE2EB); static const Color textPrimary = Color(0xFF232934); static const Color textSecondary = Color(0xFF6E7888); // ───────────────────────────────────────────────────────────────────────── // Full brand scale (50..900) // ───────────────────────────────────────────────────────────────────────── static const Color brand50 = Color(0xFFEEF4FB); static const Color brand100 = Color(0xFFD6E5F5); static const Color brand200 = Color(0xFFADC9EA); static const Color brand300 = Color(0xFF7FA8DA); static const Color brand400 = Color(0xFF4F86C6); static const Color brand500 = Color(0xFF2563AC); static const Color brand600 = Color(0xFF1B4F8E); static const Color brand700 = Color(0xFF154072); static const Color brand800 = Color(0xFF0F3057); static const Color brand900 = Color(0xFF0A1F3B); // ───────────────────────────────────────────────────────────────────────── // Full neutral (gray) scale // ───────────────────────────────────────────────────────────────────────── static const Color gray0 = Color(0xFFFFFFFF); static const Color gray25 = Color(0xFFFBFCFD); static const Color gray50 = Color(0xFFF5F7FA); static const Color gray100 = Color(0xFFECEFF4); static const Color gray200 = Color(0xFFDCE2EB); static const Color gray300 = Color(0xFFC2CAD6); static const Color gray400 = Color(0xFF99A3B3); static const Color gray500 = Color(0xFF6E7888); static const Color gray600 = Color(0xFF4F5867); static const Color gray700 = Color(0xFF353C48); static const Color gray800 = Color(0xFF232934); static const Color gray900 = Color(0xFF141821); // ───────────────────────────────────────────────────────────────────────── // Accent (bordeaux) scale // ───────────────────────────────────────────────────────────────────────── static const Color accent50 = Color(0xFFFAEEF0); static const Color accent100 = Color(0xFFF1D2D7); static const Color accent500 = Color(0xFF8B2331); static const Color accent700 = Color(0xFF5F1621); // ───────────────────────────────────────────────────────────────────────── // Semantic scale // ───────────────────────────────────────────────────────────────────────── static const Color success50 = Color(0xFFE8F5EE); static const Color success500 = Color(0xFF2E8B57); static const Color success700 = Color(0xFF1F6B41); static const Color warning50 = Color(0xFFFFF4DB); static const Color warning500 = Color(0xFFE08E00); static const Color warning700 = Color(0xFFA66700); static const Color danger50 = Color(0xFFFDECEC); static const Color danger500 = Color(0xFFD14343); static const Color danger700 = Color(0xFF9E2A2A); static const Color info50 = Color(0xFFE5F1FB); static const Color info500 = Color(0xFF2F7BD0); static const Color info700 = Color(0xFF1F5C9F); // ───────────────────────────────────────────────────────────────────────── // State colors // ───────────────────────────────────────────────────────────────────────── static const Color rowHover = Color(0xFFEEF4FB); static const Color tableHeader = Color(0xFFF5F7FA); static const Color borderSubtle = Color(0xFFECEFF4); // ───────────────────────────────────────────────────────────────────────── // Radii // ───────────────────────────────────────────────────────────────────────── static const double radiusSm = 4.0; static const double radiusMd = 6.0; static const double radiusLg = 10.0; // ───────────────────────────────────────────────────────────────────────── // Spacing (4px base) // ───────────────────────────────────────────────────────────────────────── static const double space1 = 4.0; static const double space2 = 8.0; static const double space3 = 12.0; static const double space4 = 16.0; static const double space5 = 20.0; static const double space6 = 24.0; static const double space8 = 32.0; // ───────────────────────────────────────────────────────────────────────── // ThemeData // ───────────────────────────────────────────────────────────────────────── static ThemeData light() { return ThemeData( useMaterial3: true, colorScheme: ColorScheme.fromSeed( seedColor: primary, brightness: Brightness.light, ).copyWith( primary: primary, onPrimary: Colors.white, secondary: brand400, surface: surface, onSurface: textPrimary, error: danger, outline: border, outlineVariant: borderSubtle, ), scaffoldBackgroundColor: background, appBarTheme: const AppBarTheme( backgroundColor: primary, foregroundColor: Colors.white, elevation: 0, centerTitle: false, toolbarHeight: 56, titleTextStyle: TextStyle( fontSize: 16, fontWeight: FontWeight.w600, color: Colors.white, letterSpacing: 0.4, ), ), cardTheme: CardThemeData( color: surface, elevation: 0, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(radiusLg), side: const BorderSide(color: border, width: 1), ), margin: const EdgeInsets.all(0), ), elevatedButtonTheme: ElevatedButtonThemeData( style: ElevatedButton.styleFrom( backgroundColor: primary, foregroundColor: Colors.white, minimumSize: const Size(0, 40), padding: const EdgeInsets.symmetric(horizontal: 18), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(radiusMd), ), textStyle: const TextStyle( fontSize: 14, fontWeight: FontWeight.w500, letterSpacing: 0.2, ), elevation: 0, ).copyWith( backgroundColor: WidgetStateProperty.resolveWith((states) { if (states.contains(WidgetState.pressed)) return primaryDark; if (states.contains(WidgetState.hovered)) return brand600; return primary; }), overlayColor: WidgetStateProperty.all(Colors.white.withValues(alpha: 0.08)), ), ), outlinedButtonTheme: OutlinedButtonThemeData( style: OutlinedButton.styleFrom( foregroundColor: brand700, minimumSize: const Size(0, 40), padding: const EdgeInsets.symmetric(horizontal: 18), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(radiusMd), ), side: const BorderSide(color: border, width: 1), textStyle: const TextStyle( fontSize: 14, fontWeight: FontWeight.w500, ), ).copyWith( backgroundColor: WidgetStateProperty.resolveWith((states) { if (states.contains(WidgetState.pressed)) return gray100; if (states.contains(WidgetState.hovered)) return gray50; return surface; }), ), ), textButtonTheme: TextButtonThemeData( style: TextButton.styleFrom( foregroundColor: primary, minimumSize: const Size(0, 36), padding: const EdgeInsets.symmetric(horizontal: 12), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(radiusSm), ), ), ), inputDecorationTheme: InputDecorationTheme( border: OutlineInputBorder( borderRadius: BorderRadius.circular(radiusMd), borderSide: const BorderSide(color: border), ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(radiusMd), borderSide: const BorderSide(color: border), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(radiusMd), borderSide: const BorderSide(color: primary, width: 1.5), ), errorBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(radiusMd), borderSide: const BorderSide(color: danger), ), hoverColor: gray50, contentPadding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10), isDense: true, filled: true, fillColor: surface, labelStyle: const TextStyle(fontSize: 13, color: textSecondary), hintStyle: TextStyle(fontSize: 13, color: gray400), ), dividerTheme: const DividerThemeData( color: borderSubtle, thickness: 1, space: 1, ), chipTheme: ChipThemeData( backgroundColor: gray100, labelStyle: const TextStyle(fontSize: 12, color: textPrimary), side: BorderSide.none, padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 0), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(999), ), ), tooltipTheme: TooltipThemeData( decoration: BoxDecoration( color: gray900, borderRadius: BorderRadius.circular(radiusSm), ), textStyle: const TextStyle(color: Colors.white, fontSize: 12), padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 6), ), textTheme: const TextTheme( displayLarge: TextStyle(fontSize: 36, fontWeight: FontWeight.w600, color: brand900, height: 1.2, letterSpacing: 0.4), displayMedium: TextStyle(fontSize: 28, fontWeight: FontWeight.w600, color: brand900, height: 1.2, letterSpacing: 0.4), headlineSmall: TextStyle(fontSize: 22, fontWeight: FontWeight.w600, color: gray900, height: 1.3), titleLarge: TextStyle(fontSize: 18, fontWeight: FontWeight.w600, color: gray900, height: 1.35), titleMedium: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: textPrimary, height: 1.4), titleSmall: TextStyle(fontSize: 14, fontWeight: FontWeight.w500, color: textPrimary, height: 1.4), bodyLarge: TextStyle(fontSize: 14, color: textPrimary, height: 1.55), bodyMedium: TextStyle(fontSize: 14, color: textPrimary, height: 1.55), bodySmall: TextStyle(fontSize: 12, color: textSecondary, height: 1.5), labelLarge: TextStyle(fontSize: 13, color: textPrimary, fontWeight: FontWeight.w500), labelMedium: TextStyle(fontSize: 12, color: textSecondary, letterSpacing: 0.4), labelSmall: TextStyle(fontSize: 11, color: textSecondary, letterSpacing: 0.4), ), pageTransitionsTheme: const PageTransitionsTheme( builders: { TargetPlatform.windows: FadeUpwardsPageTransitionsBuilder(), TargetPlatform.macOS: FadeUpwardsPageTransitionsBuilder(), TargetPlatform.linux: FadeUpwardsPageTransitionsBuilder(), }, ), ); } }