import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:flutter_animate/flutter_animate.dart'; class AppColors { static const primary = Color(0xFF1A56DB); static const primaryLight = Color(0xFF3B82F6); static const primaryDark = Color(0xFF1E40AF); static const accent = Color(0xFF00C9A7); static const accentLight = Color(0xFF6EE7B7); static const background = Color(0xFFF8FAFC); static const surface = Colors.white; static const error = Color(0xFFEF4444); static const warning = Color(0xFFF59E0B); static const success = Color(0xFF10B981); static const textPrimary = Color(0xFF1E293B); static const textSecondary = Color(0xFF64748B); static const textTertiary = Color(0xFF94A3B8); static const divider = Color(0xFFE2E8F0); static const cardShadow = Color(0x1A000000); static const gradientStart = Color(0xFF1A56DB); static const gradientEnd = Color(0xFF00C9A7); static const chatUserBubble = Color(0xFF1A56DB); static const chatAiBubble = Color(0xFFF1F5F9); static const scanOverlay = Color(0x801A56DB); } class AppTheme { static ThemeData get lightTheme { return ThemeData( useMaterial3: true, brightness: Brightness.light, colorScheme: const ColorScheme.light( primary: AppColors.primary, onPrimary: Colors.white, secondary: AppColors.accent, onSecondary: Colors.white, surface: AppColors.surface, onSurface: AppColors.textPrimary, error: AppColors.error, onError: Colors.white, background: AppColors.background, onBackground: AppColors.textPrimary, ), scaffoldBackgroundColor: AppColors.background, textTheme: GoogleFonts.notoSansScTextTheme().copyWith( displayLarge: GoogleFonts.notoSansSc( fontSize: 32, fontWeight: FontWeight.bold, color: AppColors.textPrimary, ), displayMedium: GoogleFonts.notoSansSc( fontSize: 24, fontWeight: FontWeight.bold, color: AppColors.textPrimary, ), titleLarge: GoogleFonts.notoSansSc( fontSize: 20, fontWeight: FontWeight.w600, color: AppColors.textPrimary, ), titleMedium: GoogleFonts.notoSansSc( fontSize: 16, fontWeight: FontWeight.w600, color: AppColors.textPrimary, ), bodyLarge: GoogleFonts.notoSansSc( fontSize: 16, color: AppColors.textPrimary, ), bodyMedium: GoogleFonts.notoSansSc( fontSize: 14, color: AppColors.textSecondary, ), labelLarge: GoogleFonts.notoSansSc( fontSize: 14, fontWeight: FontWeight.w500, ), ), appBarTheme: AppBarTheme( elevation: 0, centerTitle: true, backgroundColor: AppColors.surface, foregroundColor: AppColors.textPrimary, systemOverlayStyle: SystemUiOverlayStyle.dark, titleTextStyle: GoogleFonts.notoSansSc( fontSize: 18, fontWeight: FontWeight.w600, color: AppColors.textPrimary, ), ), cardTheme: CardThemeData( elevation: 0, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16), ), color: AppColors.surface, ), inputDecorationTheme: InputDecorationTheme( filled: true, fillColor: AppColors.background, border: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: BorderSide.none, ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: BorderSide.none, ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: const BorderSide(color: AppColors.primary, width: 1.5), ), errorBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: const BorderSide(color: AppColors.error, width: 1), ), contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14), hintStyle: GoogleFonts.notoSansSc( fontSize: 14, color: AppColors.textTertiary, ), ), elevatedButtonTheme: ElevatedButtonThemeData( style: ElevatedButton.styleFrom( elevation: 0, padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 14), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), backgroundColor: AppColors.primary, foregroundColor: Colors.white, textStyle: GoogleFonts.notoSansSc( fontSize: 16, fontWeight: FontWeight.w600, ), ), ), outlinedButtonTheme: OutlinedButtonThemeData( style: OutlinedButton.styleFrom( padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 14), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), side: const BorderSide(color: AppColors.primary), foregroundColor: AppColors.primary, textStyle: GoogleFonts.notoSansSc( fontSize: 14, fontWeight: FontWeight.w500, ), ), ), textButtonTheme: TextButtonThemeData( style: TextButton.styleFrom( foregroundColor: AppColors.primary, textStyle: GoogleFonts.notoSansSc( fontSize: 14, fontWeight: FontWeight.w500, ), ), ), floatingActionButtonTheme: const FloatingActionButtonThemeData( backgroundColor: AppColors.primary, foregroundColor: Colors.white, elevation: 4, ), bottomNavigationBarTheme: const BottomNavigationBarThemeData( backgroundColor: AppColors.surface, selectedItemColor: AppColors.primary, unselectedItemColor: AppColors.textTertiary, type: BottomNavigationBarType.fixed, elevation: 8, ), chipTheme: ChipThemeData( backgroundColor: AppColors.background, selectedColor: AppColors.primary.withOpacity(0.1), labelStyle: GoogleFonts.notoSansSc(fontSize: 12), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), ), dividerTheme: const DividerThemeData( color: AppColors.divider, thickness: 1, space: 1, ), tabBarTheme: TabBarThemeData( labelColor: AppColors.primary, unselectedLabelColor: AppColors.textSecondary, labelStyle: GoogleFonts.notoSansSc( fontSize: 14, fontWeight: FontWeight.w600, ), unselectedLabelStyle: GoogleFonts.notoSansSc( fontSize: 14, fontWeight: FontWeight.w400, ), indicatorSize: TabBarIndicatorSize.tab, ), ); } static ThemeData get darkTheme { return lightTheme.copyWith( brightness: Brightness.dark, colorScheme: const ColorScheme.dark( primary: AppColors.primaryLight, onPrimary: Colors.white, secondary: AppColors.accent, onSecondary: Colors.white, surface: Color(0xFF1E293B), onSurface: Colors.white, error: AppColors.error, onError: Colors.white, background: Color(0xFF0F172A), onBackground: Colors.white, ), scaffoldBackgroundColor: const Color(0xFF0F172A), ); } } class AppGradients { static const primary = LinearGradient( colors: [AppColors.gradientStart, AppColors.gradientEnd], begin: Alignment.topLeft, end: Alignment.bottomRight, ); static const card = LinearGradient( colors: [Color(0xFF1A56DB), Color(0xFF2563EB)], begin: Alignment.topLeft, end: Alignment.bottomRight, ); static const shimmer = LinearGradient( colors: [Color(0xFFE2E8F0), Color(0xFFF1F5F9), Color(0xFFE2E8F0)], stops: [0.0, 0.5, 1.0], begin: Alignment(-1.0, -0.3), end: Alignment(1.0, 0.3), ); } class AppAnimations { static const defaultDuration = Duration(milliseconds: 300); static const slowDuration = Duration(milliseconds: 500); static const fastDuration = Duration(milliseconds: 150); static Widget fadeSlide(Widget child, {int delay = 0}) { return child .animate() .fadeIn(duration: defaultDuration, delay: Duration(milliseconds: delay)) .slideY(begin: 0.2, end: 0, duration: defaultDuration, delay: Duration(milliseconds: delay)); } static Widget scaleIn(Widget child, {int delay = 0}) { return child .animate() .scale(begin: const Offset(0.9, 0.9), duration: defaultDuration, delay: Duration(milliseconds: delay)) .fadeIn(duration: defaultDuration, delay: Duration(milliseconds: delay)); } }