fix(ui-design): ensure component templates include CSS placeholders

Fix critical CSS loading issue where component templates were missing
style references due to contradictory instructions.

Changes:
- Require all templates (pages and components) to generate complete HTML5 documents
- Components now use full document structure with isolated body content
- Guarantees <head> tag presence for CSS placeholder injection
- Update validation to enforce <!DOCTYPE html> requirement
- Update documentation to reflect unified template approach

This ensures ui-instantiate-prototypes.sh can reliably inject STRUCTURAL_CSS
and TOKEN_CSS placeholders, fixing component styling issues.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
catlog22
2025-10-10 12:30:17 +08:00
parent 36728b6e59
commit 4e48803424
4 changed files with 66 additions and 25 deletions

View File

@@ -202,7 +202,7 @@ detect_target_type(target_list):
command = "/workflow:ui-design:extract --base-path \"{base_path}\" " +
(--images ? "--images \"{images}\" " : "") +
(--prompt ? "--prompt \"{prompt}\" " : "") +
"--variants {style_variants}"
"--variants {style_variants} --mode explore"
SlashCommand(command) # → Phase 2
```
@@ -222,7 +222,7 @@ command = "/workflow:ui-design:generate --base-path \"{base_path}\" " +
"--style-variants {style_variants} --layout-variants {layout_variants}"
total = style_variants × layout_variants × len(inferred_target_list)
REPORT: "🚀 Phase 3: {type_icon} {targets_string} | Matrix: {s}×{l} | Total: {total} prototypes"
REPORT: "🚀 Phase 3: {type_icon} {targets_string} | Matrix: {s}×{l}×{n} = {total} prototypes"
REPORT: " → Layout planning: {len(inferred_target_list)}×{layout_variants} target-specific layouts"
SlashCommand(command) # → Phase 4
@@ -300,7 +300,7 @@ TodoWrite({todos: [
✅ UI Design Explore-Auto Workflow Complete!
Run ID: {run_id} | Session: {session_id or "standalone"}
Type: {icon} {target_type} | Matrix: {s}×{l} ({total} prototypes)
Type: {icon} {target_type} | Matrix: {s}×{l}×{n} = {total} prototypes
Phase 1: {s} style variants (extract)
Phase 2: {s} design systems (consolidate)

View File

@@ -4,6 +4,11 @@ description: Extract design style from reference images or text prompts using Cl
usage: /workflow:ui-design:extract [--base-path <path>] [--session <id>] [--images "<glob>"] [--prompt "<desc>"] [--variants <count>]
argument-hint: "[--base-path \".workflow/WFS-xxx/design-run-xxx\"] [--session WFS-xxx] [--images \"refs/*.png\"] [--prompt \"Modern minimalist\"] [--variants 3]"
parameters:
- name: --mode
type: string
enum: [imitate, explore, auto]
default: auto
description: "Extraction mode: 'imitate' (high-fidelity single style, skip divergence), 'explore' (multi-variant with contrast analysis), 'auto' (detect from --variants: 1=imitate, 2+=explore)"
- name: --variants
type: number
default: 1
@@ -85,14 +90,29 @@ CREATE: {base_path}/style-extraction/
### Phase 0.5: AI-Driven Design Space Divergence
```bash
# Step 1: Load project context
# Determine extraction mode
extraction_mode = --mode OR "auto"
IF extraction_mode == "auto":
extraction_mode = (variants_count == 1) ? "imitate" : "explore"
REPORT: "🔍 Auto-detected mode: {extraction_mode} (variants_count={variants_count})"
# Skip divergence analysis for imitate mode
IF extraction_mode == "imitate":
REPORT: "🎯 IMITATE MODE: High-fidelity single style extraction"
REPORT: " → Skipping design space divergence analysis"
REPORT: " → Proceeding to Phase 2 for direct style synthesis"
design_space_analysis = null
# Skip to Phase 2
GOTO Phase 2
# Step 1: Load project context (explore mode only)
project_context = ""
IF exists({base_path}/.brainstorming/synthesis-specification.md):
project_context = Read(synthesis-specification.md)
ELSE IF exists({base_path}/.brainstorming/ui-designer/analysis.md):
project_context = Read(ui-designer/analysis.md)
REPORT: "🎨 Analyzing design space to generate maximally contrasting directions..."
REPORT: "🎨 EXPLORE MODE: Analyzing design space to generate maximally contrasting directions..."
# Step 2: AI-driven divergent direction generation
divergence_prompt = """
@@ -154,12 +174,13 @@ REPORT: "💾 Saved design space analysis to design-space-analysis.json"
**Analysis Prompt Template**:
```
Generate {variants_count} design style proposals, each guided by its pre-analyzed design direction.
Generate {variants_count} design style proposals{IF extraction_mode == "explore": , each guided by its pre-analyzed design direction}.
INPUT MODE: {input_mode}
{IF input_mode IN ["image", "hybrid"]: VISUAL REFERENCES: {list of loaded images}}
{IF input_mode IN ["text", "hybrid"]: TEXT GUIDANCE: "{prompt_guidance}"}
{IF extraction_mode == "explore":
DESIGN SPACE ANALYSIS: {design_space_analysis summary}
VARIANT-SPECIFIC DESIGN DIRECTIONS:
@@ -171,20 +192,29 @@ SEARCH KEYWORDS: {direction.search_keywords}
ANTI-PATTERNS (avoid): {direction.anti_keywords}
RATIONALE: {direction.rationale}
---}
}
TASK: Generate {variants_count} design style variants where EACH variant:
TASK: Generate {variants_count} design style variant{IF variants_count > 1: s} where {IF extraction_mode == "explore": EACH variant}:
{IF extraction_mode == "explore":
1. Strictly follows its pre-defined design philosophy and attributes
2. Maintains maximum contrast with other variants' attributes
3. Incorporates its design direction and avoids its anti-patterns
}
{IF extraction_mode == "imitate":
1. Provides high-fidelity replication of reference design
2. Focuses on accurate extraction of visual characteristics
}
4. Uses OKLCH color space for all color values
5. Includes complete, production-ready design token proposals
6. Applies WCAG AA accessibility guidelines (4.5:1 text, 3:1 UI)
{IF extraction_mode == "explore":
CRITICAL RULES FOR CONTRAST:
- Variant-1 should feel completely different from Variant-2/3
- Use each variant's specific attribute scores (e.g., "monochrome" vs "vibrant")
- Each variant should embody its unique design direction
- If Variant-1 is "minimal/geometric", Variant-2 must be "bold/organic" or similar contrast
}
OUTPUT FORMAT: JSON matching this structure:
{"extraction_metadata": {"session_id": "...", "input_mode": "...", "timestamp": "...", "variants_count": N},
@@ -203,7 +233,8 @@ OUTPUT FORMAT: JSON matching this structure:
// Repeat for ALL {variants_count} variants
]}
RULES: Each variant must strictly adhere to pre-defined attributes; maximize visual contrast;
RULES: {IF extraction_mode == "explore": Each variant must strictly adhere to pre-defined attributes; maximize visual contrast;}
{IF extraction_mode == "imitate": Focus on high-fidelity replication;}
all colors in OKLCH format; complete token structures; semantic naming;
WCAG AA accessibility (4.5:1 text, 3:1 UI)
```
@@ -220,10 +251,10 @@ Write({file_path: "{base_path}/style-extraction/style-cards.json", content: styl
```javascript
TodoWrite({todos: [
{content: "Validate inputs and create directories", status: "completed", activeForm: "Validating inputs"},
{content: "Analyze design space for maximum contrast", status: "completed", activeForm: "Analyzing design space"},
{content: `Generate ${variants_count} divergent design directions`, status: "completed", activeForm: "Generating directions"},
{content: "Save design space analysis for consolidation", status: "completed", activeForm: "Saving design space analysis"},
{content: `Generate ${variants_count} contrasting style variants`, status: "completed", activeForm: "Generating variants"}
{content: extraction_mode == "explore" ? "Analyze design space for maximum contrast" : "Skip design space analysis (imitate mode)", status: "completed", activeForm: extraction_mode == "explore" ? "Analyzing design space" : "Skipping analysis"},
{content: extraction_mode == "explore" ? `Generate ${variants_count} divergent design directions` : "Prepare for high-fidelity extraction", status: "completed", activeForm: extraction_mode == "explore" ? "Generating directions" : "Preparing extraction"},
{content: extraction_mode == "explore" ? "Save design space analysis for consolidation" : "Skip design space output", status: "completed", activeForm: extraction_mode == "explore" ? "Saving design space analysis" : "Skipping output"},
{content: `Generate ${variants_count} ${extraction_mode == "explore" ? "contrasting" : "high-fidelity"} style variant${variants_count > 1 ? "s" : ""}`, status: "completed", activeForm: "Generating variants"}
]});
```
@@ -231,25 +262,33 @@ TodoWrite({todos: [
```
✅ Style extraction complete for session: {session_id}
Mode: {extraction_mode == "imitate" ? "🎯 IMITATE (high-fidelity)" : "🎨 EXPLORE (contrast analysis)"}
Input mode: {input_mode}
{IF image mode: Images analyzed: {count}}
{IF prompt mode: Prompt: "{truncated_prompt}"}
{IF extraction_mode == "explore":
🎨 Design Space Analysis:
- Generated {variants_count} MAXIMALLY CONTRASTING design directions
- Min pairwise contrast distance: {design_space_analysis.contrast_verification.min_pairwise_distance}
- Strategy: {design_space_analysis.contrast_verification.strategy}
}
{IF extraction_mode == "imitate":
🎯 Imitation Mode:
- High-fidelity single style extraction
- Design space divergence skipped for faster execution
}
Generated {variants_count} style variant(s):
Generated {variants_count} style variant{variants_count > 1 ? "s" : ""}:
{FOR each card: - {card.name} ({card.id}) - {card.design_philosophy}}
📂 Outputs:
- {base_path}/style-extraction/style-cards.json
- {base_path}/style-extraction/design-space-analysis.json
{IF extraction_mode == "explore": - {base_path}/style-extraction/design-space-analysis.json}
Next: /workflow:ui-design:consolidate --session {session_id} --variants {variants_count} [--layout-variants <count>]
Note: When called from /workflow:ui-design:auto, consolidation is triggered automatically.
Note: When called from /workflow:ui-design:{extraction_mode == "imitate" ? "imitate" : "explore"}-auto, consolidation is triggered automatically.
```
## Output Structure
@@ -257,13 +296,13 @@ Note: When called from /workflow:ui-design:auto, consolidation is triggered auto
```
.workflow/WFS-{session}/design-{run_id}/style-extraction/
├── style-cards.json # Complete style variants with token proposals
└── design-space-analysis.json # Design directions for consolidation phase
└── design-space-analysis.json # Design directions (explore mode only)
OR (standalone mode):
.workflow/.design/{run_id}/style-extraction/
├── style-cards.json
└── design-space-analysis.json
└── design-space-analysis.json # Only in explore mode
```
### style-cards.json Format

View File

@@ -44,7 +44,7 @@ Generate production-ready UI prototypes (HTML/CSS) in `style × layout` matrix m
- **Token-Driven**: All styles reference per-style design-tokens.json; no hardcoded values
- **Production-Ready**: Semantic HTML5, ARIA attributes, responsive design
- **Template-Based**: Decouples HTML structure from CSS styling for optimal performance
- **Adaptive Wrapper**: Full-page structure for pages, minimal wrapper for components
- **Adaptive Wrapper**: All templates use complete HTML5 documents; body content adapts (full page structure for pages, isolated component for components)
## Execution Protocol
@@ -283,7 +283,9 @@ FOR layout_id IN range(1, layout_variants + 1):
## HTML Requirements
- Semantic HTML5 + ARIA attributes
- Wrapper: {IF page: Full document (header/nav/main/footer) | IF component: Minimal container}
- Wrapper: Always generate a complete HTML5 document (<!DOCTYPE html>, <html>, <head>, <body>)
* IF page: <body> contains full page structure (header, nav, main, footer)
* IF component: <body> contains only the component in a simple presentation wrapper
- ⚠️ CRITICAL: Include CSS placeholders in <head>:
<link rel=\"stylesheet\" href=\"{{STRUCTURAL_CSS}}\">
<link rel=\"stylesheet\" href=\"{{TOKEN_CSS}}\">
@@ -335,7 +337,7 @@ FOR layout_id IN range(1, layout_variants + 1):
# Basic validation checks
VALIDATE: len(html_content) > 100, f"HTML template too short: {html_label}"
VALIDATE: len(css_content) > 50, f"CSS template too short: {css_label}"
VALIDATE: "<!DOCTYPE html>" in html_content OR "<div" in html_content, f"Invalid HTML structure: {html_label}"
VALIDATE: "<!DOCTYPE html>" in html_content, f"Invalid HTML structure: {html_label}"
VALIDATE: "var(--" in css_content, f"Missing CSS variables: {css_label}"
html_size = get_file_size(html_path)
@@ -517,7 +519,7 @@ Generated Structure:
2. Quick Index: Open index.html
3. Instructions: See PREVIEW.md
{IF target_type == "component": Note: Components are rendered with minimal wrapper for isolated comparison.}
{IF target_type == "component": Note: Components use complete HTML5 documents with isolated body content for better comparison and styling.}
Next: /workflow:ui-design:update {--session flag if applicable}
@@ -581,7 +583,7 @@ After generation, ensure:
- [ ] File naming follows `{target}-style-{s}-layout-{l}` convention
- [ ] compare.html loads correctly with all prototypes
- [ ] Template files are reusable and style-agnostic
- [ ] Appropriate wrapper used (full-page for pages, minimal for components)
- [ ] All templates use complete HTML5 documents with appropriate body content (full structure for pages, isolated component for components)
## Key Features

View File

@@ -233,10 +233,10 @@ url_flag = screenshot_mode == "url_only" ? "--url \"{url_value}\"" : ""
# Construct optimized extraction prompt
enhanced_prompt = "Extract a single, high-fidelity design system that accurately imitates the visual style from {source_desc}. {prompt_text}"
# Force single variant
command = "/workflow:ui-design:extract --base-path \"{base_path}\" {url_flag} {images_flag} --prompt \"{enhanced_prompt}\" --variants 1"
# Force single variant with imitate mode
command = "/workflow:ui-design:extract --base-path \"{base_path}\" {url_flag} {images_flag} --prompt \"{enhanced_prompt}\" --mode imitate"
REPORT: "🚀 Phase 1: Style Extraction | Source: {source_desc} | Mode: Single style (imitation-optimized)"
REPORT: "🚀 Phase 1: Style Extraction | Source: {source_desc} | Mode: imitate (high-fidelity)"
SlashCommand(command) # → Phase 2
```