Files
Claude-Code-Workflow/.claude/commands/workflow/ui-design/generate-v2.md
catlog22 6b6367a669 feat: Add ui-generate-preview-v2.sh script for style-centric prototype preview generation
- Implemented a new script to generate compare.html and index.html for UI prototypes.
- Auto-detects styles, layouts, and targets from HTML file patterns.
- Generates an interactive comparison matrix and a simple index of prototypes.
- Includes a detailed PREVIEW.md guide with usage instructions and file structure.
2025-10-10 16:53:53 +08:00

32 KiB
Raw Blame History

name, description, usage, examples, allowed-tools
name description usage examples allowed-tools
generate-v2 Generate UI prototypes using style-centric batch generation /workflow:ui-design:generate-v2 [--targets "<list>"] [--target-type "page|component"] [--base-path <path>] [--session <id>] [--style-variants <count>] [--layout-variants <count>]
/workflow:ui-design:generate-v2 --session WFS-auth --targets "dashboard,settings" --style-variants 3 --layout-variants 3
/workflow:ui-design:generate-v2 --base-path ".workflow/WFS-auth/design-run-20250109-143022" --targets "home,pricing"
/workflow:ui-design:generate-v2 --targets "navbar,hero,card" --target-type "component" --style-variants 2 --layout-variants 2
TodoWrite(*), Read(*), Write(*), Task(ui-design-agent), Bash(*)

UI Generation Command (Style-Centric Architecture)

Executor: → @ui-design-agent Parallel Generation: Phase 2 → @ui-design-agent (S tasks, each handling L×T combinations)

Overview

Generate production-ready UI prototypes (HTML/CSS) using style-centric batch generation. Each agent handles all layout × target combinations for one style, ensuring maximum style consistency and optimal performance.

Core Philosophy

  • Style-Centric Batching: Each of S agents generates ALL L×T prototypes for one style
  • Style-Aware Structure: HTML DOM adapts based on design_attributes (density, visual_weight, etc.)
  • Performance Optimized: S agent calls for efficient generation
  • Perfect Style Consistency: All layouts for a style generated by single agent with full context
  • Token-Driven Styling: All styles reference design-tokens.json via tokens.css
  • Production-Ready: Semantic HTML5, ARIA attributes, responsive design

Execution Protocol

Phase 1: Path Resolution & Context Loading

# 1. Determine base path
IF --base-path: base_path = {provided_base_path}
ELSE IF --session: base_path = find_latest_path_matching(".workflow/WFS-{session}/design-*")
ELSE: base_path = find_latest_path_matching(".workflow/.design/*")

# 2. Determine style variant count and layout variant count
style_variants = --style-variants OR auto_detect_from_consolidation()
layout_variants = --layout-variants OR 3
VALIDATE: 1 <= style_variants <= 5
VALIDATE: 1 <= layout_variants <= 5

# Validate against actual style directories
actual_style_count = count_directories({base_path}/style-consolidation/style-*)

IF actual_style_count == 0:
    ERROR: "No style directories found"; SUGGEST: "Run /workflow:ui-design:consolidate first"; EXIT 1

IF style_variants > actual_style_count:
    WARN: "⚠️ Requested {style_variants}, but only {actual_style_count} exist"
    REPORT: "   Available styles: {list_directories}"; style_variants = actual_style_count

REPORT: "✅ Validated style variants: {style_variants}"

# 3. Enhanced target list parsing with type detection
target_list = []; target_type = "page"  # Default

# Priority 1: Unified --targets parameter
IF --targets:
    raw_targets = {--targets value}
    target_list = split_and_clean(raw_targets, delimiters=[",", ";", "、"])
    target_list = [t.strip().lower().replace(" ", "-") for t in target_list if t.strip()]

    target_type = --target-type provided ? {--target-type} : detect_target_type(target_list)
    REPORT: "🎯 Using provided targets ({target_type}): {', '.join(target_list)}"

# Priority 2: Legacy --pages parameter
ELSE IF --pages:
    raw_targets = {--pages value}
    target_list = split_and_clean(raw_targets, delimiters=[",", ";", "、"])
    target_list = [t.strip().lower().replace(" ", "-") for t in target_list if t.strip()]
    target_type = "page"
    REPORT: "📋 Using provided pages (legacy): {', '.join(target_list)}"

# Priority 3: Extract from synthesis-specification.md
ELSE IF --session:
    synthesis_spec = Read(.workflow/WFS-{session}/.brainstorming/synthesis-specification.md)
    target_list = extract_targets_from_synthesis(synthesis_spec); target_type = "page"
    REPORT: "📋 Extracted from synthesis: {', '.join(target_list)}"

# Priority 4: Detect from existing prototypes or default
ELSE:
    target_list = detect_from_prototypes({base_path}/prototypes/) OR ["home"]; target_type = "page"
    REPORT: "📋 Detected/default targets: {', '.join(target_list)}"

# 4. Validate target names
validated_targets = [t for t in target_list if regex_match(t, r"^[a-z0-9][a-z0-9_-]*$")]
invalid_targets = [t for t in target_list if t not in validated_targets]

IF invalid_targets: REPORT: "⚠️ Skipped invalid target names: {', '.join(invalid_targets)}"
VALIDATE: validated_targets not empty, "No valid targets found"
target_list = validated_targets

STORE: target_list, target_type

# 5. Verify design systems exist
FOR style_id IN range(1, style_variants + 1):
    VERIFY: exists({base_path}/style-consolidation/style-{style_id}/design-tokens.json)
    VERIFY: exists({base_path}/style-consolidation/style-{style_id}/tokens.css)

# 6. Load design space analysis (for style-aware generation)
design_space_path = "{base_path}/style-extraction/design-space-analysis.json"
IF exists(design_space_path):
    design_space_analysis = Read(design_space_path)
    REPORT: "📊 Loaded design space analysis with style attributes"
ELSE:
    WARN: "⚠️ No design space analysis found - will use basic style generation"
    design_space_analysis = null

# 7. Load requirements (if integrated mode)
IF --session:
    synthesis_spec = Read(.workflow/WFS-{session}/.brainstorming/synthesis-specification.md)
ELSE:
    synthesis_spec = null

Phase 1.5: Target-Specific Layout Planning

REPORT: "📐 Planning {layout_variants} layout strategies for each target..."

CREATE: {base_path}/prototypes/_templates/

# For each target, plan its specific layouts
FOR target IN target_list:
    REPORT: "  Planning layouts for '{target}' ({target_type})..."

    FOR layout_id IN range(1, layout_variants + 1):
        Task(ui-design-agent): "
          [TARGET_LAYOUT_PLANNING]

          TARGET: {target} | TARGET_TYPE: {target_type} | LAYOUT_ID: {layout_id}
          BASE_PATH: {base_path}
          {IF synthesis_spec: PROJECT_REQUIREMENTS: {synthesis_spec}}

          ## Task
          Research and generate layout plan JSON for '{target}' ({target_type}).

          ## Research (MCP Required)
          mcp__exa__get_code_context_exa(
            query=\"modern {target} {target_type} layout patterns 2024 2025\",
            tokensNum=\"dynamic\"
          )

          ## Output File
          Write(\"{base_path}/prototypes/_templates/{target}-layout-{layout_id}.json\", layout_plan_json)

          ## JSON Structure (Required Fields)
          ```json
          {{
            \"id\": \"layout-{layout_id}\",
            \"target\": \"{target}\",
            \"target_type\": \"{target_type}\",
            \"name\": \"Descriptive name (2-4 words)\",
            \"description\": \"2-3 sentences\",
            \"structure\": {{
              // IF page: type, regions, grid, sidebar, responsive
              // IF component: arrangement, alignment, spacing, element_order
            }},
            \"semantic_hints\": [...],
            \"accessibility_features\": [...],
            \"research_references\": [...]
          }}
          ```

          ## Requirements
          - Research-informed, target-specific, meaningfully different from other layout IDs
          - Write file directly (not text output)
        "

# Wait for all agent tasks to complete
REPORT: "⏳ Waiting for layout planning agents to complete..."

# Verify agent created layout JSON files
REPORT: "📝 Verifying agent file creation..."

FOR target IN target_list:
    FOR layout_id IN range(1, layout_variants + 1):
        layout_json_label = f"{target}-layout-{layout_id}.json"
        json_path = f"{base_path}/prototypes/_templates/{layout_json_label}"

        # Verify file exists
        VERIFY: exists(json_path), f"Layout JSON not created by agent: {layout_json_label}"

        # Validate JSON structure
        TRY:
            layout_json_content = Read(json_path)
            layout_plan = JSON.parse(layout_json_content)

            # Validate required fields
            VALIDATE: layout_plan.id == f"layout-{layout_id}", f"Invalid layout ID in {layout_json_label}"
            VALIDATE: layout_plan.target == target, f"Invalid target in {layout_json_label}"
            VALIDATE: layout_plan.target_type == target_type, f"Invalid target_type in {layout_json_label}"
            VALIDATE: layout_plan.name exists, f"Missing 'name' field in {layout_json_label}"
            VALIDATE: layout_plan.structure exists, f"Missing 'structure' field in {layout_json_label}"

            file_size = get_file_size(json_path)
            REPORT: f"   ✓ Verified: {layout_json_label} - {layout_plan.name} ({file_size} KB)"
        CATCH error:
            ERROR: f"Validation failed for {layout_json_label}: {error}"
            REPORT: f"   ⚠️ File exists but validation failed - review agent output"

REPORT: f"✅ Phase 1.5 complete: Verified {len(target_list) × layout_variants} target-specific layout files"

Phase 1.6: Convert Design Tokens to CSS

REPORT: "🎨 Converting design tokens to CSS variables..."

# Check for jq dependency
IF NOT command_exists("jq"):
    ERROR: "jq is not installed or not in PATH. The conversion script requires jq."
    REPORT: "Please install jq: macOS: brew install jq | Linux: apt-get install jq | Windows: https://stedolan.github.io/jq/download/"
    EXIT 1

# Convert design tokens to CSS for each style variant
FOR style_id IN range(1, style_variants + 1):
    tokens_json_path = "{base_path}/style-consolidation/style-${style_id}/design-tokens.json"
    tokens_css_path = "{base_path}/style-consolidation/style-${style_id}/tokens.css"
    script_path = "~/.claude/scripts/convert_tokens_to_css.sh"

    # Verify input file exists
    VERIFY: exists(tokens_json_path), f"Design tokens not found for style-{style_id}"

    # Execute conversion: cat input.json | script.sh > output.css
    Bash(cat "${tokens_json_path}" | "${script_path}" > "${tokens_css_path}")

    # Verify output was generated
    IF exit_code == 0 AND exists(tokens_css_path):
        file_size = get_file_size(tokens_css_path)
        REPORT: f"   ✓ Generated tokens.css for style-{style_id} ({file_size} KB)"
    ELSE:
        ERROR: f"Failed to generate tokens.css for style-{style_id}"
        EXIT 1

REPORT: f"✅ Phase 1.6 complete: Converted {style_variants} design token files to CSS"

Phase 1.7: Extract Token Variable Names from CSS

REPORT: "📋 Extracting actual CSS variable names from tokens.css..."
tokens_css_path = "{base_path}/style-consolidation/style-1/tokens.css"
VERIFY: exists(tokens_css_path), "tokens.css not found. Phase 1.6 may have failed."

tokens_css_content = Read(tokens_css_path)

# Extract all CSS variable names from the generated file
# Pattern: --variable-name: value;
all_token_vars = extract_css_variables(tokens_css_content)  # Regex: r'--([a-z0-9-_]+):'

# Categorize variables for better Agent understanding
color_vars = [v for v in all_token_vars if v.startswith('--color-')]
typography_vars = [v for v in all_token_vars if v.startswith(('--font-', '--line-height-', '--letter-spacing-'))]
spacing_vars = [v for v in all_token_vars if v.startswith('--spacing-')]
radius_vars = [v for v in all_token_vars if v.startswith('--border-radius-')]
shadow_vars = [v for v in all_token_vars if v.startswith('--shadow-')]
breakpoint_vars = [v for v in all_token_vars if v.startswith('--breakpoint-')]

REPORT: f"✅ Extracted {len(all_token_vars)} actual CSS variables from tokens.css"
REPORT: f"   Colors: {len(color_vars)} | Typography: {len(typography_vars)} | Spacing: {len(spacing_vars)}"

Phase 2: Style-Centric Batch Generation

Strategy: S style-centric agents, each generating L×T prototypes for one style. Performance: S agent calls for parallel execution

REPORT: "🎨 Phase 2: Launching {style_variants} style-centric agents..."
REPORT: "   Each agent generates {layout_variants}×{len(target_list)}={layout_variants * len(target_list)} prototypes"

CREATE: {base_path}/prototypes/

# Launch ONE agent task PER STYLE (parallel execution)
FOR style_id IN range(1, style_variants + 1):
    # Load style-specific context
    style_tokens_path = "{base_path}/style-consolidation/style-{style_id}/design-tokens.json"
    style_css_path = "{base_path}/style-consolidation/style-{style_id}/tokens.css"
    style_guide_path = "{base_path}/style-consolidation/style-{style_id}/style-guide.md"

    # Extract design attributes for this style (if available)
    IF design_space_analysis AND style_id <= len(design_space_analysis.divergent_directions):
        design_attributes = design_space_analysis.divergent_directions[style_id - 1]
        philosophy_name = design_attributes.philosophy_name
        attributes_summary = JSON.stringify({
            density: design_attributes.design_attributes.density,
            visual_weight: design_attributes.design_attributes.visual_weight,
            formality: design_attributes.design_attributes.formality,
            organic_vs_geometric: design_attributes.design_attributes.organic_vs_geometric,
            innovation: design_attributes.design_attributes.innovation
        })
    ELSE:
        design_attributes = null
        philosophy_name = f"Style {style_id}"
        attributes_summary = "No design attributes available"

    Task(ui-design-agent): """
      [STYLE_CENTRIC_UI_BATCH_GENERATION]

      ## 🎯 Mission
      Generate COMPLETE set of UI prototypes for Style-{style_id} across ALL targets and layouts.
      Total files to create: {layout_variants × len(target_list) × 2} (HTML + CSS pairs)

      ## 🎨 Style Context (Your Design Identity)
      STYLE_ID: {style_id}
      PHILOSOPHY: {philosophy_name}

      {IF design_attributes:
      DESIGN_ATTRIBUTES: {attributes_summary}
      - density: {design_attributes.design_attributes.density} → Affects spacing, container usage
      - visual_weight: {design_attributes.design_attributes.visual_weight} → Affects borders, shadows, nesting
      - formality: {design_attributes.design_attributes.formality} → Affects font choices, structure formality
      - organic_vs_geometric: {design_attributes.design_attributes.organic_vs_geometric} → Affects border-radius, alignment
      - innovation: {design_attributes.design_attributes.innovation} → Affects layout adventurousness
      }

      STYLE_FILES:
      - Design Tokens: {style_tokens_path}
      - CSS Variables: {style_css_path}
      - Style Guide: {style_guide_path}

      ## 📋 Batch Generation Matrix
      TARGETS: {target_list}  # Example: [dashboard, settings]
      LAYOUTS: 1 to {layout_variants}  # Example: [1, 2, 3]
      TOTAL_COMBINATIONS: {layout_variants × len(target_list)}
      TARGET_TYPE: {target_type}

      ## 🔄 Required Execution Loop

      You MUST implement this nested loop to generate all combinations:

      ```pseudocode
      FOR target IN {target_list}:
          FOR layout_id IN [1..{layout_variants}]:
              # Step 1: Load layout plan
              layout_plan_path = "{base_path}/prototypes/_templates/{target}-layout-{layout_id}.json"
              layout_plan = Read(layout_plan_path)

              # Step 2: Load CSS variables (to know what tokens exist)
              tokens_css = Read("{style_css_path}")
              available_vars = extract_all_css_variables(tokens_css)  # Pattern: --variable-name:

              # Step 3: Generate STYLE-AWARE HTML structure
              # ⚠️ CRITICAL: Structure must adapt based on design_attributes!

              html_structure = generate_html_with_style_awareness(
                  target=target,
                  layout_plan=layout_plan,
                  target_type="{target_type}",
                  design_attributes={design_attributes if design_attributes else "null"}
              )

              ## Style-Aware Structure Rules:
              {IF design_attributes:
              # Apply design_attributes to HTML structure:
              IF density == 'spacious':
                  → Use FEWER containers, flatter DOM hierarchy
                  → Example: <main><section class="card"></section></main>
              IF density == 'compact':
                  → Use MORE containers, allow nesting
                  → Example: <main><div class="grid"><div class="card-wrapper"><section></section></div></div></main>

              IF visual_weight == 'heavy':
                  → Add extra wrapper divs for border effects
                  → Example: <div class="border-container"><div class="content-wrapper">...</div></div>
              IF visual_weight == 'minimal' or 'light':
                  → Minimal wrappers, direct structure
                  → Example: <section class="card">...</section>

              IF organic_vs_geometric == 'brutalist':
                  → Hard edges, overlapping allowed, structural honesty
              IF organic_vs_geometric == 'organic':
                  → Flowing, natural hierarchy
              }

              # Step 4: Generate structural CSS using ONLY extracted variables
              # ⚠️ CRITICAL: Use var() for ALL styling, NO hardcoded values

              css_content = generate_structural_css(
                  layout_plan=layout_plan,
                  available_vars=available_vars,  # ⚠️ Only use these!
                  design_attributes={design_attributes if design_attributes else "null"}
              )

              ## CSS Requirements:
              - ALL colors use: var(--color-*)
              - ALL fonts use: var(--font-*)
              - ALL spacing use: var(--spacing-*)
              - ALL radius use: var(--border-radius-*)
              - ALL shadows use: var(--shadow-*)
              - Responsive: Use var(--breakpoint-*) for media queries

              {IF design_attributes:
              # Apply design_attributes to CSS properties:
              IF density == 'spacious':
                  → Use larger spacing values: var(--spacing-8) instead of var(--spacing-4)
              IF density == 'compact':
                  → Use smaller spacing values: var(--spacing-2) instead of var(--spacing-4)

              IF visual_weight == 'heavy':
                  → Use stronger shadows: var(--shadow-lg) instead of var(--shadow-md)
                  → Add border declarations
              IF visual_weight == 'minimal':
                  → Use subtle shadows: var(--shadow-sm) or none
                  → Minimal borders
              }

              # Step 5: HTML must include CSS placeholders
              html_content = html_structure.replace("</head>", \"\"\"
                <link rel="stylesheet" href="{{STRUCTURAL_CSS}}">
                <link rel="stylesheet" href="{{TOKEN_CSS}}">
              </head>
              \"\"\")

              # Step 6: Write files IMMEDIATELY (don't accumulate)
              output_html = "{base_path}/prototypes/{target}-style-{style_id}-layout-{layout_id}.html"
              output_css = "{base_path}/prototypes/{target}-style-{style_id}-layout-{layout_id}.css"

              Write(output_html, html_content)
              Write(output_css, css_content)

              REPORT: f"   ✓ Generated: {target}-style-{style_id}-layout-{layout_id}"
      ```

      ## ⚠️ Critical Requirements

      ### 1. HTML Generation Rules
      - **Complete HTML5 document**: <!DOCTYPE html>, <html>, <head>, <body>
      - **Semantic elements**: Use <header>, <nav>, <main>, <section>, <article>, <aside>, <footer>
      - **ARIA attributes**: aria-label, role, aria-labelledby for accessibility
      - **Responsive meta**: <meta name="viewport" content="width=device-width, initial-scale=1">
      - **CSS placeholders**: MUST include {{STRUCTURAL_CSS}} and {{TOKEN_CSS}} placeholders

      ### 2. Style-Aware Structure Adaptation
      {IF design_attributes:
      **You have design_attributes - USE THEM to vary DOM structure:**
      - Same target+layout with different styles = DIFFERENT HTML structures
      - Example: Minimalist dashboard (density=spacious) has fewer divs than Brutalist dashboard (visual_weight=heavy)
      - This is NOT just CSS differences - the HTML tree itself must adapt!
      }
      {ELSE:
      **No design_attributes available - generate clean, semantic structure**
      - Focus on layout_plan requirements
      - Use best practices for {target_type} structure
      }

      ### 3. CSS Generation Rules
      - **Token-driven**: 100% var() usage, ZERO hardcoded values
      - **Structural only**: Layout, positioning, spacing, structure
      - **NO styling**: No colors, fonts in structural CSS (handled by tokens.css)
      - **Responsive**: Mobile-first, use var(--breakpoint-*) for media queries

      ### 4. Layout Differentiation
      - layout-1 vs layout-2 vs layout-3 must be STRUCTURALLY DIFFERENT
      - Not just CSS tweaks - different grid systems, different regions
      - Refer to layout_plan.structure for each layout's unique requirements

      ### 5. Write Operations (MANDATORY)
      - Write() IMMEDIATELY after generating each prototype
      - Do NOT accumulate all content and write at end
      - Do NOT return file contents as text output
      - Each Write() creates one HTML or CSS file

      ## ✅ Completion Report

      After generating ALL {layout_variants × len(target_list)} combinations, report:

      ```
      ✅ Style-{style_id} ({philosophy_name}) Batch Generation Complete
      Files Created: {layout_variants × len(target_list) × 2} ({layout_variants × len(target_list)} HTML + {layout_variants × len(target_list)} CSS)

      {FOR target IN target_list:
      {target.capitalize()}:
        {FOR layout_id IN range(1, layout_variants + 1):
        - {target}-style-{style_id}-layout-{layout_id}.html/css ({file_size_kb} KB each)
        }
      }

      Summary: All prototypes generated with {IF design_attributes: 'style-aware structure' ELSE: 'semantic structure'}
      ```

      ## 🔑 Key Success Criteria
      - [ ] Generated exactly {layout_variants × len(target_list) × 2} files
      - [ ] All HTML files include CSS placeholders
      - [ ] All CSS files use var() exclusively (no hardcoded values)
      - [ ] {IF design_attributes: '[ ] HTML structure varies based on design_attributes' ELSE: '[ ] HTML structure follows layout_plan'}
      - [ ] Layout-1, Layout-2, Layout-3 are structurally distinct
      - [ ] All files written directly to filesystem (not returned as text)
    """

REPORT: "⏳ Phase 2: Waiting for {style_variants} style-centric agents to complete..."
REPORT: "   Expected total files: {style_variants × layout_variants × len(target_list) × 2}"

Phase 2.5: Verify Agent File Creation

REPORT: "📝 Phase 2.5: Verifying style-centric generation..."

total_expected = style_variants × layout_variants × len(target_list) × 2
total_found = 0

FOR style_id IN range(1, style_variants + 1):
    style_files_found = 0

    FOR layout_id IN range(1, layout_variants + 1):
        FOR target IN target_list:
            html_file = f"{target}-style-{style_id}-layout-{layout_id}.html"
            css_file = f"{target}-style-{style_id}-layout-{layout_id}.css"

            html_path = f"{base_path}/prototypes/{html_file}"
            css_path = f"{base_path}/prototypes/{css_file}"

            # Verify files exist
            IF exists(html_path) AND exists(css_path):
                # Validate content
                html_content = Read(html_path)
                css_content = Read(css_path)

                # Basic validation
                VALIDATE: "<!DOCTYPE html>" in html_content, f"Invalid HTML: {html_file}"
                VALIDATE: "{{STRUCTURAL_CSS}}" in html_content, f"Missing CSS placeholder: {html_file}"
                VALIDATE: "var(--" in css_content, f"Missing CSS variables: {css_file}"

                html_size = get_file_size(html_path)
                css_size = get_file_size(css_path)

                style_files_found += 2
                total_found += 2

                REPORT: f"   ✓ {html_file} ({html_size} KB) + {css_file} ({css_size} KB)"
            ELSE:
                ERROR: f"   ✗ Missing files: {target}-style-{style_id}-layout-{layout_id}.*"

    REPORT: f"  Style-{style_id}: {style_files_found}/{layout_variants * len(target_list) * 2} files verified"

IF total_found == total_expected:
    REPORT: f"✅ Phase 2.5 complete: Verified all {total_expected} files"
ELSE:
    ERROR: f"⚠️ Only {total_found}/{total_expected} files found - some agents may have failed"

Phase 3: Generate Preview Files

REPORT: "🌐 Phase 3: Generating preview files..."

# Phase 3a: Replace CSS placeholders in HTML files
FOR style_id IN range(1, style_variants + 1):
    tokens_css_rel_path = f"../style-consolidation/style-{style_id}/tokens.css"

    FOR layout_id IN range(1, layout_variants + 1):
        FOR target IN target_list:
            html_path = f"{base_path}/prototypes/{target}-style-{style_id}-layout-{layout_id}.html"
            css_path = f"{target}-style-{style_id}-layout-{layout_id}.css"  # Relative path

            IF exists(html_path):
                html_content = Read(html_path)

                # Replace placeholders
                html_content = html_content.replace("{{STRUCTURAL_CSS}}", css_path)
                html_content = html_content.replace("{{TOKEN_CSS}}", tokens_css_rel_path)

                # Write updated HTML
                Write(html_path, html_content)

REPORT: "   ✓ Updated CSS links in all HTML files"

# Phase 3b: Generate compare.html and index.html using simplified preview script
prototypes_dir = f"{base_path}/prototypes"

# Simple preview generation (no template substitution)
Bash(~/.claude/scripts/ui-generate-preview-v2.sh "{prototypes_dir}")

# The script auto-detects: S, L, T from file patterns
# The script generates: compare.html, index.html, PREVIEW.md

# Verify preview files generated
preview_files = [
    f"{base_path}/prototypes/compare.html",
    f"{base_path}/prototypes/index.html",
    f"{base_path}/prototypes/PREVIEW.md"
]

all_present = True
FOR file_path IN preview_files:
    IF exists(file_path):
        REPORT: f"   ✓ Generated: {basename(file_path)}"
    ELSE:
        WARN: f"   ✗ Missing: {basename(file_path)}"
        all_present = False

IF all_present:
    REPORT: "✅ Phase 3 complete: All preview files generated"
ELSE:
    WARN: "⚠️ Some preview files missing - script may need attention"

Phase 4: Completion

TodoWrite({todos: [
  {content: "Resolve paths and load design systems", status: "completed", activeForm: "Loading design systems"},
  {content: `Plan ${target_list.length}×${layout_variants} target-specific layouts`, status: "completed", activeForm: "Planning layouts"},
  {content: `Convert ${style_variants} design token files to CSS`, status: "completed", activeForm: "Converting tokens to CSS"},
  {content: "Extract CSS variable names from tokens.css", status: "completed", activeForm: "Extracting variable names"},
  {content: `Launch ${style_variants} style-centric agents (each handling ${layout_variants}×${target_list.length} combinations)`, status: "completed", activeForm: "Running style-centric generation"},
  {content: `Verify ${style_variants * layout_variants * target_list.length * 2} generated files`, status: "completed", activeForm: "Verifying files"},
  {content: "Generate preview files (compare.html, index.html)", status: "completed", activeForm: "Generating previews"}
]});

Completion Message:

✅ Style-Centric UI Generation Complete!

Architecture: Style-Centric Batch Generation

Configuration:
- Style Variants: {style_variants}
- Layout Variants: {layout_variants} (target-specific planning)
- Target Type: {target_type_icon} {target_type}
- Targets: {target_list}
- Total Prototypes: {style_variants * layout_variants * len(target_list)}

Agent Execution:
✅ Style-centric agents: S = {style_variants} agents
✅ Each agent handles: L×T = {layout_variants}×{len(target_list)} combinations

Design Quality:
✅ Style-Aware Structure: {IF design_space_analysis: 'YES - HTML adapts to design_attributes' ELSE: 'Standard semantic structure'}
✅ Style Consistency: PERFECT (each style by single agent)
✅ Token-Driven Styling: 100% var() usage

Output Files:
- Layout Plans: {len(target_list) × layout_variants} JSON files
- HTML Prototypes: {style_variants * layout_variants * len(target_list)} files
- CSS Files: {style_variants * layout_variants * len(target_list)} files
- Preview Files: compare.html, index.html, PREVIEW.md

Generated Structure:
📂 {base_path}/prototypes/
├── _templates/
│   └── {target}-layout-{l}.json ({len(target_list) × layout_variants} layout plans)
├── {target}-style-{s}-layout-{l}.html ({style_variants * layout_variants * len(target_list)} prototypes)
├── {target}-style-{s}-layout-{l}.css
├── compare.html (interactive S×L×T matrix)
├── index.html (quick navigation)
└── PREVIEW.md (usage instructions)

🌐 Interactive Preview:
1. Matrix View: Open compare.html (recommended)
2. Quick Index: Open index.html
3. Instructions: See PREVIEW.md

{IF design_space_analysis:
🎨 Style-Aware Generation Active:
Each style's prototypes use structure adapted to design_attributes:
- Density affects container nesting and whitespace
- Visual weight affects wrapper layers and border structure
- Same layout × same target × different style = DIFFERENT HTML trees!
}

Next: /workflow:ui-design:update {--session flag if applicable}

Note: When called from /workflow:ui-design:explore-auto, design-update is triggered automatically.

**Dynamic Values**: target_type_icon: "📄" for page, "🧩" for component

Output Structure

{base_path}/prototypes/
├── _templates/                                    # Layout planning only
│   └── {target}-layout-1.json                    # Layout plan JSON
├── {target}-style-{s}-layout-{l}.html            # Final prototypes (S×L×T)
├── {target}-style-{s}-layout-{l}.css
├── compare.html                                   # Interactive matrix
├── index.html                                     # Navigation page
└── PREVIEW.md                                     # Instructions

{base_path}/style-consolidation/
├── style-1/ (design-tokens.json, tokens.css, style-guide.md)
├── style-2/ (same structure)
└── style-{S}/ (same structure)

Error Handling

Pre-execution Checks

  • No design systems found: Error - Run /workflow:ui-design:consolidate first
  • Invalid target names: Extract from synthesis-specification.md or error with validation message
  • Missing design-space-analysis.json: WARN only - generation continues with basic structure
  • Unsupported target type: Error if target_type not in ["page", "component"]

Phase-Specific Errors

  • Agent execution errors (Phase 2): Report details, identify which style agent failed
  • Token conversion errors (Phase 1.6): Check design-tokens.json format
  • Missing files (Phase 2.5): Indicates agent failed to write - review agent output logs
  • Preview generation errors (Phase 3): Check script exists, permissions

Recovery Strategies

  • Partial generation: If some style agents succeed, you still have those prototypes
  • Retry single style: Can re-run targeting failed style directory
  • Missing design_attributes: Generation works without them - just less style-aware
  • Permission errors: Run chmod +x ~/.claude/scripts/ui-generate-preview-v2.sh

Key Features

  1. 🚀 Style-Centric Batch Generation Each agent handles ALL L×T combinations for one style with efficient parallel execution

  2. 🎨 Style-Aware Structure Adaptation HTML DOM adapts based on design_attributes (density, visual_weight, organic_vs_geometric)

  3. 📦 Intelligent Context Batching Each agent receives full style context + all layout plans + all targets

  4. Performance Optimized Parallel execution of S agents for efficient generation

  5. 🔒 Guaranteed Style Consistency All layouts for a style by single agent; Maintains philosophy throughout

  6. 📐 Target-Specific Layout Planning Each target gets custom-designed layouts via MCP research

  7. 🎯 Token-Driven Styling 100% var() usage; Each style has own tokens.css

  8. 🌐 Interactive Visualization Full-featured compare.html with matrix grid

  9. Production-Ready Output Semantic HTML5, ARIA attributes, WCAG 2.2 compliant

Integration Points

  • Input: Per-style design-tokens.json + tokens.css; design-space-analysis.json (optional); targets + layout-variants
  • Output: S×L×T HTML/CSS prototypes for /workflow:ui-design:update
  • Auto Integration: Triggered by /workflow:ui-design:explore-auto
  • Backward Compatibility: Works without design-space-analysis.json