import 'package:flutter/material.dart'; /// Central design tokens for 분신 (Bunsin). One seed color drives the whole /// Material 3 palette; `twinAccent` is a separate warm accent used only for /// the AI-authored badge/border so a twin-written bubble never reads as /// something the human actually typed (PRD §3.1 분신 뱃지). class AppTheme { AppTheme._(); static const _seed = Color(0xFF1F6F5B); static Color twinAccent(Brightness brightness) => brightness == Brightness.dark ? Colors.amber.shade300 : Colors.amber.shade800; static ThemeData light() => _build(Brightness.light); static ThemeData dark() => _build(Brightness.dark); static ThemeData _build(Brightness brightness) { final scheme = ColorScheme.fromSeed(seedColor: _seed, brightness: brightness); return ThemeData( useMaterial3: true, brightness: brightness, colorScheme: scheme, scaffoldBackgroundColor: scheme.surface, visualDensity: VisualDensity.comfortable, textTheme: _textTheme(), appBarTheme: AppBarTheme( backgroundColor: scheme.surface, foregroundColor: scheme.onSurface, surfaceTintColor: scheme.surfaceTint, elevation: 0, scrolledUnderElevation: 1, centerTitle: false, titleTextStyle: TextStyle( fontSize: 20, fontWeight: FontWeight.w800, color: scheme.onSurface, letterSpacing: -0.2, ), ), cardTheme: CardThemeData( elevation: 0, color: scheme.surfaceContainerHigh, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)), margin: EdgeInsets.zero, ), listTileTheme: ListTileThemeData( iconColor: scheme.onSurfaceVariant, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(14)), contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 6), ), dividerTheme: DividerThemeData(color: scheme.outlineVariant, space: 32, thickness: 1), inputDecorationTheme: InputDecorationTheme( filled: true, fillColor: scheme.surfaceContainerHighest, contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14), border: OutlineInputBorder( borderRadius: BorderRadius.circular(14), borderSide: BorderSide.none, ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(14), borderSide: BorderSide.none, ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(14), borderSide: BorderSide(color: scheme.primary, width: 1.6), ), errorBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(14), borderSide: BorderSide(color: scheme.error, width: 1.2), ), focusedErrorBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(14), borderSide: BorderSide(color: scheme.error, width: 1.6), ), hintStyle: TextStyle(color: scheme.onSurfaceVariant.withOpacity(0.7)), ), filledButtonTheme: FilledButtonThemeData( style: FilledButton.styleFrom( padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 14), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(14)), textStyle: const TextStyle(fontWeight: FontWeight.w700), ), ), outlinedButtonTheme: OutlinedButtonThemeData( style: OutlinedButton.styleFrom( padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 14), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(14)), ), ), textButtonTheme: TextButtonThemeData( style: TextButton.styleFrom( shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), ), ), iconButtonTheme: IconButtonThemeData( style: IconButton.styleFrom( shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), ), ), segmentedButtonTheme: SegmentedButtonThemeData( style: SegmentedButton.styleFrom( shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10), ), ), chipTheme: ChipThemeData( shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), side: BorderSide.none, backgroundColor: scheme.surfaceContainerHighest, labelStyle: TextStyle(color: scheme.onSurfaceVariant, fontWeight: FontWeight.w600, fontSize: 12), padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4), ), floatingActionButtonTheme: FloatingActionButtonThemeData( backgroundColor: scheme.primary, foregroundColor: scheme.onPrimary, elevation: 1, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(18)), ), snackBarTheme: SnackBarThemeData( behavior: SnackBarBehavior.floating, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), ), bannerTheme: MaterialBannerThemeData( backgroundColor: scheme.surfaceContainerHigh, padding: const EdgeInsets.all(16), ), dialogTheme: DialogThemeData( shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)), ), progressIndicatorTheme: ProgressIndicatorThemeData(color: scheme.primary), ); } static TextTheme _textTheme() { return const TextTheme( displaySmall: TextStyle(fontWeight: FontWeight.w800, letterSpacing: -0.5), headlineSmall: TextStyle(fontWeight: FontWeight.w800, letterSpacing: -0.3), titleLarge: TextStyle(fontWeight: FontWeight.w700), titleMedium: TextStyle(fontWeight: FontWeight.w700), titleSmall: TextStyle(fontWeight: FontWeight.w700), bodyLarge: TextStyle(height: 1.4), bodyMedium: TextStyle(height: 1.4), labelLarge: TextStyle(fontWeight: FontWeight.w700), ); } }