@champpaba/claude-agent-kit 3.6.0 → 3.6.2
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.
- package/package.json +1 -1
- package/skills/design-extract/CLAUDE.md +1 -0
- package/skills/design-extract/SKILL.md +6 -0
- package/skills/design-setup/CLAUDE.md +1 -0
- package/skills/design-setup/SKILL.md +6 -0
- package/skills/page-planner/SKILL.md +6 -0
- package/.claude/commands/designsetup.md +0 -1405
- package/.claude/commands/extract.md +0 -733
- package/.claude/commands/pageplan.md +0 -862
|
@@ -1,862 +0,0 @@
|
|
|
1
|
-
# /pageplan - Visual Page Planning
|
|
2
|
-
|
|
3
|
-
**Purpose:** Generate a visual page plan for UI implementation - component strategy, layout wireframes, animation blueprint, and asset checklist.
|
|
4
|
-
|
|
5
|
-
> **Note:** Content strategy and conversion copy are handled by `/csetup` (Adaptive Depth Research).
|
|
6
|
-
> This command focuses on **visual structure** only.
|
|
7
|
-
|
|
8
|
-
**Usage:**
|
|
9
|
-
```bash
|
|
10
|
-
# With context files
|
|
11
|
-
/pageplan @proposal.md @prd.md @project_brief.md
|
|
12
|
-
|
|
13
|
-
# Current change only (uses proposal.md in openspec/changes/)
|
|
14
|
-
/pageplan
|
|
15
|
-
|
|
16
|
-
# Specify change ID
|
|
17
|
-
/pageplan landing-page
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
---
|
|
21
|
-
|
|
22
|
-
## What This Command Does
|
|
23
|
-
|
|
24
|
-
1. **Reads User-Specified Context:**
|
|
25
|
-
- Only reads files that user mentions with `@` prefix
|
|
26
|
-
- Always reads `openspec/changes/{change-id}/proposal.md` (if exists)
|
|
27
|
-
- Always reads `openspec/changes/{change-id}/tasks.md` (for page type detection)
|
|
28
|
-
- **Always reads `openspec/changes/{change-id}/.claude/phases.md`** (if exists - for phase info) ✅ NEW v2.6.0
|
|
29
|
-
- **Always reads `design-system/data.yaml`** (design tokens + psychology, ~500 tokens) ✅
|
|
30
|
-
|
|
31
|
-
2. **Searches Existing Components:**
|
|
32
|
-
- Glob: `**/{Navbar,Footer,Sidebar,Header}*.{tsx,jsx,vue}`
|
|
33
|
-
- Grep: Common UI patterns
|
|
34
|
-
- Builds reuse vs new component list
|
|
35
|
-
|
|
36
|
-
3. **Generates page-plan.md:**
|
|
37
|
-
- Component plan (reuse vs new)
|
|
38
|
-
- Page structure (layout composition)
|
|
39
|
-
- Layout wireframe (ASCII art for Desktop/Tablet/Mobile)
|
|
40
|
-
- Animation blueprint (hover, focus, transition patterns)
|
|
41
|
-
- Asset checklist (images, icons to prepare)
|
|
42
|
-
|
|
43
|
-
4. **Outputs to:** `openspec/changes/{change-id}/page-plan.md`
|
|
44
|
-
|
|
45
|
-
> **Content & Conversion Strategy** → Handled by `/csetup` in `research-checklist.md`
|
|
46
|
-
|
|
47
|
-
---
|
|
48
|
-
|
|
49
|
-
## Implementation Instructions
|
|
50
|
-
|
|
51
|
-
### STEP 1: Detect Change Context
|
|
52
|
-
|
|
53
|
-
1. Determine the change ID:
|
|
54
|
-
- Check if user provided a change ID as command argument
|
|
55
|
-
- If not provided, search for the active change in `openspec/changes/`
|
|
56
|
-
- Look for the most recently modified change directory
|
|
57
|
-
|
|
58
|
-
**If no change ID found:**
|
|
59
|
-
```
|
|
60
|
-
❌ No active change found. Run after OpenSpec generates proposal.md
|
|
61
|
-
```
|
|
62
|
-
→ STOP
|
|
63
|
-
|
|
64
|
-
2. Set the output path:
|
|
65
|
-
- Output file: `openspec/changes/{changeId}/page-plan.md`
|
|
66
|
-
|
|
67
|
-
→ Continue to STEP 2
|
|
68
|
-
|
|
69
|
-
### STEP 2: Read Context Files
|
|
70
|
-
|
|
71
|
-
1. Extract user-mentioned files:
|
|
72
|
-
- Scan the user message for files mentioned with `@` prefix
|
|
73
|
-
- Example: `@prd.md`, `@brief.md`, `@project_brief.md`
|
|
74
|
-
- Store these as user files list
|
|
75
|
-
|
|
76
|
-
2. Define required file paths:
|
|
77
|
-
- Proposal: `openspec/changes/{changeId}/proposal.md`
|
|
78
|
-
- Tasks: `openspec/changes/{changeId}/tasks.md`
|
|
79
|
-
- Phases: `openspec/changes/{changeId}/.claude/phases.md`
|
|
80
|
-
- Design tokens: `design-system/data.yaml`
|
|
81
|
-
|
|
82
|
-
3. Build context files list:
|
|
83
|
-
- Start with user-mentioned files
|
|
84
|
-
- Add proposal.md path
|
|
85
|
-
- Filter to only files that exist on disk
|
|
86
|
-
|
|
87
|
-
4. Read all context files:
|
|
88
|
-
- Read each file in the context files list
|
|
89
|
-
- Join content with separator: `\n\n---\n\n`
|
|
90
|
-
- Store as base context
|
|
91
|
-
|
|
92
|
-
5. Read proposal.md separately (if exists):
|
|
93
|
-
- Used for individual analysis later
|
|
94
|
-
- Store as `proposalContent`
|
|
95
|
-
|
|
96
|
-
6. Read tasks.md (if exists):
|
|
97
|
-
- Used for page type detection (marketing vs dashboard)
|
|
98
|
-
- Store as `tasksContent`
|
|
99
|
-
|
|
100
|
-
7. Read phases.md (if exists):
|
|
101
|
-
- Check path: `openspec/changes/{changeId}/.claude/phases.md`
|
|
102
|
-
- Store as `phasesContent`
|
|
103
|
-
|
|
104
|
-
**If phases.md found:**
|
|
105
|
-
```
|
|
106
|
-
✅ phases.md Found - reading phase information
|
|
107
|
-
```
|
|
108
|
-
- Search for UI phase keywords: `uxui-frontend`, `frontend-mockup`, `Frontend Mockup`
|
|
109
|
-
- Count matches and report: `- UI phases detected: {count}`
|
|
110
|
-
|
|
111
|
-
**If phases.md NOT found:**
|
|
112
|
-
```
|
|
113
|
-
ℹ️ phases.md not found - run /csetup first if you want phase-aware planning
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
8. Extract brief content:
|
|
117
|
-
- Search user files for filename containing "brief"
|
|
118
|
-
- If found and exists, read it
|
|
119
|
-
- Store as `briefContent`
|
|
120
|
-
|
|
121
|
-
9. Load design tokens from data.yaml (if exists):
|
|
122
|
-
- Read `design-system/data.yaml`
|
|
123
|
-
- Parse as YAML
|
|
124
|
-
- Extract key design information:
|
|
125
|
-
- Primary color: `tokens.colors.primary.DEFAULT`
|
|
126
|
-
- Spacing scale: `tokens.spacing.scale` (array)
|
|
127
|
-
- Component library: `component_library.name`
|
|
128
|
-
- Shadows: Object keys from `tokens.shadows`
|
|
129
|
-
- Append to context with header: `# Design Tokens (data.yaml)`
|
|
130
|
-
- Include extracted values in readable format
|
|
131
|
-
|
|
132
|
-
**If data.yaml NOT found:**
|
|
133
|
-
```
|
|
134
|
-
⚠️ No data.yaml found - run /designsetup first
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
**Context size estimate:** ~1.5K tokens (data.yaml is lightweight)
|
|
138
|
-
|
|
139
|
-
→ Continue to STEP 3
|
|
140
|
-
|
|
141
|
-
### STEP 3: Search Existing Components
|
|
142
|
-
|
|
143
|
-
1. Define search patterns for common shared components:
|
|
144
|
-
- Navbar/Navigation: `**/{Navbar,Navigation}*.{tsx,jsx,vue}`
|
|
145
|
-
- Footer: `**/{Footer}*.{tsx,jsx,vue}`
|
|
146
|
-
- Sidebar/Drawer: `**/{Sidebar,Drawer}*.{tsx,jsx,vue}`
|
|
147
|
-
- Header: `**/{Header}*.{tsx,jsx,vue}`
|
|
148
|
-
|
|
149
|
-
2. For each search pattern:
|
|
150
|
-
- Run glob search to find matching files
|
|
151
|
-
- If matches found (length > 0):
|
|
152
|
-
- Extract component name from the first match file path
|
|
153
|
-
- Store component information:
|
|
154
|
-
- `name`: Component name (e.g., "Navbar")
|
|
155
|
-
- `path`: Full file path
|
|
156
|
-
- `exports`: Use grep to find exported functions/components
|
|
157
|
-
- Add to found components list
|
|
158
|
-
|
|
159
|
-
3. Build the found components list:
|
|
160
|
-
- Each entry contains: name, path, exports
|
|
161
|
-
- This list will be used to generate the "Reuse Components" section
|
|
162
|
-
|
|
163
|
-
→ Continue to STEP 4
|
|
164
|
-
|
|
165
|
-
### STEP 4: Analyze & Generate Plan
|
|
166
|
-
|
|
167
|
-
Based on context + found components, generate:
|
|
168
|
-
|
|
169
|
-
```markdown
|
|
170
|
-
# Page Plan: [Page Name]
|
|
171
|
-
> Generated from: [list of context files]
|
|
172
|
-
> Change ID: ${changeId}
|
|
173
|
-
|
|
174
|
-
## 1. Component Plan
|
|
175
|
-
|
|
176
|
-
### 🔄 Reuse Components (Found in codebase)
|
|
177
|
-
[For each found component]
|
|
178
|
-
- **[ComponentName]**
|
|
179
|
-
- Path: \`[path]\`
|
|
180
|
-
- Usage: \`<ComponentName prop="value" />\`
|
|
181
|
-
- Notes: [Any notes about usage]
|
|
182
|
-
|
|
183
|
-
### ✅ Create New Components
|
|
184
|
-
|
|
185
|
-
#### Shared Components (reusable across pages)
|
|
186
|
-
[Components that will be used in multiple pages]
|
|
187
|
-
- **[ComponentName]**
|
|
188
|
-
- Purpose: [description]
|
|
189
|
-
- Will be used in: [list pages]
|
|
190
|
-
- Store at: \`/components/[category]/[ComponentName].tsx\`
|
|
191
|
-
|
|
192
|
-
#### Page-Specific Components (used only here)
|
|
193
|
-
[Components for this page only]
|
|
194
|
-
- **[ComponentName]**
|
|
195
|
-
- Purpose: [description]
|
|
196
|
-
- Compose with: [other components]
|
|
197
|
-
- Store at: \`/app/[page]/[ComponentName].tsx\`
|
|
198
|
-
|
|
199
|
-
## 2. Page Structure
|
|
200
|
-
|
|
201
|
-
\`\`\`tsx
|
|
202
|
-
<Layout>
|
|
203
|
-
<ComponentA /> {/* Reuse */}
|
|
204
|
-
<ComponentB /> {/* New shared */}
|
|
205
|
-
<ComponentC /> {/* New specific */}
|
|
206
|
-
</Layout>
|
|
207
|
-
\`\`\`
|
|
208
|
-
|
|
209
|
-
## 2.5. 📐 Layout Wireframe (Visual Blueprint)
|
|
210
|
-
|
|
211
|
-
> **Purpose:** Visual representation of page layout for user review BEFORE implementation
|
|
212
|
-
|
|
213
|
-
### Desktop View (>1024px)
|
|
214
|
-
\`\`\`
|
|
215
|
-
┌────────────────────────────────────────────────────┐
|
|
216
|
-
│ [Logo] [Nav Menu] [CTA Button] │ ← Navbar (h-16, sticky)
|
|
217
|
-
├────────────────────────────────────────────────────┤
|
|
218
|
-
│ │
|
|
219
|
-
│ Hero Section │ ← Full viewport (h-screen)
|
|
220
|
-
│ [Large Headline] │ Background image
|
|
221
|
-
│ [Subheadline text] │ Centered content
|
|
222
|
-
│ [Primary CTA] │
|
|
223
|
-
│ │
|
|
224
|
-
├────────────────────────────────────────────────────┤
|
|
225
|
-
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
|
226
|
-
│ │ Card 1 │ │ Card 2 │ │ Card 3 │ │ ← Feature Grid
|
|
227
|
-
│ │ [Icon] │ │ [Icon] │ │ [Icon] │ │ (grid-cols-3, gap-6)
|
|
228
|
-
│ │ Title │ │ Title │ │ Title │ │ Container: max-w-7xl
|
|
229
|
-
│ │ Desc │ │ Desc │ │ Desc │ │ Padding: py-24
|
|
230
|
-
│ └──────────┘ └──────────┘ └──────────┘ │
|
|
231
|
-
├────────────────────────────────────────────────────┤
|
|
232
|
-
│ [Footer Links] [Social Icons] │ ← Footer (h-20)
|
|
233
|
-
└────────────────────────────────────────────────────┘
|
|
234
|
-
\`\`\`
|
|
235
|
-
|
|
236
|
-
### Tablet View (768-1023px)
|
|
237
|
-
\`\`\`
|
|
238
|
-
┌──────────────────────────────┐
|
|
239
|
-
│ [Logo] [Nav] [☰] │ ← Navbar (collapsed nav)
|
|
240
|
-
├──────────────────────────────┤
|
|
241
|
-
│ Hero Section │ ← h-[600px]
|
|
242
|
-
│ [Headline] │ Same layout, smaller
|
|
243
|
-
│ [CTA] │
|
|
244
|
-
├──────────────────────────────┤
|
|
245
|
-
│ ┌──────────┐ ┌──────────┐ │
|
|
246
|
-
│ │ Card 1 │ │ Card 2 │ │ ← Feature Grid
|
|
247
|
-
│ └──────────┘ └──────────┘ │ (grid-cols-2, gap-4)
|
|
248
|
-
│ ┌──────────┐ │
|
|
249
|
-
│ │ Card 3 │ │
|
|
250
|
-
│ └──────────┘ │
|
|
251
|
-
├──────────────────────────────┤
|
|
252
|
-
│ Footer (stacked) │
|
|
253
|
-
└──────────────────────────────┘
|
|
254
|
-
\`\`\`
|
|
255
|
-
|
|
256
|
-
### Mobile View (<768px)
|
|
257
|
-
\`\`\`
|
|
258
|
-
┌────────────────┐
|
|
259
|
-
│ [Logo] [☰] │ ← Navbar (hamburger)
|
|
260
|
-
├────────────────┤
|
|
261
|
-
│ Hero │ ← h-[500px]
|
|
262
|
-
│ [Headline] │ Smaller text
|
|
263
|
-
│ [CTA] │ Full-width button
|
|
264
|
-
├────────────────┤
|
|
265
|
-
│ ┌────────────┐ │
|
|
266
|
-
│ │ Card 1 │ │ ← Feature Grid
|
|
267
|
-
│ │ [Icon] │ │ (grid-cols-1, gap-4)
|
|
268
|
-
│ │ Title │ │ Full-width cards
|
|
269
|
-
│ └────────────┘ │
|
|
270
|
-
│ ┌────────────┐ │
|
|
271
|
-
│ │ Card 2 │ │
|
|
272
|
-
│ └────────────┘ │
|
|
273
|
-
│ ┌────────────┐ │
|
|
274
|
-
│ │ Card 3 │ │
|
|
275
|
-
│ └────────────┘ │
|
|
276
|
-
├────────────────┤
|
|
277
|
-
│ Footer │
|
|
278
|
-
│ (stacked) │
|
|
279
|
-
└────────────────┘
|
|
280
|
-
\`\`\`
|
|
281
|
-
|
|
282
|
-
### Spacing & Sizing Details
|
|
283
|
-
|
|
284
|
-
**Containers:**
|
|
285
|
-
- Hero: Full viewport height (h-screen desktop, h-[600px] tablet, h-[500px] mobile)
|
|
286
|
-
- Features: max-w-7xl, px-6, py-24 (desktop) → py-16 (tablet) → py-12 (mobile)
|
|
287
|
-
- Cards: Equal height, p-6 (desktop) → p-4 (mobile)
|
|
288
|
-
|
|
289
|
-
**Grid Breakpoints:**
|
|
290
|
-
- Desktop (>1024px): 3 columns (grid-cols-3)
|
|
291
|
-
- Tablet (768-1023px): 2 columns (grid-cols-2)
|
|
292
|
-
- Mobile (<768px): 1 column (grid-cols-1)
|
|
293
|
-
|
|
294
|
-
**Gaps:**
|
|
295
|
-
- Section gaps: gap-24 (desktop) → gap-16 (tablet) → gap-12 (mobile)
|
|
296
|
-
- Card gaps: gap-6 (desktop) → gap-4 (mobile)
|
|
297
|
-
|
|
298
|
-
### Responsive Behavior
|
|
299
|
-
|
|
300
|
-
| Element | Desktop | Tablet | Mobile |
|
|
301
|
-
|---------|---------|--------|--------|
|
|
302
|
-
| **Navbar** | Full menu | Collapsed | Hamburger |
|
|
303
|
-
| **Hero** | h-screen | h-[600px] | h-[500px] |
|
|
304
|
-
| **Feature Grid** | 3 cols | 2 cols | 1 col (stack) |
|
|
305
|
-
| **Cards** | Side-by-side | Wrap to 2 cols | Full-width stack |
|
|
306
|
-
| **Footer** | Horizontal | Stacked | Stacked |
|
|
307
|
-
|
|
308
|
-
---
|
|
309
|
-
|
|
310
|
-
## 2.6. 🎬 Animation Blueprint (Micro-interactions)
|
|
311
|
-
|
|
312
|
-
> **Purpose:** Define animation strategy BEFORE implementation to ensure consistency and polish
|
|
313
|
-
> **Source:** `design-system/data.yaml` (animation tokens)
|
|
314
|
-
> **Philosophy:** Match Flow Engineer Step 3 - Design animations systematically, not randomly
|
|
315
|
-
|
|
316
|
-
### Animation Principles
|
|
317
|
-
|
|
318
|
-
**From data.yaml:**
|
|
319
|
-
- **Durations:** 150ms (quick), 300ms (normal), 500ms (slow)
|
|
320
|
-
- **Easing:** ease-in-out (default), cubic-bezier for custom
|
|
321
|
-
- **Properties:** GPU-accelerated ONLY (transform, opacity) - NOT width, height, top, left
|
|
322
|
-
- **Consistency:** Same component type = same animation pattern
|
|
323
|
-
|
|
324
|
-
---
|
|
325
|
-
|
|
326
|
-
### Button Animations
|
|
327
|
-
|
|
328
|
-
#### Primary CTA Button
|
|
329
|
-
**Hover State:**
|
|
330
|
-
- Properties: `transform` (scale 1.05) + `box-shadow` (md → lg)
|
|
331
|
-
- Duration: 150ms (fast, responsive feel)
|
|
332
|
-
- Easing: ease-in-out
|
|
333
|
-
- Code: `transition-all duration-150 hover:scale-105 hover:shadow-lg`
|
|
334
|
-
|
|
335
|
-
**Active State:**
|
|
336
|
-
- Properties: `transform` (scale 0.95)
|
|
337
|
-
- Duration: 100ms (immediate feedback)
|
|
338
|
-
- Code: `active:scale-95`
|
|
339
|
-
|
|
340
|
-
**Loading State:**
|
|
341
|
-
- Properties: `opacity` (text → 70%), spinner fade-in
|
|
342
|
-
- Duration: 300ms
|
|
343
|
-
- Code: `disabled:opacity-70` + spinner component
|
|
344
|
-
|
|
345
|
-
**Full Example:**
|
|
346
|
-
Primary CTA button should include these Tailwind classes:
|
|
347
|
-
- Base styles: `px-6 py-3 bg-primary text-primary-foreground rounded-md`
|
|
348
|
-
- Transition: `transition-all duration-150`
|
|
349
|
-
- Hover effects: `hover:scale-105 hover:shadow-lg`
|
|
350
|
-
- Active state: `active:scale-95`
|
|
351
|
-
- Disabled state: `disabled:opacity-70`
|
|
352
|
-
- Button text: "Get Started" (or context-appropriate CTA)
|
|
353
|
-
|
|
354
|
-
#### Secondary Button
|
|
355
|
-
**Hover State:**
|
|
356
|
-
- Properties: `background-color` shift, `border-color` shift
|
|
357
|
-
- Duration: 150ms
|
|
358
|
-
- Code: `transition-colors duration-150 hover:bg-secondary/80`
|
|
359
|
-
|
|
360
|
-
---
|
|
361
|
-
|
|
362
|
-
### Card Animations
|
|
363
|
-
|
|
364
|
-
#### Feature Card / Product Card
|
|
365
|
-
**Hover State:**
|
|
366
|
-
- Properties: `box-shadow` elevation (sm → xl)
|
|
367
|
-
- Duration: 300ms (smooth, elegant)
|
|
368
|
-
- Easing: ease-in-out
|
|
369
|
-
- Code: `transition-shadow duration-300 hover:shadow-xl`
|
|
370
|
-
|
|
371
|
-
**Border Glow (Optional):**
|
|
372
|
-
- Properties: `border-color` subtle shift
|
|
373
|
-
- Duration: 300ms
|
|
374
|
-
- Code: `hover:border-primary/50`
|
|
375
|
-
|
|
376
|
-
**Full Example:**
|
|
377
|
-
Feature/product card container should include:
|
|
378
|
-
- Base styles: `p-6 bg-card border border-border rounded-lg`
|
|
379
|
-
- Transition: `transition-shadow duration-300`
|
|
380
|
-
- Hover effects: `hover:shadow-xl hover:border-primary/50`
|
|
381
|
-
- Content: Card content elements go inside container
|
|
382
|
-
|
|
383
|
-
#### Interactive Card (Clickable)
|
|
384
|
-
**Hover State:**
|
|
385
|
-
- Same as feature card + cursor pointer
|
|
386
|
-
- Code: `cursor-pointer transition-shadow duration-300 hover:shadow-xl`
|
|
387
|
-
|
|
388
|
-
**Active State:**
|
|
389
|
-
- Properties: `transform` (scale 0.98) - subtle press feedback
|
|
390
|
-
- Duration: 100ms
|
|
391
|
-
- Code: `active:scale-98`
|
|
392
|
-
|
|
393
|
-
---
|
|
394
|
-
|
|
395
|
-
### Input & Form Animations
|
|
396
|
-
|
|
397
|
-
#### Text Input / Select / Combobox
|
|
398
|
-
**Focus State:**
|
|
399
|
-
- Properties: `box-shadow` (ring-2 appears), `border-color` shift
|
|
400
|
-
- Duration: 200ms (balanced - not too fast, not slow)
|
|
401
|
-
- Easing: ease-in-out
|
|
402
|
-
- Code: `transition-all duration-200 focus:ring-2 focus:ring-primary focus:border-primary`
|
|
403
|
-
|
|
404
|
-
**Error State:**
|
|
405
|
-
- Properties: `border-color` (→ destructive), optional shake
|
|
406
|
-
- Duration: 300ms
|
|
407
|
-
- Code: `border-destructive` (static) or `animate-shake` (if shake defined)
|
|
408
|
-
|
|
409
|
-
**Full Example:**
|
|
410
|
-
Text input field should include:
|
|
411
|
-
- Base styles: `w-full px-3 py-2 border border-input rounded-md`
|
|
412
|
-
- Transition: `transition-all duration-200`
|
|
413
|
-
- Focus effects: `focus:ring-2 focus:ring-primary focus:border-primary`
|
|
414
|
-
- Placeholder styling: `placeholder:text-muted-foreground`
|
|
415
|
-
|
|
416
|
-
---
|
|
417
|
-
|
|
418
|
-
### Navigation Animations
|
|
419
|
-
|
|
420
|
-
#### Desktop Menu Hover
|
|
421
|
-
**Menu Item Hover:**
|
|
422
|
-
- Properties: `background-color` subtle shift
|
|
423
|
-
- Duration: 150ms
|
|
424
|
-
- Code: `transition-colors duration-150 hover:bg-accent`
|
|
425
|
-
|
|
426
|
-
#### Mobile Menu (Slide-in)
|
|
427
|
-
**Hamburger → Sidebar:**
|
|
428
|
-
- Properties: `transform` (translateX -100% → 0)
|
|
429
|
-
- Duration: 300ms
|
|
430
|
-
- Easing: cubic-bezier(0.4, 0, 0.2, 1)
|
|
431
|
-
- Library: Framer Motion or Tailwind transition
|
|
432
|
-
|
|
433
|
-
**Example (Framer Motion):**
|
|
434
|
-
Mobile sidebar with slide-in animation:
|
|
435
|
-
- Component: motion.div wrapper
|
|
436
|
-
- Initial state: `x: "-100%"` (off-screen left)
|
|
437
|
-
- Animate state: `x: 0` (slide to visible position)
|
|
438
|
-
- Exit state: `x: "-100%"` (slide back off-screen)
|
|
439
|
-
- Transition settings: `duration: 0.3`, `ease: [0.4, 0, 0.2, 1]`
|
|
440
|
-
- Content: Sidebar navigation elements inside wrapper
|
|
441
|
-
|
|
442
|
-
---
|
|
443
|
-
|
|
444
|
-
### Icon Animations
|
|
445
|
-
|
|
446
|
-
#### Chevron / Arrow (Dropdown)
|
|
447
|
-
**Expand/Collapse:**
|
|
448
|
-
- Properties: `transform` (rotate 0deg → 180deg)
|
|
449
|
-
- Duration: 200ms
|
|
450
|
-
- Code: `transition-transform duration-200 [data-state=open]:rotate-180`
|
|
451
|
-
|
|
452
|
-
#### Loading Spinner
|
|
453
|
-
**Continuous Rotation:**
|
|
454
|
-
- Properties: `transform` (rotate 360deg)
|
|
455
|
-
- Duration: 1000ms (1s per rotation)
|
|
456
|
-
- Easing: linear (consistent speed)
|
|
457
|
-
- Code: `animate-spin` (Tailwind utility)
|
|
458
|
-
|
|
459
|
-
---
|
|
460
|
-
|
|
461
|
-
### Modal / Dialog Animations
|
|
462
|
-
|
|
463
|
-
#### Modal Entrance
|
|
464
|
-
**Background Overlay:**
|
|
465
|
-
- Properties: `opacity` (0 → 100%)
|
|
466
|
-
- Duration: 200ms
|
|
467
|
-
- Code: `transition-opacity duration-200`
|
|
468
|
-
|
|
469
|
-
**Dialog Content:**
|
|
470
|
-
- Properties: `opacity` + `transform` (scale 0.95 → 1)
|
|
471
|
-
- Duration: 300ms
|
|
472
|
-
- Easing: ease-in-out
|
|
473
|
-
- Library: Framer Motion or Radix UI (built-in)
|
|
474
|
-
|
|
475
|
-
---
|
|
476
|
-
|
|
477
|
-
### Performance Guidelines
|
|
478
|
-
|
|
479
|
-
**GPU-accelerated (preferred):**
|
|
480
|
-
- `transform` (translate, scale, rotate)
|
|
481
|
-
- `opacity`
|
|
482
|
-
- `filter` (blur, brightness)
|
|
483
|
-
|
|
484
|
-
**Avoid for animations (CPU-intensive):**
|
|
485
|
-
- `width`, `height` (causes layout recalculation)
|
|
486
|
-
- `top`, `left`, `margin` (use `transform` instead)
|
|
487
|
-
- `font-size` (causes text reflow)
|
|
488
|
-
|
|
489
|
-
**Example:**
|
|
490
|
-
Wrong approach (causes reflow):
|
|
491
|
-
- Using `className="hover:w-full hover:h-auto"` triggers layout recalculation
|
|
492
|
-
- CPU-intensive, janky on mobile
|
|
493
|
-
|
|
494
|
-
Correct approach (GPU-accelerated):
|
|
495
|
-
- Use `className="hover:scale-105 transform"` instead
|
|
496
|
-
- Smooth 60fps animations on all devices
|
|
497
|
-
|
|
498
|
-
---
|
|
499
|
-
|
|
500
|
-
### Animation Consistency Checklist
|
|
501
|
-
|
|
502
|
-
**Before implementing components:**
|
|
503
|
-
- [ ] All buttons use scale + shadow pattern (150ms)
|
|
504
|
-
- [ ] All cards use shadow elevation pattern (300ms)
|
|
505
|
-
- [ ] All inputs use ring pattern (200ms)
|
|
506
|
-
- [ ] All durations from data.yaml (150/300/500ms)
|
|
507
|
-
- [ ] All properties GPU-accelerated (transform, opacity)
|
|
508
|
-
- [ ] No random durations (e.g., 200ms, 400ms) unless intentional
|
|
509
|
-
- [ ] Tested on mobile (animations not janky)
|
|
510
|
-
|
|
511
|
-
---
|
|
512
|
-
|
|
513
|
-
### Design Rationale
|
|
514
|
-
|
|
515
|
-
**Why these patterns?**
|
|
516
|
-
1. **Scale + Shadow (Buttons):** Creates depth, signals interactivity
|
|
517
|
-
2. **Shadow Elevation (Cards):** Subtle, elegant, matches Material Design
|
|
518
|
-
3. **Ring (Inputs):** Clear focus indicator, accessibility compliant
|
|
519
|
-
4. **Short Durations (150-300ms):** Feels responsive, not sluggish
|
|
520
|
-
5. **GPU Properties:** 60fps smooth animations, no jank
|
|
521
|
-
|
|
522
|
-
**Inspiration:** Based on extracted animations from reference sites + data.yaml
|
|
523
|
-
|
|
524
|
-
---
|
|
525
|
-
|
|
526
|
-
## 2.7. 🔄 UI States Definition
|
|
527
|
-
|
|
528
|
-
> **Purpose:** Define ALL possible states for each interactive component BEFORE implementation
|
|
529
|
-
> **Source:** Based on UX best practices and accessibility requirements
|
|
530
|
-
> **Philosophy:** Users should NEVER see a blank screen or unexplained error
|
|
531
|
-
|
|
532
|
-
### Why Define States Upfront?
|
|
533
|
-
|
|
534
|
-
1. **Prevents blank screens** - Empty state planned from start
|
|
535
|
-
2. **Better UX** - Loading indicators reduce perceived wait time
|
|
536
|
-
3. **Accessibility** - Screen readers need proper ARIA attributes
|
|
537
|
-
4. **Consistency** - Same state patterns across all components
|
|
538
|
-
|
|
539
|
-
---
|
|
540
|
-
|
|
541
|
-
### State Categories
|
|
542
|
-
|
|
543
|
-
For each interactive component/page section, define:
|
|
544
|
-
|
|
545
|
-
| State | When | Visual | Accessibility |
|
|
546
|
-
|-------|------|--------|---------------|
|
|
547
|
-
| **Empty** | No data exists | Illustration + CTA | `role="status"` |
|
|
548
|
-
| **Loading** | Fetching data | Skeleton/Spinner | `aria-busy="true"` |
|
|
549
|
-
| **Success** | Action completed | Checkmark + message | `aria-live="polite"` |
|
|
550
|
-
| **Error** | Something failed | Error message + retry | `role="alert"` |
|
|
551
|
-
| **Disabled** | Not available | Muted + explanation | `aria-disabled="true"` |
|
|
552
|
-
|
|
553
|
-
---
|
|
554
|
-
|
|
555
|
-
### State Definitions Per Component
|
|
556
|
-
|
|
557
|
-
#### [Component Name] States
|
|
558
|
-
|
|
559
|
-
**Empty State:**
|
|
560
|
-
- Visual: [Illustration description]
|
|
561
|
-
- Message: "[Friendly message explaining empty state]"
|
|
562
|
-
- CTA: [Button text and action]
|
|
563
|
-
- Example: "No notes yet. Start your first reflection!"
|
|
564
|
-
|
|
565
|
-
**Loading State:**
|
|
566
|
-
- Type: Skeleton / Spinner / Progress bar
|
|
567
|
-
- Min duration: 300ms (prevent flash)
|
|
568
|
-
- Placement: [Where loading indicator appears]
|
|
569
|
-
|
|
570
|
-
**Success State:**
|
|
571
|
-
- Visual: [Checkmark, animation, color]
|
|
572
|
-
- Message: "[Confirmation message]"
|
|
573
|
-
- Auto-dismiss: Yes/No (if yes, after X seconds)
|
|
574
|
-
- Next action: [Suggested next step]
|
|
575
|
-
|
|
576
|
-
**Error State:**
|
|
577
|
-
- Visual: [Error icon, border color]
|
|
578
|
-
- Message: "[Specific error description]"
|
|
579
|
-
- Recovery: [Retry button, help text]
|
|
580
|
-
- Inline vs Banner: [Where error appears]
|
|
581
|
-
|
|
582
|
-
**Disabled State:**
|
|
583
|
-
- Visual: [Opacity, cursor style]
|
|
584
|
-
- Reason: "[Why it's disabled]"
|
|
585
|
-
- When enabled: [Condition to enable]
|
|
586
|
-
|
|
587
|
-
---
|
|
588
|
-
|
|
589
|
-
### Example: Note List Component
|
|
590
|
-
|
|
591
|
-
\`\`\`
|
|
592
|
-
📝 Note List States:
|
|
593
|
-
|
|
594
|
-
Empty:
|
|
595
|
-
Visual: Notebook illustration (aria-hidden="true")
|
|
596
|
-
Message: "No reflections yet"
|
|
597
|
-
CTA: "Start Writing" → opens editor
|
|
598
|
-
|
|
599
|
-
Loading:
|
|
600
|
-
Type: Skeleton (3 note cards)
|
|
601
|
-
Duration: min 300ms
|
|
602
|
-
ARIA: aria-busy="true", aria-label="Loading notes"
|
|
603
|
-
|
|
604
|
-
Success (after save):
|
|
605
|
-
Visual: Green checkmark toast
|
|
606
|
-
Message: "Note saved!"
|
|
607
|
-
Auto-dismiss: 3 seconds
|
|
608
|
-
ARIA: role="status", aria-live="polite"
|
|
609
|
-
|
|
610
|
-
Error (failed to load):
|
|
611
|
-
Visual: Red banner at top
|
|
612
|
-
Message: "Unable to load notes. Check your connection."
|
|
613
|
-
CTA: "Retry" button
|
|
614
|
-
ARIA: role="alert"
|
|
615
|
-
|
|
616
|
-
Disabled (offline mode):
|
|
617
|
-
Visual: Muted colors, no hover effects
|
|
618
|
-
Message: "You're offline. Notes will sync when connected."
|
|
619
|
-
\`\`\`
|
|
620
|
-
|
|
621
|
-
---
|
|
622
|
-
|
|
623
|
-
### State Checklist
|
|
624
|
-
|
|
625
|
-
**Before implementing each component:**
|
|
626
|
-
|
|
627
|
-
- [ ] Empty state has friendly message + CTA
|
|
628
|
-
- [ ] Loading uses skeleton (content) or spinner (actions)
|
|
629
|
-
- [ ] Loading shows for minimum 300ms
|
|
630
|
-
- [ ] Success confirms action clearly
|
|
631
|
-
- [ ] Error explains what went wrong
|
|
632
|
-
- [ ] Error provides recovery action (retry/help)
|
|
633
|
-
- [ ] Disabled explains WHY
|
|
634
|
-
- [ ] All states have proper ARIA attributes
|
|
635
|
-
- [ ] Transitions between states are smooth (200ms)
|
|
636
|
-
- [ ] Reduced motion respected for transitions
|
|
637
|
-
|
|
638
|
-
---
|
|
639
|
-
|
|
640
|
-
## 3. 📦 Assets to Prepare (Performance-Optimized)
|
|
641
|
-
|
|
642
|
-
> **Performance Note:** Follow image optimization best practices for faster load times and better SEO.
|
|
643
|
-
> See: `.claude/contexts/patterns/performance-optimization.md`
|
|
644
|
-
|
|
645
|
-
### Images (Apply Performance Checklist)
|
|
646
|
-
|
|
647
|
-
**For each image, provide:**
|
|
648
|
-
|
|
649
|
-
- [ ] **filename.webp** (1920x1080)
|
|
650
|
-
→ **Source:** filename.jpg (compress to WebP, quality 85%)
|
|
651
|
-
→ **Responsive sizes:** 768w, 1024w, 1920w (generate 3 sizes for responsive)
|
|
652
|
-
→ **Loading strategy:**
|
|
653
|
-
- `loading="lazy"` (if below fold - most images)
|
|
654
|
-
- `loading="eager"` (if hero/above fold - rare)
|
|
655
|
-
→ **Alt text:** Descriptive alt text for accessibility
|
|
656
|
-
→ **Place at:** `/public/images/`
|
|
657
|
-
→ **Purpose:** [description - where used on page]
|
|
658
|
-
→ **Estimated size:** ~80KB WebP (was ~450KB JPEG) = **-82% reduction**
|
|
659
|
-
→ **LCP impact:** Hero images affect LCP score - optimize first!
|
|
660
|
-
|
|
661
|
-
**Example:**
|
|
662
|
-
```
|
|
663
|
-
- [ ] **hero-background.webp** (1920x1080)
|
|
664
|
-
→ Source: hero-background.jpg (compress via TinyPNG/Squoosh)
|
|
665
|
-
→ Sizes: hero-768.webp, hero-1024.webp, hero-1920.webp
|
|
666
|
-
→ Loading: eager (hero image, above fold)
|
|
667
|
-
→ Alt: "Students taking TOEIC exam in modern classroom"
|
|
668
|
-
→ Place: /public/images/
|
|
669
|
-
→ Purpose: Hero section background
|
|
670
|
-
→ Size: 85KB WebP (was 520KB JPEG) = -84%
|
|
671
|
-
```
|
|
672
|
-
|
|
673
|
-
### Icons
|
|
674
|
-
|
|
675
|
-
**Preferred format:** SVG (scalable, tiny file size)
|
|
676
|
-
|
|
677
|
-
- [ ] **[icon-name].svg** (24x24 viewBox)
|
|
678
|
-
→ **Format:** SVG (preferred) or PNG sprite (if 10+ icons)
|
|
679
|
-
→ **Optimization:** Remove unnecessary metadata (use SVGO)
|
|
680
|
-
→ **Place at:** `/public/icons/` or inline in component
|
|
681
|
-
→ **Style:** Match data.yaml colors
|
|
682
|
-
→ **Estimated size:** 1-3KB per icon
|
|
683
|
-
|
|
684
|
-
**If using 10+ icons:** Consider SVG sprite sheet (combine → 1 HTTP request)
|
|
685
|
-
|
|
686
|
-
### Other Assets
|
|
687
|
-
- [ ] **Fonts:** Use `font-display: swap` to prevent FOIT (Flash of Invisible Text)
|
|
688
|
-
- [ ] **Videos:** Use lazy loading, provide poster image
|
|
689
|
-
- [ ] **Third-party scripts:** Load async/defer when possible
|
|
690
|
-
|
|
691
|
-
---
|
|
692
|
-
|
|
693
|
-
## 4. Design Notes
|
|
694
|
-
|
|
695
|
-
**Design System Files:**
|
|
696
|
-
- Tokens + Psychology: \`design-system/data.yaml\` (agent reads this)
|
|
697
|
-
- Human summary: \`design-system/README.md\` (for humans)
|
|
698
|
-
|
|
699
|
-
**Key Design Tokens:**
|
|
700
|
-
- Primary color: [from data.yaml]
|
|
701
|
-
- Font family: [from data.yaml]
|
|
702
|
-
- Spacing scale: [from data.yaml]
|
|
703
|
-
- Component library: [from data.yaml]
|
|
704
|
-
- Shadows: [from data.yaml]
|
|
705
|
-
|
|
706
|
-
**Agent Instructions:**
|
|
707
|
-
- uxui-frontend reads data.yaml in STEP 0.5
|
|
708
|
-
- Use theme tokens (text-foreground/70) for theme-awareness
|
|
709
|
-
- Use spacing scale (p-4, p-6) for consistency
|
|
710
|
-
|
|
711
|
-
## 5. Implementation Notes
|
|
712
|
-
|
|
713
|
-
### Component Imports (Reference)
|
|
714
|
-
\`\`\`tsx
|
|
715
|
-
// Reuse
|
|
716
|
-
[import statements for reused components]
|
|
717
|
-
|
|
718
|
-
// shadcn/ui or component library
|
|
719
|
-
[import statements]
|
|
720
|
-
|
|
721
|
-
// New (to be created)
|
|
722
|
-
[import statements with comments]
|
|
723
|
-
\`\`\`
|
|
724
|
-
|
|
725
|
-
---
|
|
726
|
-
|
|
727
|
-
## Next Steps
|
|
728
|
-
1. ✅ Review layout wireframe & component plan
|
|
729
|
-
2. ✅ Prepare assets (images, icons) per checklist
|
|
730
|
-
3. ✅ Run \`/csetup ${changeId}\` for research & content strategy
|
|
731
|
-
4. ✅ Run \`/cdev ${changeId}\` to implement
|
|
732
|
-
```
|
|
733
|
-
|
|
734
|
-
### STEP 5: Write Output & Report
|
|
735
|
-
|
|
736
|
-
1. Write the page plan file:
|
|
737
|
-
- Path: `openspec/changes/{changeId}/page-plan.md`
|
|
738
|
-
- Content: The generated page plan from STEP 4
|
|
739
|
-
|
|
740
|
-
2. Count summary metrics:
|
|
741
|
-
- Found components: Count of reusable components found
|
|
742
|
-
- New shared components: Count of new shared components to create
|
|
743
|
-
- New specific components: Count of page-specific components to create
|
|
744
|
-
- Assets needed: Count of images/icons in checklist
|
|
745
|
-
- Content sections: Count of content sections generated
|
|
746
|
-
|
|
747
|
-
3. Report to user:
|
|
748
|
-
|
|
749
|
-
```
|
|
750
|
-
✅ Page plan generated!
|
|
751
|
-
|
|
752
|
-
📄 Output: openspec/changes/{changeId}/page-plan.md
|
|
753
|
-
|
|
754
|
-
📊 Summary:
|
|
755
|
-
- Found components: {count} (reuse)
|
|
756
|
-
- New shared: {count}
|
|
757
|
-
- New specific: {count}
|
|
758
|
-
- Assets needed: {count}
|
|
759
|
-
- Content sections: {count}
|
|
760
|
-
|
|
761
|
-
📝 Next Steps:
|
|
762
|
-
1. Review content in page-plan.md
|
|
763
|
-
2. Edit as needed (tone, messaging)
|
|
764
|
-
3. Prepare assets per checklist
|
|
765
|
-
4. Run: /csetup {changeId}
|
|
766
|
-
```
|
|
767
|
-
|
|
768
|
-
→ Done
|
|
769
|
-
|
|
770
|
-
---
|
|
771
|
-
|
|
772
|
-
## Example Scenarios
|
|
773
|
-
|
|
774
|
-
### Scenario 1: Landing Page (First page)
|
|
775
|
-
```bash
|
|
776
|
-
User: /pageplan @prd.md @project_brief.md
|
|
777
|
-
|
|
778
|
-
Result:
|
|
779
|
-
- Found components: 0 (empty project)
|
|
780
|
-
- New shared: Navbar, Footer (will reuse later)
|
|
781
|
-
- New specific: HeroSection, FeatureGrid
|
|
782
|
-
- Content: Headlines, descriptions from PRD
|
|
783
|
-
```
|
|
784
|
-
|
|
785
|
-
### Scenario 2: Dashboard (Has existing components)
|
|
786
|
-
```bash
|
|
787
|
-
User: /pageplan @prd.md
|
|
788
|
-
|
|
789
|
-
Result:
|
|
790
|
-
- Found components: Navbar ✅, Footer ✅
|
|
791
|
-
- New shared: Sidebar (for dashboard/profile/admin)
|
|
792
|
-
- New specific: DashboardStats, ActivityTimeline
|
|
793
|
-
- Content: Dashboard-specific text
|
|
794
|
-
```
|
|
795
|
-
|
|
796
|
-
### Scenario 3: Backend API (No UI)
|
|
797
|
-
```bash
|
|
798
|
-
User: /pageplan
|
|
799
|
-
|
|
800
|
-
Result:
|
|
801
|
-
- Error: "This change doesn't involve UI work. Skip /pageplan."
|
|
802
|
-
- OR: Detect from proposal.md and auto-skip
|
|
803
|
-
```
|
|
804
|
-
|
|
805
|
-
---
|
|
806
|
-
|
|
807
|
-
## Error Handling
|
|
808
|
-
|
|
809
|
-
1. **No change ID found:**
|
|
810
|
-
- Error: "No active change. Run after OpenSpec generates proposal."
|
|
811
|
-
|
|
812
|
-
2. **No @mentions and no proposal.md:**
|
|
813
|
-
- Error: "No context files provided. Use: /pageplan @prd.md"
|
|
814
|
-
|
|
815
|
-
3. **No UI work detected:**
|
|
816
|
-
- Warning: "This change appears to be backend/API work. /pageplan is for UI tasks."
|
|
817
|
-
- Ask: "Continue anyway? (Y/N)"
|
|
818
|
-
|
|
819
|
-
4. **data.yaml missing:**
|
|
820
|
-
- Warning: "No data.yaml found. Run /designsetup first for best results."
|
|
821
|
-
- Continue: Use general design principles as fallback
|
|
822
|
-
|
|
823
|
-
---
|
|
824
|
-
|
|
825
|
-
## Implementation Priority
|
|
826
|
-
|
|
827
|
-
**Critical:**
|
|
828
|
-
- ✅ Read user-specified files only
|
|
829
|
-
- ✅ Search existing components
|
|
830
|
-
- ✅ Generate component reuse plan
|
|
831
|
-
- ✅ Generate layout wireframe
|
|
832
|
-
- ✅ Generate animation blueprint
|
|
833
|
-
|
|
834
|
-
**Nice to have:**
|
|
835
|
-
- Asset checklist detail level
|
|
836
|
-
- Auto-detect UI vs backend tasks
|
|
837
|
-
- Suggest component classification
|
|
838
|
-
|
|
839
|
-
---
|
|
840
|
-
|
|
841
|
-
## Integration with Multi-Agent Flow
|
|
842
|
-
|
|
843
|
-
```
|
|
844
|
-
/designsetup → /pageplan → /csetup → /cdev
|
|
845
|
-
↓ ↓ ↓ ↓
|
|
846
|
-
data.yaml page-plan.md research uxui-frontend
|
|
847
|
-
patterns/ (visual) -checklist reads both
|
|
848
|
-
README.md (content)
|
|
849
|
-
```
|
|
850
|
-
|
|
851
|
-
**Separation of Concerns:**
|
|
852
|
-
- `/pageplan` = **Visual** (layout, components, animations, assets)
|
|
853
|
-
- `/csetup` = **Research** (best practices, content strategy, UX principles)
|
|
854
|
-
|
|
855
|
-
**Agent behavior:**
|
|
856
|
-
- `uxui-frontend`: Reads page-plan.md (visual) + research-checklist.md (content)
|
|
857
|
-
- `frontend`: May read page-plan.md for component locations
|
|
858
|
-
- Other agents: Ignore page-plan.md (not relevant)
|
|
859
|
-
|
|
860
|
-
---
|
|
861
|
-
|
|
862
|
-
**END OF COMMAND SPECIFICATION**
|