# Flutter Monisuo 现代化改造规范 v2.0

## 目标
将 Flutter Monisuo 应用打造为现代化、简约、专业的虚拟货币交易平台，参考 SuperDesign 设计原则。

## 设计原则

### 1. 现代化简约风格
- **Vercel/Linear 风格**：干净的深色主题，微妙的阴影，大量留白
- **避免过时设计**：不使用 Bootstrap 蓝、沉重的阴影、复杂的渐变
- **微交互**：细腻的动画反馈（150-400ms）

### 2. 明暗主题支持
- 完整的 Light/Dark 主题切换
- 使用 ColorScheme 管理主题
- 主题切换时平滑过渡

### 3. 颜色系统（基于 OKLCH 转换）

#### 现代深色主题
```dart
// Vercel/Linear 风格
background:       Color(0xFF0A0A0B)  // oklch(0.098 0.005 270)
cardBackground:   Color(0xFF111113)  // oklch(0.148 0.004 270)
primary:          Color(0xFF00D4AA)  // 品牌青绿色
primaryForeground: Color(0xFFFFFFFF)
secondary:        Color(0xFF1C1C1F)
muted:            Color(0xFF27272A)
border:           Color(0xFF27272A)
```

#### 现代浅色主题
```dart
background:       Color(0xFFFFFFFF)  // oklch(1 0 0)
cardBackground:   Color(0xFFFAFAFA)  // oklch(0.98 0 0)
primary:          Color(0xFF00B894)  // 品牌青绿色（深色版）
primaryForeground: Color(0xFFFFFFFF)
secondary:        Color(0xFFF4F4F5)
muted:            Color(0xFFE4E4E7)
border:           Color(0xFFE4E4E7)
```

#### 涨跌色（明暗通用）
```dart
up:    Color(0xFF00C853)  // 涨/买入（绿色）
down:  Color(0xFFFF5252)  // 跌/卖出（红色）
```

### 4. 字体系统

#### 使用 Google Fonts
```yaml
dependencies:
  google_fonts: ^6.1.0
```

#### 字体选择
- **主字体**：Inter（现代、清晰）
- **数字字体**：JetBrains Mono（等宽，用于价格/数量）
- **回退字体**：system-ui

#### 字号系统
```dart
// 标题
displayLarge:   32sp, weight: 700
displayMedium:  24sp, weight: 600
displaySmall:   20sp, weight: 600

// 正文
bodyLarge:      16sp, weight: 400
bodyMedium:     14sp, weight: 400
bodySmall:      12sp, weight: 400

// 数字（等宽）
numberLarge:    20sp, JetBrains Mono
numberMedium:   16sp, JetBrains Mono
numberSmall:    14sp, JetBrains Mono
```

### 5. 间距系统

```dart
class Spacing {
  static const double xs   = 4.0;   // 0.25rem
  static const double sm   = 8.0;   // 0.5rem
  static const double md   = 16.0;  // 1rem
  static const double lg   = 24.0;  // 1.5rem
  static const double xl   = 32.0;  // 2rem
  static const double xxl  = 48.0;  // 3rem
}
```

### 6. 圆角系统

```dart
class BorderRadius {
  static const double sm   = 4.0;
  static const double md   = 8.0;
  static const double lg   = 12.0;
  static const double xl   = 16.0;
  static const double xxl  = 24.0;
  static const double full = 9999.0;
}
```

### 7. 阴影系统

```dart
// 微妙的阴影（Vercel 风格）
BoxShadow(
  color: Colors.black.withOpacity(0.05),
  blurRadius: 4,
  offset: Offset(0, 2),
)

// 悬停阴影
BoxShadow(
  color: Colors.black.withOpacity(0.1),
  blurRadius: 8,
  offset: Offset(0, 4),
)
```

### 8. 动画系统

```dart
class AnimationDurations {
  static const Duration fast      = Duration(milliseconds: 150);
  static const Duration normal    = Duration(milliseconds: 250);
  static const Duration slow      = Duration(milliseconds: 400);
  static const Duration verySlow  = Duration(milliseconds: 600);
}

// Curves
Curves.easeOutCubic      // 入场动画
Curves.easeInOutCubic    // 过渡动画
Curves.elasticOut        // 弹性反馈
```

## 组件设计规范

### 1. 按钮

#### 主要按钮（Primary）
```dart
ElevatedButton(
  style: ElevatedButton.styleFrom(
    backgroundColor: Theme.of(context).colorScheme.primary,
    foregroundColor: Theme.of(context).colorScheme.onPrimary,
    minimumSize: Size(44, 44),  // 触摸目标
    padding: EdgeInsets.symmetric(horizontal: Spacing.lg, vertical: Spacing.md),
    shape: RoundedRectangleBorder(
      borderRadius: BorderRadius.circular(BorderRadius.md),
    ),
    elevation: 0,  // 现代风格：无阴影或微阴影
  ),
)
```

#### 次要按钮（Secondary）
```dart
OutlinedButton(
  style: OutlinedButton.styleFrom(
    minimumSize: Size(44, 44),
    shape: RoundedRectangleBorder(
      borderRadius: BorderRadius.circular(BorderRadius.md),
    ),
    side: BorderSide(color: Theme.of(context).colorScheme.border),
  ),
)
```

#### 幽灵按钮（Ghost）
```dart
TextButton(
  style: TextButton.styleFrom(
    minimumSize: Size(44, 44),
  ),
)
```

### 2. 卡片

```dart
Card(
  elevation: 0,  // 使用边框代替阴影
  shape: RoundedRectangleBorder(
    borderRadius: BorderRadius.circular(BorderRadius.lg),
    side: BorderSide(
      color: Theme.of(context).colorScheme.border,
      width: 1,
    ),
  ),
  color: Theme.of(context).colorScheme.cardBackground,
  child: Padding(
    padding: EdgeInsets.all(Spacing.md),
    child: Column(...),
  ),
)
```

### 3. 输入框

```dart
TextFormField(
  decoration: InputDecoration(
    filled: true,
    fillColor: Theme.of(context).colorScheme.cardBackground,
    border: OutlineInputBorder(
      borderRadius: BorderRadius.circular(BorderRadius.md),
      borderSide: BorderSide(color: Theme.of(context).colorScheme.border),
    ),
    enabledBorder: OutlineInputBorder(
      borderRadius: BorderRadius.circular(BorderRadius.md),
      borderSide: BorderSide(color: Theme.of(context).colorScheme.border),
    ),
    focusedBorder: OutlineInputBorder(
      borderRadius: BorderRadius.circular(BorderRadius.md),
      borderSide: BorderSide(
        color: Theme.of(context).colorScheme.primary,
        width: 2,
      ),
    ),
    contentPadding: EdgeInsets.symmetric(
      horizontal: Spacing.md,
      vertical: Spacing.sm,
    ),
  ),
)
```

### 4. 现代弹窗

#### 标准弹窗
```dart
showDialog(
  context: context,
  builder: (context) => Dialog(
    shape: RoundedRectangleBorder(
      borderRadius: BorderRadius.circular(BorderRadius.xl),
    ),
    backgroundColor: Theme.of(context).colorScheme.cardBackground,
    child: Container(
      padding: EdgeInsets.all(Spacing.lg),
      child: Column(
        mainAxisSize: MainAxisSize.min,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          // 标题
          Text(
            'Dialog Title',
            style: Theme.of(context).textTheme.displaySmall,
          ),
          SizedBox(height: Spacing.md),
          // 内容
          Text('Dialog content here...'),
          SizedBox(height: Spacing.lg),
          // 按钮
          Row(
            mainAxisAlignment: MainAxisAlignment.end,
            children: [
              TextButton(child: Text('Cancel')),
              SizedBox(width: Spacing.sm),
              ElevatedButton(child: Text('Confirm')),
            ],
          ),
        ],
      ),
    ),
  ),
);
```

#### 底部抽屉（Bottom Sheet）
```dart
showModalBottomSheet(
  context: context,
  isScrollControlled: true,
  backgroundColor: Colors.transparent,
  builder: (context) => Container(
    decoration: BoxDecoration(
      color: Theme.of(context).colorScheme.cardBackground,
      borderRadius: BorderRadius.vertical(
        top: Radius.circular(BorderRadius.xl),
      ),
    ),
    padding: EdgeInsets.all(Spacing.lg),
    child: Column(
      mainAxisSize: MainAxisSize.min,
      children: [
        // 拖动指示器
        Container(
          width: 40,
          height: 4,
          decoration: BoxDecoration(
            color: Theme.of(context).colorScheme.muted,
            borderRadius: BorderRadius.circular(2),
          ),
        ),
        SizedBox(height: Spacing.md),
        // 内容
        ...
      ],
    ),
  ),
);
```

### 5. 列表项

```dart
ListTile(
  contentPadding: EdgeInsets.symmetric(
    horizontal: Spacing.md,
    vertical: Spacing.sm,
  ),
  leading: Container(
    width: 40,
    height: 40,
    decoration: BoxDecoration(
      color: Theme.of(context).colorScheme.secondary,
      borderRadius: BorderRadius.circular(BorderRadius.md),
    ),
    child: Icon(icon, size: 20),
  ),
  title: Text(
    title,
    style: Theme.of(context).textTheme.bodyLarge,
  ),
  subtitle: Text(
    subtitle,
    style: Theme.of(context).textTheme.bodySmall,
  ),
  trailing: Icon(Icons.chevron_right, size: 20),
)
```

## 页面布局规范

### 1. 通用布局

```dart
Scaffold(
  backgroundColor: Theme.of(context).colorScheme.background,
  appBar: AppBar(
    backgroundColor: Theme.of(context).colorScheme.background,
    elevation: 0,
    title: Text('Page Title'),
  ),
  body: SafeArea(
    child: SingleChildScrollView(
      padding: EdgeInsets.all(Spacing.md),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          // 内容
        ],
      ),
    ),
  ),
)
```

### 2. 响应式布局

```dart
LayoutBuilder(
  builder: (context, constraints) {
    if (constraints.maxWidth >= 1024) {
      // 桌面布局
      return _DesktopLayout();
    } else if (constraints.maxWidth >= 768) {
      // 平板布局
      return _TabletLayout();
    } else {
      // 移动布局
      return _MobileLayout();
    }
  },
)
```

## 主题切换实现

### 1. 主题 Provider

```dart
class ThemeProvider extends ChangeNotifier {
  ThemeMode _themeMode = ThemeMode.system;
  
  ThemeMode get themeMode => _themeMode;
  
  void toggleTheme() {
    _themeMode = _themeMode == ThemeMode.light 
        ? ThemeMode.dark 
        : ThemeMode.light;
    notifyListeners();
  }
  
  void setTheme(ThemeMode mode) {
    _themeMode = mode;
    notifyListeners();
  }
}
```

### 2. 主题切换按钮

```dart
IconButton(
  icon: Icon(
    Provider.of<ThemeProvider>(context).themeMode == ThemeMode.light
        ? Icons.dark_mode
        : Icons.light_mode,
  ),
  onPressed: () {
    Provider.of<ThemeProvider>(context, listen: false).toggleTheme();
  },
)
```

## 无障碍设计

### 1. 对比度
- 所有文字/背景组合 >= 4.5:1（WCAG AA）
- 大文字（18sp+）>= 3:1

### 2. 触摸目标
- 最小触摸目标 44x44

### 3. 语义化
```dart
Semantics(
  label: 'Submit button',
  button: true,
  child: ElevatedButton(...),
)
```

## 禁止事项

- ❌ 使用过时的 Bootstrap 蓝 (#007bff)
- ❌ 沉重的阴影
- ❌ 复杂的渐变
- ❌ 文字与背景颜色相同
- ❌ 对比度 < 4.5:1
- ❌ 触摸目标 < 44x44
- ❌ 硬编码颜色值
- ❌ 不一致的间距/圆角

## 验证清单

- [ ] 明暗主题切换正常
- [ ] 所有页面风格一致
- [ ] 对比度 >= 4.5:1
- [ ] 触摸目标 >= 44x44
- [ ] flutter analyze 无错误
- [ ] 响应式布局正常
- [ ] 动画流畅（60fps）
- [ ] 无硬编码颜色
- [ ] 间距/圆角一致
