import 'package:flutter/material.dart'; /// User's theme preference, persisted in the learning snapshot. enum AppThemeMode { system, light, dark } /// One brightness worth of brand colours. Two const instances below hold the /// light and dark values; [AppColors] mirrors the active one so the many /// widgets that read `AppColors.x` directly recolour when the theme changes. class _Palette { const _Palette({ required this.paper, required this.surface, required this.surfaceMuted, required this.ink, required this.muted, required this.line, required this.green, required this.softGreen, required this.warm, required this.warmInk, }); final Color paper; final Color surface; final Color surfaceMuted; final Color ink; final Color muted; final Color line; final Color green; final Color softGreen; final Color warm; final Color warmInk; } const _light = _Palette( paper: Color(0xFFF5F7F3), surface: Colors.white, surfaceMuted: Color(0xFFF1F5F0), ink: Color(0xFF19211B), muted: Color(0xFF647268), line: Color(0xFFD8E1D9), green: Color(0xFF176B46), softGreen: Color(0xFFE2F3E8), warm: Color(0xFFFFF0E3), warmInk: Color(0xFF9E4C18), ); const _dark = _Palette( paper: Color(0xFF11150F), surface: Color(0xFF1B211A), surfaceMuted: Color(0xFF232B22), ink: Color(0xFFE8EEE6), muted: Color(0xFF9CA99D), line: Color(0xFF33402F), green: Color(0xFF2FA36B), softGreen: Color(0xFF17311F), warm: Color(0xFF352618), warmInk: Color(0xFFEBAA78), ); /// Brand colours for the active brightness. Values are reassigned by /// [AppColors.applyBrightness]; call it before building the widget tree. abstract final class AppColors { static Color paper = _light.paper; static Color surface = _light.surface; static Color surfaceMuted = _light.surfaceMuted; static Color ink = _light.ink; static Color muted = _light.muted; static Color line = _light.line; static Color green = _light.green; static Color softGreen = _light.softGreen; static Color warm = _light.warm; static Color warmInk = _light.warmInk; static Brightness brightness = Brightness.light; static void applyBrightness(Brightness value) { final p = value == Brightness.dark ? _dark : _light; brightness = value; paper = p.paper; surface = p.surface; surfaceMuted = p.surfaceMuted; ink = p.ink; muted = p.muted; line = p.line; green = p.green; softGreen = p.softGreen; warm = p.warm; warmInk = p.warmInk; } } ThemeData buildAppTheme(Brightness brightness) { final p = brightness == Brightness.dark ? _dark : _light; final scheme = ColorScheme.fromSeed( seedColor: p.green, brightness: brightness, ).copyWith( surface: p.surface, onSurface: p.ink, primary: p.green, onPrimary: Colors.white, outline: p.line, ); return ThemeData( useMaterial3: true, brightness: brightness, colorScheme: scheme, scaffoldBackgroundColor: p.paper, fontFamily: 'PingFang SC', appBarTheme: AppBarTheme( backgroundColor: p.surface, foregroundColor: p.ink, elevation: 0, centerTitle: false, ), textTheme: TextTheme( headlineMedium: TextStyle( color: p.ink, fontSize: 26, height: 1.25, fontWeight: FontWeight.w600, letterSpacing: -0.6, ), titleLarge: TextStyle( color: p.ink, fontSize: 18, fontWeight: FontWeight.w600, ), bodyLarge: TextStyle(color: p.ink, fontSize: 16, height: 1.5), bodyMedium: TextStyle(color: p.muted, fontSize: 14, height: 1.5), ), ); }