fix: align MotorSignal visual system with brand identity
This commit is contained in:
parent
a14d45fac7
commit
ea3650f43d
|
|
@ -6,41 +6,62 @@ import 'package:flutter/material.dart';
|
||||||
/// - Dark Mode (Cockpit OLED): deep matte blacks and vibrant saturated accents.
|
/// - Dark Mode (Cockpit OLED): deep matte blacks and vibrant saturated accents.
|
||||||
/// - Light Mode (Daylight HUD): high-contrast daylight surfaces for outdoor sunlight readability.
|
/// - Light Mode (Daylight HUD): high-contrast daylight surfaces for outdoor sunlight readability.
|
||||||
abstract final class AppColors {
|
abstract final class AppColors {
|
||||||
// Brand & High-Contrast Accents (Unified MotorSignal Palette)
|
// MotorSignal Canonical Brand Identity (Single hue family)
|
||||||
static const Color cyberCyan = Color(0xFF00B4D8);
|
static const Color brandBlue = Color(0xFF0066FF);
|
||||||
static const Color technicalBlue = Color(0xFF0077A8);
|
static const Color brandBlueStrong = Color(0xFF0047B3);
|
||||||
static const Color velocityBlue = Color(0xFF0096C7);
|
static const Color brandContainerLight = Color(0xFFD9E7FF);
|
||||||
static const Color raceRed = Color(0xFFFF3B30);
|
static const Color brandContainerDark = Color(0xFF142542);
|
||||||
static const Color hazardRed = Color(0xFFFF3B30);
|
static const Color onBrand = Color(0xFFFFFFFF);
|
||||||
static const Color launchGreen = Color(0xFF34C759);
|
static const Color onBrandContainerLight = Color(0xFF0047B3);
|
||||||
|
static const Color onBrandContainerDark = Color(0xFFD9E7FF);
|
||||||
|
|
||||||
|
// Backward-compatible token aliases mapped to canonical MotorSignal Blue
|
||||||
|
static const Color cyberCyan = brandBlue;
|
||||||
|
static const Color technicalBlue = brandBlueStrong;
|
||||||
|
static const Color velocityBlue = brandBlue;
|
||||||
|
|
||||||
|
// Semantic State Colors (Precision, not aggression)
|
||||||
|
static const Color semanticSuccess = Color(0xFF2E9B62);
|
||||||
|
static const Color semanticSuccessLight = Color(0xFF247D4F); // Contrast-adjusted for light mode readability (>= 4.5:1)
|
||||||
|
static const Color semanticWarning = Color(0xFFB97800);
|
||||||
|
static const Color semanticWarningLight = Color(0xFF8A5800); // Contrast-adjusted for light mode readability (>= 4.5:1)
|
||||||
|
static const Color semanticDanger = Color(0xFFC94444);
|
||||||
|
static const Color semanticDangerDark = Color(0xFFE05353); // Contrast-adjusted for dark mode readability (>= 4.5:1)
|
||||||
|
|
||||||
|
// Telemetry & Legacy semantic aliases
|
||||||
|
static const Color raceRed = semanticDanger;
|
||||||
|
static const Color hazardRed = semanticDanger;
|
||||||
|
static const Color launchGreen = semanticSuccess;
|
||||||
static const Color telemetryGreen = Color(0xFF30D158);
|
static const Color telemetryGreen = Color(0xFF30D158);
|
||||||
static const Color successGreen = Color(0xFF28A745);
|
static const Color successGreen = semanticSuccess;
|
||||||
static const Color warningAmber = Color(0xFFFFB300);
|
static const Color warningAmber = semanticWarning;
|
||||||
static const Color darkAmber = Color(0xFFC48100);
|
static const Color darkAmber = semanticWarningLight;
|
||||||
|
|
||||||
// Dark Mode Palette (Graphite & Technical Cockpit)
|
// Dark Neutrals (Graphite & Technical Cockpit)
|
||||||
static const Color darkBackground = Color(0xFF0D0F13);
|
static const Color darkBackground = Color(0xFF0B0D0F);
|
||||||
static const Color darkSurface = Color(0xFF13171E);
|
static const Color darkSurface = Color(0xFF14171A); // primary surface
|
||||||
static const Color darkSurfaceContainer = Color(0xFF1A1F28);
|
static const Color darkSurfaceContainer = Color(0xFF1D2226); // elevated surface
|
||||||
static const Color darkSurfaceContainerHigh = Color(0xFF222935);
|
static const Color darkSurfaceContainerHigh = Color(0xFF252B30);
|
||||||
static const Color darkSurfaceContainerHighest = Color(0xFF2B3342);
|
static const Color darkSurfaceContainerHighest = Color(0xFF2E353B);
|
||||||
static const Color darkOutline = Color(0xFF2B3342);
|
static const Color darkOutline = Color(0xFF30363B); // divider/border
|
||||||
static const Color darkOutlineVariant = Color(0xFF1F242F);
|
static const Color darkOutlineVariant = Color(0xFF22272B);
|
||||||
static const Color darkOnSurface = Color(0xFFF1F3F5);
|
static const Color darkOnSurface = Color(0xFFF5F7F8); // primary text
|
||||||
static const Color darkOnSurfaceVariant = Color(0xFF9EABB8);
|
static const Color darkOnSurfaceVariant = Color(0xFFAEB7BD); // secondary text
|
||||||
static const Color darkPrimary = Color(0xFF00B4D8);
|
static const Color darkDisabled = Color(0xFF687278); // disabled text
|
||||||
static const Color darkSecondary = Color(0xFFFF3B30);
|
static const Color darkPrimary = brandBlue;
|
||||||
|
static const Color darkSecondary = semanticDanger;
|
||||||
|
|
||||||
// Light Mode Palette (Daylight Technical HUD)
|
// Light Neutrals (Daylight Technical HUD)
|
||||||
static const Color lightBackground = Color(0xFFF3F5F8);
|
static const Color lightBackground = Color(0xFFF2F3F3);
|
||||||
static const Color lightSurface = Color(0xFFE9EDF2);
|
static const Color lightSurface = Color(0xFFFFFFFF); // primary surface
|
||||||
static const Color lightSurfaceContainer = Color(0xFFFFFFFF);
|
static const Color lightSurfaceContainer = Color(0xFFFFFFFF);
|
||||||
static const Color lightSurfaceContainerHigh = Color(0xFFE1E6EC);
|
static const Color lightSurfaceContainerHigh = Color(0xFFFAFAFA); // elevated surface
|
||||||
static const Color lightSurfaceContainerHighest = Color(0xFFD6DCE4);
|
static const Color lightSurfaceContainerHighest = Color(0xFFF0F2F4);
|
||||||
static const Color lightOutline = Color(0xFFCBD2DC);
|
static const Color lightOutline = Color(0xFFD3D7D9); // divider/border
|
||||||
static const Color lightOutlineVariant = Color(0xFFDFE4EC);
|
static const Color lightOutlineVariant = Color(0xFFE1E5E7);
|
||||||
static const Color lightOnSurface = Color(0xFF13171E);
|
static const Color lightOnSurface = Color(0xFF111417); // primary text
|
||||||
static const Color lightOnSurfaceVariant = Color(0xFF5A6675);
|
static const Color lightOnSurfaceVariant = Color(0xFF596269); // secondary text
|
||||||
static const Color lightPrimary = Color(0xFF0077A8);
|
static const Color lightDisabled = Color(0xFF9AA2A7); // disabled text
|
||||||
static const Color lightSecondary = Color(0xFFD32F2F);
|
static const Color lightPrimary = brandBlue;
|
||||||
|
static const Color lightSecondary = semanticDanger;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,12 +4,12 @@ import 'package:flutter/material.dart';
|
||||||
///
|
///
|
||||||
/// Multi-font architecture:
|
/// Multi-font architecture:
|
||||||
/// - JetBrains Mono: Dynamic numbers, telemetry readouts, timers (zero numerical jitter).
|
/// - JetBrains Mono: Dynamic numbers, telemetry readouts, timers (zero numerical jitter).
|
||||||
/// - Sora: Headlines, app headers, compass directions.
|
/// - Montserrat: Brand-forward marketing, headlines, and headers.
|
||||||
/// - Inter: Body, labels, metadata, specifications.
|
/// - DM Sans: Application UI, body text, labels, and specifications.
|
||||||
abstract final class AppTypography {
|
abstract final class AppTypography {
|
||||||
static const String fontTelemetry = 'JetBrains Mono';
|
static const String fontTelemetry = 'JetBrains Mono';
|
||||||
static const String fontHeadline = 'Sora';
|
static const String fontHeadline = 'Montserrat';
|
||||||
static const String fontBody = 'Inter';
|
static const String fontBody = 'DM Sans';
|
||||||
|
|
||||||
// Large Speedometer Readouts
|
// Large Speedometer Readouts
|
||||||
static const TextStyle speedometer = TextStyle(
|
static const TextStyle speedometer = TextStyle(
|
||||||
|
|
|
||||||
|
|
@ -10,19 +10,19 @@ class AppTheme {
|
||||||
static ThemeData get darkTheme {
|
static ThemeData get darkTheme {
|
||||||
const colorScheme = ColorScheme.dark(
|
const colorScheme = ColorScheme.dark(
|
||||||
primary: AppColors.darkPrimary,
|
primary: AppColors.darkPrimary,
|
||||||
onPrimary: Color(0xFF000000),
|
onPrimary: AppColors.onBrand,
|
||||||
primaryContainer: Color(0xFF004D56),
|
primaryContainer: AppColors.brandContainerDark,
|
||||||
onPrimaryContainer: AppColors.cyberCyan,
|
onPrimaryContainer: AppColors.onBrandContainerDark,
|
||||||
secondary: AppColors.darkSecondary,
|
secondary: AppColors.darkSecondary,
|
||||||
onSecondary: Color(0xFFFFFFFF),
|
onSecondary: Color(0xFFFFFFFF),
|
||||||
secondaryContainer: Color(0xFF5A0000),
|
secondaryContainer: Color(0xFF311414),
|
||||||
onSecondaryContainer: Color(0xFFFFB4AB),
|
onSecondaryContainer: Color(0xFFFFDAD6),
|
||||||
surface: AppColors.darkSurface,
|
surface: AppColors.darkSurface,
|
||||||
onSurface: AppColors.darkOnSurface,
|
onSurface: AppColors.darkOnSurface,
|
||||||
onSurfaceVariant: AppColors.darkOnSurfaceVariant,
|
onSurfaceVariant: AppColors.darkOnSurfaceVariant,
|
||||||
outline: AppColors.darkOutline,
|
outline: AppColors.darkOutline,
|
||||||
outlineVariant: AppColors.darkOutlineVariant,
|
outlineVariant: AppColors.darkOutlineVariant,
|
||||||
error: AppColors.hazardRed,
|
error: AppColors.semanticDanger,
|
||||||
onError: Color(0xFFFFFFFF),
|
onError: Color(0xFFFFFFFF),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -207,19 +207,19 @@ class AppTheme {
|
||||||
static ThemeData get lightTheme {
|
static ThemeData get lightTheme {
|
||||||
const colorScheme = ColorScheme.light(
|
const colorScheme = ColorScheme.light(
|
||||||
primary: AppColors.lightPrimary,
|
primary: AppColors.lightPrimary,
|
||||||
onPrimary: Color(0xFFFFFFFF),
|
onPrimary: AppColors.onBrand,
|
||||||
primaryContainer: Color(0xFFD6E4FF),
|
primaryContainer: AppColors.brandContainerLight,
|
||||||
onPrimaryContainer: Color(0xFF001B3E),
|
onPrimaryContainer: AppColors.onBrandContainerLight,
|
||||||
secondary: AppColors.lightSecondary,
|
secondary: AppColors.lightSecondary,
|
||||||
onSecondary: Color(0xFFFFFFFF),
|
onSecondary: Color(0xFFFFFFFF),
|
||||||
secondaryContainer: Color(0xFFFFDAD6),
|
secondaryContainer: Color(0xFFFDE8E8),
|
||||||
onSecondaryContainer: Color(0xFF410002),
|
onSecondaryContainer: Color(0xFF410002),
|
||||||
surface: AppColors.lightSurface,
|
surface: AppColors.lightSurface,
|
||||||
onSurface: AppColors.lightOnSurface,
|
onSurface: AppColors.lightOnSurface,
|
||||||
onSurfaceVariant: AppColors.lightOnSurfaceVariant,
|
onSurfaceVariant: AppColors.lightOnSurfaceVariant,
|
||||||
outline: AppColors.lightOutline,
|
outline: AppColors.lightOutline,
|
||||||
outlineVariant: AppColors.lightOutlineVariant,
|
outlineVariant: AppColors.lightOutlineVariant,
|
||||||
error: AppColors.hazardRed,
|
error: AppColors.semanticDanger,
|
||||||
onError: Color(0xFFFFFFFF),
|
onError: Color(0xFFFFFFFF),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -47,39 +47,39 @@ class MotorSignalThemeColors extends ThemeExtension<MotorSignalThemeColors> {
|
||||||
/// Dark Mode default telemetry tokens (Cockpit Precision).
|
/// Dark Mode default telemetry tokens (Cockpit Precision).
|
||||||
static const MotorSignalThemeColors dark = MotorSignalThemeColors(
|
static const MotorSignalThemeColors dark = MotorSignalThemeColors(
|
||||||
cyberCyan: AppColors.darkPrimary,
|
cyberCyan: AppColors.darkPrimary,
|
||||||
velocityBlue: AppColors.velocityBlue,
|
velocityBlue: AppColors.brandBlueStrong,
|
||||||
raceRed: AppColors.raceRed,
|
raceRed: AppColors.semanticDangerDark,
|
||||||
launchGreen: AppColors.launchGreen,
|
launchGreen: AppColors.semanticSuccess,
|
||||||
warningAmber: AppColors.warningAmber,
|
warningAmber: AppColors.semanticWarning,
|
||||||
telemetryGreen: AppColors.telemetryGreen,
|
telemetryGreen: AppColors.telemetryGreen,
|
||||||
leanAngleLeft: AppColors.darkPrimary,
|
leanAngleLeft: AppColors.darkPrimary,
|
||||||
leanAngleRight: AppColors.velocityBlue,
|
leanAngleRight: AppColors.brandBlueStrong,
|
||||||
gForcePositive: AppColors.launchGreen,
|
gForcePositive: AppColors.semanticSuccess,
|
||||||
gForceNegative: AppColors.raceRed,
|
gForceNegative: AppColors.semanticDangerDark,
|
||||||
speedometerDial: AppColors.darkPrimary,
|
speedometerDial: AppColors.darkPrimary,
|
||||||
speedometerGlow: Color(0x1400B4D8),
|
speedometerGlow: Color(0x140066FF),
|
||||||
surfaceContainer: AppColors.darkSurfaceContainer,
|
surfaceContainer: AppColors.darkSurfaceContainer,
|
||||||
surfaceContainerHigh: AppColors.darkSurfaceContainerHigh,
|
surfaceContainerHigh: AppColors.darkSurfaceContainerHigh,
|
||||||
surfaceContainerHighest: AppColors.darkSurfaceContainerHighest,
|
surfaceContainerHighest: AppColors.darkSurfaceContainerHighest,
|
||||||
outline: AppColors.darkOutline,
|
outline: AppColors.darkOutline,
|
||||||
outlineVariant: AppColors.darkOutlineVariant,
|
outlineVariant: AppColors.darkOutlineVariant,
|
||||||
glowShadow: Color(0x1F00B4D8),
|
glowShadow: Color(0x1F0066FF),
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Light Mode default telemetry tokens (Daylight HUD).
|
/// Light Mode default telemetry tokens (Daylight HUD).
|
||||||
static const MotorSignalThemeColors light = MotorSignalThemeColors(
|
static const MotorSignalThemeColors light = MotorSignalThemeColors(
|
||||||
cyberCyan: AppColors.lightPrimary,
|
cyberCyan: AppColors.lightPrimary,
|
||||||
velocityBlue: AppColors.velocityBlue,
|
velocityBlue: AppColors.brandBlueStrong,
|
||||||
raceRed: AppColors.lightSecondary,
|
raceRed: AppColors.semanticDanger,
|
||||||
launchGreen: AppColors.launchGreen,
|
launchGreen: AppColors.semanticSuccessLight,
|
||||||
warningAmber: AppColors.warningAmber,
|
warningAmber: AppColors.semanticWarningLight,
|
||||||
telemetryGreen: AppColors.telemetryGreen,
|
telemetryGreen: AppColors.telemetryGreen,
|
||||||
leanAngleLeft: AppColors.lightPrimary,
|
leanAngleLeft: AppColors.lightPrimary,
|
||||||
leanAngleRight: AppColors.velocityBlue,
|
leanAngleRight: AppColors.brandBlueStrong,
|
||||||
gForcePositive: AppColors.launchGreen,
|
gForcePositive: AppColors.semanticSuccessLight,
|
||||||
gForceNegative: AppColors.lightSecondary,
|
gForceNegative: AppColors.semanticDanger,
|
||||||
speedometerDial: AppColors.lightPrimary,
|
speedometerDial: AppColors.lightPrimary,
|
||||||
speedometerGlow: Color(0x0F0077A8),
|
speedometerGlow: Color(0x0F0066FF),
|
||||||
surfaceContainer: AppColors.lightSurfaceContainer,
|
surfaceContainer: AppColors.lightSurfaceContainer,
|
||||||
surfaceContainerHigh: AppColors.lightSurfaceContainerHigh,
|
surfaceContainerHigh: AppColors.lightSurfaceContainerHigh,
|
||||||
surfaceContainerHighest: AppColors.lightSurfaceContainerHighest,
|
surfaceContainerHighest: AppColors.lightSurfaceContainerHighest,
|
||||||
|
|
@ -88,6 +88,16 @@ class MotorSignalThemeColors extends ThemeExtension<MotorSignalThemeColors> {
|
||||||
glowShadow: Color(0x14000000),
|
glowShadow: Color(0x14000000),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Color get brandBlue => cyberCyan;
|
||||||
|
Color get brandBlueStrong => velocityBlue;
|
||||||
|
Color get brandContainer => surfaceContainer == AppColors.darkSurfaceContainer
|
||||||
|
? AppColors.brandContainerDark
|
||||||
|
: AppColors.brandContainerLight;
|
||||||
|
Color get onBrand => AppColors.onBrand;
|
||||||
|
Color get onBrandContainer => surfaceContainer == AppColors.darkSurfaceContainer
|
||||||
|
? AppColors.onBrandContainerDark
|
||||||
|
: AppColors.onBrandContainerLight;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
MotorSignalThemeColors copyWith({
|
MotorSignalThemeColors copyWith({
|
||||||
Color? cyberCyan,
|
Color? cyberCyan,
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import '../../core/app_info.dart';
|
||||||
import '../../core/responsive/viewport_size.dart';
|
import '../../core/responsive/viewport_size.dart';
|
||||||
import '../../core/theme/theme_extensions.dart';
|
import '../../core/theme/theme_extensions.dart';
|
||||||
import '../../core/theme/theme_mode_provider.dart';
|
import '../../core/theme/theme_mode_provider.dart';
|
||||||
|
import '../../core/theme/app_typography.dart';
|
||||||
import '../../database/database.dart';
|
import '../../database/database.dart';
|
||||||
import '../../features/rides/ride_state_machine.dart';
|
import '../../features/rides/ride_state_machine.dart';
|
||||||
import '../../services/alerts/road_alert_models.dart';
|
import '../../services/alerts/road_alert_models.dart';
|
||||||
|
|
@ -206,7 +207,7 @@ class _SettingsScreenState extends ConsumerState<SettingsScreen> {
|
||||||
return Text(
|
return Text(
|
||||||
title,
|
title,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontFamily: 'Sora',
|
fontFamily: AppTypography.fontHeadline,
|
||||||
fontSize: 13,
|
fontSize: 13,
|
||||||
fontWeight: FontWeight.w700,
|
fontWeight: FontWeight.w700,
|
||||||
letterSpacing: 0.2,
|
letterSpacing: 0.2,
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
import '../../../core/theme/theme_extensions.dart';
|
import '../../../core/theme/theme_extensions.dart';
|
||||||
|
import '../../../core/theme/app_typography.dart';
|
||||||
import '../../../services/billing/product_catalog.dart';
|
import '../../../services/billing/product_catalog.dart';
|
||||||
import '../../../services/entitlements/entitlement_providers.dart';
|
import '../../../services/entitlements/entitlement_providers.dart';
|
||||||
import '../../../services/entitlements/entitlement_state.dart';
|
import '../../../services/entitlements/entitlement_state.dart';
|
||||||
|
|
@ -123,7 +124,7 @@ class CurrentPlanCard extends ConsumerWidget {
|
||||||
Text(
|
Text(
|
||||||
planTitle,
|
planTitle,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontFamily: 'Sora',
|
fontFamily: AppTypography.fontHeadline,
|
||||||
fontSize: 13,
|
fontSize: 13,
|
||||||
fontWeight: FontWeight.w700,
|
fontWeight: FontWeight.w700,
|
||||||
color: isPro ? colors.cyberCyan : Theme.of(context).colorScheme.onSurface,
|
color: isPro ? colors.cyberCyan : Theme.of(context).colorScheme.onSurface,
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import '../../../core/theme/app_typography.dart';
|
||||||
import '../../../services/social/rider_profile_models.dart';
|
import '../../../services/social/rider_profile_models.dart';
|
||||||
|
|
||||||
/// Renders a rider's avatar using their preset styling or custom photo URL.
|
/// Renders a rider's avatar using their preset styling or custom photo URL.
|
||||||
|
|
@ -56,7 +57,7 @@ class AvatarBadge extends StatelessWidget {
|
||||||
color: primaryColor,
|
color: primaryColor,
|
||||||
fontWeight: FontWeight.w900,
|
fontWeight: FontWeight.w900,
|
||||||
fontSize: radius * 0.9,
|
fontSize: radius * 0.9,
|
||||||
fontFamily: 'Sora',
|
fontFamily: AppTypography.fontHeadline,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -13,27 +13,42 @@ void main() {
|
||||||
|
|
||||||
group('MotorSignal Design System - Tokens & Hierarchy', () {
|
group('MotorSignal Design System - Tokens & Hierarchy', () {
|
||||||
test('AppColors verifies dark and light semantic palette definitions', () {
|
test('AppColors verifies dark and light semantic palette definitions', () {
|
||||||
expect(AppColors.cyberCyan, const Color(0xFF00B4D8));
|
expect(AppColors.brandBlue, const Color(0xFF0066FF));
|
||||||
expect(AppColors.velocityBlue, const Color(0xFF0096C7));
|
expect(AppColors.brandBlueStrong, const Color(0xFF0047B3));
|
||||||
expect(AppColors.raceRed, const Color(0xFFFF3B30));
|
expect(AppColors.brandContainerLight, const Color(0xFFD9E7FF));
|
||||||
expect(AppColors.darkBackground, const Color(0xFF0D0F13));
|
expect(AppColors.brandContainerDark, const Color(0xFF142542));
|
||||||
expect(AppColors.darkSurface, const Color(0xFF13171E));
|
expect(AppColors.cyberCyan, const Color(0xFF0066FF));
|
||||||
expect(AppColors.lightBackground, const Color(0xFFF3F5F8));
|
expect(AppColors.semanticDanger, const Color(0xFFC94444));
|
||||||
expect(AppColors.lightSurface, const Color(0xFFE9EDF2));
|
expect(AppColors.semanticSuccess, const Color(0xFF2E9B62));
|
||||||
|
expect(AppColors.semanticWarning, const Color(0xFFB97800));
|
||||||
|
expect(AppColors.darkBackground, const Color(0xFF0B0D0F));
|
||||||
|
expect(AppColors.darkSurface, const Color(0xFF14171A));
|
||||||
|
expect(AppColors.darkSurfaceContainer, const Color(0xFF1D2226));
|
||||||
|
expect(AppColors.darkOutline, const Color(0xFF30363B));
|
||||||
|
expect(AppColors.darkOnSurface, const Color(0xFFF5F7F8));
|
||||||
|
expect(AppColors.darkOnSurfaceVariant, const Color(0xFFAEB7BD));
|
||||||
|
expect(AppColors.darkDisabled, const Color(0xFF687278));
|
||||||
|
expect(AppColors.lightBackground, const Color(0xFFF2F3F3));
|
||||||
|
expect(AppColors.lightSurface, const Color(0xFFFFFFFF));
|
||||||
|
expect(AppColors.lightSurfaceContainerHigh, const Color(0xFFFAFAFA));
|
||||||
|
expect(AppColors.lightOutline, const Color(0xFFD3D7D9));
|
||||||
|
expect(AppColors.lightOnSurface, const Color(0xFF111417));
|
||||||
|
expect(AppColors.lightOnSurfaceVariant, const Color(0xFF596269));
|
||||||
|
expect(AppColors.lightDisabled, const Color(0xFF9AA2A7));
|
||||||
});
|
});
|
||||||
|
|
||||||
test('AppTypography specifies authoritative multi-font system', () {
|
test('AppTypography specifies authoritative multi-font system', () {
|
||||||
expect(AppTypography.fontTelemetry, 'JetBrains Mono');
|
expect(AppTypography.fontTelemetry, 'JetBrains Mono');
|
||||||
expect(AppTypography.fontHeadline, 'Sora');
|
expect(AppTypography.fontHeadline, 'Montserrat');
|
||||||
expect(AppTypography.fontBody, 'Inter');
|
expect(AppTypography.fontBody, 'DM Sans');
|
||||||
|
|
||||||
expect(AppTypography.speedometer.fontFamily, 'JetBrains Mono');
|
expect(AppTypography.speedometer.fontFamily, 'JetBrains Mono');
|
||||||
expect(AppTypography.speedometer.fontSize, 96);
|
expect(AppTypography.speedometer.fontSize, 96);
|
||||||
expect(AppTypography.speedometer.fontWeight, FontWeight.w900);
|
expect(AppTypography.speedometer.fontWeight, FontWeight.w900);
|
||||||
|
|
||||||
expect(AppTypography.headingCompass.fontFamily, 'Sora');
|
expect(AppTypography.headingCompass.fontFamily, 'Montserrat');
|
||||||
expect(AppTypography.bodyMd.fontFamily, 'Inter');
|
expect(AppTypography.bodyMd.fontFamily, 'DM Sans');
|
||||||
expect(AppTypography.button.fontFamily, 'Sora');
|
expect(AppTypography.button.fontFamily, 'Montserrat');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('AppSpacing and AppRadius conform to 4dp base grid and 48dp touch targets', () {
|
test('AppSpacing and AppRadius conform to 4dp base grid and 48dp touch targets', () {
|
||||||
|
|
@ -55,13 +70,13 @@ void main() {
|
||||||
group('MotorSignalThemeColors Extension', () {
|
group('MotorSignalThemeColors Extension', () {
|
||||||
test('Dark and Light presets have correct brightness semantics', () {
|
test('Dark and Light presets have correct brightness semantics', () {
|
||||||
const dark = MotorSignalThemeColors.dark;
|
const dark = MotorSignalThemeColors.dark;
|
||||||
expect(dark.cyberCyan, AppColors.cyberCyan);
|
expect(dark.cyberCyan, AppColors.brandBlue);
|
||||||
expect(dark.launchGreen, AppColors.launchGreen);
|
expect(dark.launchGreen, AppColors.semanticSuccess);
|
||||||
expect(dark.surfaceContainer, AppColors.darkSurfaceContainer);
|
expect(dark.surfaceContainer, AppColors.darkSurfaceContainer);
|
||||||
|
|
||||||
const light = MotorSignalThemeColors.light;
|
const light = MotorSignalThemeColors.light;
|
||||||
expect(light.cyberCyan, AppColors.technicalBlue);
|
expect(light.cyberCyan, AppColors.brandBlue);
|
||||||
expect(light.launchGreen, AppColors.launchGreen);
|
expect(light.launchGreen, AppColors.semanticSuccessLight);
|
||||||
expect(light.surfaceContainer, AppColors.lightSurfaceContainer);
|
expect(light.surfaceContainer, AppColors.lightSurfaceContainer);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -99,7 +114,7 @@ void main() {
|
||||||
|
|
||||||
final ext = theme.extension<MotorSignalThemeColors>();
|
final ext = theme.extension<MotorSignalThemeColors>();
|
||||||
expect(ext, isNotNull);
|
expect(ext, isNotNull);
|
||||||
expect(ext?.cyberCyan, AppColors.technicalBlue);
|
expect(ext?.cyberCyan, AppColors.brandBlue);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue