@champpaba/claude-agent-kit 1.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 (80) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +561 -0
  3. package/bin/cli.js +61 -0
  4. package/lib/init.js +52 -0
  5. package/lib/update.js +73 -0
  6. package/package.json +47 -0
  7. package/template/.claude/CHANGELOG-v1.1.1.md +259 -0
  8. package/template/.claude/CLAUDE.md +329 -0
  9. package/template/.claude/agents/01-integration.md +797 -0
  10. package/template/.claude/agents/02-uxui-frontend.md +899 -0
  11. package/template/.claude/agents/03-test-debug.md +759 -0
  12. package/template/.claude/agents/04-frontend.md +1099 -0
  13. package/template/.claude/agents/05-backend.md +1217 -0
  14. package/template/.claude/agents/06-database.md +969 -0
  15. package/template/.claude/commands/agentsetup.md +1464 -0
  16. package/template/.claude/commands/cdev.md +327 -0
  17. package/template/.claude/commands/csetup.md +447 -0
  18. package/template/.claude/commands/cstatus.md +60 -0
  19. package/template/.claude/commands/cview.md +364 -0
  20. package/template/.claude/commands/psetup.md +101 -0
  21. package/template/.claude/contexts/design/accessibility.md +611 -0
  22. package/template/.claude/contexts/design/box-thinking.md +553 -0
  23. package/template/.claude/contexts/design/color-theory.md +498 -0
  24. package/template/.claude/contexts/design/index.md +247 -0
  25. package/template/.claude/contexts/design/layout.md +400 -0
  26. package/template/.claude/contexts/design/responsive.md +551 -0
  27. package/template/.claude/contexts/design/shadows.md +522 -0
  28. package/template/.claude/contexts/design/spacing.md +428 -0
  29. package/template/.claude/contexts/design/typography.md +465 -0
  30. package/template/.claude/contexts/domain/README.md +164 -0
  31. package/template/.claude/contexts/patterns/agent-coordination.md +388 -0
  32. package/template/.claude/contexts/patterns/agent-discovery.md +182 -0
  33. package/template/.claude/contexts/patterns/change-workflow.md +538 -0
  34. package/template/.claude/contexts/patterns/code-standards.md +515 -0
  35. package/template/.claude/contexts/patterns/development-principles.md +513 -0
  36. package/template/.claude/contexts/patterns/error-handling.md +478 -0
  37. package/template/.claude/contexts/patterns/error-recovery.md +365 -0
  38. package/template/.claude/contexts/patterns/frontend-component-strategy.md +365 -0
  39. package/template/.claude/contexts/patterns/git-workflow.md +207 -0
  40. package/template/.claude/contexts/patterns/logging.md +424 -0
  41. package/template/.claude/contexts/patterns/task-breakdown.md +452 -0
  42. package/template/.claude/contexts/patterns/task-classification.md +523 -0
  43. package/template/.claude/contexts/patterns/tdd-classification.md +516 -0
  44. package/template/.claude/contexts/patterns/testing.md +413 -0
  45. package/template/.claude/contexts/patterns/ui-component-consistency.md +304 -0
  46. package/template/.claude/contexts/patterns/validation-framework.md +776 -0
  47. package/template/.claude/lib/README.md +39 -0
  48. package/template/.claude/lib/agent-executor.md +258 -0
  49. package/template/.claude/lib/agent-router.md +572 -0
  50. package/template/.claude/lib/flags-updater.md +469 -0
  51. package/template/.claude/lib/tdd-classifier.md +345 -0
  52. package/template/.claude/lib/validation-gates.md +484 -0
  53. package/template/.claude/settings.local.json +42 -0
  54. package/template/.claude/templates/context-template.md +45 -0
  55. package/template/.claude/templates/flags-template.json +42 -0
  56. package/template/.claude/templates/phase-templates.json +124 -0
  57. package/template/.claude/templates/phases-sections/accessibility-test.md +17 -0
  58. package/template/.claude/templates/phases-sections/api-design.md +37 -0
  59. package/template/.claude/templates/phases-sections/backend-tests.md +16 -0
  60. package/template/.claude/templates/phases-sections/backend.md +37 -0
  61. package/template/.claude/templates/phases-sections/business-logic-validation.md +16 -0
  62. package/template/.claude/templates/phases-sections/component-tests.md +17 -0
  63. package/template/.claude/templates/phases-sections/contract-backend.md +16 -0
  64. package/template/.claude/templates/phases-sections/contract-frontend.md +16 -0
  65. package/template/.claude/templates/phases-sections/database.md +35 -0
  66. package/template/.claude/templates/phases-sections/documentation.md +17 -0
  67. package/template/.claude/templates/phases-sections/e2e-tests.md +16 -0
  68. package/template/.claude/templates/phases-sections/fix-implementation.md +17 -0
  69. package/template/.claude/templates/phases-sections/frontend-integration.md +18 -0
  70. package/template/.claude/templates/phases-sections/frontend-mockup.md +123 -0
  71. package/template/.claude/templates/phases-sections/manual-flow-test.md +15 -0
  72. package/template/.claude/templates/phases-sections/manual-ux-test.md +16 -0
  73. package/template/.claude/templates/phases-sections/refactor-implementation.md +17 -0
  74. package/template/.claude/templates/phases-sections/refactor.md +16 -0
  75. package/template/.claude/templates/phases-sections/regression-tests.md +15 -0
  76. package/template/.claude/templates/phases-sections/report.md +16 -0
  77. package/template/.claude/templates/phases-sections/responsive-test.md +16 -0
  78. package/template/.claude/templates/phases-sections/script-implementation.md +43 -0
  79. package/template/.claude/templates/phases-sections/test-coverage.md +16 -0
  80. package/template/.claude/templates/phases-sections/user-approval.md +14 -0
@@ -0,0 +1,413 @@
1
+ # Testing Strategy & TDD Methodology
2
+
3
+ **Red-Green-Refactor:** Write test → Watch it fail → Write code → Make it pass → Refactor
4
+
5
+ ---
6
+
7
+ ## Test-Driven Development (TDD)
8
+
9
+ ### Automatic TDD Classification
10
+
11
+ **Orchestrator automatically determines if TDD is required based on task content.**
12
+
13
+ You don't decide. Orchestrator decides. Your job is to **follow the `tdd_required` flag**.
14
+
15
+ ### When You Receive a Task
16
+
17
+ **Check the metadata from Orchestrator:**
18
+ ```json
19
+ {
20
+ "description": "Implement POST /api/auth/login",
21
+ "type": "critical",
22
+ "tdd_required": true,
23
+ "workflow": "red-green-refactor",
24
+ "reason": "API endpoint + authentication logic"
25
+ }
26
+ ```
27
+
28
+ ### Classification Rules (Orchestrator Logic)
29
+
30
+ ✅ **TDD Required (`tdd_required: true`) for:**
31
+ - API mutations (POST, PUT, PATCH, DELETE)
32
+ - Business logic (calculations, transformations, validation)
33
+ - External service integrations (payment, email, SMS, storage)
34
+ - Data transformations (ETL, serialization, aggregations)
35
+ - Security operations (authentication, authorization, encryption)
36
+ - Complex UI logic (multi-step forms, state machines, accessibility)
37
+
38
+ ⚠️ **Test-Alongside OK (`tdd_required: false`) for:**
39
+ - Simple GET endpoints (read-only)
40
+ - Presentational UI components
41
+ - Simple CRUD operations
42
+ - Configuration files
43
+ - Trivial utilities
44
+
45
+ **Note:** For full classification logic, see `@.claude/contexts/patterns/task-classification.md`
46
+
47
+ ### TDD Workflow (Red-Green-Refactor)
48
+
49
+ **Use when:** `tdd_required: true`
50
+
51
+ ```
52
+ 1. RED Phase - Write the test first
53
+ → Define expected behavior before implementation
54
+ → Run test → MUST FAIL (proves test works)
55
+ → Log: "tdd_red_phase"
56
+
57
+ 2. GREEN Phase - Write minimal code
58
+ → Just enough to make the test pass
59
+ → Run test → MUST PASS
60
+ → Log: "tdd_green_phase"
61
+
62
+ 3. REFACTOR Phase - Improve code quality
63
+ → Add logging for observability
64
+ → Add error handling
65
+ → Add documentation
66
+ → Run test → MUST STILL PASS
67
+ → Log: "tdd_refactor_phase"
68
+
69
+ 4. Repeat
70
+ → One test at a time
71
+ ```
72
+
73
+ ### Standard Workflow (Test-Alongside)
74
+
75
+ **Use when:** `tdd_required: false`
76
+
77
+ ```
78
+ 1. Write implementation first
79
+ 2. Write tests to verify
80
+ 3. Run tests → PASS
81
+ ```
82
+
83
+ ---
84
+
85
+ ## Testing Layers
86
+
87
+ ### 1. Unit Tests
88
+
89
+ **Purpose:** Test individual functions/modules in isolation
90
+
91
+ **Framework:** Vitest (JS/TS) | Pytest (Python)
92
+
93
+ #### TypeScript Example
94
+
95
+ ```typescript
96
+ // __tests__/scoring.test.ts
97
+ import { describe, it, expect, vi } from 'vitest'
98
+ import { calculateDiscount } from '@/lib/pricing'
99
+ import { logger } from '@/lib/logger'
100
+
101
+ vi.mock('@/lib/logger')
102
+
103
+ describe('calculateDiscount', () => {
104
+ it('applies 10% discount for members', () => {
105
+ const result = calculateDiscount(100, { isMember: true })
106
+ expect(result).toBe(90)
107
+
108
+ expect(logger.info).toHaveBeenCalledWith(
109
+ 'discount_calculated',
110
+ expect.objectContaining({
111
+ originalPrice: 100,
112
+ discount: 10,
113
+ finalPrice: 90
114
+ })
115
+ )
116
+ })
117
+
118
+ it('no discount for non-members', () => {
119
+ const result = calculateDiscount(100, { isMember: false })
120
+ expect(result).toBe(100)
121
+ })
122
+
123
+ it('throws on invalid input', () => {
124
+ expect(() => calculateDiscount(-1, {})).toThrow('Price must be positive')
125
+ })
126
+ })
127
+ ```
128
+
129
+ #### Python Example
130
+
131
+ ```python
132
+ # tests/test_pricing.py
133
+ import pytest
134
+ from app.lib.pricing import calculate_discount
135
+ from unittest.mock import patch
136
+
137
+ @pytest.mark.parametrize("price,is_member,expected", [
138
+ (100, True, 90), # Member gets 10% discount
139
+ (100, False, 100), # Non-member no discount
140
+ (50, True, 45), # Member discount on lower price
141
+ ])
142
+ def test_calculate_discount(price, is_member, expected):
143
+ result = calculate_discount(price, is_member=is_member)
144
+ assert result == expected
145
+
146
+ def test_calculate_discount_invalid_price():
147
+ with pytest.raises(ValueError, match="Price must be positive"):
148
+ calculate_discount(-1, is_member=True)
149
+ ```
150
+
151
+ **When to use:**
152
+ - Pure functions
153
+ - Business logic
154
+ - Data transformations
155
+ - Utility functions
156
+
157
+ ---
158
+
159
+ ### 2. Integration Tests
160
+
161
+ **Purpose:** Test multiple components working together
162
+
163
+ #### API Route Test (Next.js)
164
+
165
+ ```typescript
166
+ // __tests__/api/items.test.ts
167
+ import { describe, it, expect, beforeEach } from 'vitest'
168
+ import { POST } from '@/app/api/items/route'
169
+
170
+ describe('POST /api/items', () => {
171
+ it('creates item and returns 201', async () => {
172
+ const request = new Request('http://localhost/api/items', {
173
+ method: 'POST',
174
+ headers: { 'Content-Type': 'application/json' },
175
+ body: JSON.stringify({
176
+ name: 'Test Item',
177
+ price: 99.99
178
+ })
179
+ })
180
+
181
+ const response = await POST(request)
182
+ const data = await response.json()
183
+
184
+ expect(response.status).toBe(201)
185
+ expect(data.id).toBeDefined()
186
+ expect(data.name).toBe('Test Item')
187
+ })
188
+
189
+ it('returns 400 on validation error', async () => {
190
+ const request = new Request('http://localhost/api/items', {
191
+ method: 'POST',
192
+ body: JSON.stringify({ name: '' }) // Missing price
193
+ })
194
+
195
+ const response = await POST(request)
196
+ expect(response.status).toBe(400)
197
+ })
198
+ })
199
+ ```
200
+
201
+ #### API Test (FastAPI)
202
+
203
+ ```python
204
+ # tests/test_api.py
205
+ import pytest
206
+ from httpx import AsyncClient
207
+
208
+ @pytest.mark.asyncio
209
+ async def test_create_item(client: AsyncClient):
210
+ response = await client.post("/api/items", json={
211
+ "name": "Test Item",
212
+ "price": 99.99
213
+ })
214
+
215
+ assert response.status_code == 201
216
+ data = response.json()
217
+ assert data["id"] is not None
218
+ assert data["name"] == "Test Item"
219
+
220
+ @pytest.mark.asyncio
221
+ async def test_create_item_validation_error(client: AsyncClient):
222
+ response = await client.post("/api/items", json={
223
+ "name": "" # Invalid
224
+ })
225
+
226
+ assert response.status_code == 422 # Validation error
227
+ ```
228
+
229
+ **When to use:**
230
+ - API routes
231
+ - Database operations
232
+ - External service integrations
233
+ - Multi-step workflows
234
+
235
+ ---
236
+
237
+ ### 3. E2E Tests (Playwright)
238
+
239
+ **Purpose:** Test complete user flows in real browser
240
+
241
+ ```typescript
242
+ // e2e/checkout.spec.ts
243
+ import { test, expect } from '@playwright/test'
244
+
245
+ test('user completes checkout flow', async ({ page }) => {
246
+ // Add item to cart
247
+ await page.goto('/products')
248
+ await page.click('button:text("Add to Cart")')
249
+
250
+ // Go to cart
251
+ await page.click('[href="/cart"]')
252
+ await expect(page.locator('h1')).toContainText('Shopping Cart')
253
+
254
+ // Proceed to checkout
255
+ await page.click('button:text("Checkout")')
256
+
257
+ // Fill shipping info
258
+ await page.fill('#name', 'John Doe')
259
+ await page.fill('#email', 'john@example.com')
260
+ await page.fill('#address', '123 Main St')
261
+ await page.click('button:text("Continue")')
262
+
263
+ // Payment
264
+ await page.fill('#cardNumber', '4242424242424242')
265
+ await page.fill('#expiry', '12/25')
266
+ await page.fill('#cvc', '123')
267
+ await page.click('button:text("Pay Now")')
268
+
269
+ // Verify order confirmation
270
+ await expect(page.locator('h1')).toContainText('Order Confirmed')
271
+ await expect(page.locator('[data-testid="order-number"]')).toBeVisible()
272
+ })
273
+
274
+ test('shows validation errors on empty form', async ({ page }) => {
275
+ await page.goto('/checkout')
276
+ await page.click('button:text("Continue")')
277
+
278
+ await expect(page.locator('text=Name is required')).toBeVisible()
279
+ await expect(page.locator('text=Email is required')).toBeVisible()
280
+ })
281
+ ```
282
+
283
+ **When to use:**
284
+ - Complete user journeys
285
+ - Cross-browser compatibility
286
+ - UI/UX validation
287
+ - Critical paths
288
+
289
+ ---
290
+
291
+ ## Testing Best Practices
292
+
293
+ ### DO:
294
+ - ✅ Test behavior, not implementation
295
+ - ✅ Write tests first for critical code (TDD)
296
+ - ✅ Mock external dependencies
297
+ - ✅ Use descriptive test names
298
+ - ✅ Test edge cases and error scenarios
299
+ - ✅ Keep tests fast (< 1s per test)
300
+ - ✅ Verify logging in tests
301
+
302
+ ### DON'T:
303
+ - ❌ Test framework internals (React hooks, etc.)
304
+ - ❌ Test trivial code (getters/setters)
305
+ - ❌ Write flaky tests (time-dependent)
306
+ - ❌ Skip error case tests
307
+ - ❌ Commit failing tests
308
+
309
+ ---
310
+
311
+ ## Test Organization
312
+
313
+ ### TypeScript/JavaScript
314
+ ```
315
+ project/
316
+ ├── __tests__/
317
+ │ ├── unit/
318
+ │ │ ├── lib/
319
+ │ │ │ ├── pricing.test.ts
320
+ │ │ │ └── validation.test.ts
321
+ │ │ └── utils/
322
+ │ │ └── formatters.test.ts
323
+ │ ├── integration/
324
+ │ │ ├── api/
325
+ │ │ │ ├── items.test.ts
326
+ │ │ │ └── users.test.ts
327
+ │ │ └── stores/
328
+ │ │ └── app-store.test.ts
329
+ │ └── e2e/
330
+ │ ├── checkout.spec.ts
331
+ │ └── auth.spec.ts
332
+ ├── vitest.config.ts
333
+ └── playwright.config.ts
334
+ ```
335
+
336
+ ### Python
337
+ ```
338
+ project/
339
+ ├── tests/
340
+ │ ├── unit/
341
+ │ │ ├── test_pricing.py
342
+ │ │ └── test_validation.py
343
+ │ ├── integration/
344
+ │ │ ├── test_api.py
345
+ │ │ └── test_db.py
346
+ │ └── conftest.py (fixtures)
347
+ └── pytest.ini
348
+ ```
349
+
350
+ ---
351
+
352
+ ## Coverage Guidelines
353
+
354
+ | Type | Target Coverage |
355
+ |------|----------------|
356
+ | Business Logic | 95%+ |
357
+ | API Routes | 90%+ |
358
+ | Utilities | 85%+ |
359
+ | UI Components | 85%+ |
360
+
361
+ ---
362
+
363
+ ## Quick Reference
364
+
365
+ ### Vitest Commands
366
+ ```bash
367
+ pnpm test # Run all tests
368
+ pnpm test -- --run # Run without watch mode
369
+ pnpm test -- path/to/test # Run specific test
370
+ pnpm test -- --coverage # Run with coverage
371
+ ```
372
+
373
+ ### Pytest Commands
374
+ ```bash
375
+ pytest # Run all tests
376
+ pytest -v # Verbose output
377
+ pytest tests/unit/ # Run specific directory
378
+ pytest --cov=app # Run with coverage
379
+ pytest -k "test_create" # Run tests matching pattern
380
+ ```
381
+
382
+ ### Playwright Commands
383
+ ```bash
384
+ pnpm test:e2e # Run E2E tests
385
+ pnpm test:e2e --ui # Run with UI mode
386
+ pnpm test:e2e --debug # Run with debugger
387
+ ```
388
+
389
+ ---
390
+
391
+ ---
392
+
393
+ ## Trust the Classification
394
+
395
+ **Orchestrator uses comprehensive pattern matching:**
396
+ - API endpoints (HTTP methods, routes)
397
+ - Business logic (calculations, validation)
398
+ - External integrations (Stripe, SendGrid, Twilio, S3, etc.)
399
+ - Data transformations (ETL, serialization)
400
+ - Security operations (auth, encryption)
401
+
402
+ **Your responsibility:**
403
+ 1. Check `tdd_required` flag in task metadata
404
+ 2. If `true` → Use Red-Green-Refactor workflow
405
+ 3. If `false` → Use Test-Alongside workflow
406
+ 4. Log each phase for observability
407
+
408
+ **Don't override the classification unless you find a clear error.**
409
+ If classification seems wrong, report to user for pattern refinement.
410
+
411
+ ---
412
+
413
+ **💡 Remember:** Tests are documentation. Write tests that explain what your code does!
@@ -0,0 +1,304 @@
1
+ # UI Component Visual Consistency
2
+
3
+ **Core Principle:** Before creating ANY UI component, extract and reuse design tokens from existing similar components to ensure 100% visual consistency.
4
+
5
+ ---
6
+
7
+ ## 🎯 The Problem
8
+
9
+ **Symptom:** New components look "slightly different" from existing ones.
10
+
11
+ **Common Issues:**
12
+ - Icon opacity: `opacity-50` vs `text-foreground/70`
13
+ - Spacing: `px-4` vs `px-3` (inconsistent padding)
14
+ - Colors: `text-gray-500` vs `text-foreground/70` (hardcoded vs theme-aware)
15
+ - Border radius: `rounded` vs `rounded-md` (inconsistent corners)
16
+
17
+ **Root Cause:**
18
+ - ❌ Agent creates component without checking existing ones
19
+ - ❌ No visual comparison with reference components
20
+ - ❌ Missing design token extraction step
21
+ - ❌ No cross-component validation
22
+
23
+ ---
24
+
25
+ ## 📋 Mandatory Workflow
26
+
27
+ **ALWAYS follow these 6 steps before creating UI components:**
28
+
29
+ ### Step 1: Search for Similar Components
30
+
31
+ ```bash
32
+ # Find components with similar functionality
33
+ Glob: "**/*{Field,Input,Select,Dropdown}*.{tsx,jsx,vue}"
34
+ Grep: "ChevronDown"
35
+ Grep: "dropdown.*icon"
36
+ ```
37
+
38
+ **Questions to ask:**
39
+ - Is there a component with similar user interaction?
40
+ - What component has the same visual element (icon, border, shadow)?
41
+ - Which component shares the same state behavior (focus, error, disabled)?
42
+
43
+ ---
44
+
45
+ ### Step 2: Extract Design Tokens
46
+
47
+ **Read reference component and document these properties:**
48
+
49
+ #### Icon Properties
50
+ ```typescript
51
+ const ICON_TOKENS = {
52
+ component: 'ChevronDown', // Which icon?
53
+ size: 'h-4 w-4', // Dimensions
54
+ color: 'text-foreground/70', // ⚠️ NOT opacity-50
55
+ position: 'right-3 top-1/2 -translate-y-1/2', // Absolute positioning
56
+ pointer: 'pointer-events-none', // Interaction
57
+ }
58
+ ```
59
+
60
+ #### Input/Select Properties
61
+ ```typescript
62
+ const INPUT_TOKENS = {
63
+ padding: 'pl-3 pr-10 py-2', // pr-10 = space for icon
64
+ border: 'border-input',
65
+ borderError: 'border-destructive',
66
+ borderRadius: 'rounded-md',
67
+ background: 'bg-background',
68
+ text: 'text-foreground',
69
+ placeholder: 'placeholder:text-muted-foreground',
70
+
71
+ // States
72
+ focus: 'focus:ring-2 focus:ring-primary focus:ring-offset-2',
73
+ disabled: 'disabled:opacity-50 disabled:cursor-not-allowed',
74
+ transition: 'transition-colors',
75
+ }
76
+ ```
77
+
78
+ #### Layout Structure
79
+ ```typescript
80
+ const LAYOUT_TOKENS = {
81
+ wrapper: 'relative', // Required for absolute icon positioning
82
+ input: 'appearance-none', // Hide native select arrow
83
+ icon: 'absolute', // Icon positioning
84
+ }
85
+ ```
86
+
87
+ ---
88
+
89
+ ### Step 3: Apply Tokens to New Component
90
+
91
+ **Example: Creating ComboboxField**
92
+
93
+ ```typescript
94
+ // ❌ WRONG - Custom values without reference
95
+ <div>
96
+ <select className="px-4 py-3">...</select>
97
+ <ChevronDown className="opacity-50 h-5 w-5" />
98
+ </div>
99
+
100
+ // ✅ CORRECT - Extracted tokens from FormField
101
+ <div className="relative">
102
+ <Combobox className="appearance-none pl-3 pr-10 py-2 rounded-md border border-input">
103
+ ...
104
+ </Combobox>
105
+ <ChevronDown className="absolute right-3 top-1/2 -translate-y-1/2 h-4 w-4 text-foreground/70 pointer-events-none" />
106
+ </div>
107
+ ```
108
+
109
+ **Key Rules:**
110
+ 1. Use **exact same classes** for identical elements
111
+ 2. Prefer **theme tokens** (`text-foreground/70`) over hardcoded colors (`text-gray-500`)
112
+ 3. Match **spacing patterns** exactly (`pl-3 pr-10 py-2`)
113
+ 4. Reuse **state classes** (focus, hover, disabled)
114
+
115
+ ---
116
+
117
+ ### Step 4: Visual Comparison Test
118
+
119
+ **Use Browser DevTools to compare pixel-by-pixel:**
120
+
121
+ 1. Open page with both components side-by-side
122
+ 2. Press F12 → Inspect Element
123
+ 3. Compare CSS computed values:
124
+
125
+ ```css
126
+ /* Icon - Must match exactly */
127
+ width: 16px /* h-4 */
128
+ height: 16px /* w-4 */
129
+ right: 12px /* right-3 (0.75rem) */
130
+ top: 50% /* top-1/2 */
131
+ transform: translateY(-50%) /* -translate-y-1/2 */
132
+ opacity: 0.7 /* text-foreground/70 */
133
+
134
+ /* Input - Must match exactly */
135
+ padding-left: 12px /* pl-3 */
136
+ padding-right: 40px /* pr-10 */
137
+ padding-top: 8px /* py-2 */
138
+ padding-bottom: 8px /* py-2 */
139
+ border-radius: 6px /* rounded-md */
140
+ ```
141
+
142
+ 4. **If values differ → STOP and fix immediately**
143
+
144
+ ---
145
+
146
+ ### Step 5: State Consistency Check
147
+
148
+ **Test every interactive state:**
149
+
150
+ | State | Expected Behavior |
151
+ |-------|------------------|
152
+ | Normal | Icon visible, clear contrast |
153
+ | Hover | Cursor changes if interactive |
154
+ | Focus | Ring appears (same color/offset as reference) |
155
+ | Error | Border becomes `border-destructive` |
156
+ | Disabled | `opacity-50` + `cursor-not-allowed` |
157
+
158
+ **Compare each state with reference component → Must be identical**
159
+
160
+ ---
161
+
162
+ ### Step 6: Document Design Reference
163
+
164
+ **Add JSDoc comment with design lineage:**
165
+
166
+ ```typescript
167
+ /**
168
+ * ComboboxField - Searchable dropdown field
169
+ *
170
+ * VISUAL CONSISTENCY:
171
+ * - Extracted design tokens from: components/ui/form-field.tsx
172
+ * - Icon: ChevronDown (h-4 w-4, text-foreground/70, right-3)
173
+ * - Matches FormField: focus ring, error states, spacing
174
+ * - States tested: normal, focus, error, disabled
175
+ *
176
+ * @see components/ui/form-field.tsx - Reference component
177
+ */
178
+ export function ComboboxField({ ... }) {
179
+ // Implementation
180
+ }
181
+ ```
182
+
183
+ ---
184
+
185
+ ## 🚨 Red Flags (Stop Immediately)
186
+
187
+ ### ❌ Hardcoded Colors
188
+ ```typescript
189
+ // WRONG
190
+ className="text-gray-500" // Not theme-aware
191
+ className="bg-blue-600" // Hardcoded color
192
+
193
+ // CORRECT
194
+ className="text-foreground/70" // Theme token
195
+ className="bg-primary" // Theme token
196
+ ```
197
+
198
+ ### ❌ Non-Standard Opacity/Size
199
+ ```typescript
200
+ // WRONG
201
+ className="opacity-50" // Too light for foreground
202
+ className="h-5 w-5" // Larger than standard
203
+
204
+ // CORRECT
205
+ className="text-foreground/70" // Standard opacity via color
206
+ className="h-4 w-4" // Standard icon size
207
+ ```
208
+
209
+ ### ❌ Inconsistent Spacing
210
+ ```typescript
211
+ // WRONG
212
+ className="px-4 py-3" // Different from FormField
213
+
214
+ // CORRECT
215
+ className="pl-3 pr-10 py-2" // Matches FormField exactly
216
+ ```
217
+
218
+ ### ❌ Visual Discrepancy
219
+ - **If it "looks different" → STOP**
220
+ - Open browser side-by-side
221
+ - Compare with DevTools
222
+ - Fix before proceeding
223
+
224
+ ---
225
+
226
+ ## 📊 Common Design Tokens Reference
227
+
228
+ ### Dropdown Components
229
+ ```typescript
230
+ // Icon
231
+ size: 'h-4 w-4'
232
+ color: 'text-foreground/70' // ⚠️ NOT opacity-50
233
+ position: 'right-3 top-1/2 -translate-y-1/2'
234
+
235
+ // Container
236
+ padding: 'pl-3 pr-10 py-2' // pr-10 for icon space
237
+ border: 'rounded-md border border-input'
238
+ focus: 'focus:ring-2 focus:ring-primary focus:ring-offset-2'
239
+ ```
240
+
241
+ ### Input Components
242
+ ```typescript
243
+ padding: 'px-3 py-2'
244
+ border: 'rounded-md border border-input'
245
+ background: 'bg-background'
246
+ text: 'text-foreground'
247
+ placeholder: 'placeholder:text-muted-foreground'
248
+ ```
249
+
250
+ ### Button Components
251
+ ```typescript
252
+ height: 'h-10'
253
+ padding: 'px-4 py-2'
254
+ borderRadius: 'rounded-md'
255
+ fontWeight: 'font-medium'
256
+ transition: 'transition-colors'
257
+ ```
258
+
259
+ ---
260
+
261
+ ## ✅ Quick Checklist
262
+
263
+ **Before committing any UI component:**
264
+
265
+ - [ ] Found similar reference component in codebase
266
+ - [ ] Extracted all design tokens (icon, spacing, colors, states)
267
+ - [ ] Applied tokens exactly (no guessing)
268
+ - [ ] Tested visual appearance in browser
269
+ - [ ] Compared computed CSS values with DevTools
270
+ - [ ] Tested all states (normal, hover, focus, error, disabled)
271
+ - [ ] Documented reference component in JSDoc
272
+ - [ ] Visually indistinguishable from reference component
273
+
274
+ ---
275
+
276
+ ## 🎯 Summary
277
+
278
+ **One-Sentence Rule:**
279
+ > "Before creating a UI component → Find the most similar existing component → Extract its design tokens → Apply them exactly → Test that they're 100% identical"
280
+
281
+ **Prevention Strategy:**
282
+ 1. ✅ Search for reference component first
283
+ 2. ✅ Extract design tokens systematically
284
+ 3. ✅ Apply tokens without modification
285
+ 4. ✅ Validate visual consistency in browser
286
+ 5. ✅ Document design lineage
287
+
288
+ **Anti-Pattern:**
289
+ 1. ❌ Create component without checking existing ones
290
+ 2. ❌ Use custom values instead of extracted tokens
291
+ 3. ❌ Skip visual comparison test
292
+ 4. ❌ Commit without cross-component validation
293
+
294
+ ---
295
+
296
+ ## 📚 Related Patterns
297
+
298
+ - `@/.claude/contexts/patterns/frontend-component-strategy.md` - Component reuse strategy
299
+ - `@/.claude/contexts/design/index.md` - Design system foundation
300
+ - `@/.claude/contexts/design/box-thinking.md` - Layout analysis
301
+
302
+ ---
303
+
304
+ **Remember:** Visual consistency is not optional. Users notice when components "feel different" even if they can't articulate why.