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.
This prevents the common problem where screens created in different sessions drift in style, creating an inconsistent prototype that undermines the design intent. </objective>
<quick_start> <when_to_invoke> Automatically invoke this skill when:
/prototype create [screen] is called and theme.yaml existsDo NOT invoke when:
<basic_workflow>
design/prototype/theme.yamllocked: true, enforce; if false, may update<key_rules> NEVER use:
#3b82f6, #ffffffrgb(59, 130, 246)padding: 17px, margin: 32pxtext-[15px], p-[23px]ALWAYS use:
var(--color-primary), var(--space-4).btn--primary, .card, .form-input.density-compact, .density-spacious
</key_rules>
</quick_start><detailed_procedures> <theme_loading>
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
If locked: true:
If locked: false:
locked: true
</theme_loading><screen_generation>
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>
| 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 |
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>
</screen_generation>
<validation> ## Validation ChecksAfter generating screen HTML, validate:
# 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
# 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
# Check for hardcoded font-family
grep -E "font-family:\s*[^v]" screen.html # Should use var()
Ensure all visual properties use theme variables:
var(--color-*)var(--space-*)var(--text-*), var(--font-*)var(--shadow-*), var(--radius-*)
</validation>
<content_presentation>
Use context from theme.yaml to guide content structure:
<validation_output>
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)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
</validation_output>
<references> ## Related Resources.spec-flow/templates/prototype/theme.yaml.spec-flow/templates/prototype/theme.css.spec-flow/templates/prototype/base.html.spec-flow/templates/prototype/shared.cssdocs/project/style-guide.md
</references>
Search for places (restaurants, cafes, etc.) via Google Places API proxy on localhost.
Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries.
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Start voice calls via the OpenClaw voice-call plugin.
Notion API for creating and managing pages, databases, and blocks.
Gemini CLI for one-shot Q&A, summaries, and generation.
Category:developer