import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:lucide_icons_flutter/lucide_icons.dart'; /// KROW brand palette: 286CP blue carries every surface and action, 106CP /// yellow marks money and anything waiting on you, and the canvas is white. /// /// 621CP sage is still here, but it is a tint now rather than the ground: it /// fills the quiet inset blocks that would otherwise vanish against a white /// card. abstract final class KrowPalette { static const blue = Color(0xFF3752A8); static const blueDeep = Color(0xFF22366F); static const blueTint = Color(0xFFE1E6F4); static const yellow = Color(0xFFF5C842); static const yellowSoft = Color(0xFFF7E4AE); static const sage = Color(0xFFE9F3EC); static const ink = Color(0xFF26353E); static const line = Color(0xFFCFDDD3); static const mute = Color(0xFF65727A); /// Inert surfaces: a disabled button, an un-dragged swipe track. /// /// Cool grey rather than the green-grey these used to be. That tint made /// sense while sage was the canvas and a disabled control was a slightly /// darker patch of the page; against white it reads as a colour someone /// chose, which is the last thing an inert control should look like. static const disabled = Color(0xFFDFE3E6); /// The outline on an unselected control — an empty radio, an OTP box. /// Heavier than [line], which is only ever a hairline between rows. static const edge = Color(0xFFC8D0D6); } ThemeData buildKrowTheme() { final scheme = ColorScheme.fromSeed( seedColor: KrowPalette.blue, primary: KrowPalette.blue, onPrimary: Colors.white, secondary: KrowPalette.yellow, onSecondary: KrowPalette.ink, surface: Colors.white, onSurface: KrowPalette.ink, brightness: Brightness.light, ); final text = GoogleFonts.poppinsTextTheme().apply( bodyColor: KrowPalette.ink, displayColor: KrowPalette.ink, ); return ThemeData( useMaterial3: true, colorScheme: scheme, textTheme: text, scaffoldBackgroundColor: Colors.white, appBarTheme: AppBarTheme( backgroundColor: Colors.white, surfaceTintColor: Colors.transparent, foregroundColor: KrowPalette.ink, elevation: 0, centerTitle: false, titleTextStyle: GoogleFonts.poppins( fontSize: 18, fontWeight: FontWeight.w700, color: KrowPalette.ink, ), ), cardTheme: CardThemeData( color: Colors.white, elevation: 0, margin: EdgeInsets.zero, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16), side: const BorderSide(color: KrowPalette.line), ), ), // Most detail screens use a plain AppBar, whose back button would // otherwise draw Material's own glyph — a full arrow on Android and web, // a chevron on iOS. Naming it here keeps every back button in the app the // same shape as the ones built by hand with HeaderIconButton. actionIconTheme: ActionIconThemeData( backButtonIconBuilder: (context) => const Icon(LucideIcons.chevronLeft, size: 20), ), dividerTheme: const DividerThemeData( color: KrowPalette.line, thickness: 1, space: 1, ), filledButtonTheme: FilledButtonThemeData( style: FilledButton.styleFrom( minimumSize: const Size.fromHeight(52), backgroundColor: KrowPalette.blue, foregroundColor: Colors.white, disabledBackgroundColor: KrowPalette.disabled, disabledForegroundColor: const Color(0xFF949FA5), textStyle: GoogleFonts.poppins( fontSize: 15, fontWeight: FontWeight.w600, ), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(14)), ), ), outlinedButtonTheme: OutlinedButtonThemeData( style: OutlinedButton.styleFrom( minimumSize: const Size.fromHeight(52), foregroundColor: KrowPalette.ink, backgroundColor: Colors.white, side: const BorderSide(color: KrowPalette.line), textStyle: GoogleFonts.poppins( fontSize: 15, fontWeight: FontWeight.w600, ), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(14)), ), ), textButtonTheme: TextButtonThemeData( style: TextButton.styleFrom( foregroundColor: KrowPalette.blue, textStyle: GoogleFonts.poppins( fontSize: 14, fontWeight: FontWeight.w600, ), ), ), inputDecorationTheme: InputDecorationTheme( filled: true, fillColor: Colors.white, contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 16), hintStyle: GoogleFonts.poppins( fontSize: 14, color: const Color(0xFF949FA5), ), border: OutlineInputBorder( borderRadius: BorderRadius.circular(14), borderSide: const BorderSide(color: KrowPalette.line), ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(14), borderSide: const BorderSide(color: KrowPalette.line), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(14), borderSide: const BorderSide(color: KrowPalette.blue, width: 1.6), ), ), chipTheme: ChipThemeData( backgroundColor: Colors.white, side: const BorderSide(color: KrowPalette.line), labelStyle: GoogleFonts.poppins( fontSize: 12.5, fontWeight: FontWeight.w500, ), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), ), // Bottom navigation is KrowNavBar, not Material's NavigationBar, so there // is no navigationBarTheme to configure — its styling lives in the widget. snackBarTheme: SnackBarThemeData( behavior: SnackBarBehavior.floating, backgroundColor: KrowPalette.ink, contentTextStyle: GoogleFonts.poppins( fontSize: 13.5, color: Colors.white, ), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), ), ); }