/ app / lib / core / theme / app_colors.dart
app_colors.dart
  1  import 'package:flutter/material.dart';
  2  
  3  /// App color palette — dark blue cyber aesthetic
  4  abstract final class AppColors {
  5    static final AppColorScheme light = _CyberLightColors();
  6    static final AppColorScheme dark = _CyberDarkColors();
  7  
  8    /// Get colors for current brightness
  9    static AppColorScheme of(BuildContext context) {
 10      return Theme.of(context).brightness == Brightness.dark ? dark : light;
 11    }
 12  }
 13  
 14  /// Abstract color scheme interface
 15  abstract class AppColorScheme {
 16    const AppColorScheme();
 17  
 18    /// The underlying M3 ColorScheme for use in ThemeData
 19    ColorScheme get colorScheme;
 20  
 21    // Core palette
 22    Color get primary;
 23    Color get primaryVariant;
 24    Color get primaryContainer;
 25    Color get onPrimaryContainer;
 26    Color get secondary;
 27    Color get secondaryVariant;
 28  
 29    // Backgrounds
 30    Color get background;
 31    Color get surface;
 32    Color get surfaceVariant;
 33    Color get surfaceContainerLow;
 34    Color get surfaceContainer;
 35    Color get surfaceContainerHigh;
 36  
 37    // Text colors
 38    Color get onPrimary;
 39    Color get onSecondary;
 40    Color get onBackground;
 41    Color get onBackgroundSecondary;
 42    Color get onSurface;
 43  
 44    // Semantic colors
 45    Color get error;
 46    Color get errorContainer;
 47    Color get success;
 48    Color get successContainer;
 49    Color get warning;
 50    Color get warningContainer;
 51    Color get info;
 52  
 53    // Chat bubbles
 54    Color get messageBubbleOutbound;
 55    Color get messageBubbleInbound;
 56  
 57    // Borders and dividers
 58    Color get outline;
 59    Color get divider;
 60  }
 61  
 62  // Dark blue seed
 63  const _cyberSeed = Color(0xFF1565C0);
 64  
 65  /// Light theme — crisp blue accents
 66  class _CyberLightColors extends AppColorScheme {
 67    @override
 68    final ColorScheme colorScheme;
 69  
 70    _CyberLightColors()
 71        : colorScheme = ColorScheme.fromSeed(
 72            seedColor: _cyberSeed,
 73            brightness: Brightness.light,
 74          );
 75  
 76    @override Color get primary => colorScheme.primary;
 77    @override Color get primaryVariant => colorScheme.primary;
 78    @override Color get primaryContainer => colorScheme.primaryContainer;
 79    @override Color get onPrimaryContainer => colorScheme.onPrimaryContainer;
 80    @override Color get secondary => colorScheme.secondary;
 81    @override Color get secondaryVariant => colorScheme.secondaryContainer;
 82  
 83    @override Color get background => colorScheme.surface;
 84    @override Color get surface => colorScheme.surfaceContainerHigh;
 85    @override Color get surfaceVariant => colorScheme.surfaceContainerHighest;
 86    @override Color get surfaceContainerLow => colorScheme.surfaceContainerLow;
 87    @override Color get surfaceContainer => colorScheme.surfaceContainer;
 88    @override Color get surfaceContainerHigh => colorScheme.surfaceContainerHigh;
 89  
 90    @override Color get onPrimary => colorScheme.onPrimary;
 91    @override Color get onSecondary => colorScheme.onSecondary;
 92    @override Color get onBackground => colorScheme.onSurface;
 93    @override Color get onBackgroundSecondary => colorScheme.onSurfaceVariant;
 94    @override Color get onSurface => colorScheme.onSurface;
 95  
 96    @override Color get error => colorScheme.error;
 97    @override Color get errorContainer => colorScheme.errorContainer;
 98    @override Color get success => const Color(0xFF2E7D32);
 99    @override Color get successContainer => const Color(0xFFE8F5E9);
100    @override Color get warning => const Color(0xFFE65100);
101    @override Color get warningContainer => const Color(0xFFFFF3E0);
102    @override Color get info => colorScheme.primary;
103  
104    @override Color get messageBubbleOutbound => const Color(0xFFD6E4F0);
105    @override Color get messageBubbleInbound => const Color(0xFFECEFF1);
106  
107    @override Color get outline => colorScheme.outline;
108    @override Color get divider => colorScheme.outlineVariant;
109  }
110  
111  /// Dark theme — deep navy with electric blue accents
112  class _CyberDarkColors extends AppColorScheme {
113    @override
114    final ColorScheme colorScheme;
115  
116    _CyberDarkColors()
117        : colorScheme = ColorScheme.fromSeed(
118            seedColor: _cyberSeed,
119            brightness: Brightness.dark,
120          ).copyWith(
121            // Deep navy surfaces
122            surface: const Color(0xFF060A10),
123            onSurface: const Color(0xFFDDE3EC),
124            surfaceContainerLowest: const Color(0xFF040810),
125            surfaceContainerLow: const Color(0xFF0A1018),
126            surfaceContainer: const Color(0xFF0E1520),
127            surfaceContainerHigh: const Color(0xFF141C28),
128            surfaceContainerHighest: const Color(0xFF1A2332),
129            // Electric blue primary
130            primary: const Color(0xFF6AB1FF),
131            onPrimary: const Color(0xFF001C3B),
132            primaryContainer: const Color(0xFF0D3B6E),
133            onPrimaryContainer: const Color(0xFFD4E8FF),
134            // Cool-tinted outlines
135            outline: const Color(0xFF2A3545),
136            outlineVariant: const Color(0xFF1A2535),
137          );
138  
139    @override Color get primary => colorScheme.primary;
140    @override Color get primaryVariant => colorScheme.primary;
141    @override Color get primaryContainer => colorScheme.primaryContainer;
142    @override Color get onPrimaryContainer => colorScheme.onPrimaryContainer;
143    @override Color get secondary => colorScheme.secondary;
144    @override Color get secondaryVariant => colorScheme.secondaryContainer;
145  
146    @override Color get background => colorScheme.surface;
147    @override Color get surface => colorScheme.surfaceContainerHigh;
148    @override Color get surfaceVariant => colorScheme.surfaceContainerHighest;
149    @override Color get surfaceContainerLow => colorScheme.surfaceContainerLow;
150    @override Color get surfaceContainer => colorScheme.surfaceContainer;
151    @override Color get surfaceContainerHigh => colorScheme.surfaceContainerHigh;
152  
153    @override Color get onPrimary => colorScheme.onPrimary;
154    @override Color get onSecondary => colorScheme.onSecondary;
155    @override Color get onBackground => colorScheme.onSurface;
156    @override Color get onBackgroundSecondary => const Color(0xFF8A95A8);
157    @override Color get onSurface => colorScheme.onSurface;
158  
159    // Neon semantic colors
160    @override Color get error => const Color(0xFFFF5252);
161    @override Color get errorContainer => const Color(0xFF3D1010);
162    @override Color get success => const Color(0xFF69F0AE);
163    @override Color get successContainer => const Color(0xFF0A2A18);
164    @override Color get warning => const Color(0xFFFFD740);
165    @override Color get warningContainer => const Color(0xFF332B00);
166    @override Color get info => colorScheme.primary;
167  
168    // Chat bubbles — high contrast for readability
169    // Outbound: medium-dark blue, text is onPrimaryContainer (#D4E8FF) — bright white-blue on navy
170    @override Color get messageBubbleOutbound => const Color(0xFF0D3B6E);
171    // Inbound: slightly lighter surface, text is onSurface (#DDE3EC) — bright grey on dark
172    @override Color get messageBubbleInbound => const Color(0xFF1A2332);
173  
174    @override Color get outline => colorScheme.outline;
175    @override Color get divider => colorScheme.outlineVariant;
176  }