@champpaba/claude-agent-kit 1.4.0 → 1.4.1
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/.claude/agents/02-uxui-frontend.md +111 -2
- package/.claude/commands/pageplan.md +369 -9
- package/.claude/contexts/design/box-thinking.md +358 -0
- package/.claude/contexts/patterns/animation-patterns.md +768 -0
- package/.claude/contexts/patterns/performance-optimization.md +421 -0
- package/.claude/contexts/patterns/ui-component-consistency.md +49 -2
- package/.claude/lib/agent-executor.md +69 -10
- package/.claude/templates/page-plan-example.md +131 -0
- package/README.md +102 -3
- package/bin/cli.js +0 -2
- package/lib/helpers.js +108 -0
- package/lib/init.js +18 -13
- package/lib/update.js +48 -31
- package/package.json +1 -1
|
@@ -94,16 +94,19 @@ Read: .changes/{change-id}/page-plan.md
|
|
|
94
94
|
- Suggest: User should run `/designsetup` to generate style guide
|
|
95
95
|
|
|
96
96
|
**If page-plan.md exists:**
|
|
97
|
-
- ✅ Read and load page-plan.md (contains component reuse plan, content draft, assets)
|
|
97
|
+
- ✅ Read and load page-plan.md (contains component reuse plan, content draft, assets, **animation blueprint**)
|
|
98
98
|
- Extract:
|
|
99
|
+
- **Section 2.6 - Animation Blueprint** (🆕 animation strategy for all components)
|
|
99
100
|
- Component reuse list (which components already exist)
|
|
100
101
|
- Component new list (which to create)
|
|
101
102
|
- Content draft (headlines, descriptions, copy)
|
|
102
103
|
- Asset paths (images, icons locations)
|
|
103
104
|
- **OPTIMIZATION:** Skip STEP 3 (component search) - page-plan already did this!
|
|
105
|
+
- **CRITICAL:** If Section 2.6 exists, animations are **pre-designed** - follow blueprint exactly
|
|
104
106
|
|
|
105
107
|
**If page-plan.md does NOT exist:**
|
|
106
108
|
- ℹ️ No page plan - will search for components manually in STEP 3
|
|
109
|
+
- ⚠️ No animation blueprint - fallback to `.claude/contexts/patterns/animation-patterns.md`
|
|
107
110
|
|
|
108
111
|
**Report when complete:**
|
|
109
112
|
```
|
|
@@ -122,8 +125,10 @@ Read: .changes/{change-id}/page-plan.md
|
|
|
122
125
|
|
|
123
126
|
📋 Page Plan: ✅ page-plan.md loaded (3 reuse, 2 new, 4 assets)
|
|
124
127
|
→ Will skip component search (STEP 3)
|
|
128
|
+
🎬 Animation Blueprint: ✅ Section 2.6 loaded (buttons, cards, inputs pre-designed)
|
|
125
129
|
OR
|
|
126
130
|
📋 Page Plan: ℹ️ Not found - will search components in STEP 3
|
|
131
|
+
🎬 Animation Blueprint: ⚠️ Not found - using animation-patterns.md (fallback)
|
|
127
132
|
|
|
128
133
|
🎯 Ready to create UI components!
|
|
129
134
|
```
|
|
@@ -198,10 +203,112 @@ const TOKENS = {
|
|
|
198
203
|
spacing: { padding: '[value]', gap: '[value]' },
|
|
199
204
|
colors: { bg: '[token]', text: '[token]' },
|
|
200
205
|
shadows: '[value]',
|
|
201
|
-
radius: '[value]'
|
|
206
|
+
radius: '[value]',
|
|
207
|
+
// 🆕 Animation tokens (MANDATORY - v1.4.0)
|
|
208
|
+
animation: {
|
|
209
|
+
hover: '[classes]', // e.g., hover:scale-105 hover:shadow-lg
|
|
210
|
+
focus: '[classes]', // e.g., focus:ring-2 focus:ring-primary
|
|
211
|
+
active: '[classes]', // e.g., active:scale-95
|
|
212
|
+
transition: '[value]', // e.g., transition-all duration-150
|
|
213
|
+
duration: '[token]', // e.g., 150ms, 300ms, 500ms (from STYLE_TOKENS.json)
|
|
214
|
+
easing: '[token]', // e.g., ease-in-out
|
|
215
|
+
description: '[rationale]' // Why this animation pattern?
|
|
216
|
+
}
|
|
202
217
|
}
|
|
203
218
|
```
|
|
204
219
|
|
|
220
|
+
**Animation Token Extraction Rules:**
|
|
221
|
+
1. ✅ Extract from reference component (STEP 3 search results)
|
|
222
|
+
2. ✅ Fallback to page-plan.md Section 2.6 (if exists)
|
|
223
|
+
3. ✅ Fallback to animation-patterns.md (component patterns)
|
|
224
|
+
4. ✅ Use durations from STYLE_TOKENS.json (150ms, 300ms, 500ms)
|
|
225
|
+
5. ❌ NO random durations (200ms, 250ms, 400ms)
|
|
226
|
+
6. ❌ NO random patterns (button A scales, button B changes color)
|
|
227
|
+
|
|
228
|
+
### 📋 Step 4.5: Performance Optimization Checklist (MANDATORY)
|
|
229
|
+
|
|
230
|
+
**→ See:** `.claude/contexts/patterns/performance-optimization.md` for complete guide
|
|
231
|
+
|
|
232
|
+
**Before implementing ANY component, apply these optimizations:**
|
|
233
|
+
|
|
234
|
+
#### **Images (Primary Focus)**
|
|
235
|
+
|
|
236
|
+
- [ ] **Format:** Use WebP with fallback (NOT JPEG/PNG only)
|
|
237
|
+
```tsx
|
|
238
|
+
// ✅ CORRECT
|
|
239
|
+
<picture>
|
|
240
|
+
<source srcset="hero.webp" type="image/webp">
|
|
241
|
+
<img src="hero.jpg" alt="Hero" loading="lazy" />
|
|
242
|
+
</picture>
|
|
243
|
+
|
|
244
|
+
// ❌ WRONG
|
|
245
|
+
<img src="hero.jpg" alt="Hero" />
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
- [ ] **Lazy Loading:** `loading="lazy"` for below-fold images
|
|
249
|
+
```tsx
|
|
250
|
+
// ✅ Below fold (most images)
|
|
251
|
+
<img src="product.webp" alt="Product" loading="lazy" width={400} height={300} />
|
|
252
|
+
|
|
253
|
+
// ✅ Above fold (hero only)
|
|
254
|
+
<img src="hero.webp" alt="Hero" loading="eager" width={1920} height={1080} />
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
- [ ] **Dimensions:** ALWAYS specify width/height (prevent layout shift)
|
|
258
|
+
```tsx
|
|
259
|
+
// ✅ CORRECT (prevents CLS)
|
|
260
|
+
<img src="product.webp" alt="Product" width={400} height={300} />
|
|
261
|
+
|
|
262
|
+
// ❌ WRONG (causes layout shift)
|
|
263
|
+
<img src="product.webp" alt="Product" />
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
- [ ] **Responsive Images:** Generate 3 sizes for images > 400px width
|
|
267
|
+
```tsx
|
|
268
|
+
// ✅ CORRECT (mobile saves bandwidth)
|
|
269
|
+
<img
|
|
270
|
+
src="hero-1920.webp"
|
|
271
|
+
srcset="hero-768.webp 768w, hero-1024.webp 1024w, hero-1920.webp 1920w"
|
|
272
|
+
sizes="(max-width: 768px) 100vw, 1920px"
|
|
273
|
+
alt="Hero"
|
|
274
|
+
width={1920}
|
|
275
|
+
height={1080}
|
|
276
|
+
/>
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
#### **Code (Secondary Focus)**
|
|
280
|
+
|
|
281
|
+
- [ ] **Lazy Load Heavy Components:** Use dynamic imports for charts, modals, editors
|
|
282
|
+
```tsx
|
|
283
|
+
// ✅ CORRECT (only load when needed)
|
|
284
|
+
const HeavyChart = dynamic(() => import('./HeavyChart'), {
|
|
285
|
+
loading: () => <div>Loading...</div>,
|
|
286
|
+
ssr: false
|
|
287
|
+
})
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
- [ ] **Use React.memo() for expensive components:** Prevent unnecessary re-renders
|
|
291
|
+
```tsx
|
|
292
|
+
// ✅ CORRECT (memoize expensive list)
|
|
293
|
+
export const ProductList = memo(function ProductList({ products }) {
|
|
294
|
+
return products.map(product => <ProductCard key={product.id} {...product} />)
|
|
295
|
+
})
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
#### **Quick Validation**
|
|
299
|
+
|
|
300
|
+
**Before committing code, verify:**
|
|
301
|
+
1. All images have `width` and `height` attributes ✓
|
|
302
|
+
2. Below-fold images have `loading="lazy"` ✓
|
|
303
|
+
3. Hero images use `loading="eager"` ✓
|
|
304
|
+
4. Using WebP format (with fallback) ✓
|
|
305
|
+
5. No arbitrary spacing values (use spacing scale) ✓
|
|
306
|
+
|
|
307
|
+
**Performance Impact:**
|
|
308
|
+
- LCP: -50-60% (faster hero image load)
|
|
309
|
+
- Bundle size: -30-40% (code splitting)
|
|
310
|
+
- Image size: -80% (WebP + compression)
|
|
311
|
+
|
|
205
312
|
### 📋 Step 5: Pre-Implementation Report (REQUIRED)
|
|
206
313
|
|
|
207
314
|
Provide complete analysis covering steps 1-4 BEFORE writing code.
|
|
@@ -230,6 +337,8 @@ Provide complete analysis covering steps 1-4 BEFORE writing code.
|
|
|
230
337
|
- @.claude/contexts/design/accessibility.md
|
|
231
338
|
- @.claude/contexts/patterns/ui-component-consistency.md (CRITICAL!)
|
|
232
339
|
- @.claude/contexts/patterns/frontend-component-strategy.md
|
|
340
|
+
- @.claude/contexts/patterns/animation-patterns.md (Animations & micro-interactions)
|
|
341
|
+
- @.claude/contexts/patterns/performance-optimization.md (Image optimization, lazy loading)
|
|
233
342
|
|
|
234
343
|
### Project-Specific (If Exists)
|
|
235
344
|
- `design-system/STYLE_GUIDE.md` (Priority #1 - loaded in STEP 0.5)
|
|
@@ -163,20 +163,380 @@ Based on context + found components, generate:
|
|
|
163
163
|
</Layout>
|
|
164
164
|
\`\`\`
|
|
165
165
|
|
|
166
|
-
##
|
|
166
|
+
## 2.5. 📐 Layout Wireframe (Visual Blueprint)
|
|
167
167
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
168
|
+
> **Purpose:** Visual representation of page layout for user review BEFORE implementation
|
|
169
|
+
|
|
170
|
+
### Desktop View (>1024px)
|
|
171
|
+
\`\`\`
|
|
172
|
+
┌────────────────────────────────────────────────────┐
|
|
173
|
+
│ [Logo] [Nav Menu] [CTA Button] │ ← Navbar (h-16, sticky)
|
|
174
|
+
├────────────────────────────────────────────────────┤
|
|
175
|
+
│ │
|
|
176
|
+
│ Hero Section │ ← Full viewport (h-screen)
|
|
177
|
+
│ [Large Headline] │ Background image
|
|
178
|
+
│ [Subheadline text] │ Centered content
|
|
179
|
+
│ [Primary CTA] │
|
|
180
|
+
│ │
|
|
181
|
+
├────────────────────────────────────────────────────┤
|
|
182
|
+
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
|
183
|
+
│ │ Card 1 │ │ Card 2 │ │ Card 3 │ │ ← Feature Grid
|
|
184
|
+
│ │ [Icon] │ │ [Icon] │ │ [Icon] │ │ (grid-cols-3, gap-6)
|
|
185
|
+
│ │ Title │ │ Title │ │ Title │ │ Container: max-w-7xl
|
|
186
|
+
│ │ Desc │ │ Desc │ │ Desc │ │ Padding: py-24
|
|
187
|
+
│ └──────────┘ └──────────┘ └──────────┘ │
|
|
188
|
+
├────────────────────────────────────────────────────┤
|
|
189
|
+
│ [Footer Links] [Social Icons] │ ← Footer (h-20)
|
|
190
|
+
└────────────────────────────────────────────────────┘
|
|
191
|
+
\`\`\`
|
|
192
|
+
|
|
193
|
+
### Tablet View (768-1023px)
|
|
194
|
+
\`\`\`
|
|
195
|
+
┌──────────────────────────────┐
|
|
196
|
+
│ [Logo] [Nav] [☰] │ ← Navbar (collapsed nav)
|
|
197
|
+
├──────────────────────────────┤
|
|
198
|
+
│ Hero Section │ ← h-[600px]
|
|
199
|
+
│ [Headline] │ Same layout, smaller
|
|
200
|
+
│ [CTA] │
|
|
201
|
+
├──────────────────────────────┤
|
|
202
|
+
│ ┌──────────┐ ┌──────────┐ │
|
|
203
|
+
│ │ Card 1 │ │ Card 2 │ │ ← Feature Grid
|
|
204
|
+
│ └──────────┘ └──────────┘ │ (grid-cols-2, gap-4)
|
|
205
|
+
│ ┌──────────┐ │
|
|
206
|
+
│ │ Card 3 │ │
|
|
207
|
+
│ └──────────┘ │
|
|
208
|
+
├──────────────────────────────┤
|
|
209
|
+
│ Footer (stacked) │
|
|
210
|
+
└──────────────────────────────┘
|
|
211
|
+
\`\`\`
|
|
212
|
+
|
|
213
|
+
### Mobile View (<768px)
|
|
214
|
+
\`\`\`
|
|
215
|
+
┌────────────────┐
|
|
216
|
+
│ [Logo] [☰] │ ← Navbar (hamburger)
|
|
217
|
+
├────────────────┤
|
|
218
|
+
│ Hero │ ← h-[500px]
|
|
219
|
+
│ [Headline] │ Smaller text
|
|
220
|
+
│ [CTA] │ Full-width button
|
|
221
|
+
├────────────────┤
|
|
222
|
+
│ ┌────────────┐ │
|
|
223
|
+
│ │ Card 1 │ │ ← Feature Grid
|
|
224
|
+
│ │ [Icon] │ │ (grid-cols-1, gap-4)
|
|
225
|
+
│ │ Title │ │ Full-width cards
|
|
226
|
+
│ └────────────┘ │
|
|
227
|
+
│ ┌────────────┐ │
|
|
228
|
+
│ │ Card 2 │ │
|
|
229
|
+
│ └────────────┘ │
|
|
230
|
+
│ ┌────────────┐ │
|
|
231
|
+
│ │ Card 3 │ │
|
|
232
|
+
│ └────────────┘ │
|
|
233
|
+
├────────────────┤
|
|
234
|
+
│ Footer │
|
|
235
|
+
│ (stacked) │
|
|
236
|
+
└────────────────┘
|
|
237
|
+
\`\`\`
|
|
238
|
+
|
|
239
|
+
### Spacing & Sizing Details
|
|
240
|
+
|
|
241
|
+
**Containers:**
|
|
242
|
+
- Hero: Full viewport height (h-screen desktop, h-[600px] tablet, h-[500px] mobile)
|
|
243
|
+
- Features: max-w-7xl, px-6, py-24 (desktop) → py-16 (tablet) → py-12 (mobile)
|
|
244
|
+
- Cards: Equal height, p-6 (desktop) → p-4 (mobile)
|
|
245
|
+
|
|
246
|
+
**Grid Breakpoints:**
|
|
247
|
+
- Desktop (>1024px): 3 columns (grid-cols-3)
|
|
248
|
+
- Tablet (768-1023px): 2 columns (grid-cols-2)
|
|
249
|
+
- Mobile (<768px): 1 column (grid-cols-1)
|
|
250
|
+
|
|
251
|
+
**Gaps:**
|
|
252
|
+
- Section gaps: gap-24 (desktop) → gap-16 (tablet) → gap-12 (mobile)
|
|
253
|
+
- Card gaps: gap-6 (desktop) → gap-4 (mobile)
|
|
254
|
+
|
|
255
|
+
### Responsive Behavior
|
|
256
|
+
|
|
257
|
+
| Element | Desktop | Tablet | Mobile |
|
|
258
|
+
|---------|---------|--------|--------|
|
|
259
|
+
| **Navbar** | Full menu | Collapsed | Hamburger |
|
|
260
|
+
| **Hero** | h-screen | h-[600px] | h-[500px] |
|
|
261
|
+
| **Feature Grid** | 3 cols | 2 cols | 1 col (stack) |
|
|
262
|
+
| **Cards** | Side-by-side | Wrap to 2 cols | Full-width stack |
|
|
263
|
+
| **Footer** | Horizontal | Stacked | Stacked |
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
## 2.6. 🎬 Animation Blueprint (Micro-interactions)
|
|
268
|
+
|
|
269
|
+
> **Purpose:** Define animation strategy BEFORE implementation to ensure consistency and polish
|
|
270
|
+
> **Source:** `design-system/STYLE_TOKENS.json` (animation tokens)
|
|
271
|
+
> **Philosophy:** Match Flow Engineer Step 3 - Design animations systematically, not randomly
|
|
272
|
+
|
|
273
|
+
### Animation Principles
|
|
274
|
+
|
|
275
|
+
**From STYLE_TOKENS.json:**
|
|
276
|
+
- **Durations:** 150ms (quick), 300ms (normal), 500ms (slow)
|
|
277
|
+
- **Easing:** ease-in-out (default), cubic-bezier for custom
|
|
278
|
+
- **Properties:** GPU-accelerated ONLY (transform, opacity) - NOT width, height, top, left
|
|
279
|
+
- **Consistency:** Same component type = same animation pattern
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
### Button Animations
|
|
284
|
+
|
|
285
|
+
#### Primary CTA Button
|
|
286
|
+
**Hover State:**
|
|
287
|
+
- Properties: `transform` (scale 1.05) + `box-shadow` (md → lg)
|
|
288
|
+
- Duration: 150ms (fast, responsive feel)
|
|
289
|
+
- Easing: ease-in-out
|
|
290
|
+
- Code: `transition-all duration-150 hover:scale-105 hover:shadow-lg`
|
|
291
|
+
|
|
292
|
+
**Active State:**
|
|
293
|
+
- Properties: `transform` (scale 0.95)
|
|
294
|
+
- Duration: 100ms (immediate feedback)
|
|
295
|
+
- Code: `active:scale-95`
|
|
296
|
+
|
|
297
|
+
**Loading State:**
|
|
298
|
+
- Properties: `opacity` (text → 70%), spinner fade-in
|
|
299
|
+
- Duration: 300ms
|
|
300
|
+
- Code: `disabled:opacity-70` + spinner component
|
|
301
|
+
|
|
302
|
+
**Full Example:**
|
|
303
|
+
```tsx
|
|
304
|
+
<button className="px-6 py-3 bg-primary text-primary-foreground rounded-md
|
|
305
|
+
transition-all duration-150
|
|
306
|
+
hover:scale-105 hover:shadow-lg
|
|
307
|
+
active:scale-95
|
|
308
|
+
disabled:opacity-70">
|
|
309
|
+
Get Started
|
|
310
|
+
</button>
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
#### Secondary Button
|
|
314
|
+
**Hover State:**
|
|
315
|
+
- Properties: `background-color` shift, `border-color` shift
|
|
316
|
+
- Duration: 150ms
|
|
317
|
+
- Code: `transition-colors duration-150 hover:bg-secondary/80`
|
|
318
|
+
|
|
319
|
+
---
|
|
320
|
+
|
|
321
|
+
### Card Animations
|
|
322
|
+
|
|
323
|
+
#### Feature Card / Product Card
|
|
324
|
+
**Hover State:**
|
|
325
|
+
- Properties: `box-shadow` elevation (sm → xl)
|
|
326
|
+
- Duration: 300ms (smooth, elegant)
|
|
327
|
+
- Easing: ease-in-out
|
|
328
|
+
- Code: `transition-shadow duration-300 hover:shadow-xl`
|
|
329
|
+
|
|
330
|
+
**Border Glow (Optional):**
|
|
331
|
+
- Properties: `border-color` subtle shift
|
|
332
|
+
- Duration: 300ms
|
|
333
|
+
- Code: `hover:border-primary/50`
|
|
334
|
+
|
|
335
|
+
**Full Example:**
|
|
336
|
+
```tsx
|
|
337
|
+
<div className="p-6 bg-card border border-border rounded-lg
|
|
338
|
+
transition-shadow duration-300
|
|
339
|
+
hover:shadow-xl hover:border-primary/50">
|
|
340
|
+
{/* Card content */}
|
|
341
|
+
</div>
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
#### Interactive Card (Clickable)
|
|
345
|
+
**Hover State:**
|
|
346
|
+
- Same as feature card + cursor pointer
|
|
347
|
+
- Code: `cursor-pointer transition-shadow duration-300 hover:shadow-xl`
|
|
348
|
+
|
|
349
|
+
**Active State:**
|
|
350
|
+
- Properties: `transform` (scale 0.98) - subtle press feedback
|
|
351
|
+
- Duration: 100ms
|
|
352
|
+
- Code: `active:scale-98`
|
|
353
|
+
|
|
354
|
+
---
|
|
355
|
+
|
|
356
|
+
### Input & Form Animations
|
|
357
|
+
|
|
358
|
+
#### Text Input / Select / Combobox
|
|
359
|
+
**Focus State:**
|
|
360
|
+
- Properties: `box-shadow` (ring-2 appears), `border-color` shift
|
|
361
|
+
- Duration: 200ms (balanced - not too fast, not slow)
|
|
362
|
+
- Easing: ease-in-out
|
|
363
|
+
- Code: `transition-all duration-200 focus:ring-2 focus:ring-primary focus:border-primary`
|
|
364
|
+
|
|
365
|
+
**Error State:**
|
|
366
|
+
- Properties: `border-color` (→ destructive), optional shake
|
|
367
|
+
- Duration: 300ms
|
|
368
|
+
- Code: `border-destructive` (static) or `animate-shake` (if shake defined)
|
|
369
|
+
|
|
370
|
+
**Full Example:**
|
|
371
|
+
```tsx
|
|
372
|
+
<input className="w-full px-3 py-2 border border-input rounded-md
|
|
373
|
+
transition-all duration-200
|
|
374
|
+
focus:ring-2 focus:ring-primary focus:border-primary
|
|
375
|
+
placeholder:text-muted-foreground" />
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
---
|
|
379
|
+
|
|
380
|
+
### Navigation Animations
|
|
381
|
+
|
|
382
|
+
#### Desktop Menu Hover
|
|
383
|
+
**Menu Item Hover:**
|
|
384
|
+
- Properties: `background-color` subtle shift
|
|
385
|
+
- Duration: 150ms
|
|
386
|
+
- Code: `transition-colors duration-150 hover:bg-accent`
|
|
387
|
+
|
|
388
|
+
#### Mobile Menu (Slide-in)
|
|
389
|
+
**Hamburger → Sidebar:**
|
|
390
|
+
- Properties: `transform` (translateX -100% → 0)
|
|
391
|
+
- Duration: 300ms
|
|
392
|
+
- Easing: cubic-bezier(0.4, 0, 0.2, 1)
|
|
393
|
+
- Library: Framer Motion or Tailwind transition
|
|
394
|
+
|
|
395
|
+
**Example (Framer Motion):**
|
|
396
|
+
```tsx
|
|
397
|
+
<motion.div
|
|
398
|
+
initial={{ x: "-100%" }}
|
|
399
|
+
animate={{ x: 0 }}
|
|
400
|
+
exit={{ x: "-100%" }}
|
|
401
|
+
transition={{ duration: 0.3, ease: [0.4, 0, 0.2, 1] }}>
|
|
402
|
+
{/* Sidebar content */}
|
|
403
|
+
</motion.div>
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
---
|
|
407
|
+
|
|
408
|
+
### Icon Animations
|
|
409
|
+
|
|
410
|
+
#### Chevron / Arrow (Dropdown)
|
|
411
|
+
**Expand/Collapse:**
|
|
412
|
+
- Properties: `transform` (rotate 0deg → 180deg)
|
|
413
|
+
- Duration: 200ms
|
|
414
|
+
- Code: `transition-transform duration-200 [data-state=open]:rotate-180`
|
|
415
|
+
|
|
416
|
+
#### Loading Spinner
|
|
417
|
+
**Continuous Rotation:**
|
|
418
|
+
- Properties: `transform` (rotate 360deg)
|
|
419
|
+
- Duration: 1000ms (1s per rotation)
|
|
420
|
+
- Easing: linear (consistent speed)
|
|
421
|
+
- Code: `animate-spin` (Tailwind utility)
|
|
422
|
+
|
|
423
|
+
---
|
|
424
|
+
|
|
425
|
+
### Modal / Dialog Animations
|
|
426
|
+
|
|
427
|
+
#### Modal Entrance
|
|
428
|
+
**Background Overlay:**
|
|
429
|
+
- Properties: `opacity` (0 → 100%)
|
|
430
|
+
- Duration: 200ms
|
|
431
|
+
- Code: `transition-opacity duration-200`
|
|
432
|
+
|
|
433
|
+
**Dialog Content:**
|
|
434
|
+
- Properties: `opacity` + `transform` (scale 0.95 → 1)
|
|
435
|
+
- Duration: 300ms
|
|
436
|
+
- Easing: ease-in-out
|
|
437
|
+
- Library: Framer Motion or Radix UI (built-in)
|
|
438
|
+
|
|
439
|
+
---
|
|
440
|
+
|
|
441
|
+
### Performance Rules (CRITICAL!)
|
|
442
|
+
|
|
443
|
+
**✅ DO USE (GPU-accelerated):**
|
|
444
|
+
- `transform` (translate, scale, rotate)
|
|
445
|
+
- `opacity`
|
|
446
|
+
- `filter` (blur, brightness)
|
|
447
|
+
|
|
448
|
+
**❌ DON'T USE (CPU-intensive, causes reflow):**
|
|
449
|
+
- `width`, `height` (causes layout recalculation)
|
|
450
|
+
- `top`, `left`, `margin` (use `transform` instead)
|
|
451
|
+
- `font-size` (causes text reflow)
|
|
452
|
+
|
|
453
|
+
**Example:**
|
|
454
|
+
```tsx
|
|
455
|
+
// ❌ WRONG (causes reflow)
|
|
456
|
+
className="hover:w-full hover:h-auto"
|
|
457
|
+
|
|
458
|
+
// ✅ CORRECT (GPU-accelerated)
|
|
459
|
+
className="hover:scale-105 transform"
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
---
|
|
463
|
+
|
|
464
|
+
### Animation Consistency Checklist
|
|
465
|
+
|
|
466
|
+
**Before implementing components:**
|
|
467
|
+
- [ ] All buttons use scale + shadow pattern (150ms)
|
|
468
|
+
- [ ] All cards use shadow elevation pattern (300ms)
|
|
469
|
+
- [ ] All inputs use ring pattern (200ms)
|
|
470
|
+
- [ ] All durations from STYLE_TOKENS.json (150/300/500ms)
|
|
471
|
+
- [ ] All properties GPU-accelerated (transform, opacity)
|
|
472
|
+
- [ ] No random durations (e.g., 200ms, 400ms) unless intentional
|
|
473
|
+
- [ ] Tested on mobile (animations not janky)
|
|
474
|
+
|
|
475
|
+
---
|
|
476
|
+
|
|
477
|
+
### Design Rationale
|
|
478
|
+
|
|
479
|
+
**Why these patterns?**
|
|
480
|
+
1. **Scale + Shadow (Buttons):** Creates depth, signals interactivity
|
|
481
|
+
2. **Shadow Elevation (Cards):** Subtle, elegant, matches Material Design
|
|
482
|
+
3. **Ring (Inputs):** Clear focus indicator, accessibility compliant
|
|
483
|
+
4. **Short Durations (150-300ms):** Feels responsive, not sluggish
|
|
484
|
+
5. **GPU Properties:** 60fps smooth animations, no jank
|
|
485
|
+
|
|
486
|
+
**Inspiration:** Based on extracted animations from reference sites + STYLE_TOKENS.json
|
|
487
|
+
|
|
488
|
+
---
|
|
489
|
+
|
|
490
|
+
## 3. 📦 Assets to Prepare (Performance-Optimized)
|
|
491
|
+
|
|
492
|
+
> **Performance Note:** Follow image optimization best practices for faster load times and better SEO.
|
|
493
|
+
> See: `.claude/contexts/patterns/performance-optimization.md`
|
|
494
|
+
|
|
495
|
+
### Images (Apply Performance Checklist)
|
|
496
|
+
|
|
497
|
+
**For each image, provide:**
|
|
498
|
+
|
|
499
|
+
- [ ] **filename.webp** (1920x1080)
|
|
500
|
+
→ **Source:** filename.jpg (compress to WebP, quality 85%)
|
|
501
|
+
→ **Responsive sizes:** 768w, 1024w, 1920w (generate 3 sizes for responsive)
|
|
502
|
+
→ **Loading strategy:**
|
|
503
|
+
- `loading="lazy"` (if below fold - most images)
|
|
504
|
+
- `loading="eager"` (if hero/above fold - rare)
|
|
505
|
+
→ **Alt text:** Descriptive alt text for accessibility
|
|
506
|
+
→ **Place at:** `/public/images/`
|
|
507
|
+
→ **Purpose:** [description - where used on page]
|
|
508
|
+
→ **Estimated size:** ~80KB WebP (was ~450KB JPEG) = **-82% reduction**
|
|
509
|
+
→ **LCP impact:** Hero images affect LCP score - optimize first!
|
|
510
|
+
|
|
511
|
+
**Example:**
|
|
512
|
+
```
|
|
513
|
+
- [ ] **hero-background.webp** (1920x1080)
|
|
514
|
+
→ Source: hero-background.jpg (compress via TinyPNG/Squoosh)
|
|
515
|
+
→ Sizes: hero-768.webp, hero-1024.webp, hero-1920.webp
|
|
516
|
+
→ Loading: eager (hero image, above fold)
|
|
517
|
+
→ Alt: "Students taking TOEIC exam in modern classroom"
|
|
518
|
+
→ Place: /public/images/
|
|
519
|
+
→ Purpose: Hero section background
|
|
520
|
+
→ Size: 85KB WebP (was 520KB JPEG) = -84%
|
|
521
|
+
```
|
|
172
522
|
|
|
173
523
|
### Icons
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
524
|
+
|
|
525
|
+
**Preferred format:** SVG (scalable, tiny file size)
|
|
526
|
+
|
|
527
|
+
- [ ] **[icon-name].svg** (24x24 viewBox)
|
|
528
|
+
→ **Format:** SVG (preferred) or PNG sprite (if 10+ icons)
|
|
529
|
+
→ **Optimization:** Remove unnecessary metadata (use SVGO)
|
|
530
|
+
→ **Place at:** `/public/icons/` or inline in component
|
|
531
|
+
→ **Style:** Match STYLE_GUIDE colors
|
|
532
|
+
→ **Estimated size:** 1-3KB per icon
|
|
533
|
+
|
|
534
|
+
**If using 10+ icons:** Consider SVG sprite sheet (combine → 1 HTTP request)
|
|
177
535
|
|
|
178
536
|
### Other Assets
|
|
179
|
-
[Fonts
|
|
537
|
+
- [ ] **Fonts:** Use `font-display: swap` to prevent FOIT (Flash of Invisible Text)
|
|
538
|
+
- [ ] **Videos:** Use lazy loading, provide poster image
|
|
539
|
+
- [ ] **Third-party scripts:** Load async/defer when possible
|
|
180
540
|
|
|
181
541
|
---
|
|
182
542
|
|