# ダークモード視認性ガイドライン ## 目的 ダークモード実装時に「背景と同化して見えない」問題を防ぐための開発ガイドラインです。 ## 基本原則 ### 1. **色の明示的指定** ❌ **NG**: `Theme.of(context).primaryColor` をダークモードで直接使用 ```dart // NG例: ダークモードでは #8AB4F6 になり、暗い背景で見えにくい color: Theme.of(context).primaryColor ``` ✅ **OK**: brightness チェックで明示的に明るい色を指定 ```dart // OK例: ダークモードでは明るい青 (#64B5F6) を使用 color: Theme.of(context).brightness == Brightness.dark ? const Color(0xFF64B5F6) // より明るい青 : Theme.of(context).primaryColor // #376495 ``` ### 2. **推奨カラーパレット** #### アクセント色(選択状態、重要なUI要素) | 用途 | ライトモード | ダークモード | |------|------------|------------| | プライマリ(通常) | `#376495` (AppTheme.posimaiBlue) | `#64B5F6` (明るい青) | | プライマリ(強調) | `AppTheme.posimaiBlue` | `#8AB4F6` (Theme.primaryColor) | | チェックマーク | `Theme.primaryColor` | `#64B5F6` | | 選択中チップ | `AppTheme.posimaiBlue` | `colorScheme.primary` (#8AB4F6) | #### テキスト色 | 用途 | ライトモード | ダークモード | |------|------------|------------| | 本文 | `Colors.black87` | `Colors.white` | | 副見出し | `Colors.grey[600]` | `Colors.grey[300]` | | 薄い表示 | `Colors.grey[400]` | `Colors.grey[500]` | #### 背景・ボーダー | 用途 | ライトモード | ダークモード | |------|------------|------------| | カード背景 | `Colors.white` | `#1E1E1E` | | ダイアログ背景 | `Colors.white` | `#2C2C2C` | | ボーダー(通常) | `Colors.grey[300]` | `Colors.grey[700]` | | ボーダー(強調) | `Colors.grey[400]` | `Colors.grey[600]` | ### 3. **コンポーネント別パターン** #### ダイアログ選択肢(SimpleDialogOption) ```dart Icon( isSelected ? Icons.check : Icons.circle_outlined, color: isSelected ? (Theme.of(context).brightness == Brightness.dark ? const Color(0xFF64B5F6) // ダークモード用の明るい青 : Theme.of(context).primaryColor) : Colors.grey[400], ) ``` #### FilterChip(フィルタチップ) ```dart FilterChip( selected: isSelected, selectedColor: Theme.of(context).brightness == Brightness.dark ? colorScheme.primary // #8AB4F6 : AppTheme.posimaiBlue, side: isSelected ? BorderSide( color: Theme.of(context).brightness == Brightness.dark ? colorScheme.primary : AppTheme.posimaiBlue, width: 1.5, ) : null, // 非選択時の明示的なスタイル指定 backgroundColor: isDark ? Colors.grey[800]?.withValues(alpha: 0.5) : null, side: BorderSide( color: isDark ? Colors.grey[700]! : colorScheme.outline.withValues(alpha: 0.5), ), ) ``` #### ボタン(AlertDialog内のElevatedButton) ```dart ElevatedButton( style: ElevatedButton.styleFrom( // ダークモードでも見えるよう固定色を使用 backgroundColor: AppTheme.posimaiBlue, // #376495 foregroundColor: Colors.white, ), child: const Text('確認'), ) ``` #### SnackBar ```dart SnackBar( content: Text( 'メッセージ', style: TextStyle( color: isDark ? Colors.white : Colors.white, // 明示的に白を指定 ), ), backgroundColor: isDark ? const Color(0xFF2C2C2C) // ダーク背景 : Colors.grey[850], behavior: SnackBarBehavior.floating, ) ``` #### バッジカウンター ```dart Container( decoration: BoxDecoration( color: Theme.of(context).brightness == Brightness.dark ? const Color(0xFF64B5F6).withValues(alpha: 0.15) : Theme.of(context).primaryColor.withValues(alpha: 0.1), border: Border.all( color: Theme.of(context).brightness == Brightness.dark ? const Color(0xFF64B5F6).withValues(alpha: 0.4) : Theme.of(context).primaryColor.withValues(alpha: 0.3), ), ), child: Text( '2 / 3', style: TextStyle( color: Theme.of(context).brightness == Brightness.dark ? const Color(0xFF64B5F6) : Theme.of(context).primaryColor, ), ), ) ``` ## 開発時のチェックリスト ### 新機能実装時 - [ ] ライトモードで表示確認 - [ ] **ダークモードで表示確認(必須)** - [ ] 以下の要素が見えるか確認: - [ ] テキスト(タイトル、本文、ラベル) - [ ] アイコン(選択状態、非選択状態) - [ ] ボーダー・区切り線 - [ ] ボタン(通常、選択、無効) - [ ] カウンター・バッジ表示 ### コードレビュー時 - [ ] `Theme.of(context).primaryColor` の使用箇所でbrightness チェックがあるか - [ ] `const TextStyle()` に明示的な color 指定があるか - [ ] `Colors.grey` のような曖昧な色ではなく、明示的な階調(`Colors.grey[300]`等)を使用しているか ## よくある問題と解決策 ### 問題1: チェックマークが見えない **原因**: `Theme.of(context).primaryColor` がダークモードで薄くなる **解決**: 明示的に `#64B5F6` を指定 ### 問題2: バッジカウンターが見えない **原因**: 背景色とテキスト色のコントラストが不足 **解決**: ダークモード用に明るい色 (`#64B5F6`) とアルファ値を調整した背景を使用 ### 問題3: ボタンが見えない **原因**: `Theme.of(context).primaryColor` が背景と同化 **解決**: 固定色 `AppTheme.posimaiBlue` (#376495) を使用 ### 問題4: SnackBarメッセージが読めない **原因**: テキスト色が明示されておらず、デフォルトが暗い色になる **解決**: `color: Colors.white` を明示的に指定 ## 色のコントラスト比基準 WCAG 2.1 AA基準(最低限): - 通常テキスト: **4.5:1** 以上 - 大きいテキスト(18pt以上、14pt太字以上): **3:1** 以上 推奨ツール: - [WebAIM Contrast Checker](https://webaim.org/resources/contrastchecker/) - [Coolors Contrast Checker](https://coolors.co/contrast-checker) ## 実装例リファレンス 実装済みファイル: - `lib/screens/soul_screen.dart`: ダイアログチェックマーク - `lib/widgets/gamification/badge_case.dart`: バッジカウンター - `lib/widgets/settings/backup_settings_section.dart`: ダイアログボタン - `lib/screens/camera_screen.dart`: SnackBarメッセージ - `lib/widgets/home/sake_filter_chips.dart`: フィルタチップ --- **更新日**: 2026-01-18 **バージョン**: 1.0