UI: Cyber/IT design overhaul with semantic status tokens (Material 3)
Re-theme TasQ with a refined enterprise "Cyber/IT" identity on Material 3. Functionality is unchanged — only color/shape tokens and a few state widgets. Foundation: - Hand-tuned light + dark ColorSchemes (deep-slate surfaces, azure/teal/violet accents), tightened 12-16dp shape language, flat hairline-outlined cards. - New AppStatusColors theme extension (success/warning/danger/info/neutral, per-brightness) replacing scattered raw Colors.green/orange/red/grey so status color is consistent and legible in dark mode. - New TechChip mono primitive; StatusPill.kind; M3Card hairline variants; tightened AppSurfaces radii. Per-screen: - Tokenized status colors + radii across dashboard, tickets, tasks, IT service requests, attendance, whereabouts, network map, reports charts, auth, and shared/admin screens. Added _ticketStatusKind/_taskStatusKind/_isrStatusKind mappers so status carries meaning consistently. - Fixed white pie-slice borders for dark mode; dropped ad-hoc dialog radius overrides in favor of the theme default. Categorical palettes (leave-type icons, team color picker, distribution charts) intentionally preserved. Verified: flutter analyze lib clean; flutter build web green; visual QA in light and dark (dashboard, tickets, attendance). Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
+187
-91
@@ -3,57 +3,140 @@ import 'package:google_fonts/google_fonts.dart';
|
||||
|
||||
import 'app_typography.dart';
|
||||
import 'app_surfaces.dart';
|
||||
import 'app_status_colors.dart';
|
||||
|
||||
/// M3 Expressive theme for TasQ.
|
||||
/// Refined enterprise **Cyber/IT** theme for TasQ, built on Material 3.
|
||||
///
|
||||
/// Key differences from the previous Hybrid M2/M3 theme:
|
||||
/// * Cards use **tonal elevation** (surfaceTint color overlays) instead of
|
||||
/// drop-shadows, giving surfaces an organic, seed-tinted look.
|
||||
/// * Large containers use the M3 standard **28 dp** corner radius.
|
||||
/// * Buttons follow the M3 hierarchy: FilledButton (primary), Tonal, Elevated,
|
||||
/// Outlined, and Text.
|
||||
/// * NavigationBar / NavigationRail use pill-shaped indicators with the
|
||||
/// secondary-container tonal color.
|
||||
/// * Spring-physics inspired durations: transitions default to 400 ms with an
|
||||
/// emphasized easing curve.
|
||||
/// Identity:
|
||||
/// * Deep slate surfaces (dark) / cool near-white (light) with an electric
|
||||
/// **azure** primary, **teal** secondary and **violet** tertiary.
|
||||
/// * Cards use a flat tonal fill plus a hairline outline (no drop shadow) for a
|
||||
/// precise, technical feel.
|
||||
/// * A tightened 12–16 dp shape language (see [AppSurfaces]).
|
||||
/// * Monospace ([AppMonoText]) reserved for technical data — IDs, IPs, ports,
|
||||
/// timestamps — and chip labels.
|
||||
/// * Semantic status tokens ([AppStatusColors]) drive all status/priority color.
|
||||
class AppTheme {
|
||||
/// The seed color drives M3's entire tonal palette generation.
|
||||
static const Color _seed = Color(0xFF4A6FA5);
|
||||
const AppTheme._();
|
||||
|
||||
/// Brand azure — anchors M3's neutral tonal ramp generation.
|
||||
static const Color _seed = Color(0xFF2D7FF9);
|
||||
|
||||
static const AppSurfaces _surfaces = AppSurfaces(
|
||||
cardRadius: 12,
|
||||
compactCardRadius: 10,
|
||||
containerRadius: 16,
|
||||
dialogRadius: 20,
|
||||
chipRadius: 8,
|
||||
);
|
||||
|
||||
// ────────────────────────────────────────────────────────────
|
||||
// COLOR SCHEMES (hand-tuned cyber palette)
|
||||
// ────────────────────────────────────────────────────────────
|
||||
static ColorScheme _darkScheme() {
|
||||
return ColorScheme.fromSeed(
|
||||
seedColor: _seed,
|
||||
brightness: Brightness.dark,
|
||||
).copyWith(
|
||||
primary: const Color(0xFF4EA8FF),
|
||||
onPrimary: const Color(0xFF04263F),
|
||||
primaryContainer: const Color(0xFF0E3A5F),
|
||||
onPrimaryContainer: const Color(0xFFCFE7FF),
|
||||
secondary: const Color(0xFF2DD4BF),
|
||||
onSecondary: const Color(0xFF00201C),
|
||||
secondaryContainer: const Color(0xFF0C4B45),
|
||||
onSecondaryContainer: const Color(0xFFB8F5EC),
|
||||
tertiary: const Color(0xFFA78BFA),
|
||||
onTertiary: const Color(0xFF1C0E3F),
|
||||
tertiaryContainer: const Color(0xFF3A2A6B),
|
||||
onTertiaryContainer: const Color(0xFFE7DDFF),
|
||||
error: const Color(0xFFF87171),
|
||||
onError: const Color(0xFF2A0A0A),
|
||||
errorContainer: const Color(0xFF5A1A1A),
|
||||
onErrorContainer: const Color(0xFFFFC9C4),
|
||||
surface: const Color(0xFF0E141B),
|
||||
onSurface: const Color(0xFFE3E9F0),
|
||||
onSurfaceVariant: const Color(0xFFA7B4C2),
|
||||
surfaceContainerLowest: const Color(0xFF080C11),
|
||||
surfaceContainerLow: const Color(0xFF141B23),
|
||||
surfaceContainer: const Color(0xFF17202A),
|
||||
surfaceContainerHigh: const Color(0xFF1E2833),
|
||||
surfaceContainerHighest: const Color(0xFF26313D),
|
||||
surfaceDim: const Color(0xFF0B0F14),
|
||||
surfaceBright: const Color(0xFF2A3542),
|
||||
outline: const Color(0xFF3A4A5A),
|
||||
outlineVariant: const Color(0xFF283440),
|
||||
surfaceTint: const Color(0xFF4EA8FF),
|
||||
inverseSurface: const Color(0xFFE3E9F0),
|
||||
onInverseSurface: const Color(0xFF111820),
|
||||
inversePrimary: const Color(0xFF0B6BCB),
|
||||
);
|
||||
}
|
||||
|
||||
static ColorScheme _lightScheme() {
|
||||
return ColorScheme.fromSeed(
|
||||
seedColor: _seed,
|
||||
brightness: Brightness.light,
|
||||
).copyWith(
|
||||
primary: const Color(0xFF0B6BCB),
|
||||
onPrimary: const Color(0xFFFFFFFF),
|
||||
primaryContainer: const Color(0xFFD3E7FF),
|
||||
onPrimaryContainer: const Color(0xFF00294A),
|
||||
secondary: const Color(0xFF0F766E),
|
||||
onSecondary: const Color(0xFFFFFFFF),
|
||||
secondaryContainer: const Color(0xFFB8F1E8),
|
||||
onSecondaryContainer: const Color(0xFF00201C),
|
||||
tertiary: const Color(0xFF6D28D9),
|
||||
onTertiary: const Color(0xFFFFFFFF),
|
||||
tertiaryContainer: const Color(0xFFE9DDFF),
|
||||
onTertiaryContainer: const Color(0xFF23005C),
|
||||
error: const Color(0xFFDC2626),
|
||||
onError: const Color(0xFFFFFFFF),
|
||||
errorContainer: const Color(0xFFFBD9D6),
|
||||
onErrorContainer: const Color(0xFF450A0A),
|
||||
surface: const Color(0xFFF6F8FB),
|
||||
onSurface: const Color(0xFF111820),
|
||||
onSurfaceVariant: const Color(0xFF42505F),
|
||||
surfaceContainerLowest: const Color(0xFFFFFFFF),
|
||||
surfaceContainerLow: const Color(0xFFF0F4F9),
|
||||
surfaceContainer: const Color(0xFFEDF1F6),
|
||||
surfaceContainerHigh: const Color(0xFFE4EAF2),
|
||||
surfaceContainerHighest: const Color(0xFFDCE4EE),
|
||||
surfaceDim: const Color(0xFFD7DEE8),
|
||||
surfaceBright: const Color(0xFFF6F8FB),
|
||||
outline: const Color(0xFF73808F),
|
||||
outlineVariant: const Color(0xFFC3CDDA),
|
||||
surfaceTint: const Color(0xFF0B6BCB),
|
||||
inverseSurface: const Color(0xFF111820),
|
||||
onInverseSurface: const Color(0xFFEFF3F8),
|
||||
inversePrimary: const Color(0xFFA6C8FF),
|
||||
);
|
||||
}
|
||||
|
||||
// ────────────────────────────────────────────────────────────
|
||||
// LIGHT
|
||||
// ────────────────────────────────────────────────────────────
|
||||
static ThemeData light() {
|
||||
final base = ThemeData(
|
||||
colorScheme: ColorScheme.fromSeed(
|
||||
seedColor: _seed,
|
||||
brightness: Brightness.light,
|
||||
),
|
||||
useMaterial3: true,
|
||||
return _apply(
|
||||
ThemeData(colorScheme: _lightScheme(), useMaterial3: true),
|
||||
AppStatusColors.light,
|
||||
);
|
||||
|
||||
return _apply(base);
|
||||
}
|
||||
|
||||
// ────────────────────────────────────────────────────────────
|
||||
// DARK
|
||||
// ────────────────────────────────────────────────────────────
|
||||
static ThemeData dark() {
|
||||
final base = ThemeData(
|
||||
colorScheme: ColorScheme.fromSeed(
|
||||
seedColor: _seed,
|
||||
brightness: Brightness.dark,
|
||||
),
|
||||
useMaterial3: true,
|
||||
return _apply(
|
||||
ThemeData(colorScheme: _darkScheme(), useMaterial3: true),
|
||||
AppStatusColors.dark,
|
||||
);
|
||||
|
||||
return _apply(base);
|
||||
}
|
||||
|
||||
// ────────────────────────────────────────────────────────────
|
||||
// SHARED BUILDER
|
||||
// ────────────────────────────────────────────────────────────
|
||||
static ThemeData _apply(ThemeData base) {
|
||||
static ThemeData _apply(ThemeData base, AppStatusColors status) {
|
||||
final cs = base.colorScheme;
|
||||
final isDark = cs.brightness == Brightness.dark;
|
||||
|
||||
@@ -68,18 +151,17 @@ class AppTheme {
|
||||
const TextStyle(letterSpacing: 0.2),
|
||||
);
|
||||
|
||||
const surfaces = AppSurfaces(
|
||||
cardRadius: 16,
|
||||
compactCardRadius: 12,
|
||||
containerRadius: 28,
|
||||
dialogRadius: 28,
|
||||
chipRadius: 12,
|
||||
);
|
||||
final surfaces = _surfaces;
|
||||
|
||||
// Card fill: flat tonal surface + hairline outline (cyber "panel" look).
|
||||
final cardColor = isDark ? cs.surfaceContainer : cs.surfaceContainerLowest;
|
||||
|
||||
return base.copyWith(
|
||||
textTheme: textTheme,
|
||||
scaffoldBackgroundColor: isDark ? cs.surface : cs.surfaceContainerLowest,
|
||||
extensions: [mono, surfaces],
|
||||
scaffoldBackgroundColor: isDark
|
||||
? const Color(0xFF0B0F14)
|
||||
: cs.surfaceContainerLowest,
|
||||
extensions: [mono, surfaces, status],
|
||||
|
||||
// ── AppBar ──────────────────────────────────────────────
|
||||
appBarTheme: AppBarTheme(
|
||||
@@ -99,22 +181,27 @@ class AppTheme {
|
||||
),
|
||||
),
|
||||
|
||||
// ── Cards — M3 Elevated (tonal surface tint, no hard shadow) ──
|
||||
// ── Cards — flat tonal fill + hairline outline (no hard shadow) ──
|
||||
cardTheme: CardThemeData(
|
||||
color: isDark ? cs.surfaceContainer : cs.surfaceContainerLow,
|
||||
elevation: 1,
|
||||
color: cardColor,
|
||||
elevation: 0,
|
||||
margin: EdgeInsets.zero,
|
||||
shadowColor: Colors.transparent,
|
||||
surfaceTintColor: cs.surfaceTint,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
|
||||
surfaceTintColor: Colors.transparent,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(surfaces.cardRadius),
|
||||
side: BorderSide(color: cs.outlineVariant),
|
||||
),
|
||||
),
|
||||
|
||||
// ── Chips ───────────────────────────────────────────────
|
||||
// ── Chips — mono label, tight radius ────────────────────
|
||||
chipTheme: ChipThemeData(
|
||||
backgroundColor: cs.surfaceContainerHighest,
|
||||
side: BorderSide.none,
|
||||
labelStyle: textTheme.labelSmall,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
|
||||
side: BorderSide(color: cs.outlineVariant),
|
||||
labelStyle: mono.label,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(surfaces.chipRadius),
|
||||
),
|
||||
),
|
||||
|
||||
// ── Dividers ────────────────────────────────────────────
|
||||
@@ -123,17 +210,17 @@ class AppTheme {
|
||||
// ── Input Fields ────────────────────────────────────────
|
||||
inputDecorationTheme: InputDecorationTheme(
|
||||
filled: true,
|
||||
fillColor: cs.surfaceContainerLow,
|
||||
fillColor: isDark ? cs.surfaceContainerLow : cs.surfaceContainer,
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
borderRadius: BorderRadius.circular(surfaces.cardRadius),
|
||||
borderSide: BorderSide(color: cs.outlineVariant),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
borderRadius: BorderRadius.circular(surfaces.cardRadius),
|
||||
borderSide: BorderSide(color: cs.outlineVariant),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
borderRadius: BorderRadius.circular(surfaces.cardRadius),
|
||||
borderSide: BorderSide(color: cs.primary, width: 2),
|
||||
),
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
@@ -142,87 +229,84 @@ class AppTheme {
|
||||
),
|
||||
),
|
||||
|
||||
// ── Buttons — M3 Expressive hierarchy ───────────────────
|
||||
// ── Buttons — M3 hierarchy, tightened shapes ────────────
|
||||
filledButtonTheme: FilledButtonThemeData(
|
||||
style: FilledButton.styleFrom(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
borderRadius: BorderRadius.circular(surfaces.cardRadius),
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 16),
|
||||
textStyle: textTheme.labelLarge?.copyWith(
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
textStyle: textTheme.labelLarge?.copyWith(fontWeight: FontWeight.w600),
|
||||
),
|
||||
),
|
||||
elevatedButtonTheme: ElevatedButtonThemeData(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: cs.surfaceContainerLow,
|
||||
backgroundColor: cs.surfaceContainerHigh,
|
||||
foregroundColor: cs.primary,
|
||||
elevation: 1,
|
||||
elevation: 0,
|
||||
shadowColor: Colors.transparent,
|
||||
surfaceTintColor: cs.surfaceTint,
|
||||
surfaceTintColor: Colors.transparent,
|
||||
side: BorderSide(color: cs.outlineVariant),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
borderRadius: BorderRadius.circular(surfaces.cardRadius),
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 16),
|
||||
textStyle: textTheme.labelLarge?.copyWith(
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
textStyle: textTheme.labelLarge?.copyWith(fontWeight: FontWeight.w600),
|
||||
),
|
||||
),
|
||||
outlinedButtonTheme: OutlinedButtonThemeData(
|
||||
style: OutlinedButton.styleFrom(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
borderRadius: BorderRadius.circular(surfaces.cardRadius),
|
||||
),
|
||||
side: BorderSide(color: cs.outline),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 14),
|
||||
textStyle: textTheme.labelLarge?.copyWith(
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
textStyle: textTheme.labelLarge?.copyWith(fontWeight: FontWeight.w600),
|
||||
),
|
||||
),
|
||||
textButtonTheme: TextButtonThemeData(
|
||||
style: TextButton.styleFrom(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
borderRadius: BorderRadius.circular(surfaces.cardRadius),
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||
textStyle: textTheme.labelLarge?.copyWith(
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
textStyle: textTheme.labelLarge?.copyWith(fontWeight: FontWeight.w600),
|
||||
),
|
||||
),
|
||||
iconButtonTheme: IconButtonThemeData(
|
||||
style: IconButton.styleFrom(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
borderRadius: BorderRadius.circular(surfaces.compactCardRadius),
|
||||
),
|
||||
),
|
||||
),
|
||||
segmentedButtonTheme: SegmentedButtonThemeData(
|
||||
style: ButtonStyle(
|
||||
shape: WidgetStateProperty.all(
|
||||
RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
|
||||
RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(surfaces.cardRadius),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
// ── FAB — M3 Expressive ──────────────────────────────────
|
||||
// ── FAB ──────────────────────────────────────────────────
|
||||
floatingActionButtonTheme: FloatingActionButtonThemeData(
|
||||
backgroundColor: cs.primaryContainer,
|
||||
foregroundColor: cs.onPrimaryContainer,
|
||||
elevation: 3,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(surfaces.containerRadius),
|
||||
),
|
||||
),
|
||||
|
||||
// ── Navigation — M3 Expressive pill indicators ──────────
|
||||
// ── Navigation — pill indicators ────────────────────────
|
||||
navigationDrawerTheme: NavigationDrawerThemeData(
|
||||
backgroundColor: cs.surface,
|
||||
indicatorColor: cs.secondaryContainer,
|
||||
tileHeight: 56,
|
||||
indicatorShape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(28),
|
||||
borderRadius: BorderRadius.circular(surfaces.containerRadius),
|
||||
),
|
||||
),
|
||||
navigationRailTheme: NavigationRailThemeData(
|
||||
@@ -238,14 +322,14 @@ class AppTheme {
|
||||
),
|
||||
indicatorColor: cs.secondaryContainer,
|
||||
indicatorShape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(28),
|
||||
borderRadius: BorderRadius.circular(surfaces.containerRadius),
|
||||
),
|
||||
),
|
||||
navigationBarTheme: NavigationBarThemeData(
|
||||
backgroundColor: cs.surfaceContainer,
|
||||
indicatorColor: cs.secondaryContainer,
|
||||
indicatorShape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
borderRadius: BorderRadius.circular(surfaces.cardRadius),
|
||||
),
|
||||
labelTextStyle: WidgetStateProperty.resolveWith((states) {
|
||||
final selected = states.contains(WidgetState.selected);
|
||||
@@ -260,15 +344,19 @@ class AppTheme {
|
||||
|
||||
// ── List Tiles ──────────────────────────────────────────
|
||||
listTileTheme: ListTileThemeData(
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(surfaces.cardRadius),
|
||||
),
|
||||
tileColor: Colors.transparent,
|
||||
contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 4),
|
||||
),
|
||||
|
||||
// ── Dialogs ─────────────────────────────────────────────
|
||||
dialogTheme: DialogThemeData(
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(28)),
|
||||
surfaceTintColor: cs.surfaceTint,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(surfaces.dialogRadius),
|
||||
),
|
||||
surfaceTintColor: Colors.transparent,
|
||||
backgroundColor: isDark
|
||||
? cs.surfaceContainerHigh
|
||||
: cs.surfaceContainerLowest,
|
||||
@@ -276,20 +364,24 @@ class AppTheme {
|
||||
|
||||
// ── Bottom Sheets ───────────────────────────────────────
|
||||
bottomSheetTheme: BottomSheetThemeData(
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.vertical(top: Radius.circular(28)),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.vertical(
|
||||
top: Radius.circular(surfaces.dialogRadius),
|
||||
),
|
||||
),
|
||||
backgroundColor: isDark
|
||||
? cs.surfaceContainerHigh
|
||||
: cs.surfaceContainerLowest,
|
||||
surfaceTintColor: cs.surfaceTint,
|
||||
surfaceTintColor: Colors.transparent,
|
||||
showDragHandle: true,
|
||||
),
|
||||
|
||||
// ── Snackbar ────────────────────────────────────────────
|
||||
snackBarTheme: SnackBarThemeData(
|
||||
behavior: SnackBarBehavior.floating,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(surfaces.compactCardRadius),
|
||||
),
|
||||
),
|
||||
|
||||
// ── Search Bar ──────────────────────────────────────────
|
||||
@@ -297,7 +389,9 @@ class AppTheme {
|
||||
elevation: WidgetStateProperty.all(0),
|
||||
backgroundColor: WidgetStateProperty.all(cs.surfaceContainerHigh),
|
||||
shape: WidgetStateProperty.all(
|
||||
RoundedRectangleBorder(borderRadius: BorderRadius.circular(28)),
|
||||
RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(surfaces.containerRadius),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -305,7 +399,7 @@ class AppTheme {
|
||||
tooltipTheme: TooltipThemeData(
|
||||
decoration: BoxDecoration(
|
||||
color: cs.inverseSurface,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderRadius: BorderRadius.circular(surfaces.chipRadius),
|
||||
),
|
||||
textStyle: textTheme.bodySmall?.copyWith(color: cs.onInverseSurface),
|
||||
),
|
||||
@@ -323,8 +417,10 @@ class AppTheme {
|
||||
|
||||
// ── PopupMenu ───────────────────────────────────────────
|
||||
popupMenuTheme: PopupMenuThemeData(
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
|
||||
surfaceTintColor: cs.surfaceTint,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(surfaces.compactCardRadius),
|
||||
),
|
||||
surfaceTintColor: Colors.transparent,
|
||||
color: isDark ? cs.surfaceContainerHigh : cs.surfaceContainerLowest,
|
||||
),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user