OnboardingPozoAppv1/flutter_app/lib/theme.dart

176 lines
5.3 KiB
Dart
Raw Permalink Normal View History

import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
class PozoTheme {
// Brand color palette definitions
static const Color primary = Color(0xFFBA1A20);
static const Color primaryContainer = Color(0xFFD32F2F);
static const Color onPrimary = Color(0xFFFFFFFF);
static const Color background = Color(0xFFF9F9F9);
static const Color surface = Color(0xFFF9F9F9);
static const Color surfaceContainerLowest = Color(0xFFFFFFFF);
static const Color surfaceContainerLow = Color(0xFFF3F3F3);
static const Color surfaceContainerHigh = Color(0xFFE8E8E8);
static const Color onSurface = Color(0xFF1A1C1C);
static const Color onSurfaceVariant = Color(0xFF5B403D);
static const Color outline = Color(0xFF8F6F6C);
static const Color outlineVariant = Color(0xFFE4BEBA);
static const Color tertiary = Color(0xFF016619);
static const Color tertiaryFixed = Color(0xFF9DF898);
static const Color error = Color(0xFFBA1A1A);
static ThemeData get lightTheme {
return ThemeData(
useMaterial3: true,
colorScheme: const ColorScheme.light(
primary: primary,
primaryContainer: primaryContainer,
onPrimary: onPrimary,
surface: surface,
onSurface: onSurface,
onSurfaceVariant: onSurfaceVariant,
outline: outline,
outlineVariant: outlineVariant,
tertiary: tertiary,
error: error,
),
scaffoldBackgroundColor: background,
textTheme: TextTheme(
// Plus Jakarta Sans headings
displayLarge: GoogleFonts.plusJakartaSans(
fontSize: 30,
fontWeight: FontWeight.bold,
height: 1.25,
color: onSurface,
),
headlineLarge: GoogleFonts.plusJakartaSans(
fontSize: 24,
fontWeight: FontWeight.bold,
height: 1.33,
color: onSurface,
),
headlineMedium: GoogleFonts.plusJakartaSans(
fontSize: 22,
fontWeight: FontWeight.w600,
height: 1.27,
color: onSurface,
),
// Inter helper body fonts
bodyLarge: GoogleFonts.inter(
fontSize: 18,
fontWeight: FontWeight.normal,
height: 1.44,
color: onSurfaceVariant,
),
bodyMedium: GoogleFonts.inter(
fontSize: 16,
fontWeight: FontWeight.normal,
height: 1.5,
color: onSurfaceVariant,
),
labelLarge: GoogleFonts.inter(
fontSize: 20,
fontWeight: FontWeight.w600,
height: 1.2,
letterSpacing: 0.5,
),
labelMedium: GoogleFonts.inter(
fontSize: 14,
fontWeight: FontWeight.w500,
height: 1.4,
letterSpacing: 1.0,
),
labelSmall: GoogleFonts.inter(
fontSize: 11,
fontWeight: FontWeight.bold,
letterSpacing: 1.0,
),
),
// Inputs decorating styles
inputDecorationTheme: InputDecorationTheme(
filled: true,
fillColor: surfaceContainerLowest,
contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 18),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(16),
borderSide: const BorderSide(color: outlineVariant),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(16),
borderSide: const BorderSide(color: outlineVariant),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(16),
borderSide: const BorderSide(color: primary, width: 1.5),
),
errorBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(16),
borderSide: const BorderSide(color: error),
),
hintStyle: GoogleFonts.inter(color: outlineVariant, fontSize: 16),
),
// Button themes helper
elevatedButtonTheme: ElevatedButtonThemeData(
style: ElevatedButton.styleFrom(
backgroundColor: primary,
foregroundColor: onPrimary,
minimumSize: const Size.fromHeight(54),
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
textStyle: GoogleFonts.plusJakartaSans(
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
),
);
}
}
extension ResponsiveLayout on BuildContext {
double get responsivePadding {
final width = MediaQuery.of(this).size.width;
if (width < 600) {
return 16.0;
} else if (width < 1024) {
return 24.0;
} else {
return 32.0;
}
}
double get responsiveMargin {
final width = MediaQuery.of(this).size.width;
if (width < 600) {
return 12.0;
} else if (width < 1024) {
return 20.0;
} else {
return 28.0;
}
}
double get responsiveGap {
final width = MediaQuery.of(this).size.width;
if (width < 600) {
return 16.0;
} else if (width < 1024) {
return 24.0;
} else {
return 32.0;
}
}
bool get isMobile => MediaQuery.of(this).size.width < 600;
bool get isTablet => MediaQuery.of(this).size.width >= 600 && MediaQuery.of(this).size.width < 1024;
bool get isWeb => MediaQuery.of(this).size.width >= 1024;
}