@champpaba/claude-agent-kit 1.7.1 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/.claude/CHANGELOG-v1.1.1.md +259 -259
  2. package/.claude/CLAUDE.md +79 -90
  3. package/.claude/agents/01-integration.md +11 -7
  4. package/.claude/agents/02-uxui-frontend.md +11 -6
  5. package/.claude/agents/03-test-debug.md +11 -7
  6. package/.claude/agents/04-frontend.md +11 -7
  7. package/.claude/agents/05-backend.md +11 -6
  8. package/.claude/agents/06-database.md +11 -7
  9. package/.claude/commands/cdev.md +110 -7
  10. package/.claude/commands/csetup.md +306 -39
  11. package/.claude/commands/cstatus.md +60 -60
  12. package/.claude/commands/cview.md +364 -364
  13. package/.claude/commands/designsetup.md +1401 -336
  14. package/.claude/commands/extract.md +520 -245
  15. package/.claude/commands/pageplan.md +171 -47
  16. package/.claude/contexts/design/accessibility.md +611 -611
  17. package/.claude/contexts/design/layout.md +400 -400
  18. package/.claude/contexts/design/responsive.md +551 -551
  19. package/.claude/contexts/design/shadows.md +522 -522
  20. package/.claude/contexts/design/typography.md +465 -465
  21. package/.claude/contexts/domain/README.md +164 -164
  22. package/.claude/contexts/patterns/agent-coordination.md +388 -388
  23. package/.claude/contexts/patterns/agent-discovery.md +3 -2
  24. package/.claude/contexts/patterns/change-workflow.md +538 -538
  25. package/.claude/contexts/patterns/code-standards.md +39 -0
  26. package/.claude/contexts/patterns/development-principles.md +513 -513
  27. package/.claude/contexts/patterns/error-handling.md +478 -478
  28. package/.claude/contexts/patterns/error-recovery.md +365 -365
  29. package/.claude/contexts/patterns/logging.md +424 -424
  30. package/.claude/contexts/patterns/task-breakdown.md +452 -452
  31. package/.claude/contexts/patterns/task-classification.md +523 -523
  32. package/.claude/contexts/patterns/tdd-classification.md +516 -516
  33. package/.claude/contexts/patterns/testing.md +413 -413
  34. package/.claude/contexts/patterns/validation-framework.md +776 -776
  35. package/.claude/lib/agent-executor.md +76 -1
  36. package/.claude/lib/agent-router.md +572 -572
  37. package/.claude/lib/flags-updater.md +469 -469
  38. package/.claude/lib/tdd-classifier.md +345 -345
  39. package/.claude/lib/validation-gates.md +484 -484
  40. package/.claude/settings.local.json +42 -42
  41. package/.claude/templates/context-template.md +45 -45
  42. package/.claude/templates/flags-template.json +42 -42
  43. package/.claude/templates/phase-templates.json +19 -29
  44. package/.claude/templates/phases-sections/accessibility-test.md +17 -17
  45. package/.claude/templates/phases-sections/api-design.md +37 -37
  46. package/.claude/templates/phases-sections/backend-tests.md +16 -16
  47. package/.claude/templates/phases-sections/backend.md +37 -37
  48. package/.claude/templates/phases-sections/business-logic-validation.md +16 -16
  49. package/.claude/templates/phases-sections/component-tests.md +17 -17
  50. package/.claude/templates/phases-sections/contract-backend.md +16 -16
  51. package/.claude/templates/phases-sections/contract-frontend.md +16 -16
  52. package/.claude/templates/phases-sections/database.md +35 -35
  53. package/.claude/templates/phases-sections/e2e-tests.md +16 -16
  54. package/.claude/templates/phases-sections/fix-implementation.md +17 -17
  55. package/.claude/templates/phases-sections/frontend-integration.md +18 -18
  56. package/.claude/templates/phases-sections/frontend-mockup.md +123 -123
  57. package/.claude/templates/phases-sections/manual-flow-test.md +15 -15
  58. package/.claude/templates/phases-sections/manual-ux-test.md +16 -16
  59. package/.claude/templates/phases-sections/refactor-implementation.md +17 -17
  60. package/.claude/templates/phases-sections/refactor.md +16 -16
  61. package/.claude/templates/phases-sections/regression-tests.md +15 -15
  62. package/.claude/templates/phases-sections/responsive-test.md +16 -16
  63. package/.claude/templates/phases-sections/script-implementation.md +43 -43
  64. package/.claude/templates/phases-sections/test-coverage.md +16 -16
  65. package/.claude/templates/phases-sections/user-approval.md +14 -14
  66. package/LICENSE +21 -21
  67. package/README.md +103 -351
  68. package/package.json +1 -1
  69. package/.claude/commands/agentsetup.md +0 -1464
  70. package/.claude/commands/psetup.md +0 -101
  71. package/.claude/templates/phases-sections/documentation.md +0 -17
  72. package/.claude/templates/phases-sections/report.md +0 -16
@@ -1,8 +1,8 @@
1
- # /designsetup - Synthesize Style Guide from Extracted Data
1
+ # /designsetup - Interactive Design System Setup
2
2
 
3
3
  You are a senior design systems architect with experience at FANG-level companies.
4
4
 
5
- Your task is to analyze extracted design data, synthesize with project context, and generate a comprehensive STYLE_GUIDE.md with AI-recommended style directions.
5
+ Your task is to guide user through an **interactive design system setup** with verbose options, theme selection, and decorative direction.
6
6
 
7
7
  ---
8
8
 
@@ -24,50 +24,59 @@ Examples:
24
24
 
25
25
  ## 🎯 Mission
26
26
 
27
- Generate production-ready style guide at: `design-system/STYLE_GUIDE.md`
27
+ Generate lean design system files:
28
+ - `design-system/tokens.json` (~800 tokens) - **PRIMARY: Agent reads this**
29
+ - `design-system/patterns/*.md` - Code patterns (selective loading)
30
+ - `design-system/STYLE_GUIDE.md` (~2000 tokens) - **Human-readable (no code)**
28
31
 
29
32
  **Process:**
30
- 1. Load all extracted data from `design-system/extracted/`
31
- 2. Analyze project context (from @files or user input)
32
- 3. Generate 2-3 style direction options with AI reasoning
33
- 4. User selects preferred option
34
- 5. Generate comprehensive STYLE_GUIDE.md (17 sections, 1500-2000 lines)
33
+ 1. Load all extracted data from `.claude/extractions/*.json`
34
+ 2. Present verbose style options with Match scores
35
+ 3. **Interactive Loop** (max 3 rounds): Present Feedback Adjust
36
+ 4. Theme selection + Decorative direction recommendation
37
+ 5. Generate tokens.json + patterns/*.md + STYLE_GUIDE.md
35
38
 
36
39
  **Key Principles:**
37
- 1. **Multi-Source Synthesis**: Combine best patterns from all extracted sites
38
- 2. **Context-Aware**: Match style to target audience + brand personality
39
- 3. **Transparent Reasoning**: Show why each option fits
40
- 4. **User Choice**: Present options with pros/cons, let user decide
40
+ 1. **Interactive Loop**: User must accept 100% before generating
41
+ 2. **Verbose Options**: Show full details (characteristics, feel, examples)
42
+ 3. **Theme + Decorations**: Agent recommends based on project context
43
+ 4. **Lean Output**: tokens.json for agents, STYLE_GUIDE.md for humans
41
44
 
42
45
  ---
43
46
 
44
47
  ## STEP 0: Discovery & Validation
45
48
 
46
49
  ```javascript
47
- // 1. Find extracted sites
48
- const extractedFiles = glob('design-system/extracted/*/data.yaml');
50
+ // 1. Find extracted sites from .claude/extractions/
51
+ const extractedFiles = glob('.claude/extractions/*.json').filter(f => !f.includes('merged-insights'));
52
+ const mergedInsightsPath = '.claude/extractions/merged-insights.json';
49
53
 
50
54
  if (extractedFiles.length === 0) {
51
55
  return error(`
52
56
  ❌ No extracted data found
53
57
 
54
58
  Please extract at least 1 site first:
55
- /extract https://airbnb.com
56
- /extract https://blackbird.com
57
- /extract https://linear.app
59
+ /extract https://motherduck.com
60
+ /extract https://linear.app https://stripe.com
58
61
 
59
62
  Then run: /designsetup @prd.md @project.md
60
63
  `);
61
64
  }
62
65
 
63
- // 2. Load all extracted data
66
+ // 2. Load all extracted site data
64
67
  const extractedData = {};
65
68
  for (const file of extractedFiles) {
66
- const siteName = path.dirname(file).split('/').pop();
67
- extractedData[siteName] = YAML.parse(Read(file));
69
+ const siteName = path.basename(file, '.json');
70
+ extractedData[siteName] = JSON.parse(Read(file));
71
+ }
72
+
73
+ // 3. Load merged insights if exists (for multi-site)
74
+ let mergedInsights = null;
75
+ if (exists(mergedInsightsPath)) {
76
+ mergedInsights = JSON.parse(Read(mergedInsightsPath));
68
77
  }
69
78
 
70
- // 3. Load context files
79
+ // 4. Load context files
71
80
  const contextArgs = args.filter(arg => arg.startsWith('@'));
72
81
  const contexts = {};
73
82
 
@@ -88,15 +97,17 @@ if (contextArgs.length > 0) {
88
97
 
89
98
  **Report:**
90
99
  ```
91
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
100
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
92
101
  🎨 Design Setup Started
93
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
102
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
94
103
 
95
104
  📊 Extracted Sites: ${Object.keys(extractedData).length}
96
105
  ${Object.entries(extractedData).map(([site, data]) =>
97
- ` - ${site} (${data.meta.coverage.percentage}% coverage, ${data.meta.extracted_at.split('T')[0]})`
106
+ ` - ${site}: ${data.style.detected} (${data.style.confidence}% confidence)`
98
107
  ).join('\n')}
99
108
 
109
+ ${mergedInsights ? `📋 Merged Insights: Available (${mergedInsights.meta.sites_count} sites)` : ''}
110
+
100
111
  📁 Context Files: ${Object.keys(contexts).length || 'None (will use interactive mode)'}
101
112
  ${Object.keys(contexts).length > 0 ? Object.keys(contexts).map(c => ` - ${c}`).join('\n') : ''}
102
113
 
@@ -222,77 +233,399 @@ if (!contextAnalysis.has_context) {
222
233
 
223
234
  ---
224
235
 
225
- ## STEP 2: Style Direction Analysis (AI Pondering)
236
+ ## STEP 2: Interactive Style Selection (Verbose + Loop)
226
237
 
227
- Instructions:
228
- 1. Wrap thinking in <pondering> tags
229
- 2. Consider:
230
- - Which extracted patterns fit target audience best?
231
- - Which style matches brand personality?
232
- - What differentiates from competitors?
233
- - What are implementation trade-offs?
234
- 3. Recommend 2-3 distinct style directions
235
- 4. Rank by fit score (0-100)
238
+ > **Key Change:** Interactive loop until user accepts 100%
236
239
 
237
- Return JSON:
238
- {
239
- "pondering": "...",
240
- "recommended_count": 2 or 3,
241
- "options": [
242
- {
243
- "name": "Neo-Brutalism" | "Warm Minimalist" | "Modern Professional" | "Playful Rounded" | "Technical Clean" | other,
244
- "fit_score": 0-100,
245
- "rationale": "Why this fits (2-3 sentences)",
246
- "sources": {
247
- "colors": "site-name | custom",
248
- "shadows": "site-name",
249
- "typography": "site-name | custom",
250
- "spacing": "site-name",
251
- "button_hover": "site-name",
252
- "card_hover": "site-name",
253
- "input_focus": "site-name",
254
- "border_radius": "site-name",
255
- "overall_vibe": "site-name"
256
- },
257
- "customizations": [
258
- "Adapt Airbnb warmth to bold colors",
259
- "Use Blackbird hard shadows instead of soft"
260
- ],
261
- "advantages": [
262
- "string (3-5 advantages)"
263
- ],
264
- "disadvantages": [
265
- "string (2-4 disadvantages)"
240
+ ```javascript
241
+ let round = 1;
242
+ let maxRounds = 3;
243
+ let userAccepted = false;
244
+ let selectedStyle = null;
245
+ let selectedAnimations = [];
246
+ let selectedTheme = null;
247
+
248
+ while (!userAccepted && round <= maxRounds) {
249
+ output(`
250
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
251
+ 📋 ROUND ${round}/${maxRounds}: Style Selection
252
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
253
+ `);
254
+
255
+ // ========== STYLE OPTIONS (VERBOSE) ==========
256
+
257
+ const styleOptions = [];
258
+
259
+ // Generate options from extracted data
260
+ for (const [siteName, data] of Object.entries(extractedData)) {
261
+ styleOptions.push({
262
+ site: siteName,
263
+ style: data.style.detected,
264
+ confidence: data.style.confidence,
265
+ characteristics: data.style.characteristics,
266
+ feel: data.style.feel,
267
+ colors: data.colors.primary,
268
+ animations: data.animation_libraries,
269
+ scrollPatterns: data.scroll_animations.patterns,
270
+ decorativeTypes: data.decorative_elements.types
271
+ });
272
+ }
273
+
274
+ // Calculate match scores based on context
275
+ const scoredOptions = styleOptions.map(opt => {
276
+ let score = opt.confidence;
277
+
278
+ // Bonus for matching brand personality
279
+ if (contextAnalysis.brand_personality) {
280
+ if (contextAnalysis.brand_personality.includes('bold') &&
281
+ (opt.style === 'Neo-Brutalism' || opt.style === 'Playful/Creative')) {
282
+ score += 15;
283
+ }
284
+ if (contextAnalysis.brand_personality.includes('professional') &&
285
+ (opt.style === 'Minimalist' || opt.style === 'Modern SaaS')) {
286
+ score += 15;
287
+ }
288
+ if (contextAnalysis.brand_personality.includes('playful') &&
289
+ opt.style === 'Playful/Creative') {
290
+ score += 15;
291
+ }
292
+ if (contextAnalysis.brand_personality.includes('minimal') &&
293
+ opt.style === 'Minimalist') {
294
+ score += 15;
295
+ }
296
+ }
297
+
298
+ return { ...opt, matchScore: Math.min(score, 100) };
299
+ }).sort((a, b) => b.matchScore - a.matchScore);
300
+
301
+ // Display verbose options
302
+ for (const [index, option] of scoredOptions.entries()) {
303
+ const letter = String.fromCharCode(65 + index);
304
+ const isRecommended = index === 0;
305
+
306
+ output(`
307
+ ┌─────────────────────────────────────────────────────────────┐
308
+ │ Option ${letter}: ${option.style} ${isRecommended ? '⭐ RECOMMENDED' : ''}
309
+ │ Source: ${option.site}
310
+ │ Match Score: ${option.matchScore}%
311
+ ├─────────────────────────────────────────────────────────────┤
312
+
313
+ │ 📝 Characteristics:
314
+ │ ${option.characteristics.map(c => ` • ${c}`).join('\n│ ')}
315
+
316
+ │ 🎭 Feel: ${option.feel}
317
+
318
+ │ 🎨 Colors: ${option.colors.join(', ')}
319
+
320
+ │ 🎬 Animations Available:
321
+ │ ${option.animations.length > 0 ? option.animations.map(a => ` • ${a.name}`).join('\n│ ') : ' (none detected)'}
322
+
323
+ │ 📜 Scroll Patterns:
324
+ │ ${option.scrollPatterns.length > 0 ? option.scrollPatterns.map(p => ` • ${p}`).join('\n│ ') : ' (none detected)'}
325
+
326
+ │ 🖼️ Decorative Elements:
327
+ │ ${option.decorativeTypes.length > 0 ? option.decorativeTypes.map(d => ` • ${d}`).join('\n│ ') : ' (none detected)'}
328
+
329
+ └─────────────────────────────────────────────────────────────┘
330
+ `);
331
+ }
332
+
333
+ // Ask user to select or provide feedback
334
+ const styleChoice = await AskUserQuestion({
335
+ questions: [{
336
+ question: "เลือก style ที่ชอบ หรือพิมพ์ feedback:",
337
+ header: "Style",
338
+ multiSelect: false,
339
+ options: [
340
+ ...scoredOptions.map((opt, i) => ({
341
+ label: `${String.fromCharCode(65 + i)}: ${opt.style}`,
342
+ description: `${opt.matchScore}% match - ${opt.feel}`
343
+ })),
344
+ { label: "Mix/Custom", description: "ผสมหลาย style หรือปรับแต่งเอง" }
266
345
  ]
346
+ }]
347
+ });
348
+
349
+ if (styleChoice.answers["Style"] === "Mix/Custom") {
350
+ output(`
351
+ พิมพ์ความต้องการ (ตัวอย่าง: "ชอบ border ของ A แต่อยากได้สี soft กว่านี้"):
352
+ `);
353
+ const customInput = await getUserTextInput();
354
+
355
+ // AI interprets and adjusts
356
+ output(`
357
+ 🤖 กำลังปรับตาม feedback: "${customInput}"...
358
+ `);
359
+
360
+ round++;
361
+ continue; // Loop again with adjusted options
362
+ }
363
+
364
+ // User selected a style
365
+ const selectedIndex = styleChoice.answers["Style"].charCodeAt(0) - 65;
366
+ selectedStyle = scoredOptions[selectedIndex];
367
+
368
+ // ========== ANIMATION SELECTION ==========
369
+
370
+ output(`
371
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
372
+ 📋 ROUND ${round}/${maxRounds}: Animation Selection
373
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
374
+ `);
375
+
376
+ // Collect all available animations from all sites
377
+ const allAnimations = [];
378
+
379
+ for (const [siteName, data] of Object.entries(extractedData)) {
380
+ // Animation libraries
381
+ for (const lib of data.animation_libraries) {
382
+ allAnimations.push({
383
+ type: 'library',
384
+ name: lib.name,
385
+ source: siteName,
386
+ description: `${lib.name} library detected`
387
+ });
267
388
  }
268
- ]
269
- }
270
389
 
271
- Important:
272
- - Option 1 = highest fit score (primary recommendation)
273
- - Option 2 = good alternative (different approach)
274
- - Option 3 (if needed) = safe fallback
275
- - Each option should be DISTINCT (different visual feel)
276
- - Source mapping must reference actual extracted sites
390
+ // Scroll patterns
391
+ for (const pattern of data.scroll_animations.patterns) {
392
+ allAnimations.push({
393
+ type: 'scroll',
394
+ name: pattern,
395
+ source: siteName,
396
+ description: `Scroll animation: ${pattern}`
397
+ });
398
+ }
399
+
400
+ // Component animations
401
+ if (data.component_animations.button_hover !== 'none') {
402
+ allAnimations.push({
403
+ type: 'component',
404
+ name: `Button: ${data.component_animations.button_hover}`,
405
+ source: siteName,
406
+ description: data.component_animations.button_hover
407
+ });
408
+ }
409
+ if (data.component_animations.card_hover !== 'none') {
410
+ allAnimations.push({
411
+ type: 'component',
412
+ name: `Card: ${data.component_animations.card_hover}`,
413
+ source: siteName,
414
+ description: data.component_animations.card_hover
415
+ });
416
+ }
417
+ }
418
+
419
+ // Display animations
420
+ output(`
421
+ 🎬 Available Animations (จาก references ทั้งหมด):
422
+
423
+ ${allAnimations.map((anim, i) => `
424
+ [${i + 1}] ${anim.name}
425
+ Type: ${anim.type}
426
+ Source: ${anim.source}
427
+ Description: ${anim.description}
428
+ `).join('')}
429
+ `);
430
+
431
+ const animChoice = await AskUserQuestion({
432
+ questions: [{
433
+ question: "เลือก animations ที่ต้องการ (เลือกได้หลายอัน):",
434
+ header: "Animations",
435
+ multiSelect: true,
436
+ options: allAnimations.map((anim, i) => ({
437
+ label: `${anim.name}`,
438
+ description: `From ${anim.source}: ${anim.description}`
439
+ }))
440
+ }]
441
+ });
442
+
443
+ selectedAnimations = animChoice.answers["Animations"]
444
+ ? animChoice.answers["Animations"].split(',').map(s => s.trim())
445
+ : [];
446
+
447
+ // ========== THEME + DECORATIVE DIRECTION ==========
448
+
449
+ output(`
450
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
451
+ 📋 ROUND ${round}/${maxRounds}: Theme & Decorative Direction
452
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
453
+ `);
454
+
455
+ // AI recommends themes based on context
456
+ const themePrompt = `
457
+ Based on project context, recommend 3-4 theme options.
458
+
459
+ Project Context:
460
+ - Product Type: ${contextAnalysis.product_type}
461
+ - Target Audience: ${contextAnalysis.target_audience?.demographics || 'Unknown'}
462
+ - Brand Personality: ${contextAnalysis.brand_personality?.join(', ') || 'Unknown'}
463
+ ${Object.keys(contexts).length > 0 ? `- Context Files: ${Object.keys(contexts).join(', ')}` : ''}
464
+ ${Object.keys(contexts).length > 0 ? `- Brief Summary: ${Object.values(contexts)[0]?.substring(0, 500)}` : ''}
465
+
466
+ Return JSON array:
467
+ [
468
+ {
469
+ "name": "Theme Name",
470
+ "description": "What this theme represents",
471
+ "feeling": "How it makes users feel",
472
+ "decorative_elements": ["element1", "element2", "element3"],
473
+ "avoid_elements": ["avoid1", "avoid2"],
474
+ "icons_suggestion": ["Lucide icon names"],
475
+ "match_reason": "Why this theme fits the project"
476
+ }
477
+ ]
277
478
  `;
278
479
 
279
- const styleOptions = await LLM({
280
- prompt: ponderingPrompt,
281
- response_format: 'json',
282
- max_tokens: 4000
283
- });
480
+ const themeOptions = await LLM({
481
+ prompt: themePrompt,
482
+ response_format: 'json'
483
+ });
484
+
485
+ output(`
486
+ 🎨 Theme Recommendations (based on your project):
487
+ `);
488
+
489
+ for (const [index, theme] of themeOptions.entries()) {
490
+ output(`
491
+ ┌─────────────────────────────────────────────────────────────┐
492
+ │ Theme ${String.fromCharCode(65 + index)}: ${theme.name}
493
+ ├─────────────────────────────────────────────────────────────┤
494
+
495
+ │ 📝 Description: ${theme.description}
496
+ │ 🎭 Feeling: ${theme.feeling}
497
+
498
+ │ ✅ Decorative Elements (Use):
499
+ │ ${theme.decorative_elements.map(e => ` • ${e}`).join('\n│ ')}
500
+
501
+ │ ❌ Avoid:
502
+ │ ${theme.avoid_elements.map(e => ` • ${e}`).join('\n│ ')}
503
+
504
+ │ 🎯 Icons (Lucide): ${theme.icons_suggestion.join(', ')}
505
+
506
+ │ 💡 Why: ${theme.match_reason}
507
+
508
+ └─────────────────────────────────────────────────────────────┘
509
+ `);
510
+ }
511
+
512
+ const themeChoice = await AskUserQuestion({
513
+ questions: [{
514
+ question: "เลือก theme หรือพิมพ์ custom:",
515
+ header: "Theme",
516
+ multiSelect: false,
517
+ options: [
518
+ ...themeOptions.map((t, i) => ({
519
+ label: `${String.fromCharCode(65 + i)}: ${t.name}`,
520
+ description: `${t.feeling} - ${t.decorative_elements.slice(0, 3).join(', ')}`
521
+ })),
522
+ { label: "No Theme", description: "ไม่ใช้ theme - geometric/abstract" },
523
+ { label: "Custom", description: "กำหนด theme เอง" }
524
+ ]
525
+ }]
526
+ });
527
+
528
+ if (themeChoice.answers["Theme"] === "Custom") {
529
+ output(`พิมพ์ theme ที่ต้องการ (ตัวอย่าง: "อวกาศ - จรวด, ดาวเทียม, ดาว"):`);
530
+ const customTheme = await getUserTextInput();
531
+ selectedTheme = {
532
+ name: 'Custom',
533
+ description: customTheme,
534
+ decorative_elements: customTheme.split(',').map(s => s.trim()),
535
+ avoid_elements: []
536
+ };
537
+ } else if (themeChoice.answers["Theme"] === "No Theme") {
538
+ selectedTheme = {
539
+ name: 'Abstract',
540
+ description: 'No specific theme - geometric and abstract decorations',
541
+ decorative_elements: ['geometric shapes', 'gradients', 'blobs'],
542
+ avoid_elements: []
543
+ };
544
+ } else {
545
+ const themeIndex = themeChoice.answers["Theme"].charCodeAt(0) - 65;
546
+ selectedTheme = themeOptions[themeIndex];
547
+ }
548
+
549
+ // ========== CONFIRMATION ==========
550
+
551
+ output(`
552
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
553
+ ✅ SUMMARY - Please Confirm
554
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
555
+
556
+ 🎨 Style: ${selectedStyle.style} (from ${selectedStyle.site})
557
+ Feel: ${selectedStyle.feel}
558
+
559
+ 🎬 Animations Enabled:
560
+ ${selectedAnimations.map(a => ` ✅ ${a}`).join('\n') || ' (none selected)'}
561
+
562
+ 🎭 Theme: ${selectedTheme.name}
563
+ Decorations: ${selectedTheme.decorative_elements.join(', ')}
564
+ Avoid: ${selectedTheme.avoid_elements.join(', ') || '(none)'}
565
+
566
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
567
+ `);
568
+
569
+ const confirmation = await AskUserQuestion({
570
+ questions: [{
571
+ question: "ยืนยันการตั้งค่านี้?",
572
+ header: "Confirm",
573
+ multiSelect: false,
574
+ options: [
575
+ { label: "Yes, Generate", description: "สร้าง design system ตามนี้" },
576
+ { label: "Adjust", description: "ปรับแต่งอีกรอบ" },
577
+ { label: "Start Over", description: "เริ่มใหม่ตั้งแต่ต้น" }
578
+ ]
579
+ }]
580
+ });
581
+
582
+ if (confirmation.answers["Confirm"] === "Yes, Generate") {
583
+ userAccepted = true;
584
+ } else if (confirmation.answers["Confirm"] === "Start Over") {
585
+ round = 1;
586
+ } else {
587
+ round++;
588
+ }
589
+
590
+ if (round > maxRounds && !userAccepted) {
591
+ output(`
592
+ ⚠️ ครบ ${maxRounds} รอบแล้ว
593
+
594
+ แนะนำ:
595
+ 1. รัน /extract กับ reference ใหม่
596
+ 2. หรือ accept แล้วค่อย manual edit ไฟล์ที่สร้าง
597
+ `);
598
+
599
+ const forceChoice = await AskUserQuestion({
600
+ questions: [{
601
+ question: "ต้องการ generate ตาม settings ปัจจุบันไหม?",
602
+ header: "Force",
603
+ multiSelect: false,
604
+ options: [
605
+ { label: "Yes", description: "Generate ตาม settings ล่าสุด" },
606
+ { label: "Cancel", description: "ยกเลิก" }
607
+ ]
608
+ }]
609
+ });
610
+
611
+ if (forceChoice.answers["Force"] === "Yes") {
612
+ userAccepted = true;
613
+ } else {
614
+ return output('Design setup cancelled.');
615
+ }
616
+ }
617
+ }
284
618
  ```
285
619
 
286
620
  **Report:**
287
621
  ```
288
- Style Directions Generated!
622
+ User Selection Complete!
289
623
 
290
- 🎨 ${styleOptions.recommended_count} options created
291
- - Primary: ${styleOptions.options[0].name} (${styleOptions.options[0].fit_score}% fit)
292
- - Alternative: ${styleOptions.options[1].name} (${styleOptions.options[1].fit_score}% fit)
293
- ${styleOptions.options[2] ? `- Fallback: ${styleOptions.options[2].name} (${styleOptions.options[2].fit_score}% fit)` : ''}
624
+ 🎨 Style: ${selectedStyle.style}
625
+ 🎬 Animations: ${selectedAnimations.length} selected
626
+ 🎭 Theme: ${selectedTheme.name}
294
627
 
295
- 🔄 Generating option previews...
628
+ 🔄 Generating design system files...
296
629
  ```
297
630
 
298
631
  ---
@@ -782,322 +1115,1054 @@ Write('design-system/STYLE_GUIDE.md', styleGuideMD);
782
1115
 
783
1116
  ---
784
1117
 
785
- ## STEP 5.5: Generate STYLE_TOKENS.json (Context Optimization)
1118
+ ## STEP 5.5: Generate tokens.json (Enhanced v2.0.0)
786
1119
 
787
- > **New in v1.2.0:** Generate lightweight design tokens file for token-efficient loading
1120
+ > **Enhanced v2.0.0:** tokens.json now includes style, theme, animations, decorative_direction, and patterns_index
788
1121
 
789
1122
  ```javascript
790
1123
  output(`
791
- 🔄 Extracting design tokens for efficient loading...
1124
+ 🔄 Generating enhanced tokens.json...
792
1125
  `);
793
1126
 
794
- // Extract design tokens from STYLE_GUIDE.md
795
- const tokensPrompt = `
796
- You are extracting design tokens from the STYLE_GUIDE.md into a lightweight JSON format.
797
-
798
- Source: STYLE_GUIDE.md content below
799
- ${styleGuideMD}
800
-
801
- Task: Extract ALL design tokens into JSON format following this exact structure:
802
-
803
- {
1127
+ // Build tokens.json from user selections + extracted data
1128
+ const tokensData = {
804
1129
  "$schema": "https://json-schema.org/draft-07/schema",
805
- "version": "1.0.0",
1130
+ "version": "2.0.0",
806
1131
  "meta": {
807
- "generated_at": "${new Date().toISOString()}",
808
- "generated_by": "/designsetup command",
809
- "source": "design-system/STYLE_GUIDE.md",
810
- "design_style": "${selectedOption.name}",
811
- "description": "Lightweight design tokens extracted from STYLE_GUIDE.md (~500 tokens vs ~5000 tokens for full guide)"
1132
+ "generated_at": new Date().toISOString(),
1133
+ "generated_by": "/designsetup command v2.0.0",
1134
+ "source_sites": Object.keys(extractedData),
1135
+ "description": "Design tokens for agents (~800 tokens). Human-readable guide: STYLE_GUIDE.md"
812
1136
  },
813
- "tokens": {
814
- "colors": {
815
- "primary": {
816
- "DEFAULT": "[extract from guide]",
817
- "foreground": "[extract]",
818
- "hover": "[extract or generate]",
819
- "description": "Primary brand color for CTAs, links, and accents",
820
- "tailwind": "bg-primary, text-primary, border-primary"
821
- },
822
- "secondary": { ... },
823
- "background": { ... },
824
- "foreground": { ... },
825
- "border": { ... },
826
- "semantic": {
827
- "success": "[extract]",
828
- "warning": "[extract]",
829
- "error": "[extract]",
830
- "info": "[extract]"
831
- }
832
- },
833
- "spacing": {
834
- "scale": [extract spacing scale array],
835
- "description": "4px or 8px base unit spacing scale",
836
- "tailwind_mapping": { ... },
837
- "common_patterns": {
838
- "component_padding": "p-4 (16px) or p-6 (24px)",
839
- "section_gap": "gap-8 (32px) or gap-12 (48px)",
840
- "layout_margin": "mt-16 (64px) or mt-24 (96px)"
841
- }
842
- },
843
- "typography": {
844
- "font_family": { ... },
845
- "font_size": { ... },
846
- "font_weight": { ... },
847
- "line_height": { ... },
848
- "headings": { ... }
1137
+
1138
+ // ========== NEW: Style & Theme (from user selection) ==========
1139
+ "style": {
1140
+ "name": selectedStyle.style,
1141
+ "confidence": selectedStyle.confidence,
1142
+ "characteristics": selectedStyle.characteristics,
1143
+ "feel": selectedStyle.feel,
1144
+ "source_site": selectedStyle.site
1145
+ },
1146
+
1147
+ "theme": {
1148
+ "name": selectedTheme.name,
1149
+ "description": selectedTheme.description,
1150
+ "feeling": selectedTheme.feeling || selectedTheme.description,
1151
+ "decorative_elements": {
1152
+ "use": selectedTheme.decorative_elements,
1153
+ "avoid": selectedTheme.avoid_elements
849
1154
  },
850
- "shadows": {
851
- "sm": "[extract]",
852
- "DEFAULT": "[extract]",
853
- "md": "[extract]",
854
- "lg": "[extract]",
855
- "xl": "[extract]",
856
- "usage": {
857
- "cards": "shadow-md",
858
- "dropdowns": "shadow-lg",
859
- "modals": "shadow-xl",
860
- "buttons_hover": "shadow-sm"
861
- }
1155
+ "icons_suggestion": selectedTheme.icons_suggestion || ["Lucide icons"]
1156
+ },
1157
+
1158
+ // ========== NEW: Animations (from user selection) ==========
1159
+ "animations": {
1160
+ "enabled": selectedAnimations.length > 0,
1161
+ "libraries": extractedData[selectedStyle.site]?.animation_libraries || [],
1162
+ "selected_patterns": selectedAnimations,
1163
+ "scroll_animations": {
1164
+ "enabled": selectedAnimations.some(a =>
1165
+ a.includes('scroll') || a.includes('parallax') || a.includes('fade') || a.includes('stacking')
1166
+ ),
1167
+ "patterns": extractedData[selectedStyle.site]?.scroll_animations?.patterns || []
862
1168
  },
863
- "borders": {
864
- "radius": { ... },
865
- "width": { ... },
866
- "usage": { ... }
1169
+ "component_animations": {
1170
+ "button_hover": extractedData[selectedStyle.site]?.component_animations?.button_hover || "scale + shadow",
1171
+ "card_hover": extractedData[selectedStyle.site]?.component_animations?.card_hover || "translateY + shadow",
1172
+ "input_focus": extractedData[selectedStyle.site]?.component_animations?.input_focus || "ring"
867
1173
  },
868
- "animation": {
869
- "duration": { ... },
870
- "easing": { ... },
871
- "common": { ... }
1174
+ "duration": {
1175
+ "fast": "150ms",
1176
+ "normal": "200ms",
1177
+ "slow": "300ms"
872
1178
  },
873
- "breakpoints": { ... },
874
- "z_index": { ... }
875
- },
876
- "component_library": {
877
- "name": "[extract from guide]",
878
- "install_command": "[extract]",
879
- "common_components": [extract array]
1179
+ "easing": {
1180
+ "default": "ease-in-out",
1181
+ "bounce": "cubic-bezier(0.68, -0.55, 0.265, 1.55)"
1182
+ }
880
1183
  },
881
- "component_patterns": {
882
- "button": {
883
- "primary": "[extract full Tailwind classes from Button component section - exact copy of primary button pattern]",
884
- "secondary": "[extract secondary button pattern]",
885
- "ghost": "[extract ghost button pattern]",
886
- "outline": "[extract outline button pattern]",
887
- "destructive": "[extract destructive/danger button pattern]",
888
- "link": "[extract link button pattern]",
889
- "icon": "[extract icon-only button pattern]",
890
- "sizes": {
891
- "sm": "[extract small button classes]",
892
- "md": "[extract medium/default button classes]",
893
- "lg": "[extract large button classes]"
894
- },
895
- "states": {
896
- "default": "[base classes]",
897
- "hover": "[hover state classes]",
898
- "active": "[active/pressed state classes]",
899
- "disabled": "[disabled state classes]",
900
- "loading": "[loading state classes with spinner]"
901
- }
1184
+
1185
+ // ========== Colors (from selected style's source) ==========
1186
+ "colors": {
1187
+ "primary": {
1188
+ "DEFAULT": selectedStyle.colors[0] || "#0d7276",
1189
+ "foreground": "#ffffff",
1190
+ "hover": darkenColor(selectedStyle.colors[0] || "#0d7276", 10),
1191
+ "tailwind": "bg-primary, text-primary, border-primary"
902
1192
  },
903
- "card": {
904
- "default": "[extract default card pattern with border/shadow/padding]",
905
- "elevated": "[extract elevated card with larger shadow]",
906
- "outlined": "[extract outlined card variant]",
907
- "interactive": "[extract interactive card with hover effects]",
908
- "composition": {
909
- "header": "[extract card header classes]",
910
- "content": "[extract card content/body classes]",
911
- "footer": "[extract card footer classes]",
912
- "image": "[extract card image wrapper classes]"
913
- }
1193
+ "secondary": {
1194
+ "DEFAULT": selectedStyle.colors[1] || "#64748b",
1195
+ "foreground": "#ffffff",
1196
+ "hover": darkenColor(selectedStyle.colors[1] || "#64748b", 10)
914
1197
  },
915
- "input": {
916
- "base": "[extract base input field classes]",
917
- "variants": {
918
- "default": "[extract default input]",
919
- "error": "[extract error state input with red border]",
920
- "success": "[extract success state input]",
921
- "disabled": "[extract disabled input]"
922
- },
923
- "sizes": {
924
- "sm": "[extract small input]",
925
- "md": "[extract medium input]",
926
- "lg": "[extract large input]"
927
- }
1198
+ "accent": {
1199
+ "DEFAULT": selectedStyle.colors[2] || selectedStyle.colors[0] || "#f97316",
1200
+ "foreground": "#ffffff"
928
1201
  },
929
- "form_field": {
930
- "wrapper": "[extract form field wrapper classes]",
931
- "label": "[extract label classes]",
932
- "input": "[reference to input.base]",
933
- "helper_text": "[extract helper text classes]",
934
- "error_message": "[extract error message classes with red text]",
935
- "composition": "[extract full form field pattern: label + input + helper + error]"
1202
+ "background": {
1203
+ "DEFAULT": "#ffffff",
1204
+ "muted": "#f1f5f9",
1205
+ "subtle": "#f8fafc"
936
1206
  },
937
- "badge": {
938
- "default": "[extract default badge]",
939
- "variants": {
940
- "primary": "[extract primary badge]",
941
- "secondary": "[extract secondary badge]",
942
- "success": "[extract success/green badge]",
943
- "warning": "[extract warning/yellow badge]",
944
- "error": "[extract error/red badge]",
945
- "outline": "[extract outline badge]"
946
- }
1207
+ "foreground": {
1208
+ "DEFAULT": "#0a0a0a",
1209
+ "muted": "#64748b",
1210
+ "subtle": "#94a3b8"
947
1211
  },
948
- "alert": {
949
- "base": "[extract base alert classes]",
950
- "variants": {
951
- "info": "[extract info alert with blue accent]",
952
- "success": "[extract success alert with green accent]",
953
- "warning": "[extract warning alert with yellow accent]",
954
- "error": "[extract error alert with red accent]"
955
- },
956
- "composition": {
957
- "wrapper": "[alert container classes]",
958
- "icon": "[icon wrapper classes]",
959
- "content": "[content wrapper classes]",
960
- "title": "[alert title classes]",
961
- "description": "[alert description classes]",
962
- "actions": "[action buttons wrapper classes]"
963
- }
1212
+ "border": {
1213
+ "DEFAULT": "#e2e8f0",
1214
+ "hover": "#cbd5e1",
1215
+ "focus": selectedStyle.colors[0] || "#0d7276"
1216
+ },
1217
+ "semantic": {
1218
+ "success": "#10b981",
1219
+ "warning": "#f59e0b",
1220
+ "error": "#ef4444",
1221
+ "info": "#3b82f6"
964
1222
  }
965
1223
  },
966
- "layout_patterns": {
967
- "container": {
968
- "default": "[extract default container: max-w-7xl mx-auto px-4 sm:px-6 lg:px-8]",
969
- "narrow": "[extract narrow container: max-w-4xl]",
970
- "wide": "[extract wide container: max-w-screen-2xl]",
971
- "full": "[extract full-width: w-full]",
972
- "fluid": "[extract fluid container with responsive padding]"
973
- },
974
- "grid": {
975
- "auto": "[extract auto-fit grid: grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6]",
976
- "feature": "[extract feature grid: grid grid-cols-1 md:grid-cols-3 gap-8]",
977
- "dashboard": "[extract dashboard grid: grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4]",
978
- "gallery": "[extract gallery grid: grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-2]",
979
- "masonry": "[extract masonry-style grid classes]"
1224
+
1225
+ // ========== Typography (from extracted data) ==========
1226
+ "typography": {
1227
+ "font_family": {
1228
+ "sans": extractedData[selectedStyle.site]?.typography?.fonts[0] || "'Inter', sans-serif",
1229
+ "mono": "'Fira Code', monospace"
980
1230
  },
981
- "flex": {
982
- "row_center": "[extract centered row: flex items-center justify-center]",
983
- "row_between": "[extract space-between row: flex items-center justify-between]",
984
- "row_start": "[extract left-aligned row: flex items-center justify-start]",
985
- "col_center": "[extract centered column: flex flex-col items-center justify-center]",
986
- "col_start": "[extract top-aligned column: flex flex-col items-start]"
1231
+ "font_size": {
1232
+ "xs": "12px", "sm": "14px", "base": "16px", "lg": "18px",
1233
+ "xl": "20px", "2xl": "24px", "3xl": "30px", "4xl": "36px", "5xl": "48px"
987
1234
  },
988
- "section_spacing": {
989
- "tight": "[extract tight section spacing: py-8 md:py-12]",
990
- "normal": "[extract normal section spacing: py-12 md:py-16]",
991
- "loose": "[extract loose section spacing: py-16 md:py-24]",
992
- "hero": "[extract hero section spacing: py-20 md:py-32]"
1235
+ "font_weight": {
1236
+ "normal": "400", "medium": "500", "semibold": "600", "bold": "700"
993
1237
  },
994
- "page_layouts": {
995
- "landing": "[extract landing page layout structure]",
996
- "dashboard": "[extract dashboard layout: sidebar + main content]",
997
- "auth": "[extract auth page layout: centered card]",
998
- "settings": "[extract settings page layout: tabs + content]"
1238
+ "headings": {
1239
+ "h1": "text-5xl font-bold",
1240
+ "h2": "text-4xl font-bold",
1241
+ "h3": "text-3xl font-semibold",
1242
+ "h4": "text-2xl font-semibold",
1243
+ "h5": "text-xl font-medium",
1244
+ "h6": "text-lg font-medium"
1245
+ }
1246
+ },
1247
+
1248
+ // ========== Spacing (from extracted data) ==========
1249
+ "spacing": {
1250
+ "scale": extractedData[selectedStyle.site]?.spacing?.common || [4, 8, 12, 16, 24, 32, 48, 64, 96],
1251
+ "grid_base": extractedData[selectedStyle.site]?.spacing?.grid_base || "8px",
1252
+ "common_patterns": {
1253
+ "component_padding": "p-4 (16px) or p-6 (24px)",
1254
+ "section_gap": "gap-8 (32px) or gap-12 (48px)",
1255
+ "layout_margin": "mt-16 (64px) or mt-24 (96px)"
1256
+ }
1257
+ },
1258
+
1259
+ // ========== Shadows (from extracted data) ==========
1260
+ "shadows": {
1261
+ "values": extractedData[selectedStyle.site]?.shadows || [
1262
+ "0 1px 2px 0 rgb(0 0 0 / 0.05)",
1263
+ "0 4px 6px -1px rgb(0 0 0 / 0.1)",
1264
+ "0 10px 15px -3px rgb(0 0 0 / 0.1)"
1265
+ ],
1266
+ "usage": {
1267
+ "cards": "shadow-md",
1268
+ "dropdowns": "shadow-lg",
1269
+ "modals": "shadow-xl",
1270
+ "buttons_hover": "shadow-sm"
999
1271
  }
1000
1272
  },
1273
+
1274
+ // ========== Borders (from extracted data) ==========
1275
+ "borders": {
1276
+ "radius": extractedData[selectedStyle.site]?.border_radius || ["4px", "8px", "12px", "9999px"],
1277
+ "usage": {
1278
+ "inputs": "rounded-md",
1279
+ "buttons": "rounded-lg",
1280
+ "cards": "rounded-xl",
1281
+ "avatars": "rounded-full"
1282
+ }
1283
+ },
1284
+
1285
+ // ========== NEW: Patterns Index (references to patterns/*.md) ==========
1286
+ "patterns_index": {
1287
+ "buttons": "design-system/patterns/buttons.md",
1288
+ "scroll_animations": "design-system/patterns/scroll-animations.md",
1289
+ "decorations": "design-system/patterns/decorations.md",
1290
+ "cards": "design-system/patterns/cards.md",
1291
+ "forms": "design-system/patterns/forms.md"
1292
+ },
1293
+
1294
+ // ========== Component Library ==========
1295
+ "component_library": {
1296
+ "name": "shadcn/ui",
1297
+ "install_command": "npx shadcn-ui@latest init",
1298
+ "common_components": ["button", "card", "input", "select", "dialog", "dropdown-menu", "badge", "avatar", "tooltip"]
1299
+ },
1300
+
1301
+ // ========== Critical Rules ==========
1001
1302
  "critical_rules": {
1002
1303
  "colors": [
1003
- "❌ NO hardcoded hex values (#64748b)",
1004
- "✅ USE theme tokens (text-foreground/70)",
1005
- "❌ NO random opacity values",
1006
- "✅ USE consistent opacity scale (/50, /70, /90)"
1304
+ "❌ NO hardcoded hex values",
1305
+ "✅ USE theme tokens (bg-primary, text-foreground)"
1007
1306
  ],
1008
1307
  "spacing": [
1009
- "❌ NO arbitrary values (p-5, gap-7, mt-15)",
1010
- "✅ USE spacing scale (p-4, p-6, gap-8, mt-16)",
1011
- "❌ NO hardcoded px values",
1012
- "✅ USE Tailwind scale"
1308
+ "❌ NO arbitrary values (p-5, gap-7)",
1309
+ "✅ USE spacing scale (p-4, p-6, gap-8)"
1013
1310
  ],
1014
1311
  "consistency": [
1015
- "❌ NO mixing patterns (shadow-sm on Card A, shadow-lg on Card B)",
1016
- "✅ USE consistent patterns (all cards use shadow-md)",
1017
- "❌ NO mixing border radius (rounded-md vs rounded-lg)",
1018
- "✅ USE same border radius for similar components"
1312
+ "❌ NO mixing patterns",
1313
+ "✅ USE consistent patterns from tokens"
1019
1314
  ]
1020
1315
  }
1316
+ };
1317
+
1318
+ // Helper function to darken color
1319
+ function darkenColor(hex, percent) {
1320
+ const num = parseInt(hex.replace('#', ''), 16);
1321
+ const amt = Math.round(2.55 * percent);
1322
+ const R = Math.max((num >> 16) - amt, 0);
1323
+ const G = Math.max((num >> 8 & 0x00FF) - amt, 0);
1324
+ const B = Math.max((num & 0x0000FF) - amt, 0);
1325
+ return '#' + (0x1000000 + R * 0x10000 + G * 0x100 + B).toString(16).slice(1);
1021
1326
  }
1022
1327
 
1023
- IMPORTANT:
1024
- - Extract ALL values from STYLE_GUIDE.md (don't use placeholders)
1025
- - If a value isn't in the guide, infer it logically (e.g., hover = 10% darker than DEFAULT)
1026
- - Keep descriptions concise but clear
1027
- - Return ONLY valid JSON (no markdown, no explanations)
1328
+ // Write tokens.json
1329
+ Write('design-system/tokens.json', JSON.stringify(tokensData, null, 2));
1330
+ output(`✅ tokens.json generated (~800 tokens)`);
1331
+ ```
1332
+
1333
+ ---
1334
+
1335
+ ## STEP 5.6: Generate patterns/*.md Files
1336
+
1337
+ > **Code patterns for agents** - Selective loading based on page type
1338
+
1339
+ ```javascript
1340
+ output(`
1341
+ 🔄 Generating pattern files...
1342
+ `);
1343
+
1344
+ // Create patterns directory
1345
+ mkdir('design-system/patterns');
1346
+
1347
+ // ========== 1. buttons.md ==========
1348
+ const buttonsPattern = `# Button Patterns
1349
+
1350
+ > **Source:** ${selectedStyle.site} | **Style:** ${selectedStyle.style}
1351
+ > **Load when:** Any UI page
1352
+
1353
+ ## Primary Button
1354
+ \`\`\`tsx
1355
+ <button className="
1356
+ bg-primary text-primary-foreground
1357
+ px-4 py-2 rounded-lg
1358
+ font-medium
1359
+ ${tokensData.animations.component_animations.button_hover === 'scale + shadow'
1360
+ ? 'hover:scale-105 hover:shadow-md'
1361
+ : 'hover:bg-primary/90'}
1362
+ transition-all duration-200
1363
+ focus:outline-none focus:ring-2 focus:ring-primary/50
1364
+ disabled:opacity-50 disabled:cursor-not-allowed
1365
+ ">
1366
+ Button Text
1367
+ </button>
1368
+ \`\`\`
1369
+
1370
+ ## Secondary Button
1371
+ \`\`\`tsx
1372
+ <button className="
1373
+ bg-secondary text-secondary-foreground
1374
+ px-4 py-2 rounded-lg
1375
+ font-medium
1376
+ hover:bg-secondary/80
1377
+ transition-all duration-200
1378
+ ">
1379
+ Secondary
1380
+ </button>
1381
+ \`\`\`
1382
+
1383
+ ## Ghost Button
1384
+ \`\`\`tsx
1385
+ <button className="
1386
+ bg-transparent text-foreground
1387
+ px-4 py-2 rounded-lg
1388
+ font-medium
1389
+ hover:bg-muted
1390
+ transition-all duration-200
1391
+ ">
1392
+ Ghost
1393
+ </button>
1394
+ \`\`\`
1395
+
1396
+ ## Outline Button
1397
+ \`\`\`tsx
1398
+ <button className="
1399
+ bg-transparent text-primary
1400
+ border border-primary
1401
+ px-4 py-2 rounded-lg
1402
+ font-medium
1403
+ hover:bg-primary hover:text-primary-foreground
1404
+ transition-all duration-200
1405
+ ">
1406
+ Outline
1407
+ </button>
1408
+ \`\`\`
1409
+
1410
+ ## Icon Button
1411
+ \`\`\`tsx
1412
+ <button className="
1413
+ p-2 rounded-lg
1414
+ hover:bg-muted
1415
+ transition-all duration-200
1416
+ ">
1417
+ <Icon className="w-5 h-5" />
1418
+ </button>
1419
+ \`\`\`
1420
+
1421
+ ## Button Sizes
1422
+ \`\`\`tsx
1423
+ // Small
1424
+ className="px-3 py-1.5 text-sm rounded-md"
1425
+
1426
+ // Medium (default)
1427
+ className="px-4 py-2 text-base rounded-lg"
1428
+
1429
+ // Large
1430
+ className="px-6 py-3 text-lg rounded-lg"
1431
+ \`\`\`
1028
1432
  `;
1029
1433
 
1030
- const tokensJSON = await LLM({
1031
- prompt: tokensPrompt,
1032
- max_tokens: 4000,
1033
- temperature: 0.1 // Low temperature for consistent extraction
1034
- });
1434
+ Write('design-system/patterns/buttons.md', buttonsPattern);
1035
1435
 
1036
- // Validate JSON
1037
- try {
1038
- JSON.parse(tokensJSON);
1039
- Write('design-system/STYLE_TOKENS.json', tokensJSON);
1040
- output(`✅ STYLE_TOKENS.json generated (~500 tokens)`);
1041
- } catch (e) {
1042
- warn(`⚠️ Failed to generate STYLE_TOKENS.json: ${e.message}`);
1043
- warn(`Continuing without tokens file...`);
1044
- }
1436
+ // ========== 2. scroll-animations.md ==========
1437
+ const scrollAnimationsPattern = `# Scroll Animation Patterns
1438
+
1439
+ > **Source:** ${selectedStyle.site} | **Style:** ${selectedStyle.style}
1440
+ > **Load when:** Landing pages, marketing pages
1441
+ > **Libraries:** ${tokensData.animations.libraries.map(l => l.name).join(', ') || 'CSS/Tailwind'}
1442
+
1443
+ ## Enabled Patterns
1444
+ ${selectedAnimations.length > 0 ? selectedAnimations.map(a => `- ${a}`).join('\n') : '- No scroll animations selected'}
1445
+
1446
+ ---
1447
+
1448
+ ## Fade In on Scroll (CSS)
1449
+ \`\`\`tsx
1450
+ // Add to component
1451
+ const [isVisible, setIsVisible] = useState(false);
1452
+ const ref = useRef(null);
1453
+
1454
+ useEffect(() => {
1455
+ const observer = new IntersectionObserver(
1456
+ ([entry]) => setIsVisible(entry.isIntersecting),
1457
+ { threshold: 0.1 }
1458
+ );
1459
+ if (ref.current) observer.observe(ref.current);
1460
+ return () => observer.disconnect();
1461
+ }, []);
1462
+
1463
+ return (
1464
+ <div
1465
+ ref={ref}
1466
+ className={\`
1467
+ transition-all duration-700
1468
+ \${isVisible ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-8'}
1469
+ \`}
1470
+ >
1471
+ {children}
1472
+ </div>
1473
+ );
1474
+ \`\`\`
1475
+
1476
+ ## Stacking Cards (GSAP ScrollTrigger)
1477
+ \`\`\`tsx
1478
+ // Requires: npm install gsap
1479
+
1480
+ import { gsap } from 'gsap';
1481
+ import { ScrollTrigger } from 'gsap/ScrollTrigger';
1482
+
1483
+ gsap.registerPlugin(ScrollTrigger);
1484
+
1485
+ useEffect(() => {
1486
+ const cards = gsap.utils.toArray('.stacking-card');
1487
+
1488
+ cards.forEach((card, i) => {
1489
+ gsap.to(card, {
1490
+ scrollTrigger: {
1491
+ trigger: card,
1492
+ start: 'top 80%',
1493
+ end: 'top 20%',
1494
+ scrub: true,
1495
+ },
1496
+ y: -50 * i,
1497
+ scale: 1 - (0.05 * i),
1498
+ opacity: 1 - (0.1 * i),
1499
+ });
1500
+ });
1501
+ }, []);
1502
+
1503
+ // JSX
1504
+ <div className="stacking-card bg-card p-6 rounded-xl shadow-md sticky top-20">
1505
+ Card Content
1506
+ </div>
1507
+ \`\`\`
1508
+
1509
+ ## Parallax Section
1510
+ \`\`\`tsx
1511
+ // CSS approach
1512
+ <div className="relative overflow-hidden">
1513
+ <div
1514
+ className="absolute inset-0 bg-cover bg-center"
1515
+ style={{
1516
+ backgroundImage: 'url(/hero-bg.jpg)',
1517
+ transform: 'translateY(var(--parallax-offset, 0))',
1518
+ }}
1519
+ />
1520
+ <div className="relative z-10 py-24">
1521
+ Content here
1522
+ </div>
1523
+ </div>
1524
+
1525
+ // Update --parallax-offset on scroll
1526
+ useEffect(() => {
1527
+ const handleScroll = () => {
1528
+ const offset = window.scrollY * 0.5;
1529
+ document.documentElement.style.setProperty('--parallax-offset', \`\${offset}px\`);
1530
+ };
1531
+ window.addEventListener('scroll', handleScroll);
1532
+ return () => window.removeEventListener('scroll', handleScroll);
1533
+ }, []);
1534
+ \`\`\`
1535
+
1536
+ ## Slide In from Side
1537
+ \`\`\`tsx
1538
+ // Left
1539
+ className="animate-slide-in-left"
1540
+ // CSS: @keyframes slide-in-left { from { transform: translateX(-100%); opacity: 0; } to { transform: translateX(0); opacity: 1; } }
1541
+
1542
+ // Right
1543
+ className="animate-slide-in-right"
1544
+ // CSS: @keyframes slide-in-right { from { transform: translateX(100%); opacity: 0; } to { transform: translateX(0); opacity: 1; } }
1545
+ \`\`\`
1546
+ `;
1547
+
1548
+ Write('design-system/patterns/scroll-animations.md', scrollAnimationsPattern);
1549
+
1550
+ // ========== 3. decorations.md ==========
1551
+ const decorationsPattern = `# Decorative Elements
1552
+
1553
+ > **Theme:** ${selectedTheme.name}
1554
+ > **Load when:** Landing pages, marketing pages (NOT dashboards)
1555
+
1556
+ ## Theme Direction
1557
+
1558
+ ### ✅ USE These Elements
1559
+ ${selectedTheme.decorative_elements.map(e => `- ${e}`).join('\n')}
1560
+
1561
+ ### ❌ AVOID These Elements
1562
+ ${selectedTheme.avoid_elements.length > 0 ? selectedTheme.avoid_elements.map(e => `- ${e}`).join('\n') : '- (none specified)'}
1563
+
1564
+ ### 🎯 Suggested Icons (Lucide)
1565
+ ${selectedTheme.icons_suggestion?.join(', ') || 'Default Lucide icons'}
1566
+
1567
+ ---
1568
+
1569
+ ## Gradient Background
1570
+ \`\`\`tsx
1571
+ // Subtle gradient overlay
1572
+ <div className="
1573
+ absolute inset-0 -z-10
1574
+ bg-gradient-to-br from-primary/5 via-transparent to-accent/5
1575
+ "/>
1576
+
1577
+ // Mesh gradient (hero sections)
1578
+ <div className="
1579
+ absolute inset-0 -z-10
1580
+ bg-[radial-gradient(ellipse_80%_80%_at_50%_-20%,rgba(var(--primary),0.3),transparent)]
1581
+ "/>
1582
+ \`\`\`
1583
+
1584
+ ## Blob Shapes
1585
+ \`\`\`tsx
1586
+ // CSS blob
1587
+ <div className="
1588
+ absolute -top-20 -right-20 w-96 h-96
1589
+ bg-primary/10 rounded-full blur-3xl
1590
+ animate-blob
1591
+ "/>
1592
+
1593
+ // CSS for animation
1594
+ // @keyframes blob {
1595
+ // 0%, 100% { transform: translate(0, 0) scale(1); }
1596
+ // 33% { transform: translate(30px, -50px) scale(1.1); }
1597
+ // 66% { transform: translate(-20px, 20px) scale(0.9); }
1598
+ // }
1599
+ \`\`\`
1600
+
1601
+ ## Grid Pattern
1602
+ \`\`\`tsx
1603
+ // Dot grid background
1604
+ <div className="
1605
+ absolute inset-0 -z-10
1606
+ bg-[radial-gradient(#e5e7eb_1px,transparent_1px)]
1607
+ [background-size:16px_16px]
1608
+ "/>
1609
+
1610
+ // Line grid
1611
+ <div className="
1612
+ absolute inset-0 -z-10
1613
+ bg-[linear-gradient(to_right,#e5e7eb_1px,transparent_1px),linear-gradient(to_bottom,#e5e7eb_1px,transparent_1px)]
1614
+ [background-size:24px_24px]
1615
+ "/>
1616
+ \`\`\`
1617
+
1618
+ ## Floating Elements
1619
+ \`\`\`tsx
1620
+ // Floating icons (for theme: ${selectedTheme.name})
1621
+ <div className="absolute top-10 left-10 animate-float opacity-20">
1622
+ <IconFromTheme className="w-12 h-12 text-primary" />
1623
+ </div>
1624
+
1625
+ // CSS
1626
+ // @keyframes float {
1627
+ // 0%, 100% { transform: translateY(0); }
1628
+ // 50% { transform: translateY(-20px); }
1629
+ // }
1630
+ \`\`\`
1631
+
1632
+ ## Dividers & Separators
1633
+ \`\`\`tsx
1634
+ // Wave divider
1635
+ <svg className="w-full h-16" viewBox="0 0 1200 120" preserveAspectRatio="none">
1636
+ <path d="M0,0V46.29c47.79,22.2,103.59,32.17,158,28,70.36-5.37,136.33-33.31,206.8-37.5C438.64,32.43,512.34,53.67,583,72.05c69.27,18,138.3,24.88,209.4,13.08,36.15-6,69.85-17.84,104.45-29.34C989.49,25,1113-14.29,1200,52.47V0Z" fill="currentColor" className="text-muted/30"/>
1637
+ </svg>
1638
+
1639
+ // Gradient line
1640
+ <div className="h-px bg-gradient-to-r from-transparent via-border to-transparent" />
1641
+ \`\`\`
1642
+ `;
1643
+
1644
+ Write('design-system/patterns/decorations.md', decorationsPattern);
1645
+
1646
+ // ========== 4. cards.md ==========
1647
+ const cardsPattern = `# Card Patterns
1648
+
1649
+ > **Source:** ${selectedStyle.site} | **Style:** ${selectedStyle.style}
1650
+ > **Load when:** Any UI page
1651
+
1652
+ ## Default Card
1653
+ \`\`\`tsx
1654
+ <div className="
1655
+ bg-card text-card-foreground
1656
+ rounded-xl border shadow-md
1657
+ p-6
1658
+ ">
1659
+ <h3 className="text-xl font-semibold mb-2">Card Title</h3>
1660
+ <p className="text-muted-foreground">Card content goes here.</p>
1661
+ </div>
1662
+ \`\`\`
1663
+
1664
+ ## Interactive Card (with hover)
1665
+ \`\`\`tsx
1666
+ <div className="
1667
+ bg-card text-card-foreground
1668
+ rounded-xl border shadow-md
1669
+ p-6
1670
+ ${tokensData.animations.component_animations.card_hover === 'translateY + shadow'
1671
+ ? 'hover:-translate-y-1 hover:shadow-lg'
1672
+ : 'hover:border-primary/50'}
1673
+ transition-all duration-200
1674
+ cursor-pointer
1675
+ ">
1676
+ <h3 className="text-xl font-semibold mb-2">Interactive Card</h3>
1677
+ <p className="text-muted-foreground">Hover me!</p>
1678
+ </div>
1679
+ \`\`\`
1680
+
1681
+ ## Feature Card
1682
+ \`\`\`tsx
1683
+ <div className="
1684
+ bg-card text-card-foreground
1685
+ rounded-xl border shadow-md
1686
+ p-6
1687
+ hover:-translate-y-1 hover:shadow-lg
1688
+ transition-all duration-200
1689
+ ">
1690
+ <div className="w-12 h-12 rounded-lg bg-primary/10 flex items-center justify-center mb-4">
1691
+ <Icon className="w-6 h-6 text-primary" />
1692
+ </div>
1693
+ <h3 className="text-lg font-semibold mb-2">Feature Title</h3>
1694
+ <p className="text-muted-foreground text-sm">
1695
+ Feature description goes here.
1696
+ </p>
1697
+ </div>
1698
+ \`\`\`
1699
+
1700
+ ## Pricing Card
1701
+ \`\`\`tsx
1702
+ <div className="
1703
+ bg-card text-card-foreground
1704
+ rounded-xl border shadow-md
1705
+ p-8
1706
+ relative overflow-hidden
1707
+ ">
1708
+ {/* Popular badge */}
1709
+ <div className="absolute top-4 right-4">
1710
+ <span className="bg-primary text-primary-foreground px-3 py-1 rounded-full text-xs font-medium">
1711
+ Popular
1712
+ </span>
1713
+ </div>
1714
+
1715
+ <h3 className="text-xl font-bold mb-2">Pro Plan</h3>
1716
+ <div className="text-4xl font-bold mb-4">
1717
+ $29<span className="text-lg text-muted-foreground">/mo</span>
1718
+ </div>
1719
+
1720
+ <ul className="space-y-3 mb-6">
1721
+ <li className="flex items-center gap-2">
1722
+ <CheckIcon className="w-5 h-5 text-primary" />
1723
+ <span>Feature 1</span>
1724
+ </li>
1725
+ {/* ... more features */}
1726
+ </ul>
1727
+
1728
+ <button className="w-full bg-primary text-primary-foreground py-2 rounded-lg">
1729
+ Get Started
1730
+ </button>
1731
+ </div>
1732
+ \`\`\`
1733
+
1734
+ ## Testimonial Card
1735
+ \`\`\`tsx
1736
+ <div className="
1737
+ bg-card text-card-foreground
1738
+ rounded-xl border shadow-md
1739
+ p-6
1740
+ ">
1741
+ <div className="flex items-center gap-4 mb-4">
1742
+ <img src="/avatar.jpg" className="w-12 h-12 rounded-full" />
1743
+ <div>
1744
+ <h4 className="font-semibold">John Doe</h4>
1745
+ <p className="text-sm text-muted-foreground">CEO, Company</p>
1746
+ </div>
1747
+ </div>
1748
+ <p className="text-muted-foreground italic">
1749
+ "This product is amazing! It has transformed how we work."
1750
+ </p>
1751
+ </div>
1752
+ \`\`\`
1753
+ `;
1754
+
1755
+ Write('design-system/patterns/cards.md', cardsPattern);
1756
+
1757
+ // ========== 5. forms.md ==========
1758
+ const formsPattern = `# Form Patterns
1759
+
1760
+ > **Source:** ${selectedStyle.site} | **Style:** ${selectedStyle.style}
1761
+ > **Load when:** Auth pages, settings, any form UI
1762
+
1763
+ ## Input Field
1764
+ \`\`\`tsx
1765
+ <div className="space-y-2">
1766
+ <label className="text-sm font-medium text-foreground">
1767
+ Email Address
1768
+ </label>
1769
+ <input
1770
+ type="email"
1771
+ placeholder="you@example.com"
1772
+ className="
1773
+ w-full px-4 py-2
1774
+ bg-background text-foreground
1775
+ border rounded-md
1776
+ focus:outline-none focus:ring-2 focus:ring-primary/50 focus:border-primary
1777
+ placeholder:text-muted-foreground
1778
+ transition-all duration-200
1779
+ "
1780
+ />
1781
+ <p className="text-sm text-muted-foreground">
1782
+ We'll never share your email.
1783
+ </p>
1784
+ </div>
1785
+ \`\`\`
1786
+
1787
+ ## Input with Error
1788
+ \`\`\`tsx
1789
+ <div className="space-y-2">
1790
+ <label className="text-sm font-medium text-foreground">
1791
+ Password
1792
+ </label>
1793
+ <input
1794
+ type="password"
1795
+ className="
1796
+ w-full px-4 py-2
1797
+ bg-background text-foreground
1798
+ border border-error rounded-md
1799
+ focus:outline-none focus:ring-2 focus:ring-error/50
1800
+ "
1801
+ />
1802
+ <p className="text-sm text-error">
1803
+ Password must be at least 8 characters.
1804
+ </p>
1805
+ </div>
1806
+ \`\`\`
1807
+
1808
+ ## Select Field
1809
+ \`\`\`tsx
1810
+ <div className="space-y-2">
1811
+ <label className="text-sm font-medium text-foreground">
1812
+ Country
1813
+ </label>
1814
+ <select className="
1815
+ w-full px-4 py-2
1816
+ bg-background text-foreground
1817
+ border rounded-md
1818
+ focus:outline-none focus:ring-2 focus:ring-primary/50
1819
+ ">
1820
+ <option value="">Select country</option>
1821
+ <option value="th">Thailand</option>
1822
+ <option value="us">United States</option>
1823
+ </select>
1824
+ </div>
1825
+ \`\`\`
1826
+
1827
+ ## Checkbox
1828
+ \`\`\`tsx
1829
+ <label className="flex items-center gap-2 cursor-pointer">
1830
+ <input
1831
+ type="checkbox"
1832
+ className="
1833
+ w-4 h-4 rounded
1834
+ border border-border
1835
+ text-primary
1836
+ focus:ring-2 focus:ring-primary/50
1837
+ "
1838
+ />
1839
+ <span className="text-sm text-foreground">
1840
+ I agree to the terms and conditions
1841
+ </span>
1842
+ </label>
1843
+ \`\`\`
1844
+
1845
+ ## Form Layout
1846
+ \`\`\`tsx
1847
+ <form className="space-y-6 max-w-md mx-auto">
1848
+ {/* Form fields */}
1849
+
1850
+ <button
1851
+ type="submit"
1852
+ className="
1853
+ w-full bg-primary text-primary-foreground
1854
+ py-2 rounded-lg font-medium
1855
+ hover:bg-primary/90
1856
+ transition-all duration-200
1857
+ "
1858
+ >
1859
+ Submit
1860
+ </button>
1861
+ </form>
1862
+ \`\`\`
1863
+ `;
1864
+
1865
+ Write('design-system/patterns/forms.md', formsPattern);
1866
+
1867
+ output(`
1868
+ ✅ Pattern files generated:
1869
+ - design-system/patterns/buttons.md
1870
+ - design-system/patterns/scroll-animations.md
1871
+ - design-system/patterns/decorations.md
1872
+ - design-system/patterns/cards.md
1873
+ - design-system/patterns/forms.md
1874
+ `);
1045
1875
  ```
1046
1876
 
1047
1877
  ---
1048
1878
 
1049
- ## STEP 6: Final Report
1879
+ ## STEP 5.7: Generate Lean STYLE_GUIDE.md (Human-Readable)
1880
+
1881
+ > **Human-readable guide** - No code, just descriptions and visuals
1882
+
1883
+ ```javascript
1884
+ output(`
1885
+ 🔄 Generating lean STYLE_GUIDE.md (human-readable)...
1886
+ `);
1887
+
1888
+ const styleGuideMD = `# ${selectedStyle.style} Design System
1050
1889
 
1890
+ > **Style:** ${selectedStyle.style}
1891
+ > **Theme:** ${selectedTheme.name}
1892
+ > **Generated:** ${new Date().toISOString().split('T')[0]}
1893
+ > **Sources:** ${Object.keys(extractedData).join(', ')}
1894
+
1895
+ ---
1896
+
1897
+ ## 1. Overview
1898
+
1899
+ This design system follows **${selectedStyle.style}** aesthetics with a **${selectedTheme.name}** theme.
1900
+
1901
+ ### Feel
1902
+ ${selectedStyle.feel}
1903
+
1904
+ ### Characteristics
1905
+ ${selectedStyle.characteristics.map(c => `- ${c}`).join('\n')}
1906
+
1907
+ ---
1908
+
1909
+ ## 2. Color Palette
1910
+
1911
+ ### Primary Color
1912
+ - **Color:** ${tokensData.colors.primary.DEFAULT}
1913
+ - **Use for:** CTAs, links, accents, interactive elements
1914
+ - **Feel:** ${selectedStyle.feel}
1915
+
1916
+ ### Secondary Color
1917
+ - **Color:** ${tokensData.colors.secondary.DEFAULT}
1918
+ - **Use for:** Secondary actions, less prominent elements
1919
+
1920
+ ### Background Colors
1921
+ - **Main:** ${tokensData.colors.background.DEFAULT} (white)
1922
+ - **Muted:** ${tokensData.colors.background.muted} (subtle sections)
1923
+ - **Subtle:** ${tokensData.colors.background.subtle} (alternating sections)
1924
+
1925
+ ### Text Colors
1926
+ - **Primary text:** ${tokensData.colors.foreground.DEFAULT}
1927
+ - **Muted text:** ${tokensData.colors.foreground.muted}
1928
+ - **Subtle text:** ${tokensData.colors.foreground.subtle}
1929
+
1930
+ ### Semantic Colors
1931
+ - **Success:** ${tokensData.colors.semantic.success} (green)
1932
+ - **Warning:** ${tokensData.colors.semantic.warning} (amber)
1933
+ - **Error:** ${tokensData.colors.semantic.error} (red)
1934
+ - **Info:** ${tokensData.colors.semantic.info} (blue)
1935
+
1936
+ ---
1937
+
1938
+ ## 3. Typography
1939
+
1940
+ ### Font Family
1941
+ - **Primary:** ${tokensData.typography.font_family.sans}
1942
+ - **Monospace:** ${tokensData.typography.font_family.mono}
1943
+
1944
+ ### Heading Sizes
1945
+ - **H1:** 48px bold - Hero headlines
1946
+ - **H2:** 36px bold - Section titles
1947
+ - **H3:** 30px semibold - Subsection titles
1948
+ - **H4:** 24px semibold - Card titles
1949
+ - **H5:** 20px medium - Feature titles
1950
+ - **H6:** 18px medium - Small titles
1951
+
1952
+ ### Body Text
1953
+ - **Large:** 18px - Feature descriptions
1954
+ - **Base:** 16px - Body text
1955
+ - **Small:** 14px - Captions, labels
1956
+ - **Extra small:** 12px - Badges, tags
1957
+
1958
+ ---
1959
+
1960
+ ## 4. Spacing System
1961
+
1962
+ ### Base Unit
1963
+ ${tokensData.spacing.grid_base} grid system
1964
+
1965
+ ### Scale
1966
+ ${tokensData.spacing.scale.map(s => `- ${s}px`).join('\n')}
1967
+
1968
+ ### Common Patterns
1969
+ - **Component padding:** 16px or 24px
1970
+ - **Section gap:** 32px or 48px
1971
+ - **Layout margin:** 64px or 96px
1972
+
1973
+ ---
1974
+
1975
+ ## 5. Shadows & Elevation
1976
+
1977
+ ### Elevation Levels
1978
+ - **Level 0:** No shadow (flat elements)
1979
+ - **Level 1:** Subtle shadow (buttons on hover)
1980
+ - **Level 2:** Medium shadow (cards)
1981
+ - **Level 3:** Large shadow (dropdowns)
1982
+ - **Level 4:** Extra large shadow (modals)
1983
+
1984
+ ### Usage
1985
+ - **Cards:** Medium shadow
1986
+ - **Dropdowns:** Large shadow
1987
+ - **Modals:** Extra large shadow
1988
+ - **Button hover:** Subtle shadow
1989
+
1990
+ ---
1991
+
1992
+ ## 6. Border Radius
1993
+
1994
+ ### Values
1995
+ ${tokensData.borders.radius.map(r => `- ${r}`).join('\n')}
1996
+
1997
+ ### Usage
1998
+ - **Inputs:** Medium radius (8px)
1999
+ - **Buttons:** Large radius (12px)
2000
+ - **Cards:** Extra large radius (16px)
2001
+ - **Avatars:** Full radius (circle)
2002
+
2003
+ ---
2004
+
2005
+ ## 7. Theme: ${selectedTheme.name}
2006
+
2007
+ ### Description
2008
+ ${selectedTheme.description}
2009
+
2010
+ ### Feeling
2011
+ ${selectedTheme.feeling || selectedTheme.description}
2012
+
2013
+ ### Decorative Elements to USE
2014
+ ${selectedTheme.decorative_elements.map(e => `- ✅ ${e}`).join('\n')}
2015
+
2016
+ ### Elements to AVOID
2017
+ ${selectedTheme.avoid_elements.length > 0 ? selectedTheme.avoid_elements.map(e => `- ❌ ${e}`).join('\n') : '- (none specified)'}
2018
+
2019
+ ### Suggested Icons
2020
+ ${selectedTheme.icons_suggestion?.join(', ') || 'Lucide icons'}
2021
+
2022
+ ---
2023
+
2024
+ ## 8. Animations
2025
+
2026
+ ### Enabled
2027
+ ${tokensData.animations.enabled ? 'Yes' : 'No'}
2028
+
2029
+ ### Libraries
2030
+ ${tokensData.animations.libraries.map(l => `- ${l.name}`).join('\n') || '- CSS/Tailwind only'}
2031
+
2032
+ ### Selected Patterns
2033
+ ${selectedAnimations.length > 0 ? selectedAnimations.map(a => `- ${a}`).join('\n') : '- No scroll animations'}
2034
+
2035
+ ### Component Animations
2036
+ - **Button hover:** ${tokensData.animations.component_animations.button_hover}
2037
+ - **Card hover:** ${tokensData.animations.component_animations.card_hover}
2038
+ - **Input focus:** ${tokensData.animations.component_animations.input_focus}
2039
+
2040
+ ### Timing
2041
+ - **Fast:** 150ms (micro-interactions)
2042
+ - **Normal:** 200ms (most transitions)
2043
+ - **Slow:** 300ms (modals, page transitions)
2044
+
2045
+ ---
2046
+
2047
+ ## 9. Component Library
2048
+
2049
+ ### Recommended
2050
+ ${tokensData.component_library.name}
2051
+
2052
+ ### Common Components
2053
+ ${tokensData.component_library.common_components.map(c => `- ${c}`).join('\n')}
2054
+
2055
+ ---
2056
+
2057
+ ## 10. Code Patterns
2058
+
2059
+ **For code examples, see:**
2060
+ - \`design-system/patterns/buttons.md\`
2061
+ - \`design-system/patterns/cards.md\`
2062
+ - \`design-system/patterns/forms.md\`
2063
+ - \`design-system/patterns/scroll-animations.md\`
2064
+ - \`design-system/patterns/decorations.md\`
2065
+
2066
+ ---
2067
+
2068
+ ## 11. Critical Rules
2069
+
2070
+ ### Colors
2071
+ - ❌ NO hardcoded hex values
2072
+ - ✅ USE theme tokens (bg-primary, text-foreground)
2073
+
2074
+ ### Spacing
2075
+ - ❌ NO arbitrary values (p-5, gap-7)
2076
+ - ✅ USE spacing scale (p-4, p-6, gap-8)
2077
+
2078
+ ### Consistency
2079
+ - ❌ NO mixing patterns
2080
+ - ✅ USE consistent patterns from tokens
2081
+
2082
+ ---
2083
+
2084
+ *Generated by /designsetup v2.0.0*
2085
+ *Sources: ${Object.keys(extractedData).join(', ')}*
2086
+ `;
2087
+
2088
+ Write('design-system/STYLE_GUIDE.md', styleGuideMD);
2089
+ output(`✅ STYLE_GUIDE.md generated (lean, human-readable, ~150 lines)`);
1051
2090
  ```
1052
- ✅ Design Setup Complete!
1053
2091
 
1054
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
2092
+ ---
1055
2093
 
1056
- 📁 Generated: design-system/STYLE_GUIDE.md
2094
+ ## STEP 6: Final Report
2095
+
2096
+ ```javascript
2097
+ output(`
2098
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
2099
+ ✅ Design Setup Complete!
2100
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1057
2101
 
1058
2102
  📊 Summary:
1059
- - Style: ${selectedOption.name}
1060
- - Fit Score: ${selectedOption.fit_score}%
1061
- - Sources: ${Object.keys(extractedData).join(', ')}
1062
- - Sections: 17/17 complete
1063
- - Lines: ~${styleGuideMD.split('\n').length}
2103
+ Style: ${selectedStyle.style} (from ${selectedStyle.site})
2104
+ Theme: ${selectedTheme.name}
2105
+ Sources: ${Object.keys(extractedData).join(', ')}
2106
+ Animations: ${selectedAnimations.length} patterns enabled
2107
+
2108
+ 🎨 Style Characteristics:
2109
+ ${selectedStyle.characteristics.slice(0, 4).map(c => ` • ${c}`).join('\n')}
1064
2110
 
1065
- 🎨 Key Features:
1066
- ${selectedOption.advantages.slice(0, 4).map(a => ` ✓ ${a}`).join('\n')}
2111
+ 🎭 Theme Direction:
2112
+ USE: ${selectedTheme.decorative_elements.slice(0, 3).join(', ')}
2113
+ AVOID: ${selectedTheme.avoid_elements.slice(0, 2).join(', ') || '(none)'}
2114
+
2115
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1067
2116
 
1068
2117
  📦 Files Created:
1069
- ✓ design-system/STYLE_GUIDE.md (final guide, ~2000 lines)
1070
- ✓ design-system/STYLE_TOKENS.json (lightweight tokens, ~500 tokens) 🆕
1071
- ✓ design-system/synthesis/options/ (${styleOptions.options.length} YAMLs)
1072
2118
 
1073
- ⚠️ Trade-offs:
1074
- ${selectedOption.disadvantages.slice(0, 2).map(d => ` • ${d}`).join('\n')}
2119
+ 🤖 FOR AGENTS (code patterns):
2120
+ ✓ design-system/tokens.json (~800 tokens)
2121
+ ✓ design-system/patterns/buttons.md
2122
+ ✓ design-system/patterns/cards.md
2123
+ ✓ design-system/patterns/forms.md
2124
+ ✓ design-system/patterns/scroll-animations.md
2125
+ ✓ design-system/patterns/decorations.md
1075
2126
 
1076
- 🎯 Component Sources:
1077
- - Colors: ${selectedOption.sources.colors}
1078
- - Shadows: ${selectedOption.sources.shadows}
1079
- - Typography: ${selectedOption.sources.typography}
1080
- - Animations: ${selectedOption.sources.button_hover}, ${selectedOption.sources.card_hover}
2127
+ 👤 FOR HUMANS (no code):
2128
+ ✓ design-system/STYLE_GUIDE.md (~150 lines)
1081
2129
 
1082
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
2130
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1083
2131
 
1084
2132
  🚀 Next Steps:
1085
2133
 
1086
2134
  1. Review generated files:
1087
- - Full guide: cat design-system/STYLE_GUIDE.md | head -100
1088
- - Tokens: cat design-system/STYLE_TOKENS.json
2135
+ cat design-system/tokens.json | head -50
2136
+ cat design-system/STYLE_GUIDE.md
2137
+
2138
+ 2. Plan your pages:
2139
+ /pageplan @prd.md @project.md
1089
2140
 
1090
- 2. Setup project (generates design-context.md):
1091
- /psetup
2141
+ 3. Setup & develop:
2142
+ /csetup feature-landing
2143
+ /cdev feature-landing
1092
2144
 
1093
- 3. Start development:
1094
- /csetup feature-login
1095
- /cdev feature-login
2145
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1096
2146
 
1097
- 4. Context Optimization (v1.2.0):
1098
- ✅ Commands use STYLE_TOKENS.json (~500 tokens, not full guide ~5K)
1099
- Agents load design-context.md + STYLE_TOKENS.json (~1.5K total)
1100
- 70% token reduction while maintaining quality ✨
2147
+ 📖 How It Works:
2148
+
2149
+ /pageplan reads:
2150
+ tokens.json (style, theme, colors, animations)
2151
+ → Auto-detects page type (landing/dashboard/auth)
2152
+ → Loads patterns/*.md selectively
2153
+
2154
+ uxui-frontend agent reads:
2155
+ → tokens.json (all tokens)
2156
+ → patterns/buttons.md (always)
2157
+ → patterns/cards.md (always)
2158
+ → patterns/scroll-animations.md (landing pages only)
2159
+ → patterns/decorations.md (landing pages only)
2160
+ → patterns/forms.md (forms only)
2161
+
2162
+ Token Savings: ~800 vs ~5000 (84% reduction) ✨
2163
+
2164
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
2165
+ `);
1101
2166
  ```
1102
2167
 
1103
2168
  ---