skills/style-guardian/SKILL.md
Style Guardian - Unified Design System Enforcement Tool. Use for: (1) Preventing hardcoded styles (colors, spacing, typography), (2) Preventing hardcoded text (i18n violations), (3) Guiding unified configuration usage, (4) Detecting and fixing style violations
npx skillsauth add tarrragon/claude style-guardianInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
| Principle | Description | Source | |-----------|-------------|--------| | Minimalism | Clean, uncluttered layouts | Flat Design | | 2D Styling | Simple, flat shapes without 3D effects | Flat Design | | Subtle Shadows | Shadows hint at interactivity (Flat 2.0) | Material Design | | Monochrome | Primarily use different saturations of blue | Project Design Spec | | Three-Color System | Blue (primary) + Green (positive) + Orange (negative) | Project Design Spec |
| File | Purpose |
|------|---------|
| lib/core/ui/ui_config.dart | Core style configuration system |
| lib/core/ui/flat_design_config.dart | Flat design component configuration |
| lib/core/ui/responsive_config.dart | Responsive layout configuration |
| lib/app/theme.dart | Application theme (uses UIColors) |
| docs/ui_design_specification.md | UI design specification document |
| Hardcoded | UIColors | Purpose | Hex |
|-----------|----------|---------|-----|
| Colors.blue | UIColors.primary | Primary buttons | #2196F3 |
| Color(0xFF2196F3) | UIColors.primary | Primary buttons | #2196F3 |
| Colors.blue[50] | UIColors.primaryLightest | Background blocks | #E3F2FD |
| Colors.blue[100] | UIColors.primaryLight | Secondary blocks | #BBDEFB |
| Colors.blue[300] | UIColors.primaryMedium | Interactive elements | #64B5F6 |
| Colors.blue[700] | UIColors.primaryDark | Selected states | #1976D2 |
| Colors.blue[900] | UIColors.primaryDarkest | Emphasis text | #0D47A1 |
| Hardcoded | UIColors | Purpose |
|-----------|----------|---------|
| Colors.green | UIColors.positive | Success, confirmation |
| Colors.green[100] | UIColors.positiveLight | Success backgrounds |
| Colors.green[700] | UIColors.positiveDark | Success emphasis |
| Hardcoded | UIColors | Purpose |
|-----------|----------|---------|
| Colors.orange | UIColors.negative | Warning, error |
| Colors.amber | UIColors.negative | Warning, caution |
| Colors.red | UIColors.negative | Project does NOT use red |
| Hardcoded | UIColors | Purpose |
|-----------|----------|---------|
| Colors.white | UIColors.surfaceLight | Card backgrounds |
| Colors.grey[50] | UIColors.backgroundLight | Page backgrounds |
| Colors.grey[600] | UIColors.onSurfaceMuted | Muted text |
| Hardcoded | UISpacing | Responsive |
|-----------|-----------|------------|
| SizedBox(height: 4) | SizedBox(height: UISpacing.xxs) | .h suffix |
| SizedBox(height: 8) | SizedBox(height: UISpacing.xs) | .h suffix |
| SizedBox(height: 12) | SizedBox(height: UISpacing.sm) | .h suffix |
| SizedBox(height: 16) | SizedBox(height: UISpacing.md) | .h suffix |
| SizedBox(height: 24) | SizedBox(height: UISpacing.lg) | .h suffix |
| SizedBox(height: 32) | SizedBox(height: UISpacing.xl) | .h suffix |
| SizedBox(width: 8) | SizedBox(width: UISpacing.xs) | .w suffix |
| Hardcoded | UISpacing |
|-----------|-----------|
| EdgeInsets.all(4) | EdgeInsets.all(UISpacing.xxs) |
| EdgeInsets.all(8) | EdgeInsets.all(UISpacing.xs) |
| EdgeInsets.all(16) | EdgeInsets.all(UISpacing.md) |
| EdgeInsets.symmetric(horizontal: 16) | EdgeInsets.symmetric(horizontal: UISpacing.md) |
| EdgeInsets.symmetric(vertical: 8) | EdgeInsets.symmetric(vertical: UISpacing.xs) |
| Hardcoded | UIFontSizes | Purpose |
|-----------|-------------|---------|
| fontSize: 10 | UIFontSizes.overline | Overline text |
| fontSize: 12 | UIFontSizes.bodySmall | Small body text |
| fontSize: 14 | UIFontSizes.bodyMedium | Standard body text |
| fontSize: 16 | UIFontSizes.bodyLarge | Large body text |
| fontSize: 18 | UIFontSizes.titleMedium | Medium titles |
| fontSize: 20 | UIFontSizes.titleLarge | Large titles |
| fontSize: 24 | UIFontSizes.headline3 | Headlines |
Use .rsp suffix for responsive scaling:
// Correct
TextStyle(fontSize: UIFontSizes.bodyMedium) // Already includes .rsp
// Incorrect
TextStyle(fontSize: 14)
TextStyle(fontSize: 14.sp) // Manual scaling
| Hardcoded | UIBorderRadius |
|-----------|----------------|
| BorderRadius.circular(4) | BorderRadius.circular(UIBorderRadius.xs) |
| BorderRadius.circular(8) | BorderRadius.circular(UIBorderRadius.sm) |
| BorderRadius.circular(12) | BorderRadius.circular(UIBorderRadius.md) |
| BorderRadius.circular(16) | BorderRadius.circular(UIBorderRadius.lg) |
| BorderRadius.circular(20) | BorderRadius.circular(UIBorderRadius.xl) |
| BorderRadius.circular(999) | BorderRadius.circular(UIBorderRadius.circular) |
i18n 硬編碼檢測、ARB 工作流程、支援語言清單詳見 /i18n-checker。
快速參考:所有使用者可見文字必須使用 context.l10n!.keyName,禁止硬編碼字串。
// Violation
Container(color: Colors.blue)
Container(color: Color(0xFF2196F3))
// Fix
Container(color: UIColors.primary)
// Violation
SizedBox(height: 16)
Padding(padding: EdgeInsets.all(8))
// Fix
SizedBox(height: UISpacing.md)
Padding(padding: EdgeInsets.all(UISpacing.xs))
// Violation
TextStyle(fontSize: 14)
// Fix
TextStyle(fontSize: UIFontSizes.bodyMedium)
// Violation
BorderRadius.circular(8)
// Fix
BorderRadius.circular(UIBorderRadius.sm)
硬編碼文字檢測和修正詳見 /i18n-checker。
Scope: lib/presentation/**/viewmodel.dart, lib/presentation/**_viewmodel.dart
Detection Pattern: String literals assigned to error/message state properties
// Violation - Hardcoded user messages in ViewModel
state = state.copyWith(errorMessage: 'Invalid file format');
state = state.copyWith(errorMessage: '網路連線失敗');
_errorMessage = 'Something went wrong';
// Fix - Use i18n or ErrorHandler
state = state.copyWith(errorMessage: context.l10n!.invalidFileFormat);
state = state.copyWith(errorMessage: ErrorHandler.getUserMessage(exception));
Allowed Exceptions:
e.toString() for unknown system exceptionscontext.l10n!.errorWithCode(code)Related: FLUTTER.md - ViewModel 層使用者訊息規範
# Scan entire project
uv run .claude/skills/style-guardian/scripts/style_checker.py scan lib/
# Scan specific directory
uv run .claude/skills/style-guardian/scripts/style_checker.py scan lib/presentation/
# Generate report
uv run .claude/skills/style-guardian/scripts/style_checker.py report
The style checker is integrated into PostEdit Hook:
lib/presentation//i18n-checker - i18n 硬編碼全量掃描和修正工作流程import 'package:book_overview_app/core/ui/ui_config.dart';
| Type | Hardcoded | Configuration |
|------|-----------|---------------|
| Color | Colors.blue | UIColors.primary |
| Success | Colors.green | UIColors.positive |
| Warning | Colors.orange | UIColors.negative |
| Spacing | 16 | UISpacing.md |
| Font | 14 | UIFontSizes.bodyMedium |
| Radius | 8 | UIBorderRadius.sm |
| Text | 'My Library' | context.l10n!.libraryTitle |
| Suffix | Purpose | Example |
|--------|---------|---------|
| .w | Width scaling | 16.w |
| .h | Height scaling | 16.h |
| .rsp | Font scaling | 14.rsp |
| .r | Radius scaling | 8.r |
Last Updated: 2026-03-02 Version: 1.0.0
development
Use when the user wants to design, redesign, shape, critique, audit, polish, clarify, distill, harden, optimize, adapt, animate, colorize, extract, or otherwise improve a frontend interface. Covers websites, landing pages, dashboards, product UI, app shells, components, forms, settings, onboarding, and empty states. Handles UX review, visual hierarchy, information architecture, cognitive load, accessibility, performance, responsive behavior, theming, anti-patterns, typography, fonts, spacing, layout, alignment, color, motion, micro-interactions, UX copy, error states, edge cases, i18n, and reusable design systems or tokens. Also use for bland designs that need to become bolder or more delightful, loud designs that should become quieter, live browser iteration on UI elements, or ambitious visual effects that should feel technically extraordinary. Not for backend-only or non-UI tasks.
development
Claude Code release notes 框架影響評估工具。比對 last-reviewed 版本篩出新版本,逐項分類(對框架有幫助 / 需評估 / 無影響 / 不適用),對採用項引導建 ANA + WRAP + spawn 落地。Use when: 執行 /release-notes 看到新版本、定期檢查 CC 更新、評估新功能對專案框架的影響時。Triggers: release notes, release-notes, CC 更新, claude code 更新, 版本更新評估, 新功能評估, 框架影響評估。
development
Assertion design judgment framework for flaky and design-quality issues. Use when writing tests, reviewing assertions, diagnosing flaky tests, or deciding if a timing/float/cache assertion is appropriate. Do NOT use for API syntax or refactoring.
tools
Chrome Extension 實機測試與 debug 工作流,以 chrome-devtools-mcp 為核心工具。Use when: (1) 完成功能後實機驗證 / manual test / 試看看 / 跑看看 / verify feature, (2) extension debug / popup 不作動 / content script 不注入 / service worker 報錯 / background 出問題, (3) 安裝 unpacked extension / load unpacked / 載入未封裝, (4) 看 console / 看 network / 看 log / view console / inspect requests, (5) 功能更新後重新載入 extension / rebuild reload / reload extension。涵蓋 Manifest V3 service worker / content script / popup / options page 的 chrome-devtools-mcp 工具呼叫流程。不取代 Puppeteer / Playwright 自動化 E2E(CI 用),定位為開發期手動驗證與 LLM-assisted debug。