bible-tracker/lib/widgets/theme.dart
2026-04-20 14:39:49 -04:00

101 lines
2.9 KiB
Dart

import 'package:flutter/material.dart';
/// Design tokens and theme construction for Bible Tracker.
///
/// Refer to `DESIGN_GUIDE.md` for the rationale behind each token.
class AppTokens {
const AppTokens._();
// Seed color — warm, scripture-inspired indigo.
static const Color seed = Color(0xFF3F51B5);
// Default palette offered when creating a new tracker.
static const List<Color> trackerPalette = <Color>[
Color(0xFF3F51B5), // indigo
Color(0xFF1E88E5), // blue
Color(0xFF00897B), // teal
Color(0xFF43A047), // green
Color(0xFFFDD835), // amber
Color(0xFFFB8C00), // orange
Color(0xFFE53935), // red
Color(0xFFD81B60), // pink
Color(0xFF8E24AA), // purple
Color(0xFF6D4C41), // brown
];
// Spacing scale (8pt grid).
static const double spaceXS = 4;
static const double spaceS = 8;
static const double spaceM = 12;
static const double spaceL = 16;
static const double spaceXL = 24;
static const double spaceXXL = 32;
// Radius scale.
static const double radiusS = 8;
static const double radiusM = 12;
static const double radiusL = 16;
}
class AppTheme {
const AppTheme._();
static ThemeData light() => _build(Brightness.light);
static ThemeData dark() => _build(Brightness.dark);
static ThemeData _build(Brightness brightness) {
final ColorScheme scheme = ColorScheme.fromSeed(
seedColor: AppTokens.seed,
brightness: brightness,
);
return ThemeData(
useMaterial3: true,
colorScheme: scheme,
scaffoldBackgroundColor: scheme.surface,
appBarTheme: AppBarTheme(
backgroundColor: scheme.surface,
foregroundColor: scheme.onSurface,
elevation: 0,
centerTitle: false,
titleTextStyle: TextStyle(
color: scheme.onSurface,
fontSize: 20,
fontWeight: FontWeight.w600,
),
),
cardTheme: CardThemeData(
color: scheme.surfaceContainerHigh,
elevation: 0,
margin: EdgeInsets.zero,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(AppTokens.radiusM),
),
),
listTileTheme: const ListTileThemeData(
contentPadding: EdgeInsets.symmetric(
horizontal: AppTokens.spaceL,
vertical: AppTokens.spaceS,
),
),
dividerTheme: DividerThemeData(
color: scheme.outlineVariant,
thickness: 0.5,
space: 0,
),
filledButtonTheme: FilledButtonThemeData(
style: FilledButton.styleFrom(
padding: const EdgeInsets.symmetric(
horizontal: AppTokens.spaceXL,
vertical: AppTokens.spaceM,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(AppTokens.radiusS),
),
),
),
progressIndicatorTheme: ProgressIndicatorThemeData(
linearTrackColor: scheme.surfaceContainerHighest,
),
);
}
}