import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; /// Nanga Kathai palette, taken from the heritage emblem. abstract final class NkColors { static const ground = Color(0xFF0B1A14); // night tea static const surface = Color(0xFF14281F); // estate static const raised = Color(0xFF1F3A2B); static const miniPlayer = Color(0xFF1A3326); static const outline = Color(0xFF2A4537); static const emblemGreen = Color(0xFF1F4A2E); static const teaLeaf = Color(0xFF7FA857); static const sun = Color(0xFFF5B335); // accent static const roofRed = Color(0xFFC9502F); static const cream = Color(0xFFFBF7EE); // primary text static const muted = Color(0xFF9FB3A6); // secondary text static const mutedOnPhoto = Color(0xFFDCE5DF); static const like = Color(0xFFE0503F); } 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, outline: NkColors.outline, error: NkColors.roofRed, ), ); // google_fonts 9 builds its TextTheme helpers on package:material_ui, so only its // TextStyle API is used here. 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.1); return base.copyWith( textTheme: body.copyWith( headlineLarge: display(32), headlineMedium: display(28), headlineSmall: display(24), titleLarge: display(20, FontWeight.w700), titleMedium: body.titleMedium?.copyWith(fontWeight: FontWeight.w700), bodySmall: body.bodySmall?.copyWith(color: NkColors.muted), ), splashFactory: InkSparkle.splashFactory, filledButtonTheme: FilledButtonThemeData( style: FilledButton.styleFrom( backgroundColor: NkColors.sun, foregroundColor: NkColors.ground, minimumSize: const Size(64, 52), shape: const StadiumBorder(), textStyle: GoogleFonts.manrope(fontSize: 16, fontWeight: FontWeight.w700), ), ), outlinedButtonTheme: OutlinedButtonThemeData( style: OutlinedButton.styleFrom( foregroundColor: NkColors.cream, minimumSize: const Size(64, 50), side: const BorderSide(color: NkColors.outline, width: 1.5), shape: const StadiumBorder(), textStyle: GoogleFonts.manrope(fontSize: 15, fontWeight: FontWeight.w700), ), ), inputDecorationTheme: InputDecorationTheme( filled: true, fillColor: NkColors.surface, hintStyle: const TextStyle(color: NkColors.muted), border: OutlineInputBorder( borderRadius: BorderRadius.circular(14), borderSide: const BorderSide(color: NkColors.outline, width: 1.5), ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(14), borderSide: const BorderSide(color: NkColors.outline, width: 1.5), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(14), borderSide: const BorderSide(color: NkColors.sun, width: 1.5), ), ), 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, ), sliderTheme: const SliderThemeData( activeTrackColor: NkColors.sun, inactiveTrackColor: Color(0x38FBF7EE), thumbColor: NkColors.sun, trackHeight: 4, overlayShape: RoundSliderOverlayShape(overlayRadius: 18), ), navigationBarTheme: NavigationBarThemeData( backgroundColor: NkColors.ground, indicatorColor: Colors.transparent, height: 72, labelTextStyle: WidgetStateProperty.resolveWith( (s) => GoogleFonts.manrope( fontSize: 12, fontWeight: FontWeight.w600, color: s.contains(WidgetState.selected) ? NkColors.sun : NkColors.muted, ), ), iconTheme: WidgetStateProperty.resolveWith( (s) => IconThemeData(color: s.contains(WidgetState.selected) ? NkColors.sun : NkColors.muted), ), ), snackBarTheme: const SnackBarThemeData( backgroundColor: NkColors.raised, contentTextStyle: TextStyle(color: NkColors.cream), behavior: SnackBarBehavior.floating, ), ); }