import 'package:flutter/material.dart'; import 'package:shadcn_ui/shadcn_ui.dart'; import 'app_colors.dart'; /// 健康管家 —— 蚂蚁阿福风格:紫蓝渐变 + 超大圆角 + 漂浮卡片 class AppTheme { AppTheme._(); // ── 主色调 ── static const Color primary = AppColors.primary; static const Color primaryLight = AppColors.primaryLight; static const Color primaryDark = AppColors.primaryDark; static const Color primaryMid = AppColors.primaryMid; static const Color accent = AppColors.accentCyan; static const Color info = AppColors.accentCyan; // ── 中性色 ── static const Color bg = AppColors.background; static const Color bgSoft = AppColors.backgroundSoft; static const Color surface = AppColors.cardBackground; static const Color surfaceInner = AppColors.cardInner; static const Color text = AppColors.textPrimary; static const Color textSub = AppColors.textSecondary; static const Color textHint = AppColors.textHint; static const Color border = AppColors.border; static const Color divider = AppColors.borderLight; // ── 语义色 ── static const Color success = AppColors.success; static const Color successLight = AppColors.successLight; static const Color error = AppColors.error; static const Color errorLight = AppColors.errorLight; static const Color warning = AppColors.warning; static const Color warningLight = AppColors.warningLight; // ── 圆角(阿福风格:超大圆角)── static const double rXs = 8; static const double rSm = 12; static const double rMd = 18; static const double rLg = 24; static const double rXl = 32; static const double rPill = 999; // ── 间距 ── static const double sXs = 4; static const double sSm = 8; static const double sMd = 12; static const double sLg = 16; static const double sXl = 20; static const double sXxl = 28; // ── 阴影(淡紫柔和阴影)── static BoxShadow get shadowCard => BoxShadow( color: AppColors.primary.withOpacity(0.08), blurRadius: 24, offset: const Offset(0, 8), ); static BoxShadow get shadowLight => BoxShadow( color: AppColors.primary.withOpacity(0.05), blurRadius: 16, offset: const Offset(0, 4), ); static BoxShadow get shadowElevated => BoxShadow( color: AppColors.primary.withOpacity(0.15), blurRadius: 32, offset: const Offset(0, 10), ); static BoxShadow get shadowButton => BoxShadow( color: AppColors.primary.withOpacity(0.25), blurRadius: 16, offset: const Offset(0, 6), ); // ── 智能体配色 ── static const Map agentColors = { 'default': AppColors.primaryLight, 'consultation': Color(0xFFE0E7FF), 'health': Color(0xFFDCFCE7), 'diet': Color(0xFFFEF3C7), 'medication': Color(0xFFFCE7F3), 'report': Color(0xFFDBEAFE), 'exercise': Color(0xFFEDE9FE), }; static Color agentLight(String? name) => agentColors[name] ?? primaryLight; // ── Material 主题 ── static ThemeData get lightTheme => ThemeData( useMaterial3: true, colorScheme: ColorScheme.fromSeed( seedColor: primary, primary: primary, primaryContainer: primaryLight, onPrimary: Colors.white, secondary: accent, surface: surface, background: bg, brightness: Brightness.light, ), scaffoldBackgroundColor: bg, splashColor: Colors.transparent, highlightColor: Colors.transparent, hoverColor: primaryLight.withOpacity(0.5), fontFamily: null, appBarTheme: AppBarTheme( backgroundColor: bg, foregroundColor: text, elevation: 0, centerTitle: false, scrolledUnderElevation: 0, titleTextStyle: TextStyle(fontSize: 22, fontWeight: FontWeight.w700, color: text), ), cardTheme: CardThemeData( color: surface, elevation: 0, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(rLg)), margin: EdgeInsets.zero, ), inputDecorationTheme: InputDecorationTheme( filled: true, fillColor: bgSoft, contentPadding: const EdgeInsets.symmetric(horizontal: sLg, vertical: 16), border: OutlineInputBorder(borderRadius: BorderRadius.circular(rMd), borderSide: BorderSide.none), enabledBorder: OutlineInputBorder(borderRadius: BorderRadius.circular(rMd), borderSide: BorderSide.none), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(rMd), borderSide: const BorderSide(color: primary, width: 2), ), hintStyle: TextStyle(color: textHint, fontSize: 16), ), elevatedButtonTheme: ElevatedButtonThemeData( style: ElevatedButton.styleFrom( backgroundColor: primary, foregroundColor: Colors.white, minimumSize: const Size(double.infinity, 56), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(rPill)), textStyle: const TextStyle(fontSize: 17, fontWeight: FontWeight.w600), elevation: 0, shadowColor: primary.withOpacity(0.3), ), ), dialogTheme: DialogThemeData(shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(rXl))), textTheme: const TextTheme( headlineLarge: TextStyle(fontSize: 28, fontWeight: FontWeight.w700, color: text, letterSpacing: -0.3), titleLarge: TextStyle(fontSize: 22, fontWeight: FontWeight.w700, color: text), titleMedium: TextStyle(fontSize: 20, fontWeight: FontWeight.w600, color: text), bodyLarge: TextStyle(fontSize: 16, color: text, height: 1.5), bodyMedium: TextStyle(fontSize: 14, color: textSub, height: 1.4), labelMedium: TextStyle(fontSize: 13, color: textSub), labelSmall: TextStyle(fontSize: 12, color: textHint), ), ); // ── Shadcn UI 主题(紫蓝系) ── static ShadThemeData get shadTheme => ShadThemeData( brightness: Brightness.light, colorScheme: ShadVioletColorScheme.light( background: bg, foreground: text, card: surface, cardForeground: text, popover: surface, popoverForeground: text, primary: primary, primaryForeground: Colors.white, secondary: primaryLight, secondaryForeground: primaryDark, muted: bgSoft, mutedForeground: textSub, accent: accent, accentForeground: Colors.white, destructive: error, destructiveForeground: Colors.white, border: border, input: border, ring: primary, selection: primaryLight, ), radius: BorderRadius.circular(rMd), ); }