| name | theme-consistency |
| description | Enforce consistent theming across all prototype mockup screens. Auto-loads theme.yaml, validates CSS variable usage, prevents hardcoded values, and maintains visual consistency session-to-session. Use during /prototype create when generating new screens. |
- Loading and enforcing theme.yaml values during mockup generation
- Preventing hardcoded colors, spacing, and typography values
- Validating new screens match established patterns
- Locking theme after first screen approval to ensure session-to-session consistency
This prevents the common problem where screens created in different sessions drift in style, creating an inconsistent prototype that undermines the design intent.
Do NOT invoke when:
- Creating the very first screen (theme not yet established)
- User explicitly requests to reset/modify theme
ALWAYS use:
- Theme CSS variables:
var(--color-primary),var(--space-4) - Shared component classes:
.btn--primary,.card,.form-input - Density classes:
.density-compact,.density-spacious
When generating any prototype screen, FIRST load the theme:
# Read design/prototype/theme.yaml
theme:
locked: true|false
palette:
primary: "oklch(55% 0.2 250)"
# ... all colors
typography:
heading_font: "Inter, system-ui, sans-serif"
# ... font settings
spacing:
unit: "8px"
# ... spacing scale
tone:
style: "professional" # affects content voice
density: "comfortable" # affects spacing multipliers
Lock Status Behavior
If locked: true:
- Theme is immutable
- All new screens MUST use existing theme values
- Warn if user requests theme changes
- Suggest creating new prototype instead
If locked: false:
- First screen is being created
- Theme values may be refined based on user feedback
- After user approves first mockup, set
locked: true
HTML Structure
Every screen MUST follow base.html structure:
<!DOCTYPE html>
<html lang="en">
<head>
<title>{{SCREEN_TITLE}} - {{APP_NAME}}</title>
<link rel="stylesheet" href="../../theme.css">
<link rel="stylesheet" href="../../shared.css">
<style>/* Screen-specific overrides only */</style>
</head>
<body class="theme-{{TONE_STYLE}} density-{{DENSITY}}">
<a href="#main-content" class="skip-link">Skip to main content</a>
<!-- Navigation (if applicable) -->
<nav class="nav nav--{{LAYOUT}}">...</nav>
<!-- Main Content -->
<main id="main-content" class="main main--{{LAYOUT}}">
{{SCREEN_CONTENT}}
</main>
</body>
</html>
CSS Variable Usage
| Element | Correct | Incorrect |
|---|---|---|
| Button background | var(--color-primary) |
#3b82f6 |
| Card padding | var(--space-4) |
32px |
| Heading size | var(--text-2xl) |
1.953rem |
| Border radius | var(--radius-md) |
8px |
| Box shadow | var(--shadow-md) |
0 4px 6px rgba(...) |
| Transition | var(--transition-base) |
150ms ease |
Component Reuse
Use shared.css classes instead of inline styles:
<!-- CORRECT -->
<button class="btn btn--primary">Submit</button>
<div class="card card--elevated">...</div>
<input class="form-input" type="text">
<!-- INCORRECT -->
<button style="background: #3b82f6; padding: 8px 16px;">Submit</button>
<div style="background: white; box-shadow: 0 4px 6px rgba(0,0,0,0.1);">...</div>
After generating screen HTML, validate:
1. No Hardcoded Colors
# Check for hex colors
grep -E "#[0-9a-fA-F]{3,6}" screen.html
# Check for rgb/rgba
grep -E "rgb\(|rgba\(" screen.html
# Check for hsl/hsla
grep -E "hsl\(|hsla\(" screen.html
2. No Hardcoded Spacing
# Check for pixel values not in variables
grep -E "padding:\s*\d+px" screen.html
grep -E "margin:\s*\d+px" screen.html
grep -E "gap:\s*\d+px" screen.html
3. Font Usage
# Check for hardcoded font-family
grep -E "font-family:\s*[^v]" screen.html # Should use var()
4. Theme Variable Coverage
Ensure all visual properties use theme variables:
- Colors:
var(--color-*) - Spacing:
var(--space-*) - Typography:
var(--text-*),var(--font-*) - Effects:
var(--shadow-*),var(--radius-*)
Use context from theme.yaml to guide content structure:
Entry/Auth Screens
- Single focus, minimal distraction
- Centered card layout
- Clear primary CTA
- Minimal navigation
Dashboard/Overview Screens
- Scannable grid layout
- Summary cards with key metrics
- Quick action shortcuts
- Navigation hub role
Create/Edit Screens
- Form-focused layout
- Progressive disclosure if complex
- Clear validation feedback
- Save/Cancel actions visible
Browse/List Screens
- Table or card grid
- Search/filter bar at top
- Pagination or infinite scroll
- Quick actions per item
Detail/View Screens
- Hero section with primary info
- Tabbed or sectioned content
- Action buttons in header
- Related items/navigation
After screen generation, output validation status:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
THEME CONSISTENCY CHECK
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Screen: dashboard-overview.html
Theme: [APP_NAME] Theme (locked)
CHECKLIST:
✅ Uses theme.css variables
✅ Imports shared.css
✅ No hardcoded colors
✅ No hardcoded spacing
✅ Uses shared component classes
✅ Follows base.html structure
✅ Includes skip link
✅ Matches layout pattern (sidebar)
✅ Applies density setting (comfortable)
STATUS: PASS
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
If violations found:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
THEME CONSISTENCY CHECK
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Screen: settings-form.html
Theme: [APP_NAME] Theme (locked)
VIOLATIONS FOUND:
Line 45: Hardcoded color
Before: background: #f3f4f6;
After: background: var(--color-neutral-100);
Line 67: Hardcoded spacing
Before: padding: 24px;
After: padding: var(--space-3);
Line 89: Missing shared class
Before: <button style="...">
After: <button class="btn btn--primary">
STATUS: FAIL (3 violations)
Auto-fixing violations...
STATUS: PASS (after fixes)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
- Theme Template:
.spec-flow/templates/prototype/theme.yaml - CSS Variables:
.spec-flow/templates/prototype/theme.css - Base HTML:
.spec-flow/templates/prototype/base.html - Shared Styles:
.spec-flow/templates/prototype/shared.css - Design Tokens:
docs/project/style-guide.md