import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; /// Nanga Kathai palette (same as the app, lib/app/theme.dart). abstract final class NkColors { static const ground = Color(0xFF0B1A14); static const surface = Color(0xFF14281F); static const raised = Color(0xFF1F3A2B); static const outline = Color(0xFF2A4537); static const teaLeaf = Color(0xFF7FA857); static const sun = Color(0xFFF5B335); static const roofRed = Color(0xFFC9502F); static const cream = Color(0xFFFBF7EE); static const muted = Color(0xFF9FB3A6); static const info = Color(0xFF6FA8C9); } ThemeData buildNkTheme() { final base = ThemeData( useMaterial3: true, brightness: Brightness.dark, scaffoldBackgroundColor: NkColors.ground, colorScheme: const ColorScheme.dark( primary: NkColors.sun, onPrimary: NkColors.ground, secondary: NkColors.teaLeaf, surface: NkColors.ground, onSurface: NkColors.cream, surfaceContainer: NkColors.surface, surfaceContainerHigh: NkColors.raised, surfaceContainerHighest: NkColors.raised, outline: NkColors.outline, outlineVariant: NkColors.outline, error: NkColors.roofRed, ), ); final body = base.textTheme.apply( fontFamily: GoogleFonts.manrope().fontFamily, bodyColor: NkColors.cream, displayColor: NkColors.cream, ); TextStyle display(double size, [FontWeight w = FontWeight.w800]) => GoogleFonts.sora(fontSize: size, fontWeight: w, color: NkColors.cream, height: 1.15); OutlineInputBorder border(Color c) => OutlineInputBorder(borderRadius: BorderRadius.circular(12), borderSide: BorderSide(color: c, width: 1.5)); return base.copyWith( textTheme: body.copyWith( headlineMedium: display(28), headlineSmall: display(22), titleLarge: display(18, FontWeight.w700), titleMedium: body.titleMedium?.copyWith(fontWeight: FontWeight.w700), bodySmall: body.bodySmall?.copyWith(color: NkColors.muted), ), filledButtonTheme: FilledButtonThemeData( style: FilledButton.styleFrom( backgroundColor: NkColors.sun, foregroundColor: NkColors.ground, minimumSize: const Size(64, 44), shape: const StadiumBorder(), textStyle: GoogleFonts.manrope(fontSize: 15, fontWeight: FontWeight.w700), ), ), outlinedButtonTheme: OutlinedButtonThemeData( style: OutlinedButton.styleFrom( foregroundColor: NkColors.cream, minimumSize: const Size(64, 42), side: const BorderSide(color: NkColors.outline, width: 1.5), shape: const StadiumBorder(), textStyle: GoogleFonts.manrope(fontSize: 14, fontWeight: FontWeight.w700), ), ), textButtonTheme: TextButtonThemeData( style: TextButton.styleFrom( foregroundColor: NkColors.sun, textStyle: GoogleFonts.manrope(fontWeight: FontWeight.w700), ), ), inputDecorationTheme: InputDecorationTheme( filled: true, fillColor: NkColors.surface, isDense: true, hintStyle: const TextStyle(color: NkColors.muted), labelStyle: const TextStyle(color: NkColors.muted), border: border(NkColors.outline), enabledBorder: border(NkColors.outline), focusedBorder: border(NkColors.sun), ), chipTheme: base.chipTheme.copyWith( backgroundColor: NkColors.raised, selectedColor: NkColors.sun, side: BorderSide.none, shape: const StadiumBorder(), labelStyle: GoogleFonts.manrope(fontWeight: FontWeight.w600, color: NkColors.cream), secondaryLabelStyle: GoogleFonts.manrope(fontWeight: FontWeight.w700, color: NkColors.ground), showCheckmark: false, ), cardTheme: CardThemeData( color: NkColors.surface, elevation: 0, margin: EdgeInsets.zero, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16), side: const BorderSide(color: NkColors.outline), ), ), dialogTheme: DialogThemeData( backgroundColor: NkColors.surface, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)), ), dividerTheme: const DividerThemeData(color: NkColors.outline, space: 1), navigationRailTheme: NavigationRailThemeData( backgroundColor: NkColors.surface, indicatorColor: NkColors.raised, selectedIconTheme: const IconThemeData(color: NkColors.sun), unselectedIconTheme: const IconThemeData(color: NkColors.muted), selectedLabelTextStyle: GoogleFonts.manrope(color: NkColors.sun, fontWeight: FontWeight.w700), unselectedLabelTextStyle: GoogleFonts.manrope(color: NkColors.muted, fontWeight: FontWeight.w600), ), checkboxTheme: CheckboxThemeData( fillColor: WidgetStateProperty.resolveWith((s) => s.contains(WidgetState.selected) ? NkColors.sun : null), checkColor: const WidgetStatePropertyAll(NkColors.ground), ), snackBarTheme: const SnackBarThemeData( backgroundColor: NkColors.raised, contentTextStyle: TextStyle(color: NkColors.cream), behavior: SnackBarBehavior.floating, width: 420, ), ); }