import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; /// BadNote design tokens — ink-desk academic aesthetic. /// Warm paper field, graphite ink, single copper accent. No Inter / no purple. abstract final class AppTokens { static const Color paper = Color(0xFFF3EDE3); static const Color paperDark = Color(0xFF1C1A17); static const Color ink = Color(0xFF1F1B16); static const Color inkMuted = Color(0xFF6B6358); static const Color rule = Color(0xFFD9CFC0); static const Color copper = Color(0xFFB45A2A); static const Color copperSoft = Color(0xFFE8C4AE); static const Color sticky = Color(0xFFF6E7A5); static const double radiusSm = 6; static const double radiusMd = 12; static const double chromePad = 16; } abstract final class AppTheme { static ThemeData light() { final base = ColorScheme.fromSeed( seedColor: AppTokens.copper, brightness: Brightness.light, surface: AppTokens.paper, primary: AppTokens.copper, onPrimary: Colors.white, onSurface: AppTokens.ink, secondary: AppTokens.inkMuted, ); return _build(base, Brightness.light); } static ThemeData dark() { final base = ColorScheme.fromSeed( seedColor: AppTokens.copperSoft, brightness: Brightness.dark, surface: AppTokens.paperDark, primary: AppTokens.copperSoft, onSurface: AppTokens.paper, ); return _build(base, Brightness.dark); } static ThemeData fromScheme(ColorScheme scheme) => _build(scheme, scheme.brightness); static ThemeData _build(ColorScheme scheme, Brightness brightness) { final display = GoogleFonts.sourceSerif4TextTheme( ThemeData(brightness: brightness).textTheme, ); final ui = GoogleFonts.ibmPlexSansTextTheme( ThemeData(brightness: brightness).textTheme, ); final merged = ui.copyWith( displayLarge: display.displayLarge?.copyWith(fontWeight: FontWeight.w600), displayMedium: display.displayMedium?.copyWith(fontWeight: FontWeight.w600), displaySmall: display.displaySmall?.copyWith(fontWeight: FontWeight.w600), headlineLarge: display.headlineLarge?.copyWith(fontWeight: FontWeight.w600), headlineMedium: display.headlineMedium?.copyWith(fontWeight: FontWeight.w600), headlineSmall: display.headlineSmall?.copyWith(fontWeight: FontWeight.w600), titleLarge: display.titleLarge?.copyWith(fontWeight: FontWeight.w600), ); return ThemeData( useMaterial3: true, colorScheme: scheme, scaffoldBackgroundColor: scheme.surface, textTheme: merged, appBarTheme: AppBarTheme( centerTitle: false, backgroundColor: scheme.surface, foregroundColor: scheme.onSurface, elevation: 0, scrolledUnderElevation: 0.5, titleTextStyle: display.titleLarge?.copyWith( color: scheme.onSurface, fontWeight: FontWeight.w600, ), ), navigationBarTheme: NavigationBarThemeData( backgroundColor: scheme.surface, indicatorColor: AppTokens.copper.withValues(alpha: 0.18), labelTextStyle: WidgetStatePropertyAll( ui.labelMedium?.copyWith(fontWeight: FontWeight.w600), ), ), navigationRailTheme: NavigationRailThemeData( backgroundColor: scheme.surface, indicatorColor: AppTokens.copper.withValues(alpha: 0.18), selectedIconTheme: IconThemeData(color: scheme.primary), unselectedIconTheme: IconThemeData(color: scheme.onSurfaceVariant), ), cardTheme: CardThemeData( color: scheme.surface, elevation: 0, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(AppTokens.radiusMd), side: BorderSide(color: AppTokens.rule.withValues(alpha: 0.7)), ), ), dividerColor: AppTokens.rule, floatingActionButtonTheme: FloatingActionButtonThemeData( backgroundColor: scheme.primary, foregroundColor: scheme.onPrimary, ), ); } }