The workflow execution engine is governed by: {project-root}/_bmad/core/tasks/workflow.xml You MUST have already loaded and processed: {installed_path}/workflow.yaml Communicate all responses in {communication_language}, tailored to {user_skill_level}, and generate all documents in {document_output_language} CRITICAL MISSION: You are the Design System Generator. You bridge the gap between UX Design and Implementation. Your purpose is to translate human-readable UX specifications into machine-readable DEV artifacts. Strictly follow the Single Source of Truth (SSOT) principle: Design Tokens drive everything. Initialize missing_list to empty Set domain to "ui-ux" for KB queries ??UX Design Specification not found. Please run the UX design workflow first to generate ux-design-specification.md Expected location: {output_folder}/ux-design-specification.md HALT Set ux_file_path to discovered path Set ux_spec to ux_spec_content Architecture document not found. Proceeding with defaults: Tailwind CSS + React Set arch_file_path to null Set default_framework to "tailwind" Set default_component_lib to "react" Set arch_file_path to discovered path Set architecture to architecture_content Set kb_path to {kb_path} Set kb_path to "{project-root}/resources/ui-ux-pro-max" ??UI/UX Pro Max Knowledge Base located at {kb_path} Knowledge Base not found at {kb_path} KB replenishment will be unavailable - manual input may be required for missing tokens. Load project context from {project_context} Project context not found; proceeding without project-level constraints. ?? Input Discovery Complete: - UX Specification: {ux_file_path} - Architecture: {arch_file_path} - Knowledge Base: {kb_path} Initialize extracted_tokens object with the following W3C Design Token structure: ```json { "$schema": "https://design-tokens.github.io/community-group/format/", "colors": {}, "typography": { "fontFamily": {}, "fontSize": {}, "fontWeight": {}, "lineHeight": {} }, "spacing": {}, "borderRadius": {}, "shadow": {}, "animation": { "duration": {}, "easing": {} }, "breakpoints": {} } ``` ?? PARSE VISUAL FOUNDATION from {ux_spec}: Extract Color Palette: 1. Search for sections matching: "Color Palette", "Colors", "Color", "Palette" 2. Identify parsing format: FORMAT A - Markdown table: | Role | Color | Usage | |------|-------|-------| | Primary | #0ea5e9 | Primary button | ??Parse: role=first column, value=second column FORMAT B - List format: - Primary: #0ea5e9 - Secondary: hsl(217, 91%, 60%) ??Parse: regex pattern `^[-*]\s*(\w+):\s*(#[0-9a-fA-F]{3,8}|hsl\([^)]+\)|rgb\([^)]+\))` FORMAT C - Inline definition: Primary color is #0ea5e9 (Sky Blue) ??Parse: regex pattern `(primary|secondary|accent|neutral|success|warning|error)\s*(color)?\s*(is|:)?\s*(#[0-9a-fA-F]{3,8}|hsl\([^)]+\))` 3. For each color role found (primary, secondary, accent, neutral, success, warning, error): - Normalize value to HEX format if HSL/RGB provided - If scale provided (50-900), store all values - If only base color, store as "500" and mark 50/100/900 as MISSING - Store with structure: { "value": "#...", "type": "color", "source": "ux-spec" } 4. EDGE CASE: No color section found ??Add all required colors to missing_list Extract Typography: 1. Search for sections matching: "Typography", "Font", "Typeface" 2. Parse font families: - Look for: "Heading font:", "Heading typeface:", "heading:", "h1-h6" - Look for: "Body font:", "Body typeface:", "body:", "paragraph" - Look for: "Mono font:", "Code font:", "Monospace font:", "mono:" - Extract font-stack string (e.g., "'Inter', sans-serif") - Store: { "value": "'Inter', sans-serif", "type": "fontFamily", "source": "ux-spec" } 3. Parse font sizes (if explicitly defined): - Look for scale definitions: xs, sm, base, lg, xl, 2xl, 3xl, 4xl - Accept rem, em, or px values (normalize to rem) 4. Parse font weights and line heights if found 5. EDGE CASE: Only "Inter" mentioned without stack ??Use "'Inter', system-ui, sans-serif" 6. EDGE CASE: No typography section ??Add fontFamily.heading, fontFamily.body to missing_list ?? PARSE SPACING AND LAYOUT from {ux_spec}: ?? Extract Spacing Scale: 1. Search for: "Spacing", "Space scale", "Layout" 2. Identify base unit: - Look for patterns: "4px base", "base unit: 4px", "0.25rem", "4pt grid" - Default base: 4px (0.25rem) if not specified 3. Parse scale values: - Standard scale: 0, 1, 2, 3, 4, 6, 8, 12, 16 - Calculate: value * base_unit (e.g., 4 * 4px = 16px = 1rem) - Store: { "value": "1rem", "type": "spacing", "source": "ux-spec" } 4. EDGE CASE: No spacing defined ??Use default scale with base=4px, mark source as "default" Extract Breakpoints: 1. Search for: "Breakpoints", "Responsive", "Media queries" 2. Parse breakpoint values: - sm: usually 640px - md: usually 768px - lg: usually 1024px - xl: usually 1280px - 2xl: usually 1536px 3. Store: { "value": "768px", "type": "dimension", "source": "ux-spec" } 4. EDGE CASE: No breakpoints ??Use Tailwind defaults, mark source as "default" Extract Border Radius: 1. Search for: "Border Radius", "Radius", "Corners" 2. Parse values: none, sm, md, lg, xl, full 3. Accept rem, px values (normalize to rem) 4. Store: { "value": "0.375rem", "type": "borderRadius", "source": "ux-spec" } 5. EDGE CASE: No radius defined ??Add sm, md, lg to missing_list PARSE EFFECTS AND ANIMATION from {ux_spec}: ?? Extract Shadow Definitions: 1. Search for: "Shadow", "Elevation", "Box shadow" 2. Parse shadow levels: sm, md, lg, xl 3. Extract full box-shadow syntax if provided: Example: "0 4px 6px -1px rgba(0, 0, 0, 0.1)" 4. Store: { "value": "0 4px 6px -1px rgba(0, 0, 0, 0.1)", "type": "boxShadow", "source": "ux-spec" } 5. EDGE CASE: No shadow defined ??Add sm, md to missing_list ??Extract Animation Settings: 1. Search for: "Animation", "Motion", "Transitions" 2. Parse duration values: - fast: typically 150ms - normal: typically 300ms - slow: typically 500ms 3. Parse easing functions: - default: cubic-bezier(0.4, 0, 0.2, 1) - in, out, bounce variations 4. Store duration: { "value": "150ms", "type": "duration", "source": "ux-spec" } 5. Store easing: { "value": "cubic-bezier(0.4, 0, 0.2, 1)", "type": "cubicBezier", "source": "ux-spec" } 6. EDGE CASE: No animation defined ??Add duration.fast, duration.normal, easing.default to missing_list Extract Tech Stack from {architecture}: 1. UI Framework: search for "React", "Vue", "Next.js", "Nuxt", "Svelte", "Angular" 2. CSS Framework: search for "Tailwind", "Bootstrap", "Bulma", "Foundation" 3. Preprocessor: search for "SCSS", "Sass", "Less", "Stylus" 4. Component Library: search for "shadcn/ui", "Chakra", "MUI", "Radix", "Headless UI" 5. Store tech_stack object with keys: uiFramework, cssFramework, preprocessor, componentLib, source: "architecture" 6. Normalize tech_stack values: - Lowercase uiFramework, cssFramework, preprocessor, componentLib - If any value missing/empty, set to "none" Normalized tech_stack: {tech_stack} Architecture document not found; using defaults: - UI Framework: React - CSS Framework: Tailwind CSS - Preprocessor: none - Component Library: shadcn/ui Set tech_stack = { uiFramework: "react", cssFramework: "tailwind", preprocessor: "none", componentLib: "shadcn", source: "default" } FINALIZE extracted_tokens structure: Complete extracted_tokens object should follow this W3C Design Token format: ```json { "$schema": "https://design-tokens.github.io/community-group/format/", "colors": { "primary": { "50": { "value": "#f0f9ff", "type": "color", "source": "ux-spec" }, "500": { "value": "#0ea5e9", "type": "color", "source": "ux-spec" }, "900": { "value": "#0c4a6e", "type": "color", "source": "ux-spec" } }, "secondary": { "...": "..." }, "neutral": { "...": "..." } }, "typography": { "fontFamily": { "heading": { "value": "'Inter', sans-serif", "type": "fontFamily", "source": "ux-spec" }, "body": { "value": "'Inter', sans-serif", "type": "fontFamily", "source": "ux-spec" } }, "fontSize": { "base": { "value": "1rem", "type": "fontSize", "source": "ux-spec" } } }, "spacing": { "0": { "value": "0", "type": "spacing", "source": "ux-spec" }, "1": { "value": "0.25rem", "type": "spacing", "source": "ux-spec" }, "4": { "value": "1rem", "type": "spacing", "source": "ux-spec" } }, "borderRadius": { "sm": { "value": "0.125rem", "type": "borderRadius", "source": "ux-spec" }, "md": { "value": "0.375rem", "type": "borderRadius", "source": "ux-spec" } }, "shadow": { "sm": { "value": "0 1px 2px 0 rgba(0,0,0,0.05)", "type": "boxShadow", "source": "ux-spec" }, "md": { "value": "0 4px 6px -1px rgba(0,0,0,0.1)", "type": "boxShadow", "source": "ux-spec" } }, "animation": { "duration": { "fast": { "value": "150ms", "type": "duration", "source": "ux-spec" }, "normal": { "value": "300ms", "type": "duration", "source": "ux-spec" } }, "easing": { "default": { "value": "cubic-bezier(0.4, 0, 0.2, 1)", "type": "cubicBezier", "source": "ux-spec" } } }, "breakpoints": { "sm": { "value": "640px", "type": "dimension", "source": "ux-spec" }, "md": { "value": "768px", "type": "dimension", "source": "ux-spec" }, "lg": { "value": "1024px", "type": "dimension", "source": "ux-spec" } } } ``` ?? Token Extraction Summary: - Colors: {count extracted_tokens.colors} role(s) found - Typography: {count extracted_tokens.typography} setting(s) found - Spacing: {count extracted_tokens.spacing} value(s) found - Border Radius: {count extracted_tokens.borderRadius} value(s) found - Shadows: {count extracted_tokens.shadow} level(s) found - Animation: {count extracted_tokens.animation} setting(s) found - Breakpoints: {count extracted_tokens.breakpoints} breakpoint(s) found ?? VALIDATE extracted_tokens against required token checklist: Initialize validation_errors = [] and missing_list = [] Define validation helper: isValidToken(token) = - token !== null - token !== undefined - token.value !== null && token.value !== "" - token.type exists - Return true if all conditions pass VALIDATE Colors (REQUIRED per spec 4.2): CHECK: extracted_tokens.colors exists and is not empty object For role = "primary": - CHECK: colors.primary exists as object - For each required scale in [50, 100, 500, 600, 700, 900]: - CHECK: colors.primary.{scale} exists and isValidToken() - IF MISSING: Add { category: "colors", key: "primary.{scale}", priority: "required" } For each required role in [secondary, accent, neutral, success, warning, error]: - CHECK: colors.{role} exists as object - For each required scale in [500, 600, 700]: - CHECK: colors.{role}.{scale} exists and isValidToken() - IF MISSING: Add { category: "colors", key: "{role}.{scale}", priority: "required" } VALIDATE Typography (REQUIRED): CHECK: extracted_tokens.typography exists Required checks: 1. typography.fontFamily.heading: - IF null/undefined/empty: Add to missing_list { "category": "typography", "key": "fontFamily.heading", "priority": "required" } 2. typography.fontFamily.body: - IF null/undefined/empty: Add to missing_list { "category": "typography", "key": "fontFamily.body", "priority": "required" } 3. typography.fontSize.base: - IF null/undefined/empty: Add to missing_list { "category": "typography", "key": "fontSize.base", "priority": "required" } VALIDATE Spacing (REQUIRED per spec 4.2): CHECK: extracted_tokens.spacing exists For each required key in [0, 1, 2, 3, 4, 6, 8, 12, 16]: - CHECK: spacing[key] exists and isValidToken() - IF MISSING: Add { category: "spacing", key: "{key}", priority: "required" } VALIDATE Border Radius (REQUIRED per spec 4.2): CHECK: extracted_tokens.borderRadius exists For each required key in [none, sm, md, lg, xl, full]: - CHECK: borderRadius[key] exists and isValidToken() - IF MISSING: Add { category: "borderRadius", key: "{key}", priority: "required" } VALIDATE Shadow (REQUIRED per spec 4.2): CHECK: extracted_tokens.shadow exists For each required key in [sm, md, lg, xl]: - CHECK: shadow[key] exists and isValidToken() - CHECK: shadow[key].value contains valid box-shadow syntax - IF MISSING: Add { category: "shadow", key: "{key}", priority: "required" } ??VALIDATE Animation (REQUIRED): CHECK: extracted_tokens.animation exists Required checks: 1. animation.duration.fast: - CHECK: exists and value matches pattern /^\d+m?s$/ - IF MISSING: Add { category: "animation", key: "duration.fast", priority: "required" } 2. animation.duration.normal: - CHECK: exists and value matches pattern /^\d+m?s$/ - IF MISSING: Add { category: "animation", key: "duration.normal", priority: "required" } 3. animation.easing.default: - CHECK: exists and value contains "cubic-bezier" or valid keyword - IF MISSING: Add { category: "animation", key: "easing.default", priority: "required" } VALIDATE Breakpoints (REQUIRED per spec 4.2): CHECK: extracted_tokens.breakpoints exists For each required key in [sm, md, lg, xl, 2xl]: - CHECK: breakpoints[key] exists and value matches /^\d+px$/ - IF MISSING: Add { category: "breakpoints", key: "{key}", priority: "required" } ?? Generate Validation Report: Set required_missing = missing_list.filter(item => item.priority === "required") Set recommended_missing = missing_list.filter(item => item.priority === "recommended") ??All REQUIRED tokens validated successfully! Set validation_status = "complete" ??VALIDATION FAILED: {required_missing.length} required token(s) missing: ``` Required Missing Tokens: {required_missing.map(m => ` - [${m.category}] ${m.key}`).join('\n')} ``` Set validation_status = "incomplete" {recommended_missing.length} recommended token(s) missing (will use defaults): ``` Recommended Missing: {recommended_missing.map(m => ` - [${m.category}] ${m.key}`).join('\n')} ``` Store missing_list for Step 4 KB replenishment Initialize replenished_items = [] Initialize kb_query_executed = false Initialize kb_query_failed = false EXTRACT STYLE KEYWORDS from {ux_spec} for KB queries: 1. Search for sections: "Design Philosophy", "Design Principles", "Style", "Visual Direction" 2. Extract style keywords using patterns: - Look for adjectives: modern, minimalist, playful, professional, bold, elegant, etc. - Look for style references: Bauhaus, Material, Apple-like, etc. - Look for industry hints: SaaS, e-commerce, portfolio, dashboard, etc. 3. Build {style} variable from found keywords (fallback: "modern professional") 4. Store {industry} from project context or infer from ux_spec content 5. Store {product_type} from project context or infer from ux_spec content Set {style} = "modern professional" No explicit style keywords found in UX Spec; using fallback: "modern professional" Set {industry} = "general" No industry context found; using fallback: "general" ?? Style Context for KB Queries: - Style: {style} - Industry: {industry} - Product Type: {product_type} Define helper function getDefaultSuggestion(item): switch(item.category): case "colors": return "#0ea5e9" (or appropriate scale value for role) case "typography": return "'Inter', system-ui, sans-serif" case "spacing": return "{item.key * 0.25}rem" (4px base grid) case "borderRadius": return sm=0.125rem, md=0.375rem, lg=0.5rem case "shadow": return Tailwind default shadows case "animation": return fast=150ms, normal=300ms, default easing case "breakpoints": return Tailwind defaults (sm=640px, md=768px, etc.) End function definition Define helper function setNestedToken(obj, keyPath, tokenValue): 1. Split keyPath by "." (e.g., "fontFamily.heading" ??["fontFamily", "heading"]) 2. Traverse obj, creating nested objects as needed 3. Set final key to tokenValue Example: setNestedToken(typography, "fontFamily.heading", {value, type, source}) ??typography.fontFamily.heading = {value, type, source} End function definition CATEGORIZE missing_list by token type: - color_missing = missing_list.filter(m => m.category === "colors") - typography_missing = missing_list.filter(m => m.category === "typography") - spacing_missing = missing_list.filter(m => m.category === "spacing" || m.category === "borderRadius") - shadow_missing = missing_list.filter(m => m.category === "shadow") - animation_missing = missing_list.filter(m => m.category === "animation") - breakpoints_missing = missing_list.filter(m => m.category === "breakpoints") Searching KB for colors... Set kb_query_executed = true Execute query: python {kb_path}/scripts/search.py "{style} {industry} color palette" --domain color --json Set kb_query_failed = true KB search script failed - colors will remain in color_missing for CSV fallback Log error details for debugging Skip KB color processing, proceed to next category No color suggestions found in KB for "{style}" style Continue without KB color suggestions Parse JSON result with structure: ```json { "results": [ { "role": "primary", "value": "#0ea5e9", "scale": { "50": "...", "500": "...", "900": "..." } }, { "role": "secondary", "value": "#6366f1" } ] } ``` For each color found in KB results: - Normalize value to HEX format: If HSL: hsl(h, s%, l%) ??Convert using: R,G,B = hslToRgb(h/360, s/100, l/100), then #RRGGBB If RGB: rgb(r, g, b) ??Convert to #RRGGBB using hex encoding If already HEX: validate format #RGB or #RRGGBB or #RRGGBBAA - Store with proper nesting: - Ensure extracted_tokens.colors[role] exists as an object If scale provided: extracted_tokens.colors[role][scaleKey] = { value, type: "color", source: "kb-suggestion" } If single value: extracted_tokens.colors[role]["500"] = { value, type: "color", source: "kb-suggestion" } - Remove from color_missing list - Append to replenished_items with source: "kb-suggestion" ??Filled {count} color tokens from KB Searching KB for typography... Set kb_query_executed = true Execute: python {kb_path}/scripts/search.py "{style} typography" --domain typography --json Set kb_query_failed = true KB search script failed - typography will remain in typography_missing for CSV fallback Parse JSON result: ```json { "results": [ { "role": "heading", "fontFamily": "'Inter', sans-serif" }, { "role": "body", "fontFamily": "'Inter', sans-serif" } ] } ``` For each typography setting found: - Store: extracted_tokens.typography.fontFamily[role] = { value, type: "fontFamily", source: "kb-suggestion" } - Remove from typography_missing list - Append to replenished_items with source: "kb-suggestion" ??Filled {count} typography tokens from KB ?? Searching KB for spacing and radius... Set kb_query_executed = true Execute: python {kb_path}/scripts/search.py "{style} spacing system" --domain spacing --json Set kb_query_failed = true KB search script failed - spacing/radius will remain in spacing_missing for CSV fallback Parse JSON result and apply Tailwind-compatible scale if found For spacing values: store with type: "spacing", source: "kb-suggestion" For borderRadius values: store with type: "borderRadius", source: "kb-suggestion" Remove filled items from spacing_missing list Append filled spacing/radius items to replenished_items with source: "kb-suggestion" ??Filled {count} spacing/radius tokens from KB ?? Searching KB for shadows... Set kb_query_executed = true Execute: python {kb_path}/scripts/search.py "{style} elevation shadow" --domain elevation --json Set kb_query_failed = true KB search script failed - shadows will remain in shadow_missing for CSV fallback Parse JSON result with box-shadow syntax For each shadow found: - Store: extracted_tokens.shadow[level] = { value: "box-shadow-syntax", type: "boxShadow", source: "kb-suggestion" } - Remove from shadow_missing list - Append to replenished_items with source: "kb-suggestion" ??Filled {count} shadow tokens from KB ??Searching KB for animation settings... Set kb_query_executed = true Execute: python {kb_path}/scripts/search.py "{style} motion animation" --domain animation --json Set kb_query_failed = true KB search script failed - animation will remain in animation_missing for CSV fallback Parse JSON result for duration and easing values For duration values: store with type: "duration", source: "kb-suggestion" For easing values: store with type: "cubicBezier", source: "kb-suggestion" Remove filled items from animation_missing list Append filled animation items to replenished_items with source: "kb-suggestion" ??Filled {count} animation tokens from KB Searching KB for breakpoints... Set kb_query_executed = true Execute: python {kb_path}/scripts/search.py "{style} responsive breakpoints" --domain layout --json Set kb_query_failed = true No breakpoint suggestions found in KB - using Tailwind defaults Apply Tailwind default breakpoints: sm=640px, md=768px, lg=1024px, xl=1280px, 2xl=1536px Mark source as "default" for these values Parse JSON result for breakpoint values For each breakpoint found: - Validate format matches /^\d+px$/ - Store: extracted_tokens.breakpoints[key] = { value, type: "dimension", source: "kb-suggestion" } - Remove from breakpoints_missing list - Append to replenished_items with source: "kb-suggestion" ??Filled {count} breakpoint tokens from KB Knowledge Base not found at {kb_path} KB replenishment unavailable - will proceed with user input and defaults. KB search failed. Choose a recovery option before continuing: [1] Retry KB search [2] Update kb_path and retry [3] Proceed with direct CSV lookup (requires explicit approval) CSV fallback note (minimal): - Reason: KB error summary - CSV used: file + keyword - Hit: row id + fields used - Tokens: affected token list HALT KB search was not executed even though missing tokens exist and KB path is available. Do not proceed with manual CSV lookup. Execute search.py for KB replenishment. HALT Initialize remaining_missing = [] Rebuild remaining_missing by concatenating all category lists after KB queries: remaining_missing = [...color_missing, ...typography_missing, ...spacing_missing, ...shadow_missing, ...animation_missing, ...breakpoints_missing] Filter remaining_missing by priority: required items first, then recommended The following design decisions require your input: | # | Category | Item | Suggested Value | Priority | |---|------|------|--------|--------| {remaining_missing.map((m, i) => `| ${i+1} | ${m.category} | ${m.key} | ${getDefaultSuggestion(m)} | ${m.priority} |`).join('\n')} Input instructions: - Provide values in order (comma or newline separated); enter "d" for default, "s" to skip (not recommended for required items), "d-all" for defaults. Please enter values or commands: For EACH user input value, validate format: COLOR validation: /^#[0-9a-fA-F]{3,8}$/ OR /^hsl\([^)]+\)$/ OR /^rgb\([^)]+\)$/ FONT validation: non-empty string (any font family name accepted) DIMENSION validation: /^\d+(\.\d+)?(px|rem|em)$/ DURATION validation: /^\d+(ms|s)$/ EASING validation: /^cubic-bezier\([^)]+\)$/ OR keywords (ease, ease-in, ease-out, linear) Format error: Item: {item.key} Input: {user_input} Expected format: {expected_format} Options: [r] Re-enter this item [d] Use default [s] Skip this item Please choose [r/d/s]: Handle user choice accordingly Use setNestedToken(extracted_tokens[category], key, { value: user_input, type: token_type, source: "user-input" }) This handles keys like "fontFamily.heading" ??typography.fontFamily.heading Remove item from remaining_missing Append to replenished_items with source: "user-input" Apply default values with source: "default" Default values reference: - colors.primary.500: "#0ea5e9" (Sky Blue) - colors.secondary.500: "#6366f1" (Indigo) - colors.neutral.500: "#64748b" (Slate) - typography.fontFamily.heading: "'Inter', system-ui, sans-serif" - typography.fontFamily.body: "'Inter', system-ui, sans-serif" - typography.fontSize.base: "1rem" - spacing.{n}: "{n * 0.25}rem" (4px base) - borderRadius.sm: "0.125rem", md: "0.375rem", lg: "0.5rem" - shadow.sm: "0 1px 2px 0 rgba(0, 0, 0, 0.05)" - shadow.md: "0 4px 6px -1px rgba(0, 0, 0, 0.1)" - animation.duration.fast: "150ms", normal: "300ms", slow: "500ms" - animation.easing.default: "cubic-bezier(0.4, 0, 0.2, 1)" - breakpoints: sm=640px, md=768px, lg=1024px, xl=1280px Append default-filled items to replenished_items with source: "default" Warning: skipping required item [{item.key}] may lead to incomplete output Confirm skip? [y/n] If confirmed skip: mark item as skipped, proceed without value CALCULATE source statistics: - Count tokens where source === "ux-spec" ??store as ux_count - Count tokens where source === "architecture" ??store as arch_count - Count tokens where source === "kb-suggestion" ??store as kb_count - Count tokens where source === "user-input" ??store as user_count - Count tokens where source === "default" ??store as default_count - Calculate total_count = ux_count + arch_count + kb_count + user_count + default_count **Token Source Statistics:** | Source | Count | Percentage | |------|------|--------| | UX Spec | {ux_count} | {(ux_count/total_count*100).toFixed(1)}% | | Architecture | {arch_count} | {(arch_count/total_count*100).toFixed(1)}% | | KB Suggestion | {kb_count} | {(kb_count/total_count*100).toFixed(1)}% | | User Input | {user_count} | {(user_count/total_count*100).toFixed(1)}% | | Default | {default_count} | {(default_count/total_count*100).toFixed(1)}% | | **Total** | **{total_count}** | **100%** | **Token Category Summary:** | Category | Filled | Source Distribution | |------|--------|----------| | Colors | {colors_count} | {colors_sources} | | Typography | {typography_count} | {typography_sources} | | Spacing | {spacing_count} | {spacing_sources} | | Border Radius | {radius_count} | {radius_sources} | | Shadow | {shadow_count} | {shadow_sources} | | Animation | {animation_count} | {animation_sources} | | Breakpoints | {breakpoints_count} | {breakpoints_sources} | **Replenished Item List:** {replenished_items.map(i => `- [${i.source}] ${i.category}.${i.key}`).join('\n')} **KB Suggestion Notes:** {kb_count} token values were filled from KB suggestions based on "{style}" style search results. You can adjust these values during Step 5 confirmation. **Note:** More than 50% of tokens use default values. Consider improving the UX design spec for more precise design system output. FINALIZE KB TRACKING STATE for Step 7 validation: Set kb_query_executed = true if ANY KB query was attempted in Step 4 Set kb_hits_found = true if ANY KB query returned non-empty results Build kb_hits_for_item = {} tracking per-item KB hit status: For each item in original missing_list: kb_hits_for_item[item.category + "." + item.key] = (KB had hit for this item) Calculate missing_with_kb_hits = count of items where kb_hits_for_item[key] === true Store these variables for Step 7 KB reference rate calculation KB Tracking State: - kb_query_executed: {kb_query_executed} - kb_hits_found: {kb_hits_found} - missing_with_kb_hits: {missing_with_kb_hits} Missing foundational design inputs detected: {missing_list} These gaps can limit output quality. Please consider adding the following web design foundations to help DEV succeed: - Color palette (primary/secondary/neutral scales) - Typography (font families, sizes, line heights, weights) - Spacing system (base unit and scale) - Layout rules (grid, breakpoints, container widths) - Component states (hover/active/disabled/focus) ?? Design System Summary Provide a concise summary of extracted tokens and component specs. Proceed with file generation? [Y/n] HALT Build design_tokens_json from extracted_tokens using W3C Design Token format Ensure "$schema" is set to "https://design-tokens.github.io/community-group/format/" Preserve source field on every token (ux-spec/architecture/kb-suggestion/user-input/default) Write file: {output_folder}/design-tokens.json Created design-tokens.json (SSOT) Generate theme.css from design_tokens_json Map tokens to CSS Custom Properties using naming rules: - colors: --color-{role}-{scale} - typography: --font-family-*, --font-size-*, --font-weight-*, --line-height-* - spacing: --spacing-{key} - borderRadius: --radius-{key} - shadow: --shadow-{key} - animation: --duration-*, --easing-* - breakpoints: --breakpoint-{key} Group variables by section with readable comments Add [data-theme="dark"] overrides for background/surface/text/text-muted if available Write file: {output_folder}/theme.css Created theme.css (CSS Custom Properties) DETECT framework strategy from tech_stack (mutually exclusive): If tech_stack.cssFramework includes "tailwind": set strategy = "tailwind" Else if tech_stack.preprocessor includes "scss" OR "sass": set strategy = "scss" Else: set strategy = "generic" Set is_tailwind = (strategy === "tailwind") Set is_scss = (strategy === "scss") Set is_vanilla = (strategy === "generic") Framework Detection: Strategy={strategy}, Tailwind={is_tailwind}, SCSS={is_scss}, Vanilla={is_vanilla} Generating Tailwind configuration... Generate tailwind.config.ts with theme.extend mapping: 1. Import type { Config } from 'tailwindcss' 2. Map colors using hsl(var(--color-{role}-{scale})) syntax for opacity modifier support: ```typescript // tailwind.config.ts - Auto-generated by Design System Generator import type { Config } from 'tailwindcss' const config: Config = { content: [ './src/**/*.{js,ts,jsx,tsx,mdx}', './app/**/*.{js,ts,jsx,tsx,mdx}', './components/**/*.{js,ts,jsx,tsx,mdx}', ], theme: { extend: { colors: { primary: { 50: 'hsl(var(--color-primary-50))', 100: 'hsl(var(--color-primary-100))', 500: 'hsl(var(--color-primary-500))', 600: 'hsl(var(--color-primary-600))', 700: 'hsl(var(--color-primary-700))', 900: 'hsl(var(--color-primary-900))', DEFAULT: 'hsl(var(--color-primary-500))', }, // ... map all color roles from design-tokens.json }, fontFamily: { heading: 'var(--font-family-heading)', body: 'var(--font-family-body)', mono: 'var(--font-family-mono)', }, fontSize: { // Map from --font-size-* variables }, spacing: { // Map from --spacing-* variables }, borderRadius: { // Map from --radius-* variables }, boxShadow: { // Map from --shadow-* variables }, transitionDuration: { fast: 'var(--duration-fast)', normal: 'var(--duration-normal)', slow: 'var(--duration-slow)', }, transitionTimingFunction: { default: 'var(--easing-default)', }, }, }, plugins: [], } export default config ``` CRITICAL: Use hsl(var(--color-name)) syntax to enable Tailwind opacity modifiers like bg-primary/50 For this to work, theme.css must store colors as HSL values without the hsl() wrapper: --color-primary-500: 199 89% 48%; /* HSL values only, no hsl() */ If theme.css uses hex values, convert to HSL space-separated format in tailwind.config.ts generation Write file: {output_folder}/tailwind.config.ts Created tailwind.config.ts (Tailwind theme extension) Generating SCSS tokens... Generate _tokens.scss with SCSS variable mappings: ```scss // _tokens.scss - Auto-generated by Design System Generator // Import this file in your main SCSS file: @use 'tokens' as *; // ===== Colors ===== $color-primary-50: var(--color-primary-50); $color-primary-500: var(--color-primary-500); // ... map all color scales // ===== Typography ===== $font-family-heading: var(--font-family-heading); $font-family-body: var(--font-family-body); $font-family-mono: var(--font-family-mono); // ===== Spacing ===== $spacing-0: var(--spacing-0); $spacing-1: var(--spacing-1); // ... map all spacing values // ===== Border Radius ===== $radius-sm: var(--radius-sm); $radius-md: var(--radius-md); $radius-lg: var(--radius-lg); // ===== Shadows ===== $shadow-sm: var(--shadow-sm); $shadow-md: var(--shadow-md); $shadow-lg: var(--shadow-lg); // ===== Animation ===== $duration-fast: var(--duration-fast); $duration-normal: var(--duration-normal); $easing-default: var(--easing-default); // ===== Mixins ===== @mixin respond-to($breakpoint) { @if $breakpoint == sm { @media (min-width: 640px) { @content; } } @else if $breakpoint == md { @media (min-width: 768px) { @content; } } @else if $breakpoint == lg { @media (min-width: 1024px) { @content; } } @else if $breakpoint == xl { @media (min-width: 1280px) { @content; } } } ``` Write file: {output_folder}/_tokens.scss Created _tokens.scss (SCSS variables and mixins) Vanilla CSS detected - no framework configuration file needed theme.css provides all CSS Custom Properties for direct use Generate global styles with framework-appropriate content: Generating Tailwind-compatible globals.css... Generate globals.css with Tailwind directives: ```css /* globals.css - Tailwind Integration */ @tailwind base; @tailwind components; @tailwind utilities; /* Import theme variables */ @import './theme.css'; /* ===== Base Layer Customizations ===== */ @layer base { html { font-family: var(--font-family-body); line-height: var(--line-height-normal); } body { background-color: var(--color-background); color: var(--color-text); } :focus-visible { outline: 2px solid var(--color-primary-500); outline-offset: 2px; } } /* ===== Reduced Motion ===== */ @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; } } ``` Generating SCSS globals.scss with reset... Generate globals.scss with Modern CSS Reset and base typography: ```scss /* globals.scss - SCSS with Modern Reset */ @import './theme.css'; /* ===== Modern CSS Reset ===== */ *, *::before, *::after { box-sizing: border-box; } * { margin: 0; padding: 0; } html { font-family: var(--font-family-body); line-height: var(--line-height-normal); } body { min-height: 100vh; background-color: var(--color-background); color: var(--color-text); } img, picture, video, canvas, svg { display: block; max-width: 100%; } input, button, textarea, select { font: inherit; } p, h1, h2, h3, h4, h5, h6 { overflow-wrap: break-word; } /* ===== Typography ===== */ h1, h2, h3, h4, h5, h6 { font-family: var(--font-family-heading); font-weight: var(--font-weight-semibold); } /* ===== Focus Styles (Accessibility) ===== */ :focus-visible { outline: 2px solid var(--color-primary-500); outline-offset: 2px; } /* ===== Reduced Motion ===== */ @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; } } ``` Generating vanilla CSS globals.css with reset... Generate globals.css with Modern CSS Reset and base typography: ```css /* globals.css - Vanilla CSS with Modern Reset */ @import './theme.css'; /* ===== Modern CSS Reset ===== */ *, *::before, *::after { box-sizing: border-box; } * { margin: 0; padding: 0; } html { font-family: var(--font-family-body); line-height: var(--line-height-normal); } body { min-height: 100vh; background-color: var(--color-background); color: var(--color-text); } img, picture, video, canvas, svg { display: block; max-width: 100%; } input, button, textarea, select { font: inherit; } p, h1, h2, h3, h4, h5, h6 { overflow-wrap: break-word; } /* ===== Typography ===== */ h1, h2, h3, h4, h5, h6 { font-family: var(--font-family-heading); font-weight: var(--font-weight-semibold); } /* ===== Focus Styles (Accessibility) ===== */ :focus-visible { outline: 2px solid var(--color-primary-500); outline-offset: 2px; } /* ===== Reduced Motion ===== */ @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; } } ``` Ensure all values reference CSS variables from theme.css (SSOT) Write file: {output_folder}/globals.scss Created globals.scss (Global Styles) Write file: {output_folder}/globals.css Created globals.css (Global Styles) Determine componentLibrary from tech_stack.componentLib (default: "shadcn") Determine effectsLibrary (default: "framer-motion", or "none" if not used) Include "$schema" only if component-specs.schema.json is available (optional) Build component-specs.json with meta and component definitions: - Button: variants (primary/secondary/outline/ghost), sizes (sm/md/lg), states (disabled/loading), animation (hover/tap) - Card: base + variants (elevated/outlined) - Input: base + states (focus/error/disabled) Write file: {output_folder}/component-specs.json Created component-specs.json (Component Definitions) === Step 6 Generation Summary === Framework Strategy: {strategy} Generated Files: {strategy === 'tailwind' ? 'design-tokens.json, theme.css, tailwind.config.ts, globals.css, component-specs.json' : (strategy === 'scss' ? 'design-tokens.json, theme.css, _tokens.scss, globals.scss, component-specs.json' : 'design-tokens.json, theme.css, globals.css, component-specs.json')} Initialize validation_report = { errors: [], warnings: [], metrics: {} } Initialize format_errors = [], completeness_errors = [], kb_errors = [], consistency_errors = [] 📋 VALIDATE JSON SYNTAX: Attempt to parse design-tokens.json as JSON: Extract error line number and message from parse error Add to format_errors: { "type": "SYNTAX", "file": "design-tokens.json", "location": "line {error_line}", "error": "{error_message}", "suggestion": "Check for missing commas, brackets, or invalid characters at the specified location" } Set design_tokens_json_valid = true ✅ design-tokens.json: JSON syntax valid Attempt to parse component-specs.json as JSON: Extract error line number and message from parse error Add to format_errors: { "type": "SYNTAX", "file": "component-specs.json", "location": "line {error_line}", "error": "{error_message}", "suggestion": "Check for missing commas, brackets, or invalid characters at the specified location" } Set component_specs_json_valid = true ✅ component-specs.json: JSON syntax valid 📋 VALIDATE CSS SYNTAX: Validate theme.css CSS syntax: 1. Check bracket balance: count of '{' must equal count of '}' 2. Check property format: each line inside {} should match pattern /^\s*[\w-]+:\s*.+;?\s*$/ or be a comment 3. Check for unclosed comments: /* must have matching */ 4. Check for invalid selectors: selectors should not contain unescaped special characters Add to format_errors: { "type": "SYNTAX", "file": "theme.css", "location": "file-level", "error": "Unbalanced brackets: {open_count} opening vs {close_count} closing", "suggestion": "Check for missing or extra braces" } Add to format_errors: { "type": "SYNTAX", "file": "theme.css", "location": "line {line_number}", "error": "Invalid CSS property format: '{invalid_line}'", "suggestion": "Ensure format is 'property: value;'" } Set theme_css_valid = true ✅ theme.css: CSS syntax valid Validate global styles syntax with detailed location tracking: 1. Initialize globals_line_number = 0 2. For each line in {strategy === 'scss' ? 'globals.scss' : 'globals.css'}: globals_line_number++ Track bracket_depth: '{' increases, '}' decreases 3. Bracket balance check: if final bracket_depth != 0, report unbalanced 4. Comment closure check: verify /* has matching */ 5. If strategy === "scss": skip strict property format checks (allow SCSS variables/nesting) 6. If strategy !== "scss": validate each property line matches /^\s*[\w-]+:\s*.+;?\s*$/ Add to format_errors: { "type": "SYNTAX", "file": "{strategy === 'scss' ? 'globals.scss' : 'globals.css'}", "location": "file-level", "error": "Unbalanced brackets: {open_count} opening vs {close_count} closing", "suggestion": "Check for missing or extra braces" } Add to format_errors: { "type": "SYNTAX", "file": "{strategy === 'scss' ? 'globals.scss' : 'globals.css'}", "location": "line {globals_line_number}", "error": "Invalid CSS property format: '{invalid_line}'", "suggestion": "Ensure format is 'property: value;'" } Set globals_css_valid = true {strategy === 'scss' ? 'globals.scss' : 'globals.css'}: CSS syntax valid 📋 VALIDATE COMPLETENESS (per spec 4.2): Define required_tokens checklist from design-system-generator-spec.md Section 4.2: Required Token Categories: - colors: primary (50/100/500/600/700/900), secondary/accent/neutral/success/warning/error (each 500/600/700) - typography: fontFamily (heading/body/mono), fontSize (xs~4xl), fontWeight (normal/medium/semibold/bold), lineHeight (tight/normal/relaxed) - spacing: 0/1/2/3/4/6/8/12/16 - borderRadius: none/sm/md/lg/xl/full - shadow: sm/md/lg/xl - animation: duration (fast/normal/slow), easing (default/in/out/bounce) - breakpoints: sm/md/lg/xl/2xl CHECK colors completeness: For primary: verify 50, 100, 500, 600, 700, 900 exist For secondary, accent, neutral, success, warning, error: verify 500, 600, 700 exist Add to completeness_errors: { "type": "COMPLETENESS", "category": "colors", "missing": ["{list of missing color scales}"], "suggestion": "Add missing color values or run KB replenishment" } CHECK typography completeness: fontFamily: heading, body, mono fontSize: xs, sm, base, lg, xl, 2xl, 3xl, 4xl fontWeight: normal, medium, semibold, bold lineHeight: tight, normal, relaxed Add missing items to completeness_errors with category: "typography" CHECK spacing completeness: 0, 1, 2, 3, 4, 6, 8, 12, 16 Add missing items to completeness_errors with category: "spacing" CHECK borderRadius completeness: none, sm, md, lg, xl, full Add missing items to completeness_errors with category: "borderRadius" CHECK shadow completeness: sm, md, lg, xl Add missing items to completeness_errors with category: "shadow" CHECK animation completeness: duration: fast, normal, slow easing: default, in, out, bounce Add missing items to completeness_errors with category: "animation" CHECK breakpoints completeness: sm, md, lg, xl, 2xl Add missing items to completeness_errors with category: "breakpoints" CALCULATE completeness metrics at TOKEN-LEVEL: Define total_required_tokens = 73 per spec 4.2: - colors: 6 (primary) + 3*6 (secondary~error) = 24 - typography: 3 (fontFamily) + 8 (fontSize) + 4 (fontWeight) + 3 (lineHeight) = 18 - spacing: 9 (0,1,2,3,4,6,8,12,16) - borderRadius: 6 (none,sm,md,lg,xl,full) - shadow: 4 (sm,md,lg,xl) - animation: 3 (duration) + 4 (easing) = 7 - breakpoints: 5 (sm,md,lg,xl,2xl) Count missing_tokens_count by iterating all required token paths and checking existence found_tokens = 73 - missing_tokens_count completeness_rate = (found_tokens / 73) * 100 Store in validation_report.metrics.completeness_rate Completeness Rate: {completeness_rate}% ({found_tokens}/73 tokens) ?? COMPLETENESS WARNING: {missing_tokens_count} required tokens missing Missing tokens by category: {completeness_errors.map(e => ` - [${e.category}] ${e.missing.join(', ')}`).join('\n')} Suggestion: Add missing token paths with source (ux-spec/kb-suggestion/user-input/default) 📋 VALIDATE KB REFERENCE (P0 Risk Control): Retrieve kb_query_executed and kb_hits_found from Step 4 execution state Count tokens with source === "kb-suggestion" as kb_sourced_count Count tokens from missing_list that had KB hits as missing_with_kb_hits Add to kb_errors: { "type": "KB_REFERENCE", "error": "KB had hits but no tokens use source: kb-suggestion", "detail": "KB query returned results for style '{style}' but output tokens do not reflect KB suggestions", "suggestion": "Review Step 4 KB replenishment logic - KB hits should be applied to extracted_tokens" } ❌ KB REFERENCE ERROR: KB had hits but no tokens use source: kb-suggestion â„šī¸ KB Query: No hits found for style '{style}' - fallback sources allowed No KB reference error - user-input and default sources are permitted CALCULATE KB reference rate: kb_reference_rate = (kb_sourced_count / missing_with_kb_hits) * 100 Store in validation_report.metrics.kb_reference_rate 📊 KB Reference Rate: {kb_reference_rate}% ({kb_sourced_count}/{missing_with_kb_hits} tokens from KB) âš ī¸ KB Reference Rate below target (70%) Add warning to validation_report.warnings â„šī¸ KB Reference Rate: N/A (no tokens required KB replenishment or KB had no hits) Set kb_reference_rate = "N/A" in validation_report.metrics 📋 VALIDATE CONTENT CONSISTENCY: CHECK theme.css custom properties match design-tokens.json: 1. Extract all CSS custom properties from theme.css (--color-*, --font-*, --spacing-*, etc.) 2. For each custom property, verify corresponding token exists in design-tokens.json 3. Verify values are consistent (allow for format differences like #hex vs rgb) Add to consistency_errors: { "type": "CONTENT_CONSISTENCY", "file": "theme.css", "error": "Custom property '{property_name}' not found in design-tokens.json", "suggestion": "Add corresponding token or remove orphan custom property" } CHECK design-tokens.json tokens have corresponding CSS custom properties (reverse check): 1. For each token in design-tokens.json: - Build expected CSS property name using naming convention: * colors.{role}.{scale} -> --color-{role}-{scale} * typography.fontFamily.{key} -> --font-family-{key} * typography.fontSize.{key} -> --font-size-{key} * spacing.{key} -> --spacing-{key} * borderRadius.{key} -> --radius-{key} * shadow.{key} -> --shadow-{key} * animation.duration.{key} -> --duration-{key} * animation.easing.{key} -> --easing-{key} * breakpoints.{key} -> --breakpoint-{key} 2. Verify the expected CSS property exists in theme.css Add to consistency_errors: { "type": "CONTENT_CONSISTENCY", "file": "theme.css", "error": "Token '{token_path}' has no corresponding CSS custom property '{expected_css_property}'", "suggestion": "Add CSS custom property '{expected_css_property}' to theme.css :root selector" } CHECK theme.css contains dark theme variant: Search for [data-theme="dark"] or .dark or @media (prefers-color-scheme: dark) Add to consistency_errors: { "type": "CONTENT_CONSISTENCY", "file": "theme.css", "error": "Dark theme variant not found", "suggestion": "Add [data-theme=\"dark\"] section with color overrides" } ✅ theme.css: Dark theme variant present CHECK global styles file contains required content: 1. CSS Reset: search for "box-sizing: border-box" and "margin: 0" Add to consistency_errors: { "type": "CONTENT_CONSISTENCY", "file": "{strategy === 'scss' ? 'globals.scss' : 'globals.css'}", "error": "CSS reset not found", "suggestion": "Add modern CSS reset (box-sizing, margin reset)" } 2. Focus styles: search for ":focus-visible" or ":focus" Add to consistency_errors: { "type": "CONTENT_CONSISTENCY", "file": "{strategy === 'scss' ? 'globals.scss' : 'globals.css'}", "error": "Focus styles for accessibility not found", "suggestion": "Add :focus-visible styles for keyboard navigation accessibility" } 3. Reduced motion: search for "prefers-reduced-motion" Add to consistency_errors: { "type": "CONTENT_CONSISTENCY", "file": "{strategy === 'scss' ? 'globals.scss' : 'globals.css'}", "error": "Reduced motion media query not found", "suggestion": "Add @media (prefers-reduced-motion: reduce) for accessibility" } {strategy === 'scss' ? 'globals.scss' : 'globals.css'}: CSS reset and accessibility styles present CHECK component-specs.json covers core components: Required components: Button, Card, Input Add to consistency_errors: { "type": "CONTENT_CONSISTENCY", "file": "component-specs.json", "error": "Required component '{component_name}' not found", "suggestion": "Add {component_name} component specification with base styles and variants" } ✅ component-specs.json: All core components (Button, Card, Input) present 📋 GENERATE VALIDATION REPORT: Combine all error arrays: all_errors = [...format_errors, ...completeness_errors, ...kb_errors, ...consistency_errors] format_correct_count = (design_tokens_json_valid ? 1 : 0) + (component_specs_json_valid ? 1 : 0) + (theme_css_valid ? 1 : 0) + (globals_css_valid ? 1 : 0) format_correctness_rate = (format_correct_count / 4) * 100 Store in validation_report.metrics.format_correctness_rate ❌ VALIDATION ERRORS FOUND: {all_errors.length} issue(s) Error Details: For each error in all_errors: --- Type: {error.type} File: {error.file || 'N/A'} Location: {error.location || 'N/A'} Error: {error.error} Suggestion: {error.suggestion} --- =============================================================== VALIDATION REPORT SUMMARY =============================================================== | Metric | Target | Actual | Status | |---------------------|---------|---------------------|--------| | KB Reference Rate | > 70% | {kb_reference_rate}%| {kb_reference_rate === 'N/A' ? 'âŦœ N/A' : (kb_reference_rate >= 70 ? '✅ PASS' : 'âš ī¸ BELOW')} | | Completeness | 100% | {completeness_rate}%| {completeness_rate === 100 ? '✅ PASS' : '❌ FAIL'} | | Format Correctness | 100% | {format_correctness_rate}%| {format_correctness_rate === 100 ? '✅ PASS' : '❌ FAIL'} | | Content Consistency | 100% | {consistency_errors.length === 0 ? '100%' : 'Issues'}| {consistency_errors.length === 0 ? '✅ PASS' : 'âš ī¸ ISSUES'} | =============================================================== ASSESS Dev Usability (composite metric): 1. Output file coverage: 4/4 files generated? 2. JSON/CSS lint: format_correctness_rate === 100? 3. No blocking errors: format_errors.length === 0? ✅ DEV USABILITY: READY All output files are valid and complete. Dev Agent can proceed with implementation. Set validation_report.dev_usability = "READY" ❌ DEV USABILITY: BLOCKED Output files have syntax errors that must be fixed before use. See error details above for specific issues and suggestions. Set validation_report.dev_usability = "BLOCKED" âš ī¸ DEV USABILITY: USABLE WITH GAPS Output files are syntactically valid but incomplete. Dev Agent may need to add missing tokens during implementation. Consider running KB replenishment or providing missing values. Set validation_report.dev_usability = "USABLE_WITH_GAPS" Validate against checklist at {validation} using {project-root}/_bmad/core/tasks/validate-workflow.xml ??Design System Generation Complete! Generated files in: {output_folder} 1. design-tokens.json (SSOT) 2. theme.css (Variables) 3. tailwind.config.ts (Tailwind theme extension) 4. globals.css (Global Styles) 5. component-specs.json (Component Definitions) 1. design-tokens.json (SSOT) 2. theme.css (Variables) 3. _tokens.scss (SCSS variables and mixins) 4. globals.scss (Global Styles) 5. component-specs.json (Component Definitions) 1. design-tokens.json (SSOT) 2. theme.css (Variables) 3. globals.css (Global Styles) 4. component-specs.json (Component Definitions) Report completion