From e26031ad17d7c064f38fb24656ba0d5a06fb74a4 Mon Sep 17 00:00:00 2001 From: sion123 <450702724@qq.com> Date: Sun, 29 Mar 2026 20:34:52 +0800 Subject: [PATCH] =?UTF-8?q?feat(monisuo-dev):=20=E9=87=8D=E6=9E=84?= =?UTF-8?q?=E5=BC=80=E5=8F=91=E6=B5=81=E7=A8=8B=E4=B8=BA=E4=BA=94=E9=98=B6?= =?UTF-8?q?=E6=AE=B5=E5=B9=B6=E4=BC=98=E5=8C=96Agent=E5=8D=8F=E4=BD=9C?= =?UTF-8?q?=E6=9C=BA=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 更新开发流程描述,细化为需求定义→架构设计→模块化开发→精简测试→功能验证→构建六个环节 - 重构Phase 3为精简+测试,移除构建步骤,新增独立的Phase 5构建阶段 - 优化Agent协作流程:Phase 3输出审查报告供Phase 4使用,避免重复读取代码 - 明确各阶段职责分工,增加Spec同步要求确保Agent间信息一致性 - 添加Phase 5构建阶段,专门处理后端和Flutter构建任务 - 完善Bug修复循环,明确各Agent失败时的修复流程 --- .agents/skills/monisuo-dev/SKILL.md | 90 ++- .agents/skills/superdesign-flutter/SKILL.md | 621 -------------------- 2 files changed, 68 insertions(+), 643 deletions(-) delete mode 100644 .agents/skills/superdesign-flutter/SKILL.md diff --git a/.agents/skills/monisuo-dev/SKILL.md b/.agents/skills/monisuo-dev/SKILL.md index 62f75d7..3a80e6f 100644 --- a/.agents/skills/monisuo-dev/SKILL.md +++ b/.agents/skills/monisuo-dev/SKILL.md @@ -1,6 +1,6 @@ --- name: monisuo-dev -description: Monisuo 项目结构化开发流程。需求分析 → 架构设计 → 开发 → 测试构建。 +description: Monisuo 项目结构化开发流程。需求分析 → 架构设计 → 模块化开发 → 精简测试 → 功能验证 → 构建。 --- # Monisuo 开发工作流 @@ -8,18 +8,25 @@ description: Monisuo 项目结构化开发流程。需求分析 → 架构设计 ## 流程概览 ``` -Phase 1: 需求定义 → Phase 1.5: 架构设计 → Phase 2: 模块化开发 +Phase 1: 需求定义 → Phase 1.5: 架构设计 → Phase 2: 模块化开发(子任务逐步推进) ↑ │ │ ↓ - │ [Agent A] Phase 3: 精简 + 测试 + 构建 + │ 主对话:同步更新 Spec + │ │ + │ ↓ + │ [Agent A] Phase 3: 精简 + 测试 → 输出审查报告 │ │ │ ↓ (通过) - │ [Agent B] Phase 4: 功能验证(用例驱动) + │ [Agent B] Phase 4: 功能验证(接收审查报告) + │ │ + │ ↓ (通过) + │ [Agent C] Phase 5: 构建 │ │ └──────────────── Bug 修复 ←──────────────────┘ ``` -**Phase 1-1.5-2 在主对话完成,Phase 3 和 Phase 4 分别启动独立 Agent。** +**Phase 1/1.5/2 在主对话完成,Phase 3/4/5 分别启动独立 Agent。** +**所有 Agent prompt 中的 `[feature-name]` 由主对话替换为实际值后再传入。** --- @@ -86,28 +93,38 @@ Phase 1: 需求定义 → Phase 1.5: 架构设计 → Phase 2: 模块化开发 ## Phase 2: 模块化开发 -依据 Spec 中的 API 契约和数据模型,自底向上开发: +依据 Spec 中的 API 契约和数据模型,**按子模块逐步推进**,自底向上开发: ``` -1. 数据层 → 2. 后端 API → 3. 前端实现 - DDL/Entity Controller/Service Model/Provider/UI +2a. 数据层 → 2b. 后端 API → 2c. Flutter 前端 → 2d. Admin 前端(如有) + DDL/Entity Controller/Service Model/Provider/UI Vue Pages ``` +### 子模块执行方式 +- 每个子模块独立完成,不与其他子模块混在一起 +- 每完成一个子模块,确认无编译错误再进入下一个 +- 后端子模块完成后可先验证 API,前端再对接 + ### 代码规范 - Flutter: `flutter analyze` 无错,用 AppSpacing/AppRadius/AppColorScheme,禁止硬编码颜色 - Java: Lombok 简化,资金变动方法加 `@Transactional(rollbackFor = Exception.class)`,RESTful 设计 +### Spec 同步 +Phase 2 全部完成后、启动 Agent 前,**主对话必须更新 Spec**: +- 实际实现与设计有差异时,以实现为准更新 Spec +- 确保 Phase 3/4 的 Agent 读到的是最新状态 + --- -## Phase 3: 精简 + 测试 + 构建(Agent A) +## Phase 3: 精简 + 测试(Agent A) -Phase 2 完成后,启动独立 Agent 执行代码精简、自动化测试和构建。 +Phase 2 完成且 Spec 已同步后,启动独立 Agent 执行代码精简和自动化测试。 ### 启动 Agent A ``` Agent( - description: "精简+测试验证与构建", + description: "精简+测试验证", prompt: | 你是 Monisuo 项目质量 Agent,独立完成以下任务,不要询问用户。 @@ -129,19 +146,19 @@ Agent( - Flutter: cd flutter_monisuo && flutter test - API: ./tests/api/test-[feature].sh(如存在) - ## 5. 构建 - - 后端: mvn clean package -DskipTests → target/monisuo-*.jar - - Flutter: cd flutter_monisuo && flutter build web --release --dart-define=ENV=prod → build/web/ + ## 5. 输出审查报告(供 Agent B 使用) + ### 代码审查摘要 + - 变更文件列表及每个文件的核心改动 + - 代码规范检查结果 + - 精简改动摘要(改了什么、为什么改) - ## 6. 输出报告 + ### 测试结果 | 项目 | 状态 | 备注 | |------|------|------| | 代码审查 | ✅/❌ | | | 代码精简 | ✅/❌ | 改动摘要 | | 后端测试 | ✅/❌ | | | Flutter 测试 | ✅/❌ | | - | 后端构建 | ✅/❌ | | - | Flutter 构建 | ✅/❌ | | 如有 Bug,列出:文件、原因、修复建议。返回主对话修复后重新验证。 ) @@ -151,7 +168,7 @@ Agent( ## Phase 4: 功能验证(Agent B) -**Agent A 全部通过后**,启动第二个独立 Agent,基于 Spec 中的测试用例验证功能正确性。 +**Agent A 全部通过后**,启动独立 Agent。Agent B 接收 Agent A 的审查报告,避免重复读代码。 ### 启动 Agent B @@ -165,9 +182,9 @@ Agent( - 路径: docs/features/[feature-name].md - 提取「测试用例」和「验收标准」 - ## 2. 读取变更代码 - - git diff 查看本次变更的文件列表 - - 阅读变更的 Controller、Service、Provider、UI 代码 + ## 2. 利用审查报告 + - Agent A 已完成代码审查,变更文件列表和核心改动见报告 + - 仅对报告未覆盖的逻辑路径做补充阅读 - 对照 Spec 中的 API 设计,确认实现与契约一致 ## 3. 逐条验证测试用例 @@ -199,8 +216,37 @@ Agent( --- +## Phase 5: 构建(Agent C) + +**Agent A 和 Agent B 全部通过后**,启动独立 Agent 执行构建。 + +### 启动 Agent C + +``` +Agent( + description: "项目构建", + prompt: | + 你是 Monisuo 项目构建 Agent,独立完成构建任务,不要询问用户。 + + ## 1. 构建 + - 后端: mvn clean package -DskipTests → target/monisuo-*.jar + - Flutter: cd flutter_monisuo && flutter build web --release --dart-define=ENV=prod → build/web/ + + ## 2. 输出报告 + | 项目 | 状态 | 备注 | + |------|------|------| + | 后端构建 | ✅/❌ | 产物路径 | + | Flutter 构建 | ✅/❌ | 产物路径 | + + 如有构建失败,列出:模块、错误信息、修复建议。返回主对话修复后重新构建。 +) +``` + +--- + ## Bug 修复循环 -- **Agent A 失败**(测试/构建不通过)→ 主对话修复 Bug → 重新启动 Agent A +- **Agent A 失败**(测试不通过)→ 主对话修复 Bug → 重新启动 Agent A - **Agent B 失败**(功能验证不通过)→ 主对话修复逻辑 → 重新启动 Agent B +- **Agent C 失败**(构建不通过)→ 主对话修复构建问题 → 重新启动 Agent C - **全部通过** → 开发完成 diff --git a/.agents/skills/superdesign-flutter/SKILL.md b/.agents/skills/superdesign-flutter/SKILL.md deleted file mode 100644 index ee13891..0000000 --- a/.agents/skills/superdesign-flutter/SKILL.md +++ /dev/null @@ -1,621 +0,0 @@ ---- -name: superdesign-flutter -description: Flutter Design Skill - SuperDesign adapted for Flutter/Dart development. Optimized for Material Design 3 and Flutter widgets. ---- - -# Flutter Design Skill - -Use this skill when creating Flutter UI components, screens, or any Flutter UI design work. - -This is an adapted version of SuperDesign for Flutter, converting web/CSS patterns to Flutter/Dart equivalents. - -## Design Workflow - -Follow this structured approach for Flutter UI design: - -- **Layout Design** — Think through widget structure, create ASCII wireframes -- **Theme Design** — Define colors, text styles, spacing, shadows -- **Animation Design** — Plan micro-interactions and transitions -- **Implementation** — Generate Flutter/Dart code - -### 1. Layout Design - -Before coding, sketch the widget tree in ASCII format: - -``` -┌─────────────────────────────────────┐ -│ Scaffold / AppBar │ -├─────────────────────────────────────┤ -│ │ -│ Hero Section (Column) │ -│ - Title Text │ -│ - CTA ElevatedButton │ -│ │ -├─────────────────────────────────────┤ -│ Row (3x Feature Cards) │ -│ ┌─────┐ ┌─────┐ ┌─────┐ │ -│ │Card │ │Card │ │Card │ │ -│ └─────┘ └─────┘ └─────┘ │ -├─────────────────────────────────────┤ -│ BottomNavigationBar │ -└─────────────────────────────────────┘ -``` - -### 2. Theme Guidelines - -#### Color Rules: - -- NEVER use generic blue (Colors.blue) — it looks dated -- Prefer Material Design 3 color system (ColorScheme) -- Use Theme.of(context).colorScheme for semantic colors -- Support both light and dark mode with ColorScheme - -#### OKLCH to Flutter Color Conversion: - -Convert OKLCH values to Flutter Color using this helper: - -```dart -import 'package:flutter/material.dart'; - -/// Convert OKLCH to Flutter Color -/// Example: oklch(0.205 0 0) → Color -Color oklchToColor(double l, double c, double h) { - // Simplified conversion - for accurate conversion use a color library - // This is a placeholder implementation - final hue = h; - final chroma = c; - final lightness = l; - - // Convert to HSL then to RGB - // For production, use package:flutter_color or similar - return HSLColor.fromAHSL(1.0, hue, chroma, lightness).toColor(); -} - -// Modern Dark Mode Colors (Vercel/Linear style) -class ModernDarkColors { - static const background = Color(0xFFFFFFFF); // oklch(1 0 0) - static const foreground = Color(0xFF252525); // oklch(0.145 0 0) - static const primary = Color(0xFF343434); // oklch(0.205 0 0) - static const secondary = Color(0xFFF7F7F7); // oklch(0.970 0 0) - static const muted = Color(0xFFF7F7F7); // oklch(0.970 0 0) - static const border = Color(0xFFEBEBEB); // oklch(0.922 0 0) -} -``` - -#### Flutter Theme Setup: - -```dart -MaterialApp( - theme: ThemeData( - useMaterial3: true, - colorScheme: ColorScheme.fromSeed( - seedColor: Color(0xFF343434), // Modern neutral - brightness: Brightness.light, - ), - fontFamily: 'Inter', - ), - darkTheme: ThemeData( - useMaterial3: true, - colorScheme: ColorScheme.fromSeed( - seedColor: Color(0xFF343434), - brightness: Brightness.dark, - ), - fontFamily: 'Inter', - ), -); -``` - -#### Font Selection (Google Fonts): - -Use `google_fonts` package: - -```yaml -# pubspec.yaml -dependencies: - google_fonts: ^6.1.0 -``` - -```dart -import 'package:google_fonts/google_fonts.dart'; - -// Sans-serif fonts -final inter = GoogleFonts.inter(); -final roboto = GoogleFonts.roboto(); -final poppins = GoogleFonts.poppins(); -final montserrat = GoogleFonts.montserrat(); -final outfit = GoogleFonts.outfit(); -final dmSans = GoogleFonts.dmSans(); - -// Monospace fonts -final jetBrainsMono = GoogleFonts.jetBrainsMono(); -final firaCode = GoogleFonts.firaCode(); -final sourceCodePro = GoogleFonts.sourceCodePro(); -``` - -#### Spacing System: - -```dart -/// Spacing scale based on 4.0 (instead of 0.25rem) -class Spacing { - static const double xs = 4.0; - static const double sm = 8.0; - static const double md = 16.0; - static const double lg = 24.0; - static const double xl = 32.0; - static const double xxl = 48.0; -} - -// Usage -Padding( - padding: EdgeInsets.all(Spacing.md), // 16.0 - child: Text('Content'), -) -``` - -### 3. Theme Patterns - -#### Modern Dark Mode (Vercel/Linear style): - -```dart -ThemeData( - useMaterial3: true, - colorScheme: ColorScheme( - brightness: Brightness.light, - background: Color(0xFFFFFFFF), - onBackground: Color(0xFF252525), - primary: Color(0xFF343434), - onPrimary: Color(0xFFFBFBFB), - secondary: Color(0xFFF7F7F7), - onSecondary: Color(0xFF252525), - surface: Color(0xFFFFFFFF), - onSurface: Color(0xFF252525), - outline: Color(0xFFEBEBEB), - ), - cardTheme: CardTheme( - elevation: 0, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10.0), // 0.625rem - ), - ), -); -``` - -#### Neo-Brutalism (90s revival): - -```dart -ThemeData( - useMaterial3: true, - colorScheme: ColorScheme( - brightness: Brightness.light, - background: Color(0xFFFFFFFF), - onBackground: Color(0xFF000000), - primary: Color(0xFFFF6B35), // Vibrant orange - secondary: Color(0xFF4ECDC4), // Teal - tertiary: Color(0xFF5B5F97), // Purple - outline: Color(0xFF000000), - ), - cardTheme: CardTheme( - elevation: 0, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(0), // No radius - side: BorderSide(color: Colors.black, width: 2), - ), - ), - elevatedButtonTheme: ElevatedButtonThemeData( - style: ElevatedButton.styleFrom( - elevation: 0, - shadowColor: Colors.transparent, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(0), - ), - ), - ), -); -``` - -#### Glassmorphism: - -```dart -class GlassCard extends StatelessWidget { - final Widget child; - - const GlassCard({required this.child}); - - @override - Widget build(BuildContext context) { - return ClipRRect( - borderRadius: BorderRadius.circular(16.0), - child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10), - child: Container( - decoration: BoxDecoration( - color: Colors.white.withOpacity(0.1), - border: Border.all( - color: Colors.white.withOpacity(0.2), - width: 1, - ), - borderRadius: BorderRadius.circular(16.0), - ), - child: child, - ), - ), - ); - } -} -``` - -### 4. Animation Guidelines - -#### Flutter Animation Equivalents: - -```dart -// Button press animation (150ms) -class AnimatedButton extends StatefulWidget { - @override - _AnimatedButtonState createState() => _AnimatedButtonState(); -} - -class _AnimatedButtonState extends State - with SingleTickerProviderStateMixin { - late AnimationController _controller; - late Animation _scaleAnimation; - - @override - void initState() { - super.initState(); - _controller = AnimationController( - duration: Duration(milliseconds: 150), - vsync: this, - ); - _scaleAnimation = Tween(begin: 1.0, end: 0.95).animate( - CurvedAnimation(parent: _controller, curve: Curves.easeInOut), - ); - } - - @override - Widget build(BuildContext context) { - return GestureDetector( - onTapDown: (_) => _controller.forward(), - onTapUp: (_) => _controller.reverse(), - onTapCancel: () => _controller.reverse(), - child: ScaleTransition( - scale: _scaleAnimation, - child: ElevatedButton(...), - ), - ); - } -} - -// Fade in animation (400ms) -class FadeInWidget extends StatefulWidget { - final Widget child; - const FadeInWidget({required this.child}); - @override - _FadeInWidgetState createState() => _FadeInWidgetState(); -} - -class _FadeInWidgetState extends State - with SingleTickerProviderStateMixin { - late AnimationController _controller; - late Animation _opacity; - late Animation _slide; - - @override - void initState() { - super.initState(); - _controller = AnimationController( - duration: Duration(milliseconds: 400), - vsync: this, - ); - _opacity = Tween(begin: 0.0, end: 1.0).animate(_controller); - _slide = Tween(begin: Offset(0, 0.05), end: Offset.zero) - .animate(CurvedAnimation(parent: _controller, curve: Curves.easeOut)); - _controller.forward(); - } - - @override - Widget build(BuildContext context) { - return SlideTransition( - position: _slide, - child: FadeTransition(opacity: _opacity, child: widget.child), - ); - } -} -``` - -#### Common Animation Durations: - -```dart -class AnimationDurations { - static const Duration buttonPress = Duration(milliseconds: 150); - static const Duration hover = Duration(milliseconds: 200); - static const Duration fadeIn = Duration(milliseconds: 400); - static const Duration slideIn = Duration(milliseconds: 350); - static const Duration bounce = Duration(milliseconds: 600); - static const Duration pageTransition = Duration(milliseconds: 300); -} -``` - -### 5. Widget Patterns - -#### Responsive Layout: - -```dart -class ResponsiveLayout extends StatelessWidget { - final Widget mobile; - final Widget? tablet; - final Widget? desktop; - - const ResponsiveLayout({ - required this.mobile, - this.tablet, - this.desktop, - }); - - @override - Widget build(BuildContext context) { - return LayoutBuilder( - builder: (context, constraints) { - if (constraints.maxWidth >= 1024) { - return desktop ?? tablet ?? mobile; - } else if (constraints.maxWidth >= 768) { - return tablet ?? mobile; - } else { - return mobile; - } - }, - ); - } -} - -// Usage -ResponsiveLayout( - mobile: MobileLayout(), - tablet: TabletLayout(), - desktop: DesktopLayout(), -) -``` - -#### Icons: - -```dart -// Use Material Icons (built-in) -Icon(Icons.home) -Icon(Icons.settings) - -// Or use Cupertino Icons -Icon(CupertinoIcons.house) -Icon(CupertinoIcons.settings) - -// For custom icons, use flutter_svg -import 'package:flutter_svg/flutter_svg.dart'; -SvgPicture.asset('assets/icons/custom_icon.svg') -``` - -#### Images: - -```dart -// Network images with error handling -Image.network( - 'https://images.unsplash.com/photo-xxx?w=800&h=600', - errorBuilder: (context, error, stackTrace) { - return Icon(Icons.error); - }, - loadingBuilder: (context, child, loadingProgress) { - if (loadingProgress == null) return child; - return CircularProgressIndicator(); - }, -) - -// Asset images -Image.asset('assets/images/placeholder.png') - -// Use cached_network_image for better performance -CachedNetworkImage( - imageUrl: 'https://images.unsplash.com/photo-xxx?w=800&h=600', - placeholder: (context, url) => CircularProgressIndicator(), - errorWidget: (context, url, error) => Icon(Icons.error), -) -``` - -### 6. Accessibility - -```dart -// Semantic labels for screen readers -Semantics( - label: 'Submit button', - button: true, - enabled: true, - child: ElevatedButton(...), -) - -// Minimum touch target (44x44) -MaterialButton( - minWidth: 44, - height: 44, - child: Text('Button'), - onPressed: () {}, -) - -// Sufficient color contrast (4.5:1 minimum) -// Use tools like https://webaim.org/resources/contrastchecker/ -``` - -### 7. Component Design Tips - -#### Cards: - -```dart -Card( - elevation: 2, // Subtle shadow - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(12.0), - ), - child: Padding( - padding: EdgeInsets.all(16.0), // p-4 - child: Column(...), - ), -) - -// Hover effect (web only) -InkWell( - onTap: () {}, - hoverColor: Colors.transparent, - splashColor: Colors.transparent, - child: MouseRegion( - cursor: SystemMouseCursors.click, - child: AnimatedContainer( - duration: Duration(milliseconds: 200), - transform: Matrix4.identity()..translate(0.0, _isHovered ? -2.0 : 0.0), - decoration: BoxDecoration( - boxShadow: [ - BoxShadow( - color: Colors.black.withOpacity(_isHovered ? 0.15 : 0.1), - blurRadius: _isHovered ? 12 : 8, - offset: Offset(0, _isHovered ? 4 : 2), - ), - ], - ), - child: Card(...), - ), - ), -) -``` - -#### Buttons: - -```dart -// Primary button -ElevatedButton( - style: ElevatedButton.styleFrom( - minimumSize: Size(44, 44), // Touch target - padding: EdgeInsets.symmetric(horizontal: 24, vertical: 12), - ), - onPressed: () {}, - child: Text('Primary'), -) - -// Secondary button -OutlinedButton( - style: OutlinedButton.styleFrom( - minimumSize: Size(44, 44), - ), - onPressed: () {}, - child: Text('Secondary'), -) - -// Ghost button -TextButton( - style: TextButton.styleFrom( - minimumSize: Size(44, 44), - ), - onPressed: () {}, - child: Text('Ghost'), -) -``` - -#### Forms: - -```dart -TextFormField( - decoration: InputDecoration( - labelText: 'Email', // Clear label above input - border: OutlineInputBorder(), - focusedBorder: OutlineInputBorder( - borderSide: BorderSide(color: Theme.of(context).colorScheme.primary, width: 2), - ), - errorBorder: OutlineInputBorder( - borderSide: BorderSide(color: Theme.of(context).colorScheme.error), - ), - ), - validator: (value) { - if (value == null || value.isEmpty) { - return 'Please enter email'; - } - return null; - }, -) - -// Spacing between fields -SizedBox(height: 16.0) -``` - -#### Navigation: - -```dart -// Bottom navigation bar -BottomNavigationBar( - currentIndex: _currentIndex, - onTap: (index) => setState(() => _currentIndex = index), - items: [ - BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Home'), - BottomNavigationBarItem(icon: Icon(Icons.settings), label: 'Settings'), - ], -) - -// Navigation Rail (for tablets) -NavigationRail( - selectedIndex: _selectedIndex, - onDestinationSelected: (index) => setState(() => _selectedIndex = index), - destinations: [ - NavigationRailDestination(icon: Icon(Icons.home), label: Text('Home')), - NavigationRailDestination(icon: Icon(Icons.settings), label: Text('Settings')), - ], -) -``` - -### 8. Flutter-Specific Best Practices - -#### Performance: - -```dart -// Use const constructors when possible -const Text('Static text') -const SizedBox(height: 16) - -// Use ListView.builder for long lists -ListView.builder( - itemCount: items.length, - itemBuilder: (context, index) { - return ListTile(title: Text(items[index])); - }, -) - -// Avoid rebuilding widgets with const -const MyStaticWidget() -``` - -#### State Management: - -```dart -// Simple state with StatefulWidget -setState(() { - _counter++; -}); - -// For complex state, use provider, riverpod, or bloc -// Example with provider: -Consumer( - builder: (context, model, child) { - return Text('${model.value}'); - }, -) -``` - -## Quick Reference - -| Element | Flutter Recommendation | -|---------|------------------------| -| Primary font | Inter, Outfit, DM Sans (google_fonts) | -| Code font | JetBrains Mono, Fira Code (google_fonts) | -| Border radius | 8.0 - 16.0 (modern), 0 (brutalist) | -| Shadow | BoxShadow with elevation 2-4 | -| Spacing | 4.0 base unit (Spacing class) | -| Animation | 150-400ms, Curves.easeOut | -| Colors | ColorScheme.fromSeed (Material 3) | -| Touch targets | Minimum 44x44 | - ---- - -Based on SuperDesign patterns — https://superdesign.dev -Adapted for Flutter/Dart — Material Design 3