mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-11 02:33:51 +08:00
refactor: 重构UI设计工作流的交互模式和字段架构
主要变更: 1. animation-extract.md 重构交互流程 - Phase 2 交互从Agent移至主流程(参考artifacts.md模式) - 使用【问题N - 标签】格式,提供方向性指导而非具体示例 - Phase 3 Agent改为纯合成任务(无用户交互) - 保留独立的animation-tokens.json输出 2. style-extract.md 字段扩展优化 - 保留字段扩展:typography.combinations、opacity、component_styles、border_radius、shadows - 移除animations字段(由专门的animation-tokens.json提供) - 完善design-tokens.json格式文档 3. generate.md 支持新字段 - 保留animation-tokens.json可选加载 - 支持typography.combinations、opacity、component_styles - 生成对应CSS类(组件样式类、排版预设类) 4. batch-generate.md 字段支持 - 解析新的design-tokens字段结构 - 使用组件预设和排版预设 架构改进: - 清晰分离:design-tokens.json(基础设计系统)+ animation-tokens.json(动画配置) - 主流程交互:用户决策在主流程完成,Agent只负责合成 - 字段完整性:保留所有设计系统扩展字段 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -170,128 +170,318 @@ ELSE:
|
|||||||
extraction_insufficient = true
|
extraction_insufficient = true
|
||||||
```
|
```
|
||||||
|
|
||||||
### Step 2: Interactive Question Workflow (Agent)
|
### Step 2: Generate Animation Questions (Main Flow)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# If extraction failed or insufficient, use interactive questioning
|
# If extraction failed or insufficient, use interactive questioning
|
||||||
IF extraction_insufficient OR extraction_mode == "interactive":
|
IF extraction_insufficient OR extraction_mode == "interactive":
|
||||||
REPORT: "🤔 Launching interactive animation specification mode"
|
REPORT: "🤔 Interactive animation specification mode"
|
||||||
|
REPORT: " Context: {has_design_context ? 'Aligning with design tokens' : 'Standalone animation system'}"
|
||||||
|
REPORT: " Focus: {focus_types}"
|
||||||
|
|
||||||
# Launch ui-design-agent for interactive questioning
|
# Determine question categories based on focus_types
|
||||||
Task(ui-design-agent): `
|
question_categories = []
|
||||||
[ANIMATION_SPECIFICATION_TASK]
|
IF "all" IN focus_types OR "transitions" IN focus_types:
|
||||||
Guide user through animation design decisions via structured questions
|
question_categories.append("timing_scale")
|
||||||
|
question_categories.append("easing_philosophy")
|
||||||
|
|
||||||
SESSION: {session_id} | MODE: interactive | BASE_PATH: {base_path}
|
IF "all" IN focus_types OR "interactions" IN focus_types OR "hover" IN focus_types:
|
||||||
|
question_categories.append("button_interactions")
|
||||||
|
question_categories.append("card_interactions")
|
||||||
|
question_categories.append("input_interactions")
|
||||||
|
|
||||||
## Context
|
IF "all" IN focus_types OR "page" IN focus_types:
|
||||||
- Design tokens available: {has_design_context}
|
question_categories.append("page_transitions")
|
||||||
- Focus areas: {focus_types}
|
|
||||||
- Extracted data: {animations_extracted ? "Partial CSS data available" : "No CSS data"}
|
|
||||||
|
|
||||||
## Interactive Workflow
|
IF "all" IN focus_types OR "loading" IN focus_types:
|
||||||
|
question_categories.append("loading_states")
|
||||||
|
|
||||||
For each animation category, ASK user and WAIT for response:
|
IF "all" IN focus_types OR "scroll" IN focus_types:
|
||||||
|
question_categories.append("scroll_animations")
|
||||||
|
```
|
||||||
|
|
||||||
### 1. Transition Duration Scale
|
### Step 3: Output Questions in Text Format (Main Flow)
|
||||||
QUESTION: "What timing scale feels right for your design?"
|
|
||||||
OPTIONS:
|
|
||||||
- "Fast & Snappy" (100-200ms transitions)
|
|
||||||
- "Balanced" (200-400ms transitions)
|
|
||||||
- "Smooth & Deliberate" (400-600ms transitions)
|
|
||||||
- "Custom" (specify values)
|
|
||||||
|
|
||||||
### 2. Easing Philosophy
|
```markdown
|
||||||
QUESTION: "What easing style matches your brand?"
|
# Generate and output structured questions
|
||||||
OPTIONS:
|
REPORT: ""
|
||||||
- "Linear" (constant speed, technical feel)
|
REPORT: "===== 动画规格交互式配置 ====="
|
||||||
- "Ease-Out" (fast start, natural feel)
|
REPORT: ""
|
||||||
- "Ease-In-Out" (balanced, polished feel)
|
|
||||||
- "Spring/Bounce" (playful, modern feel)
|
|
||||||
- "Custom" (specify cubic-bezier)
|
|
||||||
|
|
||||||
### 3. Common Interactions (Ask for each)
|
question_number = 1
|
||||||
FOR interaction IN ["button-hover", "link-hover", "card-hover", "modal-open", "dropdown-toggle"]:
|
questions_output = []
|
||||||
QUESTION: "How should {interaction} animate?"
|
|
||||||
OPTIONS:
|
|
||||||
- "Subtle" (color/opacity change only)
|
|
||||||
- "Lift" (scale + shadow increase)
|
|
||||||
- "Slide" (transform translateY)
|
|
||||||
- "Fade" (opacity transition)
|
|
||||||
- "None" (no animation)
|
|
||||||
- "Custom" (describe behavior)
|
|
||||||
|
|
||||||
### 4. Page Transitions
|
# Q1: Timing Scale (if included)
|
||||||
QUESTION: "Should page/route changes have animations?"
|
IF "timing_scale" IN question_categories:
|
||||||
IF YES:
|
REPORT: "【问题{question_number} - 时间尺度】您的设计需要什么样的过渡速度?"
|
||||||
ASK: "What style?"
|
REPORT: "a) 快速敏捷"
|
||||||
OPTIONS:
|
REPORT: " 说明:100-200ms 过渡,适合工具型应用和即时反馈场景"
|
||||||
- "Fade" (crossfade between views)
|
REPORT: "b) 平衡适中"
|
||||||
- "Slide" (swipe left/right)
|
REPORT: " 说明:200-400ms 过渡,通用选择,符合多数用户预期"
|
||||||
- "Zoom" (scale in/out)
|
REPORT: "c) 流畅舒缓"
|
||||||
- "None"
|
REPORT: " 说明:400-600ms 过渡,适合品牌展示和沉浸式体验"
|
||||||
|
REPORT: "d) 自定义"
|
||||||
|
REPORT: " 说明:需要指定具体数值和使用场景"
|
||||||
|
REPORT: ""
|
||||||
|
questions_output.append({id: question_number, category: "timing_scale", options: ["a", "b", "c", "d"]})
|
||||||
|
question_number += 1
|
||||||
|
|
||||||
### 5. Loading States
|
# Q2: Easing Philosophy (if included)
|
||||||
QUESTION: "What loading animation style?"
|
IF "easing_philosophy" IN question_categories:
|
||||||
OPTIONS:
|
REPORT: "【问题{question_number} - 缓动风格】哪种缓动曲线符合您的品牌调性?"
|
||||||
- "Spinner" (rotating circle)
|
REPORT: "a) 线性匀速"
|
||||||
- "Pulse" (opacity pulse)
|
REPORT: " 说明:恒定速度,技术感和精确性,适合数据可视化"
|
||||||
- "Skeleton" (shimmer effect)
|
REPORT: "b) 快入慢出"
|
||||||
- "Progress Bar" (linear fill)
|
REPORT: " 说明:快速启动自然减速,最接近物理世界,通用推荐"
|
||||||
- "Custom" (describe)
|
REPORT: "c) 慢入慢出"
|
||||||
|
REPORT: " 说明:平滑对称,精致优雅,适合高端品牌"
|
||||||
|
REPORT: "d) 弹性效果"
|
||||||
|
REPORT: " 说明:Spring/Bounce 回弹,活泼现代,适合互动性强的应用"
|
||||||
|
REPORT: ""
|
||||||
|
questions_output.append({id: question_number, category: "easing_philosophy", options: ["a", "b", "c", "d"]})
|
||||||
|
question_number += 1
|
||||||
|
|
||||||
### 6. Micro-interactions
|
# Q3-5: Interaction Animations (button, card, input - if included)
|
||||||
QUESTION: "Should form inputs have micro-interactions?"
|
IF "button_interactions" IN question_categories:
|
||||||
IF YES:
|
REPORT: "【问题{question_number} - 按钮交互】按钮悬停/点击时如何反馈?"
|
||||||
ASK: "What interactions?"
|
REPORT: "a) 微妙变化"
|
||||||
OPTIONS:
|
REPORT: " 说明:仅颜色/透明度变化,适合简约设计"
|
||||||
- "Focus state animation" (border/shadow transition)
|
REPORT: "b) 抬升效果"
|
||||||
- "Error shake" (horizontal shake on error)
|
REPORT: " 说明:轻微缩放+阴影加深,增强物理感知"
|
||||||
- "Success check" (checkmark animation)
|
REPORT: "c) 滑动移位"
|
||||||
- "All of the above"
|
REPORT: " 说明:Transform translateY,视觉引导明显"
|
||||||
|
REPORT: "d) 无动画"
|
||||||
|
REPORT: " 说明:静态交互,性能优先或特定品牌要求"
|
||||||
|
REPORT: ""
|
||||||
|
questions_output.append({id: question_number, category: "button_interactions", options: ["a", "b", "c", "d"]})
|
||||||
|
question_number += 1
|
||||||
|
|
||||||
### 7. Scroll Animations
|
IF "card_interactions" IN question_categories:
|
||||||
QUESTION: "Should elements animate on scroll?"
|
REPORT: "【问题{question_number} - 卡片交互】卡片悬停时的动画效果?"
|
||||||
IF YES:
|
REPORT: "a) 阴影加深"
|
||||||
ASK: "What scroll animation style?"
|
REPORT: " 说明:Box-shadow 变化,层次感增强"
|
||||||
OPTIONS:
|
REPORT: "b) 上浮效果"
|
||||||
- "Fade In" (opacity 0→1)
|
REPORT: " 说明:Transform translateY(-4px),明显的空间层次"
|
||||||
- "Slide Up" (translateY + fade)
|
REPORT: "c) 缩放放大"
|
||||||
- "Scale In" (scale 0.9→1 + fade)
|
REPORT: " 说明:Scale(1.02),突出焦点内容"
|
||||||
- "Stagger" (sequential delays)
|
REPORT: "d) 无动画"
|
||||||
- "None"
|
REPORT: " 说明:静态卡片,性能或设计考量"
|
||||||
|
REPORT: ""
|
||||||
|
questions_output.append({id: question_number, category: "card_interactions", options: ["a", "b", "c", "d"]})
|
||||||
|
question_number += 1
|
||||||
|
|
||||||
## Output Generation
|
IF "input_interactions" IN question_categories:
|
||||||
|
REPORT: "【问题{question_number} - 表单交互】输入框是否需要微交互反馈?"
|
||||||
|
REPORT: "a) 聚焦动画"
|
||||||
|
REPORT: " 说明:边框/阴影过渡,清晰的状态指示"
|
||||||
|
REPORT: "b) 错误抖动"
|
||||||
|
REPORT: " 说明:水平shake动画,错误提示更明显"
|
||||||
|
REPORT: "c) 成功勾选"
|
||||||
|
REPORT: " 说明:Checkmark 动画,完成反馈"
|
||||||
|
REPORT: "d) 全部包含"
|
||||||
|
REPORT: " 说明:聚焦+错误+成功的完整反馈体系"
|
||||||
|
REPORT: "e) 无微交互"
|
||||||
|
REPORT: " 说明:标准表单,无额外动画"
|
||||||
|
REPORT: ""
|
||||||
|
questions_output.append({id: question_number, category: "input_interactions", options: ["a", "b", "c", "d", "e"]})
|
||||||
|
question_number += 1
|
||||||
|
|
||||||
Based on user responses, generate structured data:
|
# Q6: Page Transitions (if included)
|
||||||
|
IF "page_transitions" IN question_categories:
|
||||||
|
REPORT: "【问题{question_number} - 页面过渡】页面/路由切换是否需要过渡动画?"
|
||||||
|
REPORT: "a) 淡入淡出"
|
||||||
|
REPORT: " 说明:Crossfade 效果,平滑过渡不突兀"
|
||||||
|
REPORT: "b) 滑动切换"
|
||||||
|
REPORT: " 说明:Swipe left/right,方向性导航"
|
||||||
|
REPORT: "c) 缩放过渡"
|
||||||
|
REPORT: " 说明:Scale in/out,空间层次感"
|
||||||
|
REPORT: "d) 无过渡"
|
||||||
|
REPORT: " 说明:即时切换,性能优先"
|
||||||
|
REPORT: ""
|
||||||
|
questions_output.append({id: question_number, category: "page_transitions", options: ["a", "b", "c", "d"]})
|
||||||
|
question_number += 1
|
||||||
|
|
||||||
1. Create animation-specification.json with user choices:
|
# Q7: Loading States (if included)
|
||||||
- timing_scale (fast/balanced/slow/custom)
|
IF "loading_states" IN question_categories:
|
||||||
- easing_philosophy (linear/ease-out/ease-in-out/spring)
|
REPORT: "【问题{question_number} - 加载状态】加载时使用何种动画风格?"
|
||||||
- interactions: {interaction_name: {type, properties, timing}}
|
REPORT: "a) 旋转加载器"
|
||||||
- page_transitions: {enabled, style, duration}
|
REPORT: " 说明:Spinner 圆形旋转,通用加载指示"
|
||||||
- loading_animations: {style, duration}
|
REPORT: "b) 脉冲闪烁"
|
||||||
- scroll_animations: {enabled, style, stagger_delay}
|
REPORT: " 说明:Opacity pulse,轻量级反馈"
|
||||||
|
REPORT: "c) 骨架屏"
|
||||||
|
REPORT: " 说明:Shimmer effect,内容占位预览"
|
||||||
|
REPORT: "d) 进度条"
|
||||||
|
REPORT: " 说明:Linear fill,进度量化展示"
|
||||||
|
REPORT: ""
|
||||||
|
questions_output.append({id: question_number, category: "loading_states", options: ["a", "b", "c", "d"]})
|
||||||
|
question_number += 1
|
||||||
|
|
||||||
2. Write to {base_path}/.intermediates/animation-analysis/animation-specification.json
|
# Q8: Scroll Animations (if included)
|
||||||
|
IF "scroll_animations" IN question_categories:
|
||||||
|
REPORT: "【问题{question_number} - 滚动动画】元素是否在滚动时触发动画?"
|
||||||
|
REPORT: "a) 淡入出现"
|
||||||
|
REPORT: " 说明:Opacity 0→1,渐进式内容呈现"
|
||||||
|
REPORT: "b) 上滑出现"
|
||||||
|
REPORT: " 说明:TranslateY + fade,方向性引导"
|
||||||
|
REPORT: "c) 缩放淡入"
|
||||||
|
REPORT: " 说明:Scale 0.9→1 + fade,聚焦效果"
|
||||||
|
REPORT: "d) 交错延迟"
|
||||||
|
REPORT: " 说明:Stagger 序列动画,列表渐次呈现"
|
||||||
|
REPORT: "e) 无滚动动画"
|
||||||
|
REPORT: " 说明:静态内容,性能或可访问性考量"
|
||||||
|
REPORT: ""
|
||||||
|
questions_output.append({id: question_number, category: "scroll_animations", options: ["a", "b", "c", "d", "e"]})
|
||||||
|
question_number += 1
|
||||||
|
|
||||||
## Critical Requirements
|
REPORT: "支持格式:"
|
||||||
- ✅ Use Write() tool immediately for specification file
|
REPORT: "- 空格分隔:1a 2b 3c"
|
||||||
- ✅ Wait for user response after EACH question before proceeding
|
REPORT: "- 逗号分隔:1a,2b,3c"
|
||||||
- ✅ Validate responses and ask for clarification if needed
|
REPORT: "- 自由组合:1a 2b,3c"
|
||||||
- ✅ Provide sensible defaults if user skips questions
|
REPORT: ""
|
||||||
- ❌ NO external research or MCP calls
|
REPORT: "请输入您的选择:"
|
||||||
`
|
```
|
||||||
|
|
||||||
|
### Step 4: Wait for User Input (Main Flow)
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
# Wait for user input
|
||||||
|
user_raw_input = WAIT_FOR_USER_INPUT()
|
||||||
|
|
||||||
|
# Store raw input for debugging
|
||||||
|
REPORT: "收到输入: {user_raw_input}"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 5: Parse User Answers (Main Flow)
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
# Intelligent input parsing (support multiple formats)
|
||||||
|
answers = {}
|
||||||
|
|
||||||
|
# Parse input using intelligent matching
|
||||||
|
# Support formats: "1a 2b 3c", "1a,2b,3c", "1a 2b,3c"
|
||||||
|
parsed_responses = PARSE_USER_INPUT(user_raw_input, questions_output)
|
||||||
|
|
||||||
|
# Validate parsing
|
||||||
|
IF parsed_responses.is_valid:
|
||||||
|
# Map question numbers to categories
|
||||||
|
FOR response IN parsed_responses.answers:
|
||||||
|
question_id = response.question_id
|
||||||
|
selected_option = response.option
|
||||||
|
|
||||||
|
# Find category for this question
|
||||||
|
FOR question IN questions_output:
|
||||||
|
IF question.id == question_id:
|
||||||
|
category = question.category
|
||||||
|
answers[category] = selected_option
|
||||||
|
REPORT: "✅ 问题{question_id} ({category}): 选择 {selected_option}"
|
||||||
|
break
|
||||||
|
ELSE:
|
||||||
|
REPORT: "❌ 输入格式无法识别,请参考格式示例重新输入:"
|
||||||
|
REPORT: " 示例:1a 2b 3c 4d"
|
||||||
|
# Return to Step 3 for re-input
|
||||||
|
GOTO Step 3
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 6: Write Animation Specification (Main Flow)
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
# Map user choices to specification structure
|
||||||
|
specification = {
|
||||||
|
"metadata": {
|
||||||
|
"source": "interactive",
|
||||||
|
"timestamp": NOW(),
|
||||||
|
"focus_types": focus_types,
|
||||||
|
"has_design_context": has_design_context
|
||||||
|
},
|
||||||
|
"timing_scale": MAP_TIMING_SCALE(answers.timing_scale),
|
||||||
|
"easing_philosophy": MAP_EASING_PHILOSOPHY(answers.easing_philosophy),
|
||||||
|
"interactions": {
|
||||||
|
"button": MAP_BUTTON_INTERACTION(answers.button_interactions),
|
||||||
|
"card": MAP_CARD_INTERACTION(answers.card_interactions),
|
||||||
|
"input": MAP_INPUT_INTERACTION(answers.input_interactions)
|
||||||
|
},
|
||||||
|
"page_transitions": MAP_PAGE_TRANSITIONS(answers.page_transitions),
|
||||||
|
"loading_animations": MAP_LOADING_STATES(answers.loading_states),
|
||||||
|
"scroll_animations": MAP_SCROLL_ANIMATIONS(answers.scroll_animations)
|
||||||
|
}
|
||||||
|
|
||||||
|
# Mapping functions (inline logic)
|
||||||
|
FUNCTION MAP_TIMING_SCALE(option):
|
||||||
|
SWITCH option:
|
||||||
|
CASE "a": RETURN {scale: "fast", base_duration: "150ms", range: "100-200ms"}
|
||||||
|
CASE "b": RETURN {scale: "balanced", base_duration: "300ms", range: "200-400ms"}
|
||||||
|
CASE "c": RETURN {scale: "smooth", base_duration: "500ms", range: "400-600ms"}
|
||||||
|
CASE "d": RETURN {scale: "custom", base_duration: "300ms", note: "User to provide values"}
|
||||||
|
|
||||||
|
FUNCTION MAP_EASING_PHILOSOPHY(option):
|
||||||
|
SWITCH option:
|
||||||
|
CASE "a": RETURN {style: "linear", curve: "linear"}
|
||||||
|
CASE "b": RETURN {style: "ease-out", curve: "cubic-bezier(0, 0, 0.2, 1)"}
|
||||||
|
CASE "c": RETURN {style: "ease-in-out", curve: "cubic-bezier(0.4, 0, 0.2, 1)"}
|
||||||
|
CASE "d": RETURN {style: "spring", curve: "cubic-bezier(0.34, 1.56, 0.64, 1)"}
|
||||||
|
|
||||||
|
FUNCTION MAP_BUTTON_INTERACTION(option):
|
||||||
|
SWITCH option:
|
||||||
|
CASE "a": RETURN {type: "subtle", properties: ["color", "background-color", "opacity"]}
|
||||||
|
CASE "b": RETURN {type: "lift", properties: ["transform", "box-shadow"], transform: "scale(1.02)"}
|
||||||
|
CASE "c": RETURN {type: "slide", properties: ["transform"], transform: "translateY(-2px)"}
|
||||||
|
CASE "d": RETURN {type: "none", properties: []}
|
||||||
|
|
||||||
|
FUNCTION MAP_CARD_INTERACTION(option):
|
||||||
|
SWITCH option:
|
||||||
|
CASE "a": RETURN {type: "shadow", properties: ["box-shadow"]}
|
||||||
|
CASE "b": RETURN {type: "float", properties: ["transform", "box-shadow"], transform: "translateY(-4px)"}
|
||||||
|
CASE "c": RETURN {type: "scale", properties: ["transform"], transform: "scale(1.02)"}
|
||||||
|
CASE "d": RETURN {type: "none", properties: []}
|
||||||
|
|
||||||
|
FUNCTION MAP_INPUT_INTERACTION(option):
|
||||||
|
SWITCH option:
|
||||||
|
CASE "a": RETURN {enabled: ["focus"], focus: {properties: ["border-color", "box-shadow"]}}
|
||||||
|
CASE "b": RETURN {enabled: ["error"], error: {animation: "shake", keyframes: "translateX"}}
|
||||||
|
CASE "c": RETURN {enabled: ["success"], success: {animation: "checkmark", keyframes: "draw"}}
|
||||||
|
CASE "d": RETURN {enabled: ["focus", "error", "success"]}
|
||||||
|
CASE "e": RETURN {enabled: []}
|
||||||
|
|
||||||
|
FUNCTION MAP_PAGE_TRANSITIONS(option):
|
||||||
|
SWITCH option:
|
||||||
|
CASE "a": RETURN {enabled: true, style: "fade", animation: "fadeIn/fadeOut"}
|
||||||
|
CASE "b": RETURN {enabled: true, style: "slide", animation: "slideLeft/slideRight"}
|
||||||
|
CASE "c": RETURN {enabled: true, style: "zoom", animation: "zoomIn/zoomOut"}
|
||||||
|
CASE "d": RETURN {enabled: false}
|
||||||
|
|
||||||
|
FUNCTION MAP_LOADING_STATES(option):
|
||||||
|
SWITCH option:
|
||||||
|
CASE "a": RETURN {style: "spinner", animation: "rotate", keyframes: "360deg"}
|
||||||
|
CASE "b": RETURN {style: "pulse", animation: "pulse", keyframes: "opacity"}
|
||||||
|
CASE "c": RETURN {style: "skeleton", animation: "shimmer", keyframes: "gradient-shift"}
|
||||||
|
CASE "d": RETURN {style: "progress", animation: "fill", keyframes: "width"}
|
||||||
|
|
||||||
|
FUNCTION MAP_SCROLL_ANIMATIONS(option):
|
||||||
|
SWITCH option:
|
||||||
|
CASE "a": RETURN {enabled: true, style: "fade", animation: "fadeIn"}
|
||||||
|
CASE "b": RETURN {enabled: true, style: "slideUp", animation: "slideUp", transform: "translateY(20px)"}
|
||||||
|
CASE "c": RETURN {enabled: true, style: "scaleIn", animation: "scaleIn", transform: "scale(0.9)"}
|
||||||
|
CASE "d": RETURN {enabled: true, style: "stagger", animation: "fadeIn", stagger_delay: "100ms"}
|
||||||
|
CASE "e": RETURN {enabled: false}
|
||||||
|
|
||||||
|
# Write specification file
|
||||||
|
output_path = "{base_path}/.intermediates/animation-analysis/animation-specification.json"
|
||||||
|
Write(output_path, JSON.stringify(specification, indent=2))
|
||||||
|
|
||||||
|
REPORT: "✅ Animation specification saved to {output_path}"
|
||||||
|
REPORT: " Proceeding to token synthesis..."
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
**Phase 2 Output**: `animation-specification.json` (user preferences)
|
**Phase 2 Output**: `animation-specification.json` (user preferences)
|
||||||
|
|
||||||
## Phase 3: Animation Token Synthesis (Agent)
|
## Phase 3: Animation Token Synthesis (Agent - No User Interaction)
|
||||||
|
|
||||||
**Executor**: `Task(ui-design-agent)` for token generation
|
**Executor**: `Task(ui-design-agent)` for token generation
|
||||||
|
|
||||||
|
**⚠️ CRITICAL**: This phase has NO user interaction. Agent only reads existing data and generates tokens.
|
||||||
|
|
||||||
### Step 1: Load All Input Sources
|
### Step 1: Load All Input Sources
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -305,61 +495,96 @@ IF animations_extracted:
|
|||||||
user_specification = null
|
user_specification = null
|
||||||
IF exists({base_path}/.intermediates/animation-analysis/animation-specification.json):
|
IF exists({base_path}/.intermediates/animation-analysis/animation-specification.json):
|
||||||
user_specification = Read(file)
|
user_specification = Read(file)
|
||||||
|
REPORT: "✅ Loaded user specification from Phase 2"
|
||||||
|
ELSE:
|
||||||
|
REPORT: "⚠️ No user specification found - using extracted CSS only"
|
||||||
|
|
||||||
design_tokens = null
|
design_tokens = null
|
||||||
IF has_design_context:
|
IF has_design_context:
|
||||||
design_tokens = Read({base_path}/style-extraction/style-1/design-tokens.json)
|
design_tokens = Read({base_path}/style-extraction/style-1/design-tokens.json)
|
||||||
```
|
```
|
||||||
|
|
||||||
### Step 2: Launch Token Generation Task
|
### Step 2: Launch Token Generation Task (Pure Synthesis)
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
Task(ui-design-agent): `
|
Task(ui-design-agent): `
|
||||||
[ANIMATION_TOKEN_GENERATION_TASK]
|
[ANIMATION_TOKEN_GENERATION_TASK]
|
||||||
Synthesize all animation data into production-ready animation tokens
|
Synthesize animation data into production-ready tokens - NO user interaction
|
||||||
|
|
||||||
SESSION: {session_id} | BASE_PATH: {base_path}
|
SESSION: {session_id} | BASE_PATH: {base_path}
|
||||||
|
|
||||||
## Input Sources
|
## ⚠️ CRITICAL: Pure Synthesis Task
|
||||||
1. Extracted CSS Animations: {JSON.stringify(extracted_animations) OR "None"}
|
- NO user questions or interaction
|
||||||
2. User Specification: {JSON.stringify(user_specification) OR "None"}
|
- READ existing specification files ONLY
|
||||||
3. Design Tokens Context: {JSON.stringify(design_tokens) OR "None"}
|
- Generate tokens based on available data
|
||||||
|
|
||||||
|
## Input Sources (Read-Only)
|
||||||
|
1. **Extracted CSS Animations** (if available):
|
||||||
|
${extracted_animations.length > 0 ? JSON.stringify(extracted_animations) : "None - skip CSS data"}
|
||||||
|
|
||||||
|
2. **User Specification** (REQUIRED if Phase 2 ran):
|
||||||
|
File: {base_path}/.intermediates/animation-analysis/animation-specification.json
|
||||||
|
${user_specification ? "Status: ✅ Found - READ this file for user choices" : "Status: ⚠️ Not found - use CSS extraction only"}
|
||||||
|
|
||||||
|
3. **Design Tokens Context** (for alignment):
|
||||||
|
${design_tokens ? JSON.stringify(design_tokens) : "None - standalone animation system"}
|
||||||
|
|
||||||
## Synthesis Rules
|
## Synthesis Rules
|
||||||
|
|
||||||
### Priority System
|
### Priority System
|
||||||
1. User specification (highest priority)
|
1. User specification from animation-specification.json (highest priority)
|
||||||
2. Extracted CSS values (medium priority)
|
2. Extracted CSS values from animations-*.json (medium priority)
|
||||||
3. Industry best practices (fallback)
|
3. Industry best practices (fallback)
|
||||||
|
|
||||||
### Duration Normalization
|
### Duration Normalization
|
||||||
- Analyze all extracted durations
|
- IF user_specification.timing_scale EXISTS:
|
||||||
- Cluster into 3-5 semantic scales: instant, fast, normal, slow, very-slow
|
Use user's chosen scale (fast/balanced/smooth/custom)
|
||||||
|
- ELSE IF extracted CSS durations available:
|
||||||
|
Cluster extracted durations into 3-5 semantic scales
|
||||||
|
- ELSE:
|
||||||
|
Use standard scale (instant:0ms, fast:150ms, normal:300ms, slow:500ms, very-slow:800ms)
|
||||||
- Align with design token spacing scale if available
|
- Align with design token spacing scale if available
|
||||||
|
|
||||||
### Easing Standardization
|
### Easing Standardization
|
||||||
- Identify common easing functions from extracted data
|
- IF user_specification.easing_philosophy EXISTS:
|
||||||
- Map to semantic names: linear, ease-in, ease-out, ease-in-out, spring
|
Use user's chosen philosophy (linear/ease-out/ease-in-out/spring)
|
||||||
- Convert all cubic-bezier values to standard format
|
- ELSE IF extracted CSS easings available:
|
||||||
|
Identify common easing functions from CSS
|
||||||
|
- ELSE:
|
||||||
|
Use standard easings
|
||||||
|
- Map to semantic names and convert to cubic-bezier format
|
||||||
|
|
||||||
### Animation Categorization
|
### Animation Categorization
|
||||||
Organize into:
|
Organize into:
|
||||||
- transitions: Property-specific transitions (color, transform, opacity)
|
- **duration**: Timing scale (instant, fast, normal, slow, very-slow)
|
||||||
- keyframe_animations: Named @keyframe animations
|
- **easing**: Easing functions (linear, ease-in, ease-out, ease-in-out, spring)
|
||||||
- interactions: Interaction-specific presets (hover, focus, active)
|
- **transitions**: Property-specific transitions (color, transform, opacity, etc.)
|
||||||
- micro_interactions: Small feedback animations
|
- **keyframes**: Named @keyframe animations (fadeIn, slideInUp, pulse, etc.)
|
||||||
- page_transitions: Route/view change animations
|
- **interactions**: Interaction-specific presets (button-hover, card-hover, input-focus, etc.)
|
||||||
- scroll_animations: Scroll-triggered animations
|
- **page_transitions**: Route/view change animations (if user enabled)
|
||||||
|
- **scroll_animations**: Scroll-triggered animations (if user enabled)
|
||||||
|
|
||||||
|
### User Specification Integration
|
||||||
|
IF user_specification EXISTS:
|
||||||
|
- Map user choices to token values:
|
||||||
|
* timing_scale → duration values
|
||||||
|
* easing_philosophy → easing curves
|
||||||
|
* interactions.button → interactions.button-hover token
|
||||||
|
* interactions.card → interactions.card-hover token
|
||||||
|
* interactions.input → micro-interaction tokens
|
||||||
|
* page_transitions → page_transitions tokens
|
||||||
|
* loading_animations → loading state tokens
|
||||||
|
* scroll_animations → scroll_animations tokens
|
||||||
|
|
||||||
## Generate Files
|
## Generate Files
|
||||||
|
|
||||||
### 1. animation-tokens.json
|
### 1. animation-tokens.json
|
||||||
Complete animation token structure:
|
Complete animation token structure using var() references:
|
||||||
|
|
||||||
{
|
{
|
||||||
"duration": {
|
"duration": {
|
||||||
"instant": "0ms",
|
"instant": "0ms",
|
||||||
"fast": "150ms",
|
"fast": "150ms", # Adjust based on user_specification.timing_scale
|
||||||
"normal": "300ms",
|
"normal": "300ms",
|
||||||
"slow": "500ms",
|
"slow": "500ms",
|
||||||
"very-slow": "800ms"
|
"very-slow": "800ms"
|
||||||
@@ -367,7 +592,7 @@ Task(ui-design-agent): `
|
|||||||
"easing": {
|
"easing": {
|
||||||
"linear": "linear",
|
"linear": "linear",
|
||||||
"ease-in": "cubic-bezier(0.4, 0, 1, 1)",
|
"ease-in": "cubic-bezier(0.4, 0, 1, 1)",
|
||||||
"ease-out": "cubic-bezier(0, 0, 0.2, 1)",
|
"ease-out": "cubic-bezier(0, 0, 0.2, 1)", # Adjust based on user_specification.easing_philosophy
|
||||||
"ease-in-out": "cubic-bezier(0.4, 0, 0.2, 1)",
|
"ease-in-out": "cubic-bezier(0.4, 0, 0.2, 1)",
|
||||||
"spring": "cubic-bezier(0.34, 1.56, 0.64, 1)"
|
"spring": "cubic-bezier(0.34, 1.56, 0.64, 1)"
|
||||||
},
|
},
|
||||||
@@ -389,66 +614,74 @@ Task(ui-design-agent): `
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"keyframes": {
|
"keyframes": {
|
||||||
"fadeIn": {
|
"fadeIn": {"0%": {"opacity": "0"}, "100%": {"opacity": "1"}},
|
||||||
"0%": {"opacity": "0"},
|
"slideInUp": {"0%": {"transform": "translateY(20px)", "opacity": "0"}, "100%": {"transform": "translateY(0)", "opacity": "1"}},
|
||||||
"100%": {"opacity": "1"}
|
"pulse": {"0%, 100%": {"opacity": "1"}, "50%": {"opacity": "0.7"}},
|
||||||
},
|
# Add more keyframes based on user_specification choices
|
||||||
"slideInUp": {
|
|
||||||
"0%": {"transform": "translateY(20px)", "opacity": "0"},
|
|
||||||
"100%": {"transform": "translateY(0)", "opacity": "1"}
|
|
||||||
},
|
|
||||||
"pulse": {
|
|
||||||
"0%, 100%": {"opacity": "1"},
|
|
||||||
"50%": {"opacity": "0.7"}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"interactions": {
|
"interactions": {
|
||||||
"button-hover": {
|
"button-hover": {
|
||||||
|
# Map from user_specification.interactions.button
|
||||||
"properties": ["background-color", "transform"],
|
"properties": ["background-color", "transform"],
|
||||||
"duration": "var(--duration-fast)",
|
"duration": "var(--duration-fast)",
|
||||||
"easing": "var(--easing-ease-out)",
|
"easing": "var(--easing-ease-out)",
|
||||||
"transform": "scale(1.02)"
|
"transform": "scale(1.02)"
|
||||||
},
|
},
|
||||||
"card-hover": {
|
"card-hover": {
|
||||||
|
# Map from user_specification.interactions.card
|
||||||
"properties": ["box-shadow", "transform"],
|
"properties": ["box-shadow", "transform"],
|
||||||
"duration": "var(--duration-normal)",
|
"duration": "var(--duration-normal)",
|
||||||
"easing": "var(--easing-ease-out)",
|
"easing": "var(--easing-ease-out)",
|
||||||
"transform": "translateY(-4px)"
|
"transform": "translateY(-4px)"
|
||||||
}
|
}
|
||||||
|
# Add input-focus, modal-open, dropdown-toggle based on user choices
|
||||||
},
|
},
|
||||||
"page_transitions": {
|
"page_transitions": {
|
||||||
|
# IF user_specification.page_transitions.enabled == true
|
||||||
"fade": {
|
"fade": {
|
||||||
"duration": "var(--duration-normal)",
|
"duration": "var(--duration-normal)",
|
||||||
"enter": "fadeIn",
|
"enter": "fadeIn",
|
||||||
"exit": "fadeOut"
|
"exit": "fadeOut"
|
||||||
}
|
}
|
||||||
|
# Add slide, zoom based on user_specification.page_transitions.style
|
||||||
},
|
},
|
||||||
"scroll_animations": {
|
"scroll_animations": {
|
||||||
|
# IF user_specification.scroll_animations.enabled == true
|
||||||
"default": {
|
"default": {
|
||||||
"animation": "fadeInUp",
|
"animation": "fadeIn", # From user_specification.scroll_animations.style
|
||||||
"duration": "var(--duration-slow)",
|
"duration": "var(--duration-slow)",
|
||||||
"easing": "var(--easing-ease-out)",
|
"easing": "var(--easing-ease-out)",
|
||||||
"threshold": "0.1",
|
"threshold": "0.1",
|
||||||
"stagger_delay": "100ms"
|
"stagger_delay": "100ms" # From user_specification if stagger chosen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
### 2. animation-guide.md
|
### 2. animation-guide.md
|
||||||
Comprehensive usage guide:
|
Comprehensive usage guide with sections:
|
||||||
- Animation philosophy and rationale
|
- **Animation Philosophy**: Rationale from user choices and CSS analysis
|
||||||
- Duration scale explanation
|
- **Duration Scale**: Explanation of timing values and usage contexts
|
||||||
- Easing function usage guidelines
|
- **Easing Functions**: When to use each easing curve
|
||||||
- Interaction animation patterns
|
- **Transition Presets**: Property-specific transition guidelines
|
||||||
- Implementation examples (CSS and JS)
|
- **Keyframe Animations**: Available animations and use cases
|
||||||
- Accessibility considerations (prefers-reduced-motion)
|
- **Interaction Patterns**: Button, card, input animation examples
|
||||||
- Performance best practices
|
- **Page Transitions**: Route change animation implementation (if enabled)
|
||||||
|
- **Scroll Animations**: Scroll-trigger setup and configuration (if enabled)
|
||||||
|
- **Implementation Examples**: CSS and JavaScript code samples
|
||||||
|
- **Accessibility**: prefers-reduced-motion media query setup
|
||||||
|
- **Performance Best Practices**: Hardware acceleration, will-change usage
|
||||||
|
|
||||||
|
## Output File Paths
|
||||||
|
- animation-tokens.json: {base_path}/animation-extraction/animation-tokens.json
|
||||||
|
- animation-guide.md: {base_path}/animation-extraction/animation-guide.md
|
||||||
|
|
||||||
## Critical Requirements
|
## Critical Requirements
|
||||||
|
- ✅ READ animation-specification.json if it exists (from Phase 2)
|
||||||
- ✅ Use Write() tool immediately for both files
|
- ✅ Use Write() tool immediately for both files
|
||||||
- ✅ Ensure all tokens use CSS Custom Property format: var(--duration-fast)
|
- ✅ All tokens use CSS Custom Property format: var(--duration-fast)
|
||||||
- ✅ Include prefers-reduced-motion media query guidance
|
- ✅ Include prefers-reduced-motion media query guidance
|
||||||
- ✅ Validate all cubic-bezier values are valid
|
- ✅ Validate all cubic-bezier values are valid (4 numbers between 0-1)
|
||||||
|
- ❌ NO user questions or interaction in this phase
|
||||||
- ❌ NO external research or MCP calls
|
- ❌ NO external research or MCP calls
|
||||||
`
|
`
|
||||||
```
|
```
|
||||||
@@ -487,8 +720,8 @@ bash(ls -lh {base_path}/animation-extraction/)
|
|||||||
TodoWrite({todos: [
|
TodoWrite({todos: [
|
||||||
{content: "Setup and input validation", status: "completed", activeForm: "Validating inputs"},
|
{content: "Setup and input validation", status: "completed", activeForm: "Validating inputs"},
|
||||||
{content: "CSS animation extraction (auto mode)", status: "completed", activeForm: "Extracting from CSS"},
|
{content: "CSS animation extraction (auto mode)", status: "completed", activeForm: "Extracting from CSS"},
|
||||||
{content: "Interactive specification (fallback)", status: "completed", activeForm: "Collecting user input"},
|
{content: "Interactive specification (main flow)", status: "completed", activeForm: "Collecting user input in main flow"},
|
||||||
{content: "Animation token synthesis (agent)", status: "completed", activeForm: "Generating tokens"},
|
{content: "Animation token synthesis (agent - no interaction)", status: "completed", activeForm: "Generating tokens via agent"},
|
||||||
{content: "Verify output files", status: "completed", activeForm: "Verifying files"}
|
{content: "Verify output files", status: "completed", activeForm: "Verifying files"}
|
||||||
]});
|
]});
|
||||||
```
|
```
|
||||||
@@ -506,7 +739,7 @@ Configuration:
|
|||||||
- ✅ CSS extracted from {len(url_list)} URL(s)
|
- ✅ CSS extracted from {len(url_list)} URL(s)
|
||||||
}
|
}
|
||||||
{IF user_specification:
|
{IF user_specification:
|
||||||
- ✅ User specification via interactive mode
|
- ✅ User specification via interactive mode (main flow)
|
||||||
}
|
}
|
||||||
{IF has_design_context:
|
{IF has_design_context:
|
||||||
- ✅ Aligned with existing design tokens
|
- ✅ Aligned with existing design tokens
|
||||||
@@ -652,11 +885,12 @@ ERROR: Invalid cubic-bezier values
|
|||||||
|
|
||||||
- **Auto-Trigger CSS Extraction** - Automatically extracts animations when --urls provided
|
- **Auto-Trigger CSS Extraction** - Automatically extracts animations when --urls provided
|
||||||
- **Hybrid Strategy** - Combines CSS extraction with interactive specification
|
- **Hybrid Strategy** - Combines CSS extraction with interactive specification
|
||||||
|
- **Main Flow Interaction** - User questions in main flow, agent only for token synthesis
|
||||||
- **Intelligent Fallback** - Gracefully handles extraction failures
|
- **Intelligent Fallback** - Gracefully handles extraction failures
|
||||||
- **Context-Aware** - Aligns with existing design tokens
|
- **Context-Aware** - Aligns with existing design tokens
|
||||||
- **Production-Ready** - CSS var() format, accessibility support
|
- **Production-Ready** - CSS var() format, accessibility support
|
||||||
- **Comprehensive Coverage** - Transitions, keyframes, interactions, scroll animations
|
- **Comprehensive Coverage** - Transitions, keyframes, interactions, scroll animations
|
||||||
- **Agent-Driven** - Autonomous token generation with ui-design-agent
|
- **Separated Concerns** - User decisions (Phase 2 main flow) → Token generation (Phase 3 agent)
|
||||||
|
|
||||||
## Integration
|
## Integration
|
||||||
|
|
||||||
|
|||||||
@@ -129,7 +129,10 @@ Task(ui-design-agent): `
|
|||||||
## Reference
|
## Reference
|
||||||
- Layout inspiration: Read("{base_path}/.intermediates/layout-analysis/inspirations/{target}-layout-ideas.txt")
|
- Layout inspiration: Read("{base_path}/.intermediates/layout-analysis/inspirations/{target}-layout-ideas.txt")
|
||||||
- Design tokens: Read("{base_path}/style-extraction/style-{style_id}/design-tokens.json")
|
- Design tokens: Read("{base_path}/style-extraction/style-{style_id}/design-tokens.json")
|
||||||
Parse ALL token values (colors, typography, spacing, borders, shadows, breakpoints)
|
Parse ALL token values including:
|
||||||
|
* colors, typography (with combinations), spacing, opacity
|
||||||
|
* border_radius, shadows, breakpoints
|
||||||
|
* component_styles (button, card, input variants)
|
||||||
${design_attributes ? "- Adapt DOM to: density, visual_weight, formality, organic_vs_geometric" : ""}
|
${design_attributes ? "- Adapt DOM to: density, visual_weight, formality, organic_vs_geometric" : ""}
|
||||||
|
|
||||||
## Generation
|
## Generation
|
||||||
@@ -152,14 +155,16 @@ Task(ui-design-agent): `
|
|||||||
|
|
||||||
2. CSS: {base_path}/prototypes/{target}-style-{style_id}-layout-N.css
|
2. CSS: {base_path}/prototypes/{target}-style-{style_id}-layout-N.css
|
||||||
- Self-contained: Direct token VALUES (no var())
|
- Self-contained: Direct token VALUES (no var())
|
||||||
- Use tokens: colors, fonts, spacing, borders, shadows
|
- Use tokens: colors, fonts, spacing, opacity, borders, shadows
|
||||||
|
- IF tokens.component_styles exists: Use component presets for buttons, cards, inputs
|
||||||
|
- IF tokens.typography.combinations exists: Use typography presets for headings and body text
|
||||||
- Device-optimized: {device_type} styles
|
- Device-optimized: {device_type} styles
|
||||||
${device_type === 'responsive' ? '- Responsive: Mobile-first @media' : '- Fixed: ' + device_type}
|
${device_type === 'responsive' ? '- Responsive: Mobile-first @media' : '- Fixed: ' + device_type}
|
||||||
${design_attributes ? `
|
${design_attributes ? `
|
||||||
- Token selection: density → spacing, visual_weight → shadows` : ""}
|
- Token selection: density → spacing, visual_weight → shadows` : ""}
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
- ✅ Token VALUES directly from design-tokens.json
|
- ✅ Token VALUES directly from design-tokens.json (with typography.combinations, opacity, component_styles support)
|
||||||
- ✅ Follow prompt requirements for {target}
|
- ✅ Follow prompt requirements for {target}
|
||||||
- ✅ Optimize for {device_type}
|
- ✅ Optimize for {device_type}
|
||||||
- ❌ NO var() refs, NO external deps
|
- ❌ NO var() refs, NO external deps
|
||||||
|
|||||||
@@ -99,7 +99,11 @@ Task(ui-design-agent): `
|
|||||||
|
|
||||||
2. Design Tokens:
|
2. Design Tokens:
|
||||||
Read("{base_path}/style-extraction/style-{style_id}/design-tokens.json")
|
Read("{base_path}/style-extraction/style-{style_id}/design-tokens.json")
|
||||||
Extract: ALL token values (colors, typography, spacing, borders, shadows, breakpoints)
|
Extract: ALL token values including:
|
||||||
|
* colors, typography (with combinations), spacing, opacity
|
||||||
|
* border_radius, shadows, breakpoints
|
||||||
|
* component_styles (button, card, input variants)
|
||||||
|
Note: typography.combinations, opacity, and component_styles fields contain preset configurations using var() references
|
||||||
|
|
||||||
3. Animation Tokens (OPTIONAL):
|
3. Animation Tokens (OPTIONAL):
|
||||||
IF exists("{base_path}/animation-extraction/animation-tokens.json"):
|
IF exists("{base_path}/animation-extraction/animation-tokens.json"):
|
||||||
@@ -133,11 +137,21 @@ Task(ui-design-agent): `
|
|||||||
- Replace ALL var(--*) with actual token values from design-tokens.json
|
- Replace ALL var(--*) with actual token values from design-tokens.json
|
||||||
Example: var(--spacing-4) → 1rem (from tokens.spacing.4)
|
Example: var(--spacing-4) → 1rem (from tokens.spacing.4)
|
||||||
Example: var(--breakpoint-md) → 768px (from tokens.breakpoints.md)
|
Example: var(--breakpoint-md) → 768px (from tokens.breakpoints.md)
|
||||||
|
Example: var(--opacity-80) → 0.8 (from tokens.opacity.80)
|
||||||
- Add visual styling using design tokens:
|
- Add visual styling using design tokens:
|
||||||
* Colors: tokens.colors.*
|
* Colors: tokens.colors.*
|
||||||
* Typography: tokens.typography.*
|
* Typography: tokens.typography.* (including combinations)
|
||||||
|
* Opacity: tokens.opacity.*
|
||||||
* Shadows: tokens.shadows.*
|
* Shadows: tokens.shadows.*
|
||||||
* Border radius: tokens.border_radius.*
|
* Border radius: tokens.border_radius.*
|
||||||
|
- IF tokens.component_styles exists: Add component style classes
|
||||||
|
* Generate classes for button variants (.btn-primary, .btn-secondary)
|
||||||
|
* Generate classes for card variants (.card-default, .card-interactive)
|
||||||
|
* Generate classes for input variants (.input-default, .input-focus, .input-error)
|
||||||
|
* Use var() references that resolve to actual token values
|
||||||
|
- IF tokens.typography.combinations exists: Add typography preset classes
|
||||||
|
* Generate classes for typography presets (.text-heading-primary, .text-body-regular, .text-caption)
|
||||||
|
* Use var() references for family, size, weight, line-height, letter-spacing
|
||||||
- IF has_animations == true: Inject animation tokens
|
- IF has_animations == true: Inject animation tokens
|
||||||
* Add CSS Custom Properties for animations at :root level:
|
* Add CSS Custom Properties for animations at :root level:
|
||||||
--duration-instant, --duration-fast, --duration-normal, etc.
|
--duration-instant, --duration-fast, --duration-normal, etc.
|
||||||
|
|||||||
@@ -418,17 +418,33 @@ Task(ui-design-agent): `
|
|||||||
Create complete design system in {base_path}/style-extraction/style-1/
|
Create complete design system in {base_path}/style-extraction/style-1/
|
||||||
|
|
||||||
1. **design-tokens.json**:
|
1. **design-tokens.json**:
|
||||||
- Complete token structure: colors (brand, surface, semantic, text, border), typography (families, sizes, weights, line heights, letter spacing), spacing (0-24 scale), border_radius (none to full), shadows (sm to xl), breakpoints (sm to 2xl)
|
- Complete token structure with ALL fields:
|
||||||
|
* colors (brand, surface, semantic, text, border) - OKLCH format
|
||||||
|
* typography (families, sizes, weights, line heights, letter spacing, combinations)
|
||||||
|
* typography.combinations: Predefined typography presets (heading-primary, heading-secondary, body-regular, body-emphasis, caption, label) using var() references
|
||||||
|
* spacing (0-24 scale)
|
||||||
|
* opacity (0, 10, 20, 40, 60, 80, 90, 100)
|
||||||
|
* border_radius (none to full)
|
||||||
|
* shadows (sm to xl)
|
||||||
|
* component_styles (button, card, input variants) - component presets using var() references
|
||||||
|
* breakpoints (sm to 2xl)
|
||||||
- All colors in OKLCH format
|
- All colors in OKLCH format
|
||||||
${extraction_mode == "explore" ? "- Start from preview colors and expand to full palette" : ""}
|
${extraction_mode == "explore" ? "- Start from preview colors and expand to full palette" : ""}
|
||||||
${extraction_mode == "explore" && refinements.enabled ? "- Apply user refinements where specified" : ""}
|
${extraction_mode == "explore" && refinements.enabled ? "- Apply user refinements where specified" : ""}
|
||||||
|
- Common Tailwind CSS usage patterns in project (if extracting from existing project)
|
||||||
|
|
||||||
2. **style-guide.md**:
|
2. **style-guide.md**:
|
||||||
- Design philosophy (${extraction_mode == "explore" ? "expand on: " + selected_direction.philosophy_name : "describe the reference design"})
|
- Design philosophy (${extraction_mode == "explore" ? "expand on: " + selected_direction.philosophy_name : "describe the reference design"})
|
||||||
- Complete color system documentation with accessibility notes
|
- Complete color system documentation with accessibility notes
|
||||||
- Typography scale and usage guidelines
|
- Typography scale and usage guidelines
|
||||||
|
- Typography Combinations section: Document each preset (heading-primary, heading-secondary, body-regular, body-emphasis, caption, label) with usage context and code examples
|
||||||
- Spacing system explanation
|
- Spacing system explanation
|
||||||
|
- Opacity & Transparency section: Opacity scale usage, common use cases (disabled states, overlays, hover effects), accessibility considerations
|
||||||
|
- Shadows & Elevation section: Shadow hierarchy and semantic usage
|
||||||
|
- Component Styles section: Document button, card, and input variants with code examples and visual descriptions
|
||||||
|
- Border Radius system and semantic usage
|
||||||
- Component examples and usage patterns
|
- Component examples and usage patterns
|
||||||
|
- Common Tailwind CSS patterns (if applicable)
|
||||||
|
|
||||||
## Critical Requirements
|
## Critical Requirements
|
||||||
- ✅ Use Write() tool immediately for each file
|
- ✅ Use Write() tool immediately for each file
|
||||||
@@ -577,15 +593,46 @@ bash(test -f {base_path}/.intermediates/style-analysis/analysis-options.json &&
|
|||||||
"text": {"primary": "oklch(...)", "secondary": "oklch(...)", "tertiary": "oklch(...)", "inverse": "oklch(...)"},
|
"text": {"primary": "oklch(...)", "secondary": "oklch(...)", "tertiary": "oklch(...)", "inverse": "oklch(...)"},
|
||||||
"border": {"default": "oklch(...)", "strong": "oklch(...)", "subtle": "oklch(...)"}
|
"border": {"default": "oklch(...)", "strong": "oklch(...)", "subtle": "oklch(...)"}
|
||||||
},
|
},
|
||||||
"typography": {"font_family": {...}, "font_size": {...}, "font_weight": {...}, "line_height": {...}, "letter_spacing": {...}},
|
"typography": {
|
||||||
|
"font_family": {...},
|
||||||
|
"font_size": {...},
|
||||||
|
"font_weight": {...},
|
||||||
|
"line_height": {...},
|
||||||
|
"letter_spacing": {...},
|
||||||
|
"combinations": {
|
||||||
|
"heading-primary": {"family": "var(--font-family-heading)", "size": "var(--font-size-3xl)", "weight": "var(--font-weight-bold)", "line_height": "var(--line-height-tight)", "letter_spacing": "var(--letter-spacing-tight)"},
|
||||||
|
"heading-secondary": {...},
|
||||||
|
"body-regular": {...},
|
||||||
|
"body-emphasis": {...},
|
||||||
|
"caption": {...},
|
||||||
|
"label": {...}
|
||||||
|
}
|
||||||
|
},
|
||||||
"spacing": {"0": "0", "1": "0.25rem", ..., "24": "6rem"},
|
"spacing": {"0": "0", "1": "0.25rem", ..., "24": "6rem"},
|
||||||
|
"opacity": {"0": "0", "10": "0.1", "20": "0.2", "40": "0.4", "60": "0.6", "80": "0.8", "90": "0.9", "100": "1"},
|
||||||
"border_radius": {"none": "0", "sm": "0.25rem", ..., "full": "9999px"},
|
"border_radius": {"none": "0", "sm": "0.25rem", ..., "full": "9999px"},
|
||||||
"shadows": {"sm": "...", "md": "...", "lg": "...", "xl": "..."},
|
"shadows": {"sm": "...", "md": "...", "lg": "...", "xl": "..."},
|
||||||
|
"component_styles": {
|
||||||
|
"button": {
|
||||||
|
"primary": {"background": "var(--color-brand-primary)", "color": "var(--color-text-inverse)", "padding": "var(--spacing-3) var(--spacing-6)", "border_radius": "var(--border-radius-md)", "font_weight": "var(--font-weight-semibold)"},
|
||||||
|
"secondary": {...},
|
||||||
|
"tertiary": {...}
|
||||||
|
},
|
||||||
|
"card": {
|
||||||
|
"default": {"background": "var(--color-surface-elevated)", "padding": "var(--spacing-6)", "border_radius": "var(--border-radius-lg)", "shadow": "var(--shadow-md)"},
|
||||||
|
"interactive": {...}
|
||||||
|
},
|
||||||
|
"input": {
|
||||||
|
"default": {"border": "1px solid var(--color-border-default)", "padding": "var(--spacing-3)", "border_radius": "var(--border-radius-md)", "background": "var(--color-surface-background)"},
|
||||||
|
"focus": {...},
|
||||||
|
"error": {...}
|
||||||
|
}
|
||||||
|
},
|
||||||
"breakpoints": {"sm": "640px", ..., "2xl": "1536px"}
|
"breakpoints": {"sm": "640px", ..., "2xl": "1536px"}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
**Requirements**: OKLCH colors, complete coverage, semantic naming, WCAG AA compliance
|
**Requirements**: OKLCH colors, complete coverage, semantic naming, WCAG AA compliance, typography combinations, component style presets, opacity scale
|
||||||
|
|
||||||
## Error Handling
|
## Error Handling
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user