472 lines
17 KiB
Dart
472 lines
17 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
|
|
|
class AppTheme {
|
|
// ACCESSIBILITY: Larger font size multiplier for elderly users (50+)
|
|
static const double fontSizeMultiplier = 1.3; // 30% larger fonts
|
|
|
|
// Brand Colors - Enhanced for better contrast
|
|
static const Color primaryGreen = Color(0xFF2E7D32); // Dark green for contrast
|
|
static const Color primaryGold = Color(0xFFFFD700);
|
|
static const Color accentBlue = Color(0xFF1565C0); // Darker blue for better contrast
|
|
static const Color accentOrange = Color(0xFFE65100); // Darker orange for better contrast
|
|
static const Color accentRed = Color(0xFFC62828); // Darker red for better contrast
|
|
|
|
// Light Theme Colors - High Contrast
|
|
static const Color lightBackground = Color(0xFFFFFFFF); // Pure white for maximum contrast
|
|
static const Color lightSurface = Color(0xFFFFFFFF);
|
|
static const Color lightPrimary = primaryGreen;
|
|
static const Color lightOnPrimary = Color(0xFFFFFFFF);
|
|
static const Color lightTextPrimary = Color(0xFF000000); // Pure black text
|
|
static const Color lightTextSecondary = Color(0xFF424242); // Dark grey, still readable
|
|
|
|
// Dark Theme Colors - High Contrast
|
|
static const Color darkBackground = Color(0xFF000000); // Pure black for maximum contrast
|
|
static const Color darkSurface = Color(0xFF121212);
|
|
static const Color darkPrimary = Color(0xFF66BB6A); // Brighter green for dark mode
|
|
static const Color darkOnPrimary = Color(0xFF000000);
|
|
static const Color darkTextPrimary = Color(0xFFFFFFFF); // Pure white text
|
|
static const Color darkTextSecondary = Color(0xFFE0E0E0); // Light grey, still readable
|
|
|
|
/// Light Theme
|
|
static ThemeData get lightTheme {
|
|
return ThemeData(
|
|
useMaterial3: true,
|
|
brightness: Brightness.light,
|
|
primaryColor: lightPrimary,
|
|
scaffoldBackgroundColor: lightBackground,
|
|
|
|
// Color Scheme
|
|
colorScheme: const ColorScheme.light(
|
|
primary: lightPrimary,
|
|
secondary: accentBlue,
|
|
tertiary: accentOrange,
|
|
error: accentRed,
|
|
surface: lightSurface,
|
|
onPrimary: lightOnPrimary,
|
|
onSecondary: Colors.white,
|
|
onSurface: Color(0xFF212121),
|
|
onError: Colors.white,
|
|
),
|
|
|
|
// AppBar Theme - Accessibility Enhanced
|
|
appBarTheme: AppBarTheme(
|
|
elevation: 3, // More elevation for better definition
|
|
centerTitle: false,
|
|
backgroundColor: lightPrimary,
|
|
foregroundColor: Colors.white,
|
|
titleTextStyle: TextStyle(
|
|
fontSize: (20.sp * fontSizeMultiplier), // Larger title
|
|
fontWeight: FontWeight.bold, // Bolder for better readability
|
|
color: Colors.white,
|
|
letterSpacing: 0.5, // Better spacing
|
|
),
|
|
iconTheme: IconThemeData(
|
|
color: Colors.white,
|
|
size: (28.w * fontSizeMultiplier), // Larger icons
|
|
),
|
|
),
|
|
|
|
// Card Theme
|
|
// Temporarily commented out due to compilation issue
|
|
// cardTheme: const CardThemeData(
|
|
// elevation: 2,
|
|
// ),
|
|
|
|
// Elevated Button Theme - Accessibility Enhanced
|
|
elevatedButtonTheme: ElevatedButtonThemeData(
|
|
style: ElevatedButton.styleFrom(
|
|
backgroundColor: lightPrimary,
|
|
foregroundColor: lightOnPrimary,
|
|
elevation: 4, // More elevation for better depth perception
|
|
padding: EdgeInsets.symmetric(
|
|
horizontal: (28.w * fontSizeMultiplier), // Larger touch target
|
|
vertical: (16.h * fontSizeMultiplier), // Taller buttons
|
|
),
|
|
minimumSize: Size(0, (52.h * fontSizeMultiplier)), // Minimum 50px height
|
|
textStyle: TextStyle(
|
|
fontSize: (18.sp * fontSizeMultiplier), // Larger text
|
|
fontWeight: FontWeight.bold, // Bolder
|
|
letterSpacing: 0.8, // Better spacing
|
|
),
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.circular(16.r), // More rounded
|
|
),
|
|
),
|
|
),
|
|
|
|
// Outlined Button Theme - Accessibility Enhanced
|
|
outlinedButtonTheme: OutlinedButtonThemeData(
|
|
style: OutlinedButton.styleFrom(
|
|
foregroundColor: lightPrimary,
|
|
side: const BorderSide(color: lightPrimary, width: 3), // Thicker border
|
|
padding: EdgeInsets.symmetric(
|
|
horizontal: (28.w * fontSizeMultiplier),
|
|
vertical: (16.h * fontSizeMultiplier),
|
|
),
|
|
minimumSize: Size(0, (52.h * fontSizeMultiplier)),
|
|
textStyle: TextStyle(
|
|
fontSize: (18.sp * fontSizeMultiplier),
|
|
fontWeight: FontWeight.bold,
|
|
letterSpacing: 0.8,
|
|
),
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.circular(16.r),
|
|
),
|
|
),
|
|
),
|
|
|
|
// Text Button Theme - Accessibility Enhanced
|
|
textButtonTheme: TextButtonThemeData(
|
|
style: TextButton.styleFrom(
|
|
foregroundColor: lightPrimary,
|
|
padding: EdgeInsets.symmetric(
|
|
horizontal: (20.w * fontSizeMultiplier),
|
|
vertical: (14.h * fontSizeMultiplier),
|
|
),
|
|
minimumSize: Size(0, (48.h * fontSizeMultiplier)),
|
|
textStyle: TextStyle(
|
|
fontSize: (18.sp * fontSizeMultiplier),
|
|
fontWeight: FontWeight.bold,
|
|
letterSpacing: 0.8,
|
|
),
|
|
),
|
|
),
|
|
|
|
// Input Decoration Theme - Accessibility Enhanced
|
|
inputDecorationTheme: InputDecorationTheme(
|
|
filled: true,
|
|
fillColor: Colors.grey.shade50,
|
|
border: OutlineInputBorder(
|
|
borderRadius: BorderRadius.circular(16.r),
|
|
borderSide: BorderSide(color: Colors.grey.shade400, width: 2), // Thicker border
|
|
),
|
|
enabledBorder: OutlineInputBorder(
|
|
borderRadius: BorderRadius.circular(16.r),
|
|
borderSide: BorderSide(color: Colors.grey.shade400, width: 2),
|
|
),
|
|
focusedBorder: OutlineInputBorder(
|
|
borderRadius: BorderRadius.circular(16.r),
|
|
borderSide: const BorderSide(color: lightPrimary, width: 3), // Thicker focus border
|
|
),
|
|
errorBorder: OutlineInputBorder(
|
|
borderRadius: BorderRadius.circular(16.r),
|
|
borderSide: const BorderSide(color: accentRed, width: 3),
|
|
),
|
|
contentPadding: EdgeInsets.symmetric(
|
|
horizontal: (20.w * fontSizeMultiplier),
|
|
vertical: (18.h * fontSizeMultiplier), // More padding
|
|
),
|
|
labelStyle: TextStyle(
|
|
fontSize: (17.sp * fontSizeMultiplier), // Larger labels
|
|
fontWeight: FontWeight.w600,
|
|
),
|
|
hintStyle: TextStyle(
|
|
fontSize: (17.sp * fontSizeMultiplier),
|
|
color: Colors.grey.shade600,
|
|
),
|
|
),
|
|
|
|
// Icon Theme - Accessibility Enhanced
|
|
iconTheme: IconThemeData(
|
|
color: Colors.grey.shade800, // Darker for better contrast
|
|
size: (28.w * fontSizeMultiplier), // Larger icons
|
|
),
|
|
|
|
// Floating Action Button Theme
|
|
floatingActionButtonTheme: FloatingActionButtonThemeData(
|
|
backgroundColor: lightPrimary,
|
|
foregroundColor: lightOnPrimary,
|
|
elevation: 4,
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.circular(16.r),
|
|
),
|
|
),
|
|
|
|
// Bottom Navigation Bar Theme - Accessibility Enhanced
|
|
bottomNavigationBarTheme: BottomNavigationBarThemeData(
|
|
backgroundColor: lightSurface,
|
|
selectedItemColor: lightPrimary,
|
|
unselectedItemColor: Colors.grey.shade700, // Darker for better contrast
|
|
selectedLabelStyle: TextStyle(
|
|
fontSize: (15.sp * fontSizeMultiplier), // Larger labels
|
|
fontWeight: FontWeight.bold,
|
|
),
|
|
unselectedLabelStyle: TextStyle(
|
|
fontSize: (14.sp * fontSizeMultiplier),
|
|
fontWeight: FontWeight.w600,
|
|
),
|
|
selectedIconTheme: IconThemeData(
|
|
size: (32.w * fontSizeMultiplier), // Larger icons
|
|
),
|
|
unselectedIconTheme: IconThemeData(
|
|
size: (28.w * fontSizeMultiplier),
|
|
),
|
|
type: BottomNavigationBarType.fixed,
|
|
elevation: 8,
|
|
),
|
|
|
|
// Divider Theme - Accessibility Enhanced
|
|
dividerTheme: DividerThemeData(
|
|
color: Colors.grey.shade400, // Darker for better visibility
|
|
thickness: 2, // Thicker for better visibility
|
|
space: 2,
|
|
),
|
|
|
|
// Chip Theme - Accessibility Enhanced
|
|
chipTheme: ChipThemeData(
|
|
backgroundColor: Colors.grey.shade200,
|
|
selectedColor: lightPrimary.withOpacity(0.2),
|
|
labelStyle: TextStyle(
|
|
fontSize: (16.sp * fontSizeMultiplier), // Larger text
|
|
fontWeight: FontWeight.w600,
|
|
),
|
|
padding: EdgeInsets.symmetric(
|
|
horizontal: (16.w * fontSizeMultiplier),
|
|
vertical: (12.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: Colors.grey.shade900, // Darker for better contrast
|
|
contentTextStyle: TextStyle(
|
|
fontSize: (17.sp * fontSizeMultiplier), // Larger text
|
|
color: Colors.white,
|
|
fontWeight: FontWeight.w600,
|
|
),
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.circular(16.r),
|
|
),
|
|
behavior: SnackBarBehavior.floating,
|
|
actionTextColor: primaryGold, // High contrast action color
|
|
),
|
|
);
|
|
}
|
|
|
|
/// Dark Theme
|
|
static ThemeData get darkTheme {
|
|
return ThemeData(
|
|
useMaterial3: true,
|
|
brightness: Brightness.dark,
|
|
primaryColor: darkPrimary,
|
|
scaffoldBackgroundColor: darkBackground,
|
|
|
|
// Color Scheme
|
|
colorScheme: const ColorScheme.dark(
|
|
primary: darkPrimary,
|
|
secondary: accentBlue,
|
|
tertiary: accentOrange,
|
|
error: accentRed,
|
|
surface: darkSurface,
|
|
onPrimary: darkOnPrimary,
|
|
onSecondary: Colors.white,
|
|
onSurface: Color(0xFFE0E0E0),
|
|
onError: Colors.white,
|
|
),
|
|
|
|
// AppBar Theme - Accessibility Enhanced
|
|
appBarTheme: AppBarTheme(
|
|
elevation: 3,
|
|
centerTitle: false,
|
|
backgroundColor: darkSurface,
|
|
foregroundColor: Colors.white,
|
|
titleTextStyle: TextStyle(
|
|
fontSize: (20.sp * fontSizeMultiplier),
|
|
fontWeight: FontWeight.bold,
|
|
color: Colors.white,
|
|
letterSpacing: 0.5,
|
|
),
|
|
iconTheme: IconThemeData(
|
|
color: Colors.white,
|
|
size: (28.w * fontSizeMultiplier),
|
|
),
|
|
),
|
|
|
|
// Card Theme - Accessibility Enhanced
|
|
// cardTheme: CardThemeData(
|
|
// elevation: 6, // More elevation for better depth in dark mode
|
|
// color: darkSurface,
|
|
// shape: RoundedRectangleBorder(
|
|
// borderRadius: BorderRadius.circular(16.r),
|
|
// ),
|
|
// margin: EdgeInsets.symmetric(horizontal: 8.w, vertical: 6.h), // More spacing
|
|
// ),
|
|
|
|
// Elevated Button Theme - Accessibility Enhanced
|
|
elevatedButtonTheme: ElevatedButtonThemeData(
|
|
style: ElevatedButton.styleFrom(
|
|
backgroundColor: darkPrimary,
|
|
foregroundColor: darkOnPrimary,
|
|
elevation: 4,
|
|
padding: EdgeInsets.symmetric(
|
|
horizontal: (28.w * fontSizeMultiplier),
|
|
vertical: (16.h * fontSizeMultiplier),
|
|
),
|
|
minimumSize: Size(0, (52.h * fontSizeMultiplier)),
|
|
textStyle: TextStyle(
|
|
fontSize: (18.sp * fontSizeMultiplier),
|
|
fontWeight: FontWeight.bold,
|
|
letterSpacing: 0.8,
|
|
),
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.circular(16.r),
|
|
),
|
|
),
|
|
),
|
|
|
|
// Outlined Button Theme - Accessibility Enhanced
|
|
outlinedButtonTheme: OutlinedButtonThemeData(
|
|
style: OutlinedButton.styleFrom(
|
|
foregroundColor: darkPrimary,
|
|
side: BorderSide(color: darkPrimary, width: 3), // Thicker border
|
|
padding: EdgeInsets.symmetric(
|
|
horizontal: (28.w * fontSizeMultiplier),
|
|
vertical: (16.h * fontSizeMultiplier),
|
|
),
|
|
minimumSize: Size(0, (52.h * fontSizeMultiplier)),
|
|
textStyle: TextStyle(
|
|
fontSize: (18.sp * fontSizeMultiplier),
|
|
fontWeight: FontWeight.bold,
|
|
letterSpacing: 0.8,
|
|
),
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.circular(16.r),
|
|
),
|
|
),
|
|
),
|
|
|
|
// Text Button Theme
|
|
textButtonTheme: TextButtonThemeData(
|
|
style: TextButton.styleFrom(
|
|
foregroundColor: darkPrimary,
|
|
padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 8.h),
|
|
textStyle: TextStyle(
|
|
fontSize: 16.sp,
|
|
fontWeight: FontWeight.w600,
|
|
),
|
|
),
|
|
),
|
|
|
|
// Input Decoration Theme
|
|
inputDecorationTheme: InputDecorationTheme(
|
|
filled: true,
|
|
fillColor: const Color(0xFF2C2C2C),
|
|
border: OutlineInputBorder(
|
|
borderRadius: BorderRadius.circular(12.r),
|
|
borderSide: const BorderSide(color: Color(0xFF424242)),
|
|
),
|
|
enabledBorder: OutlineInputBorder(
|
|
borderRadius: BorderRadius.circular(12.r),
|
|
borderSide: const BorderSide(color: Color(0xFF424242)),
|
|
),
|
|
focusedBorder: OutlineInputBorder(
|
|
borderRadius: BorderRadius.circular(12.r),
|
|
borderSide: const BorderSide(color: darkPrimary, width: 2),
|
|
),
|
|
errorBorder: OutlineInputBorder(
|
|
borderRadius: BorderRadius.circular(12.r),
|
|
borderSide: const BorderSide(color: accentRed, width: 2),
|
|
),
|
|
contentPadding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 16.h),
|
|
),
|
|
|
|
// Icon Theme
|
|
iconTheme: IconThemeData(
|
|
color: Colors.grey.shade400,
|
|
size: 24.w,
|
|
),
|
|
|
|
// Floating Action Button Theme
|
|
floatingActionButtonTheme: FloatingActionButtonThemeData(
|
|
backgroundColor: darkPrimary,
|
|
foregroundColor: darkOnPrimary,
|
|
elevation: 4,
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.circular(16.r),
|
|
),
|
|
),
|
|
|
|
// Bottom Navigation Bar Theme
|
|
bottomNavigationBarTheme: BottomNavigationBarThemeData(
|
|
backgroundColor: darkSurface,
|
|
selectedItemColor: darkPrimary,
|
|
unselectedItemColor: Colors.grey.shade500,
|
|
selectedLabelStyle: TextStyle(fontSize: 12.sp, fontWeight: FontWeight.w600),
|
|
unselectedLabelStyle: TextStyle(fontSize: 12.sp),
|
|
type: BottomNavigationBarType.fixed,
|
|
elevation: 8,
|
|
),
|
|
|
|
// Divider Theme
|
|
dividerTheme: const DividerThemeData(
|
|
color: Color(0xFF424242),
|
|
thickness: 1,
|
|
space: 1,
|
|
),
|
|
|
|
// Chip Theme
|
|
chipTheme: ChipThemeData(
|
|
backgroundColor: const Color(0xFF2C2C2C),
|
|
selectedColor: darkPrimary.withOpacity(0.2),
|
|
labelStyle: TextStyle(fontSize: 14.sp, color: Colors.white),
|
|
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: const Color(0xFF323232),
|
|
contentTextStyle: TextStyle(fontSize: 14.sp, color: Colors.white),
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.circular(12.r),
|
|
),
|
|
behavior: SnackBarBehavior.floating,
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|