main
dart 96 lines 3.53 KB
Raw
1 import 'package:flutter/material.dart';
2
3 import 'providers/voice_mode_provider.dart';
4
5 /// Accent color palette used across the voice-mode UI (overlay header,
6 /// waveform visualizer, transcript badge, control buttons).
7 ///
8 /// Centralised so the same phase always renders with the same colour
9 /// regardless of which surface paints it.
10 class VoiceModePalette {
11 const VoiceModePalette._();
12
13 static Color accentFor(VoiceModePhase phase, {required bool isDark}) {
14 switch (phase) {
15 case VoiceModePhase.listening:
16 return isDark ? const Color(0xFF34D399) : const Color(0xFF059669);
17 case VoiceModePhase.processing:
18 return isDark ? const Color(0xFFA78BFA) : const Color(0xFF7C3AED);
19 case VoiceModePhase.speaking:
20 return isDark ? const Color(0xFF818CF8) : const Color(0xFF4F46E5);
21 case VoiceModePhase.idle:
22 return isDark ? const Color(0xFF94A3B8) : const Color(0xFF64748B);
23 case VoiceModePhase.error:
24 return const Color(0xFFEF4444);
25 }
26 }
27
28 /// Secondary accent color for multi-spectral gradient shaders & wave rings.
29 static Color secondaryFor(VoiceModePhase phase, {required bool isDark}) {
30 switch (phase) {
31 case VoiceModePhase.listening:
32 return isDark ? const Color(0xFF38BDF8) : const Color(0xFF0284C7);
33 case VoiceModePhase.processing:
34 return isDark ? const Color(0xFFE879F9) : const Color(0xFFC084FC);
35 case VoiceModePhase.speaking:
36 return isDark ? const Color(0xFFF472B6) : const Color(0xFFDB2777);
37 case VoiceModePhase.idle:
38 return isDark ? const Color(0xFF64748B) : const Color(0xFF475569);
39 case VoiceModePhase.error:
40 return isDark ? const Color(0xFFF87171) : const Color(0xFFDC2626);
41 }
42 }
43
44 /// Full 3D sphere gradient stops for a given phase.
45 static List<Color> sphereGradientFor(
46 VoiceModePhase phase, {
47 required bool isDark,
48 }) {
49 final accent = accentFor(phase, isDark: isDark);
50 final secondary = secondaryFor(phase, isDark: isDark);
51
52 switch (phase) {
53 case VoiceModePhase.listening:
54 return [
55 const Color(0xFFA7F3D0), // Soft mint top highlight
56 accent, // Emerald / Teal accent
57 secondary, // Cyan blue
58 const Color(0xFF0284C7), // Deep cyan edge
59 ];
60 case VoiceModePhase.processing:
61 return [
62 const Color(0xFFF0ABFC), // Bright violet light top
63 accent, // Deep purple
64 secondary, // Magenta shimmer
65 const Color(0xFF4C1D95), // Deep dark indigo edge
66 ];
67 case VoiceModePhase.speaking:
68 return [
69 const Color(0xFFFFAEE2), // Light peach pink top
70 const Color(0xFFF472B6), // Pink
71 accent, // Indigo / Purple
72 secondary, // Deep rose / cyan bottom
73 ];
74 case VoiceModePhase.idle:
75 return [
76 const Color(0xFFCBD5E1), // Cool grey light
77 accent, // Slate blue
78 secondary, // Dark slate
79 const Color(0xFF334155), // Charcoal edge
80 ];
81 case VoiceModePhase.error:
82 return [
83 const Color(0xFFFECDD3), // Soft rose pink highlight
84 const Color(0xFFF87171), // Vibrant coral red
85 accent, // Crimson red
86 const Color(0xFF991B1B), // Dark burgundy edge
87 ];
88 }
89 }
90
91 /// Subtle background used behind the centred phase icon / pill.
92 static Color subtleBg(BuildContext context, {double opacity = 0.08}) {
93 final isDark = Theme.of(context).brightness == Brightness.dark;
94 return (isDark ? Colors.white : Colors.black).withValues(alpha: opacity);
95 }
96 }