chitfund/luckychit/lib/core/themes/app_theme.dart

456 lines
15 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
// Full redesign note:
// - We keep the existing accessibility intent (larger sizes) but align visuals to a cohesive Material 3 scheme.
class AppTheme {
// ACCESSIBILITY: Larger font size multiplier for elderly users (50+)
static const double fontSizeMultiplier = 1.3; // 30% larger fonts
// Brand seed (used to generate cohesive ColorScheme)
static const Color seed = Color(0xFF0F766E); // teal (trust + finance)
static const Color accent = Color(0xFFF59E0B); // amber (celebratory, draws)
static ColorScheme _lightScheme() {
return ColorScheme.fromSeed(
seedColor: seed,
brightness: Brightness.light,
).copyWith(
tertiary: accent,
);
}
static ColorScheme _darkScheme() {
return ColorScheme.fromSeed(
seedColor: seed,
brightness: Brightness.dark,
).copyWith(
tertiary: accent,
);
}
static TextTheme _textTheme(ColorScheme scheme) {
// Use a tighter, modern scale; keep multiplier to respect original accessibility intent.
return TextTheme(
displaySmall: TextStyle(
fontSize: 34.sp * fontSizeMultiplier,
fontWeight: FontWeight.w700,
letterSpacing: -0.5,
color: scheme.onSurface,
),
headlineSmall: TextStyle(
fontSize: 22.sp * fontSizeMultiplier,
fontWeight: FontWeight.w700,
letterSpacing: -0.2,
color: scheme.onSurface,
),
titleLarge: TextStyle(
fontSize: 18.sp * fontSizeMultiplier,
fontWeight: FontWeight.w700,
color: scheme.onSurface,
),
titleMedium: TextStyle(
fontSize: 16.sp * fontSizeMultiplier,
fontWeight: FontWeight.w600,
color: scheme.onSurface,
),
bodyLarge: TextStyle(
fontSize: 15.sp * fontSizeMultiplier,
fontWeight: FontWeight.w500,
height: 1.35,
color: scheme.onSurface,
),
bodyMedium: TextStyle(
fontSize: 13.sp * fontSizeMultiplier,
fontWeight: FontWeight.w500,
height: 1.35,
color: scheme.onSurfaceVariant,
),
labelLarge: TextStyle(
fontSize: 13.sp * fontSizeMultiplier,
fontWeight: FontWeight.w600,
letterSpacing: 0.3,
color: scheme.onSurface,
),
);
}
/// Light Theme
static ThemeData get lightTheme {
final scheme = _lightScheme();
return ThemeData(
useMaterial3: true,
brightness: Brightness.light,
colorScheme: scheme,
scaffoldBackgroundColor: scheme.surface,
textTheme: _textTheme(scheme),
// AppBar Theme - Accessibility Enhanced
appBarTheme: AppBarTheme(
elevation: 0,
centerTitle: false,
backgroundColor: scheme.surface,
foregroundColor: scheme.onSurface,
titleTextStyle: _textTheme(scheme).titleLarge,
iconTheme: IconThemeData(
color: scheme.onSurface,
size: (24.w * fontSizeMultiplier),
),
),
cardTheme: CardTheme(
elevation: 0,
color: scheme.surfaceContainerHighest,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(18.r)),
margin: EdgeInsets.zero,
),
// Elevated Button Theme - Accessibility Enhanced
elevatedButtonTheme: ElevatedButtonThemeData(
style: ElevatedButton.styleFrom(
backgroundColor: scheme.primary,
foregroundColor: scheme.onPrimary,
elevation: 0,
padding: EdgeInsets.symmetric(
horizontal: (20.w * fontSizeMultiplier),
vertical: (14.h * fontSizeMultiplier),
),
minimumSize: Size(0, (48.h * fontSizeMultiplier)),
textStyle: _textTheme(scheme).labelLarge,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16.r),
),
),
),
// Outlined Button Theme - Accessibility Enhanced
outlinedButtonTheme: OutlinedButtonThemeData(
style: OutlinedButton.styleFrom(
foregroundColor: scheme.primary,
side: BorderSide(color: scheme.outline, width: 1.2),
padding: EdgeInsets.symmetric(
horizontal: (20.w * fontSizeMultiplier),
vertical: (14.h * fontSizeMultiplier),
),
minimumSize: Size(0, (48.h * fontSizeMultiplier)),
textStyle: _textTheme(scheme).labelLarge,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16.r),
),
),
),
// Text Button Theme - Accessibility Enhanced
textButtonTheme: TextButtonThemeData(
style: TextButton.styleFrom(
foregroundColor: scheme.primary,
padding: EdgeInsets.symmetric(
horizontal: (16.w * fontSizeMultiplier),
vertical: (12.h * fontSizeMultiplier),
),
minimumSize: Size(0, (44.h * fontSizeMultiplier)),
textStyle: _textTheme(scheme).labelLarge,
),
),
// Input Decoration Theme - Accessibility Enhanced
inputDecorationTheme: InputDecorationTheme(
filled: true,
fillColor: scheme.surfaceContainerHighest,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(16.r),
borderSide: BorderSide(color: scheme.outlineVariant),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(16.r),
borderSide: BorderSide(color: scheme.outlineVariant),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(16.r),
borderSide: BorderSide(color: scheme.primary, width: 2),
),
errorBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(16.r),
borderSide: BorderSide(color: scheme.error, width: 2),
),
contentPadding: EdgeInsets.symmetric(
horizontal: (16.w * fontSizeMultiplier),
vertical: (14.h * fontSizeMultiplier),
),
labelStyle: _textTheme(scheme).bodyMedium,
hintStyle: _textTheme(scheme).bodyMedium,
),
// Icon Theme - Accessibility Enhanced
iconTheme: IconThemeData(
color: scheme.onSurfaceVariant,
size: (24.w * fontSizeMultiplier),
),
// Floating Action Button Theme
floatingActionButtonTheme: FloatingActionButtonThemeData(
backgroundColor: scheme.primary,
foregroundColor: scheme.onPrimary,
elevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16.r),
),
),
// Bottom Navigation Bar Theme - Accessibility Enhanced
bottomNavigationBarTheme: BottomNavigationBarThemeData(
backgroundColor: scheme.surface,
selectedItemColor: scheme.primary,
unselectedItemColor: scheme.onSurfaceVariant,
selectedLabelStyle: _textTheme(scheme).labelLarge,
unselectedLabelStyle: _textTheme(scheme).labelLarge!.copyWith(
color: scheme.onSurfaceVariant,
fontWeight: FontWeight.w600,
),
selectedIconTheme: IconThemeData(
size: (28.w * fontSizeMultiplier),
),
unselectedIconTheme: IconThemeData(
size: (24.w * fontSizeMultiplier),
),
type: BottomNavigationBarType.fixed,
elevation: 0,
),
// Divider Theme - Accessibility Enhanced
dividerTheme: DividerThemeData(
color: scheme.outlineVariant,
thickness: 1,
space: 1,
),
// Chip Theme - Accessibility Enhanced
chipTheme: ChipThemeData(
backgroundColor: scheme.surfaceContainerHighest,
selectedColor: scheme.primaryContainer,
labelStyle: _textTheme(scheme).labelLarge,
padding: EdgeInsets.symmetric(
horizontal: (14.w * fontSizeMultiplier),
vertical: (10.h * fontSizeMultiplier),
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.r),
),
),
// Dialog Theme - Accessibility Enhanced
// dialogTheme: DialogThemeData(
// elevation: 8, // More elevation for better depth
// shape: RoundedRectangleBorder(
// borderRadius: BorderRadius.circular(20.r),
// ),
// titleTextStyle: TextStyle(
// fontSize: (22.sp * fontSizeMultiplier), // Larger titles
// fontWeight: FontWeight.bold,
// color: lightTextPrimary,
// ),
// contentTextStyle: TextStyle(
// fontSize: (17.sp * fontSizeMultiplier), // Larger content
// color: lightTextSecondary,
// height: 1.5, // Better line spacing
// ),
// ),
// Snackbar Theme - Accessibility Enhanced
snackBarTheme: SnackBarThemeData(
backgroundColor: scheme.inverseSurface,
contentTextStyle: _textTheme(scheme).bodyMedium!.copyWith(
color: scheme.onInverseSurface,
fontWeight: FontWeight.w600,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16.r),
),
behavior: SnackBarBehavior.floating,
actionTextColor: scheme.tertiary,
),
);
}
/// Dark Theme
static ThemeData get darkTheme {
final scheme = _darkScheme();
return ThemeData(
useMaterial3: true,
brightness: Brightness.dark,
colorScheme: scheme,
scaffoldBackgroundColor: scheme.surface,
textTheme: _textTheme(scheme),
// AppBar Theme - Accessibility Enhanced
appBarTheme: AppBarTheme(
elevation: 0,
centerTitle: false,
backgroundColor: scheme.surface,
foregroundColor: scheme.onSurface,
titleTextStyle: _textTheme(scheme).titleLarge,
iconTheme: IconThemeData(
color: scheme.onSurface,
size: (24.w * fontSizeMultiplier),
),
),
cardTheme: CardTheme(
elevation: 0,
color: scheme.surfaceContainerHighest,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(18.r)),
margin: EdgeInsets.zero,
),
// Elevated Button Theme - Accessibility Enhanced
elevatedButtonTheme: ElevatedButtonThemeData(
style: ElevatedButton.styleFrom(
backgroundColor: scheme.primary,
foregroundColor: scheme.onPrimary,
elevation: 0,
padding: EdgeInsets.symmetric(
horizontal: (20.w * fontSizeMultiplier),
vertical: (14.h * fontSizeMultiplier),
),
minimumSize: Size(0, (48.h * fontSizeMultiplier)),
textStyle: _textTheme(scheme).labelLarge,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16.r),
),
),
),
// Outlined Button Theme - Accessibility Enhanced
outlinedButtonTheme: OutlinedButtonThemeData(
style: OutlinedButton.styleFrom(
foregroundColor: scheme.primary,
side: BorderSide(color: scheme.outline, width: 1.2),
padding: EdgeInsets.symmetric(
horizontal: (20.w * fontSizeMultiplier),
vertical: (14.h * fontSizeMultiplier),
),
minimumSize: Size(0, (48.h * fontSizeMultiplier)),
textStyle: _textTheme(scheme).labelLarge,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16.r),
),
),
),
// Text Button Theme
textButtonTheme: TextButtonThemeData(
style: TextButton.styleFrom(
foregroundColor: scheme.primary,
padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 10.h),
textStyle: _textTheme(scheme).labelLarge,
),
),
// Input Decoration Theme
inputDecorationTheme: InputDecorationTheme(
filled: true,
fillColor: scheme.surfaceContainerHighest,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(16.r),
borderSide: BorderSide(color: scheme.outlineVariant),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(16.r),
borderSide: BorderSide(color: scheme.outlineVariant),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(16.r),
borderSide: BorderSide(color: scheme.primary, width: 2),
),
errorBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(16.r),
borderSide: BorderSide(color: scheme.error, width: 2),
),
contentPadding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 14.h),
),
// Icon Theme
iconTheme: IconThemeData(
color: scheme.onSurfaceVariant,
size: 24.w,
),
// Floating Action Button Theme
floatingActionButtonTheme: FloatingActionButtonThemeData(
backgroundColor: scheme.primary,
foregroundColor: scheme.onPrimary,
elevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16.r),
),
),
// Bottom Navigation Bar Theme
bottomNavigationBarTheme: BottomNavigationBarThemeData(
backgroundColor: scheme.surface,
selectedItemColor: scheme.primary,
unselectedItemColor: scheme.onSurfaceVariant,
selectedLabelStyle: _textTheme(scheme).labelLarge,
unselectedLabelStyle: _textTheme(scheme).labelLarge!.copyWith(
color: scheme.onSurfaceVariant,
fontWeight: FontWeight.w600,
),
type: BottomNavigationBarType.fixed,
elevation: 0,
),
// Divider Theme
dividerTheme: DividerThemeData(
color: scheme.outlineVariant,
thickness: 1,
space: 1,
),
// Chip Theme
chipTheme: ChipThemeData(
backgroundColor: scheme.surfaceContainerHighest,
selectedColor: scheme.primaryContainer,
labelStyle: _textTheme(scheme).labelLarge,
padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 8.h),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16.r),
),
),
// Dialog Theme - Accessibility Enhanced
// dialogTheme: DialogThemeData(
// backgroundColor: darkSurface,
// elevation: 8, // More elevation
// shape: RoundedRectangleBorder(
// borderRadius: BorderRadius.circular(20.r),
// ),
// titleTextStyle: TextStyle(
// fontSize: (22.sp * fontSizeMultiplier),
// fontWeight: FontWeight.bold,
// color: darkTextPrimary,
// ),
// contentTextStyle: TextStyle(
// fontSize: (17.sp * fontSizeMultiplier),
// color: darkTextSecondary,
// height: 1.5,
// ),
// ),
// Snackbar Theme
snackBarTheme: SnackBarThemeData(
backgroundColor: scheme.inverseSurface,
contentTextStyle: _textTheme(scheme).bodyMedium!.copyWith(
color: scheme.onInverseSurface,
fontWeight: FontWeight.w600,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12.r),
),
behavior: SnackBarBehavior.floating,
),
);
}
}