runable
This commit is contained in:
460
lib/core/theme/app_theme.dart
Normal file
460
lib/core/theme/app_theme.dart
Normal file
@@ -0,0 +1,460 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
import 'package:worker/core/theme/colors.dart';
|
||||
import 'package:worker/core/theme/typography.dart';
|
||||
|
||||
/// App theme configuration for Material 3 design system
|
||||
/// Provides both light and dark theme variants
|
||||
class AppTheme {
|
||||
// Prevent instantiation
|
||||
AppTheme._();
|
||||
|
||||
// ==================== Light Theme ====================
|
||||
|
||||
/// Light theme configuration
|
||||
static ThemeData lightTheme() {
|
||||
final ColorScheme colorScheme = ColorScheme.fromSeed(
|
||||
seedColor: AppColors.primaryBlue,
|
||||
brightness: Brightness.light,
|
||||
primary: AppColors.primaryBlue,
|
||||
secondary: AppColors.lightBlue,
|
||||
tertiary: AppColors.accentCyan,
|
||||
error: AppColors.danger,
|
||||
surface: AppColors.white,
|
||||
background: AppColors.grey50,
|
||||
);
|
||||
|
||||
return ThemeData(
|
||||
useMaterial3: true,
|
||||
colorScheme: colorScheme,
|
||||
fontFamily: AppTypography.fontFamily,
|
||||
|
||||
// ==================== App Bar Theme ====================
|
||||
appBarTheme: AppBarTheme(
|
||||
elevation: 0,
|
||||
centerTitle: true,
|
||||
backgroundColor: AppColors.primaryBlue,
|
||||
foregroundColor: AppColors.white,
|
||||
titleTextStyle: AppTypography.titleLarge.copyWith(
|
||||
color: AppColors.white,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
iconTheme: const IconThemeData(
|
||||
color: AppColors.white,
|
||||
size: 24,
|
||||
),
|
||||
systemOverlayStyle: SystemUiOverlayStyle.light,
|
||||
),
|
||||
|
||||
// ==================== Card Theme ====================
|
||||
cardTheme: const CardThemeData(
|
||||
elevation: 2,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.all(Radius.circular(12)),
|
||||
),
|
||||
clipBehavior: Clip.antiAlias,
|
||||
color: AppColors.white,
|
||||
margin: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
||||
),
|
||||
|
||||
// ==================== Elevated Button Theme ====================
|
||||
elevatedButtonTheme: ElevatedButtonThemeData(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: AppColors.primaryBlue,
|
||||
foregroundColor: AppColors.white,
|
||||
elevation: 2,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
textStyle: AppTypography.buttonText,
|
||||
minimumSize: const Size(64, 48),
|
||||
),
|
||||
),
|
||||
|
||||
// ==================== Text Button Theme ====================
|
||||
textButtonTheme: TextButtonThemeData(
|
||||
style: TextButton.styleFrom(
|
||||
foregroundColor: AppColors.primaryBlue,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
textStyle: AppTypography.buttonText,
|
||||
),
|
||||
),
|
||||
|
||||
// ==================== Outlined Button Theme ====================
|
||||
outlinedButtonTheme: OutlinedButtonThemeData(
|
||||
style: OutlinedButton.styleFrom(
|
||||
foregroundColor: AppColors.primaryBlue,
|
||||
side: const BorderSide(color: AppColors.primaryBlue, width: 1.5),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
textStyle: AppTypography.buttonText,
|
||||
minimumSize: const Size(64, 48),
|
||||
),
|
||||
),
|
||||
|
||||
// ==================== Input Decoration Theme ====================
|
||||
inputDecorationTheme: InputDecorationTheme(
|
||||
filled: true,
|
||||
fillColor: AppColors.white,
|
||||
contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 16),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: const BorderSide(color: AppColors.grey100, width: 1),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: const BorderSide(color: AppColors.grey100, width: 1),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: const BorderSide(color: AppColors.primaryBlue, width: 2),
|
||||
),
|
||||
errorBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: const BorderSide(color: AppColors.danger, width: 1),
|
||||
),
|
||||
focusedErrorBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: const BorderSide(color: AppColors.danger, width: 2),
|
||||
),
|
||||
labelStyle: AppTypography.bodyMedium.copyWith(
|
||||
color: AppColors.grey500,
|
||||
),
|
||||
hintStyle: AppTypography.bodyMedium.copyWith(
|
||||
color: AppColors.grey500,
|
||||
),
|
||||
errorStyle: AppTypography.bodySmall.copyWith(
|
||||
color: AppColors.danger,
|
||||
),
|
||||
),
|
||||
|
||||
// ==================== Bottom Navigation Bar Theme ====================
|
||||
bottomNavigationBarTheme: const BottomNavigationBarThemeData(
|
||||
backgroundColor: AppColors.white,
|
||||
selectedItemColor: AppColors.primaryBlue,
|
||||
unselectedItemColor: AppColors.grey500,
|
||||
selectedIconTheme: IconThemeData(
|
||||
size: 28,
|
||||
color: AppColors.primaryBlue,
|
||||
),
|
||||
unselectedIconTheme: IconThemeData(
|
||||
size: 24,
|
||||
color: AppColors.grey500,
|
||||
),
|
||||
selectedLabelStyle: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: AppTypography.fontFamily,
|
||||
),
|
||||
unselectedLabelStyle: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.normal,
|
||||
fontFamily: AppTypography.fontFamily,
|
||||
),
|
||||
type: BottomNavigationBarType.fixed,
|
||||
elevation: 8,
|
||||
),
|
||||
|
||||
// ==================== Floating Action Button Theme ====================
|
||||
floatingActionButtonTheme: const FloatingActionButtonThemeData(
|
||||
backgroundColor: AppColors.accentCyan,
|
||||
foregroundColor: AppColors.white,
|
||||
elevation: 6,
|
||||
shape: CircleBorder(),
|
||||
iconSize: 24,
|
||||
),
|
||||
|
||||
// ==================== Chip Theme ====================
|
||||
chipTheme: ChipThemeData(
|
||||
backgroundColor: AppColors.grey50,
|
||||
selectedColor: AppColors.primaryBlue,
|
||||
disabledColor: AppColors.grey100,
|
||||
secondarySelectedColor: AppColors.lightBlue,
|
||||
labelStyle: AppTypography.labelMedium,
|
||||
secondaryLabelStyle: AppTypography.labelMedium.copyWith(
|
||||
color: AppColors.white,
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
),
|
||||
|
||||
// ==================== Dialog Theme ====================
|
||||
dialogTheme: const DialogThemeData(
|
||||
backgroundColor: AppColors.white,
|
||||
elevation: 8,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.all(Radius.circular(16)),
|
||||
),
|
||||
).copyWith(
|
||||
titleTextStyle: AppTypography.headlineMedium.copyWith(
|
||||
color: AppColors.grey900,
|
||||
),
|
||||
contentTextStyle: AppTypography.bodyLarge.copyWith(
|
||||
color: AppColors.grey900,
|
||||
),
|
||||
),
|
||||
|
||||
// ==================== Snackbar Theme ====================
|
||||
snackBarTheme: SnackBarThemeData(
|
||||
backgroundColor: AppColors.grey900,
|
||||
contentTextStyle: AppTypography.bodyMedium.copyWith(
|
||||
color: AppColors.white,
|
||||
),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
behavior: SnackBarBehavior.floating,
|
||||
elevation: 4,
|
||||
),
|
||||
|
||||
// ==================== Divider Theme ====================
|
||||
dividerTheme: const DividerThemeData(
|
||||
color: AppColors.grey100,
|
||||
thickness: 1,
|
||||
space: 1,
|
||||
),
|
||||
|
||||
// ==================== Icon Theme ====================
|
||||
iconTheme: const IconThemeData(
|
||||
color: AppColors.grey900,
|
||||
size: 24,
|
||||
),
|
||||
|
||||
// ==================== List Tile Theme ====================
|
||||
listTileTheme: ListTileThemeData(
|
||||
contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
||||
titleTextStyle: AppTypography.titleMedium.copyWith(
|
||||
color: AppColors.grey900,
|
||||
),
|
||||
subtitleTextStyle: AppTypography.bodyMedium.copyWith(
|
||||
color: AppColors.grey500,
|
||||
),
|
||||
iconColor: AppColors.grey500,
|
||||
),
|
||||
|
||||
// ==================== Switch Theme ====================
|
||||
switchTheme: SwitchThemeData(
|
||||
thumbColor: MaterialStateProperty.resolveWith((states) {
|
||||
if (states.contains(MaterialState.selected)) {
|
||||
return AppColors.primaryBlue;
|
||||
}
|
||||
return AppColors.grey500;
|
||||
}),
|
||||
trackColor: MaterialStateProperty.resolveWith((states) {
|
||||
if (states.contains(MaterialState.selected)) {
|
||||
return AppColors.lightBlue;
|
||||
}
|
||||
return AppColors.grey100;
|
||||
}),
|
||||
),
|
||||
|
||||
// ==================== Checkbox Theme ====================
|
||||
checkboxTheme: CheckboxThemeData(
|
||||
fillColor: MaterialStateProperty.resolveWith((states) {
|
||||
if (states.contains(MaterialState.selected)) {
|
||||
return AppColors.primaryBlue;
|
||||
}
|
||||
return AppColors.white;
|
||||
}),
|
||||
checkColor: MaterialStateProperty.all(AppColors.white),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
),
|
||||
|
||||
// ==================== Radio Theme ====================
|
||||
radioTheme: RadioThemeData(
|
||||
fillColor: MaterialStateProperty.resolveWith((states) {
|
||||
if (states.contains(MaterialState.selected)) {
|
||||
return AppColors.primaryBlue;
|
||||
}
|
||||
return AppColors.grey500;
|
||||
}),
|
||||
),
|
||||
|
||||
// ==================== Progress Indicator Theme ====================
|
||||
progressIndicatorTheme: const ProgressIndicatorThemeData(
|
||||
color: AppColors.primaryBlue,
|
||||
linearTrackColor: AppColors.grey100,
|
||||
circularTrackColor: AppColors.grey100,
|
||||
),
|
||||
|
||||
// ==================== Badge Theme ====================
|
||||
badgeTheme: const BadgeThemeData(
|
||||
backgroundColor: AppColors.danger,
|
||||
textColor: AppColors.white,
|
||||
smallSize: 6,
|
||||
largeSize: 16,
|
||||
),
|
||||
|
||||
// ==================== Tab Bar Theme ====================
|
||||
tabBarTheme: const TabBarThemeData(
|
||||
labelColor: AppColors.primaryBlue,
|
||||
unselectedLabelColor: AppColors.grey500,
|
||||
indicatorColor: AppColors.primaryBlue,
|
||||
).copyWith(
|
||||
labelStyle: AppTypography.labelLarge,
|
||||
unselectedLabelStyle: AppTypography.labelLarge,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// ==================== Dark Theme ====================
|
||||
|
||||
/// Dark theme configuration
|
||||
static ThemeData darkTheme() {
|
||||
final ColorScheme colorScheme = ColorScheme.fromSeed(
|
||||
seedColor: AppColors.primaryBlue,
|
||||
brightness: Brightness.dark,
|
||||
primary: AppColors.lightBlue,
|
||||
secondary: AppColors.accentCyan,
|
||||
tertiary: AppColors.primaryBlue,
|
||||
error: AppColors.danger,
|
||||
surface: const Color(0xFF1E1E1E),
|
||||
background: const Color(0xFF121212),
|
||||
);
|
||||
|
||||
return ThemeData(
|
||||
useMaterial3: true,
|
||||
colorScheme: colorScheme,
|
||||
fontFamily: AppTypography.fontFamily,
|
||||
|
||||
// ==================== App Bar Theme ====================
|
||||
appBarTheme: AppBarTheme(
|
||||
elevation: 0,
|
||||
centerTitle: true,
|
||||
backgroundColor: const Color(0xFF1E1E1E),
|
||||
foregroundColor: AppColors.white,
|
||||
titleTextStyle: AppTypography.titleLarge.copyWith(
|
||||
color: AppColors.white,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
iconTheme: const IconThemeData(
|
||||
color: AppColors.white,
|
||||
size: 24,
|
||||
),
|
||||
systemOverlayStyle: SystemUiOverlayStyle.light,
|
||||
),
|
||||
|
||||
// ==================== Card Theme ====================
|
||||
cardTheme: const CardThemeData(
|
||||
elevation: 2,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.all(Radius.circular(12)),
|
||||
),
|
||||
clipBehavior: Clip.antiAlias,
|
||||
color: Color(0xFF1E1E1E),
|
||||
margin: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
||||
),
|
||||
|
||||
// ==================== Elevated Button Theme ====================
|
||||
elevatedButtonTheme: ElevatedButtonThemeData(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: AppColors.lightBlue,
|
||||
foregroundColor: AppColors.white,
|
||||
elevation: 2,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
textStyle: AppTypography.buttonText,
|
||||
minimumSize: const Size(64, 48),
|
||||
),
|
||||
),
|
||||
|
||||
// ==================== Input Decoration Theme ====================
|
||||
inputDecorationTheme: InputDecorationTheme(
|
||||
filled: true,
|
||||
fillColor: const Color(0xFF2A2A2A),
|
||||
contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 16),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: const BorderSide(color: Color(0xFF3A3A3A), width: 1),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: const BorderSide(color: Color(0xFF3A3A3A), width: 1),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: const BorderSide(color: AppColors.lightBlue, width: 2),
|
||||
),
|
||||
errorBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: const BorderSide(color: AppColors.danger, width: 1),
|
||||
),
|
||||
focusedErrorBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: const BorderSide(color: AppColors.danger, width: 2),
|
||||
),
|
||||
labelStyle: AppTypography.bodyMedium.copyWith(
|
||||
color: AppColors.grey500,
|
||||
),
|
||||
hintStyle: AppTypography.bodyMedium.copyWith(
|
||||
color: AppColors.grey500,
|
||||
),
|
||||
errorStyle: AppTypography.bodySmall.copyWith(
|
||||
color: AppColors.danger,
|
||||
),
|
||||
),
|
||||
|
||||
// ==================== Bottom Navigation Bar Theme ====================
|
||||
bottomNavigationBarTheme: const BottomNavigationBarThemeData(
|
||||
backgroundColor: Color(0xFF1E1E1E),
|
||||
selectedItemColor: AppColors.lightBlue,
|
||||
unselectedItemColor: AppColors.grey500,
|
||||
selectedIconTheme: IconThemeData(
|
||||
size: 28,
|
||||
color: AppColors.lightBlue,
|
||||
),
|
||||
unselectedIconTheme: IconThemeData(
|
||||
size: 24,
|
||||
color: AppColors.grey500,
|
||||
),
|
||||
selectedLabelStyle: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: AppTypography.fontFamily,
|
||||
),
|
||||
unselectedLabelStyle: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.normal,
|
||||
fontFamily: AppTypography.fontFamily,
|
||||
),
|
||||
type: BottomNavigationBarType.fixed,
|
||||
elevation: 8,
|
||||
),
|
||||
|
||||
// ==================== Floating Action Button Theme ====================
|
||||
floatingActionButtonTheme: const FloatingActionButtonThemeData(
|
||||
backgroundColor: AppColors.accentCyan,
|
||||
foregroundColor: AppColors.white,
|
||||
elevation: 6,
|
||||
shape: CircleBorder(),
|
||||
iconSize: 24,
|
||||
),
|
||||
|
||||
// ==================== Snackbar Theme ====================
|
||||
snackBarTheme: SnackBarThemeData(
|
||||
backgroundColor: const Color(0xFF2A2A2A),
|
||||
contentTextStyle: AppTypography.bodyMedium.copyWith(
|
||||
color: AppColors.white,
|
||||
),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
behavior: SnackBarBehavior.floating,
|
||||
elevation: 4,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
68
lib/core/theme/colors.dart
Normal file
68
lib/core/theme/colors.dart
Normal file
@@ -0,0 +1,68 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/// App color palette following the Worker app design system.
|
||||
///
|
||||
/// Primary colors are used for main UI elements, tier colors for membership cards,
|
||||
/// status colors for feedback, and neutral colors for text and backgrounds.
|
||||
class AppColors {
|
||||
// Primary Colors
|
||||
/// Main brand color - Used for primary buttons, app bar, etc.
|
||||
static const primaryBlue = Color(0xFF005B9A);
|
||||
|
||||
/// Light variant of primary color - Used for highlights and accents
|
||||
static const lightBlue = Color(0xFF38B6FF);
|
||||
|
||||
/// Accent color for special actions - Used for FAB, links, etc.
|
||||
static const accentCyan = Color(0xFF35C6F4);
|
||||
|
||||
// Status Colors
|
||||
/// Success state - Used for completed actions, positive feedback
|
||||
static const success = Color(0xFF28a745);
|
||||
|
||||
/// Warning state - Used for caution messages, pending states
|
||||
static const warning = Color(0xFFffc107);
|
||||
|
||||
/// Danger/Error state - Used for errors, destructive actions
|
||||
static const danger = Color(0xFFdc3545);
|
||||
|
||||
/// Info state - Used for informational messages
|
||||
static const info = Color(0xFF17a2b8);
|
||||
|
||||
// Neutral Colors
|
||||
/// Lightest background shade
|
||||
static const grey50 = Color(0xFFf8f9fa);
|
||||
|
||||
/// Light background/border shade
|
||||
static const grey100 = Color(0xFFe9ecef);
|
||||
|
||||
/// Medium grey for secondary text
|
||||
static const grey500 = Color(0xFF6c757d);
|
||||
|
||||
/// Dark grey for primary text
|
||||
static const grey900 = Color(0xFF343a40);
|
||||
|
||||
/// Pure white
|
||||
static const white = Color(0xFFFFFFFF);
|
||||
|
||||
// Tier Gradients for Membership Cards
|
||||
/// Diamond tier gradient (purple-blue)
|
||||
static const diamondGradient = LinearGradient(
|
||||
colors: [Color(0xFF4A00E0), Color(0xFF8E2DE2)],
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
);
|
||||
|
||||
/// Platinum tier gradient (grey-silver)
|
||||
static const platinumGradient = LinearGradient(
|
||||
colors: [Color(0xFF7F8C8D), Color(0xFFBDC3C7)],
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
);
|
||||
|
||||
/// Gold tier gradient (yellow-orange)
|
||||
static const goldGradient = LinearGradient(
|
||||
colors: [Color(0xFFf7b733), Color(0xFFfc4a1a)],
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
);
|
||||
}
|
||||
243
lib/core/theme/typography.dart
Normal file
243
lib/core/theme/typography.dart
Normal file
@@ -0,0 +1,243 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/// App typography system following Material 3 type scale
|
||||
/// Uses Roboto as the primary font family
|
||||
class AppTypography {
|
||||
// Prevent instantiation
|
||||
AppTypography._();
|
||||
|
||||
/// Font family used throughout the app
|
||||
static const String fontFamily = 'Roboto';
|
||||
|
||||
// ==================== Display Styles ====================
|
||||
|
||||
/// Display Large - 32sp, Bold
|
||||
/// Used for: Large hero text, splash screens
|
||||
static const TextStyle displayLarge = TextStyle(
|
||||
fontSize: 32,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontFamily: fontFamily,
|
||||
letterSpacing: 0,
|
||||
height: 1.2,
|
||||
);
|
||||
|
||||
/// Display Medium - 28sp, Semi-bold
|
||||
/// Used for: Page titles, section headers
|
||||
static const TextStyle displayMedium = TextStyle(
|
||||
fontSize: 28,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: fontFamily,
|
||||
letterSpacing: 0,
|
||||
height: 1.2,
|
||||
);
|
||||
|
||||
/// Display Small - 24sp, Semi-bold
|
||||
/// Used for: Sub-section headers
|
||||
static const TextStyle displaySmall = TextStyle(
|
||||
fontSize: 24,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: fontFamily,
|
||||
letterSpacing: 0,
|
||||
height: 1.3,
|
||||
);
|
||||
|
||||
// ==================== Headline Styles ====================
|
||||
|
||||
/// Headline Large - 24sp, Semi-bold
|
||||
/// Used for: Main headings, dialog titles
|
||||
static const TextStyle headlineLarge = TextStyle(
|
||||
fontSize: 24,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: fontFamily,
|
||||
letterSpacing: 0,
|
||||
height: 1.3,
|
||||
);
|
||||
|
||||
/// Headline Medium - 20sp, Semi-bold
|
||||
/// Used for: Card titles, list headers
|
||||
static const TextStyle headlineMedium = TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: fontFamily,
|
||||
letterSpacing: 0.15,
|
||||
height: 1.3,
|
||||
);
|
||||
|
||||
/// Headline Small - 18sp, Medium
|
||||
/// Used for: Small headers, emphasized text
|
||||
static const TextStyle headlineSmall = TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w500,
|
||||
fontFamily: fontFamily,
|
||||
letterSpacing: 0.15,
|
||||
height: 1.4,
|
||||
);
|
||||
|
||||
// ==================== Title Styles ====================
|
||||
|
||||
/// Title Large - 20sp, Medium
|
||||
/// Used for: App bar titles, prominent labels
|
||||
static const TextStyle titleLarge = TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.w500,
|
||||
fontFamily: fontFamily,
|
||||
letterSpacing: 0.15,
|
||||
height: 1.4,
|
||||
);
|
||||
|
||||
/// Title Medium - 16sp, Medium
|
||||
/// Used for: List item titles, card headers
|
||||
static const TextStyle titleMedium = TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
fontFamily: fontFamily,
|
||||
letterSpacing: 0.15,
|
||||
height: 1.5,
|
||||
);
|
||||
|
||||
/// Title Small - 14sp, Medium
|
||||
/// Used for: Small titles, tab labels
|
||||
static const TextStyle titleSmall = TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
fontFamily: fontFamily,
|
||||
letterSpacing: 0.1,
|
||||
height: 1.5,
|
||||
);
|
||||
|
||||
// ==================== Body Styles ====================
|
||||
|
||||
/// Body Large - 16sp, Regular
|
||||
/// Used for: Main body text, descriptions
|
||||
static const TextStyle bodyLarge = TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.normal,
|
||||
fontFamily: fontFamily,
|
||||
letterSpacing: 0.5,
|
||||
height: 1.5,
|
||||
);
|
||||
|
||||
/// Body Medium - 14sp, Regular
|
||||
/// Used for: Secondary body text, captions
|
||||
static const TextStyle bodyMedium = TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.normal,
|
||||
fontFamily: fontFamily,
|
||||
letterSpacing: 0.25,
|
||||
height: 1.5,
|
||||
);
|
||||
|
||||
/// Body Small - 12sp, Regular
|
||||
/// Used for: Small body text, helper text
|
||||
static const TextStyle bodySmall = TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.normal,
|
||||
fontFamily: fontFamily,
|
||||
letterSpacing: 0.4,
|
||||
height: 1.5,
|
||||
);
|
||||
|
||||
// ==================== Label Styles ====================
|
||||
|
||||
/// Label Large - 14sp, Medium
|
||||
/// Used for: Button text, input labels
|
||||
static const TextStyle labelLarge = TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
fontFamily: fontFamily,
|
||||
letterSpacing: 0.1,
|
||||
height: 1.4,
|
||||
);
|
||||
|
||||
/// Label Medium - 12sp, Medium
|
||||
/// Used for: Small button text, chips
|
||||
static const TextStyle labelMedium = TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
fontFamily: fontFamily,
|
||||
letterSpacing: 0.5,
|
||||
height: 1.4,
|
||||
);
|
||||
|
||||
/// Label Small - 12sp, Regular
|
||||
/// Used for: Overline text, tags, badges
|
||||
static const TextStyle labelSmall = TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.normal,
|
||||
fontFamily: fontFamily,
|
||||
letterSpacing: 0.5,
|
||||
height: 1.4,
|
||||
);
|
||||
|
||||
// ==================== Special Purpose Styles ====================
|
||||
|
||||
/// Points Display - 28sp, Bold
|
||||
/// Used for: Loyalty points display on member cards
|
||||
static const TextStyle pointsDisplay = TextStyle(
|
||||
fontSize: 28,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontFamily: fontFamily,
|
||||
letterSpacing: 0,
|
||||
height: 1.2,
|
||||
);
|
||||
|
||||
/// Price Large - 20sp, Bold
|
||||
/// Used for: Product prices, totals
|
||||
static const TextStyle priceLarge = TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontFamily: fontFamily,
|
||||
letterSpacing: 0,
|
||||
height: 1.3,
|
||||
);
|
||||
|
||||
/// Price Medium - 16sp, Semi-bold
|
||||
/// Used for: List item prices
|
||||
static const TextStyle priceMedium = TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: fontFamily,
|
||||
letterSpacing: 0,
|
||||
height: 1.3,
|
||||
);
|
||||
|
||||
/// Price Small - 14sp, Semi-bold
|
||||
/// Used for: Small price displays
|
||||
static const TextStyle priceSmall = TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: fontFamily,
|
||||
letterSpacing: 0,
|
||||
height: 1.3,
|
||||
);
|
||||
|
||||
/// Button Text - 14sp, Medium
|
||||
/// Used for: All button labels
|
||||
static const TextStyle buttonText = TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
fontFamily: fontFamily,
|
||||
letterSpacing: 1.25,
|
||||
height: 1.0,
|
||||
);
|
||||
|
||||
/// Overline - 10sp, Medium, Uppercase
|
||||
/// Used for: Section labels, categories
|
||||
static const TextStyle overline = TextStyle(
|
||||
fontSize: 10,
|
||||
fontWeight: FontWeight.w500,
|
||||
fontFamily: fontFamily,
|
||||
letterSpacing: 1.5,
|
||||
height: 1.6,
|
||||
);
|
||||
|
||||
/// Caption - 12sp, Regular
|
||||
/// Used for: Image captions, timestamps
|
||||
static const TextStyle caption = TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.normal,
|
||||
fontFamily: fontFamily,
|
||||
letterSpacing: 0.4,
|
||||
height: 1.33,
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user