// Version: 2.0.0 | Created: 2026-04-01 | Updated: 2026-07-03 // M8Chat brand theme — dark and light variants. // Palette from the m8chat.au Elementor kit (kit post 8): // Accent #1 "#1265ED", Blue Element "#3B8BFF", Ancop Blue "#010B46". // v2.0.0 replaces the old purple scheme, which did not match the website. import 'package:flutter/material.dart'; /// M8Chat brand colours. abstract final class M8Colours { static const Color brandBlue = Color(0xFF1265ED); static const Color accentBlue = Color(0xFF3B8BFF); static const Color darkBackground = Color(0xFF0A0F2E); static const Color darkSurface = Color(0xFF131A42); static const Color darkSurfaceVariant = Color(0xFF1C2452); static const Color onDarkSurface = Color(0xFFE8ECF5); static const Color subtleText = Color(0xFF96A0C2); static const Color errorRed = Color(0xFFCF6679); static const Color unreadGreen = Color(0xFF4CAF50); } /// Dark theme — default for M8Chat. ThemeData buildDarkTheme() { const seed = M8Colours.brandBlue; final scheme = ColorScheme.fromSeed( seedColor: seed, brightness: Brightness.dark, ).copyWith( surface: M8Colours.darkBackground, surfaceContainerHighest: M8Colours.darkSurface, primary: M8Colours.accentBlue, onSurface: M8Colours.onDarkSurface, error: M8Colours.errorRed, ); return ThemeData( useMaterial3: true, colorScheme: scheme, scaffoldBackgroundColor: M8Colours.darkBackground, appBarTheme: AppBarTheme( backgroundColor: M8Colours.darkSurface, foregroundColor: M8Colours.onDarkSurface, elevation: 0, surfaceTintColor: Colors.transparent, ), navigationBarTheme: NavigationBarThemeData( backgroundColor: M8Colours.darkSurface, indicatorColor: M8Colours.accentBlue.withAlpha(51), labelTextStyle: WidgetStateProperty.all( const TextStyle(fontSize: 12, color: M8Colours.onDarkSurface), ), ), inputDecorationTheme: InputDecorationTheme( filled: true, fillColor: M8Colours.darkSurfaceVariant, border: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: BorderSide.none, ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: const BorderSide(color: M8Colours.accentBlue, width: 2), ), labelStyle: const TextStyle(color: M8Colours.subtleText), hintStyle: const TextStyle(color: M8Colours.subtleText), ), elevatedButtonTheme: ElevatedButtonThemeData( style: ElevatedButton.styleFrom( backgroundColor: M8Colours.accentBlue, foregroundColor: Colors.white, minimumSize: const Size.fromHeight(52), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), textStyle: const TextStyle( fontSize: 16, fontWeight: FontWeight.w600, letterSpacing: 0.5, ), ), ), cardTheme: CardThemeData( color: M8Colours.darkSurface, elevation: 0, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), ), dividerTheme: const DividerThemeData( color: M8Colours.darkSurfaceVariant, thickness: 1, ), snackBarTheme: SnackBarThemeData( backgroundColor: M8Colours.darkSurfaceVariant, contentTextStyle: const TextStyle(color: M8Colours.onDarkSurface), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), behavior: SnackBarBehavior.floating, ), ); } /// Light theme — follows system preference if user selects it. ThemeData buildLightTheme() { const seed = M8Colours.brandBlue; final scheme = ColorScheme.fromSeed( seedColor: seed, brightness: Brightness.light, ); return ThemeData( useMaterial3: true, colorScheme: scheme, elevatedButtonTheme: ElevatedButtonThemeData( style: ElevatedButton.styleFrom( minimumSize: const Size.fromHeight(52), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), textStyle: const TextStyle( fontSize: 16, fontWeight: FontWeight.w600, letterSpacing: 0.5, ), ), ), inputDecorationTheme: InputDecorationTheme( filled: true, border: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: BorderSide.none, ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: BorderSide(color: scheme.primary, width: 2), ), ), snackBarTheme: SnackBarThemeData( shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), behavior: SnackBarBehavior.floating, ), ); }