@fr0mpy/component-system 2.1.1 → 3.1.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 (51) hide show
  1. package/README.md +86 -27
  2. package/bin/cli.js +155 -50
  3. package/bin/validate-compliance.js +447 -0
  4. package/bin/validate-config.js +175 -0
  5. package/bin/validate-harness.js +215 -0
  6. package/index.js +15 -0
  7. package/package.json +7 -4
  8. package/templates/agents/component-auditor.md +77 -0
  9. package/templates/agents/design-token-validator.md +72 -0
  10. package/templates/agents/harness-scaffolder.md +146 -0
  11. package/templates/agents/playwright-tester.md +437 -0
  12. package/templates/agents/style-inspector.md +81 -0
  13. package/templates/commands/component-harness.md +104 -10
  14. package/templates/commands/retheme.md +142 -0
  15. package/templates/commands/save-theme.md +50 -0
  16. package/templates/commands/setup-styling.md +386 -57
  17. package/templates/component-recipes/accordion.md +9 -9
  18. package/templates/component-recipes/alert.md +36 -23
  19. package/templates/component-recipes/avatar.md +14 -12
  20. package/templates/component-recipes/badge.md +9 -6
  21. package/templates/component-recipes/breadcrumb.md +4 -4
  22. package/templates/component-recipes/button.md +2 -2
  23. package/templates/component-recipes/checkbox.md +5 -5
  24. package/templates/component-recipes/collapsible.md +13 -13
  25. package/templates/component-recipes/combobox.md +2 -2
  26. package/templates/component-recipes/context-menu.md +11 -11
  27. package/templates/component-recipes/dialog.md +16 -16
  28. package/templates/component-recipes/drawer.md +18 -18
  29. package/templates/component-recipes/dropdown-menu.md +12 -12
  30. package/templates/component-recipes/hover-card.md +11 -11
  31. package/templates/component-recipes/label.md +4 -4
  32. package/templates/component-recipes/modal.md +9 -9
  33. package/templates/component-recipes/navigation-menu.md +19 -19
  34. package/templates/component-recipes/popover.md +10 -10
  35. package/templates/component-recipes/progress.md +10 -8
  36. package/templates/component-recipes/radio.md +6 -6
  37. package/templates/component-recipes/select.md +5 -5
  38. package/templates/component-recipes/separator.md +2 -2
  39. package/templates/component-recipes/slider.md +2 -2
  40. package/templates/component-recipes/switch.md +6 -6
  41. package/templates/component-recipes/table.md +1 -1
  42. package/templates/component-recipes/tabs.md +6 -6
  43. package/templates/component-recipes/toast.md +56 -42
  44. package/templates/component-recipes/toggle-group.md +4 -4
  45. package/templates/component-recipes/tooltip.md +5 -5
  46. package/templates/mcp/mcp.json +8 -0
  47. package/templates/playwright/playwright.config.ts +31 -0
  48. package/templates/playwright/tests/components.spec.ts +104 -0
  49. package/templates/skills/react-patterns.md +141 -0
  50. package/templates/skills/styling.md +141 -52
  51. package/templates/hooks/triggers.d/styling.json +0 -23
@@ -4,80 +4,279 @@ This command creates a personalized styling system. Once configured, the `stylin
4
4
 
5
5
  ## Workflow
6
6
 
7
- 1. **Check for existing tokens** - Look for `tailwind.config.*` or existing `.claude/styling-config.json`
8
- 2. **Ask aesthetic questions** using AskUserQuestion tool:
7
+ 1. **Check existing progress** - Resume from where we left off:
9
8
 
10
- **Q1: Import existing?**
11
- - If `tailwind.config.*` found: "Found tailwind config. Import colors/spacing from it?"
12
- - Options: [Yes, import] [No, start fresh]
9
+ ```bash
10
+ npx validate-config
11
+ ```
13
12
 
14
- **Q2: Overall aesthetic feel**
15
- - Options: [Minimal - clean, lots of whitespace] [Bold - strong colors, high contrast] [Playful - rounded, colorful, fun] [Enterprise - professional, structured] [Custom - I'll describe it]
13
+ - If config valid → check recipes
14
+ - If config missing/invalid start fresh from step 2
16
15
 
17
- **Q3: Color philosophy**
18
- - Options: [Monochrome - shades of one color] [Vibrant - bright, saturated colors] [Muted pastels - soft, calm colors] [Earth tones - natural, warm colors] [Custom - I'll provide hex values]
19
- - If Custom: Ask for primary, secondary, background, surface, text colors
16
+ For recipes, check each required file exists and has content (not empty):
17
+ - Required: button.md, card.md, input.md, badge.md, dialog.md
18
+ - If all exist with content skip to step 8 (harness question)
19
+ - If some missing → generate only the missing ones in step 6
20
20
 
21
- **Q4: Typography**
22
- - Options: [Modern sans (Inter/system)] [Classic serif] [Monospace/technical] [Custom font family]
21
+ 2. **Ask setup method** using AskUserQuestion tool:
23
22
 
24
- **Q5: Component personality**
25
- - Corners: [Sharp (rounded-none)] [Subtle (rounded-sm)] [Rounded (rounded-lg)] [Pill (rounded-full)]
26
- - Shadows: [Flat (no shadows)] [Subtle (shadow-sm)] [Pronounced (shadow-lg)] [Glassmorphism]
27
- - Density: [Compact (tight spacing)] [Comfortable (normal)] [Spacious (generous padding)]
23
+ **Q0: How do you want to define your styling?**
24
+ - Options:
25
+ - [Extract from URL (Recommended)] - Analyze an existing website's design system
26
+ - [Manual configuration] - Answer questions about colors, typography, etc.
27
+
28
+ ### If "Extract from URL" selected:
29
+
30
+ Delegate to the `style-inspector` agent:
31
+
32
+ 1. **Ask for URL**: "What website do you want to extract styling from?"
33
+
34
+ 2. **Run the style-inspector agent** — This agent handles the full extraction workflow:
35
+ - Technology detection (Wappalyzer, CRFT Lookup, or browser script)
36
+ - Design token extraction (Dembrandt CLI → Superposition → browser script fallback)
37
+ - Semantic interpretation with confidence scoring
38
+ - Translation to styling-config.json format with user's aesthetic flair
39
+
40
+ 3. **Review agent output** — The style-inspector returns structured findings with extracted tokens, detected patterns, and any gaps that need manual resolution.
41
+
42
+ 4. **Generate themeName** from the source (e.g., "stripe-inspired", "vercel-dark")
43
+
44
+ 5. **Generate config** with source attribution, then skip to step 5 (generate recipes).
45
+
46
+ ---
47
+
48
+ ### If "Manual configuration" selected:
49
+
50
+ 3. **Ask styling questions** using AskUserQuestion tool:
51
+
52
+ **Q1: Describe your desired aesthetic** (Free text)
53
+ - "Describe the look and feel you want (e.g., 'dark terminal hacker vibe', 'soft pastels for kids app', 'clean minimal SaaS')"
54
+
55
+ **Q2: Typography Configuration**
56
+
57
+ Q2a: Heading font style
58
+ - Options: [Geometric sans (modern, clean)] [Humanist sans (friendly, approachable)] [Serif (editorial, classic)] [Monospace (technical, retro)] [Enter custom font name]
59
+
60
+ Q2b: Body font style
61
+ - Options: [System stack (fastest loading)] [Clean sans (readable)] [Match heading font] [Enter custom font name]
62
+
63
+ 4. **Generate tokens from description**
64
+
65
+ Interpret the user's description and generate appropriate token values directly. Use these reference tables as guidance:
66
+
67
+ ### Color Keyword Reference
68
+
69
+ | Keywords | Base Color |
70
+ |----------|------------|
71
+ | ocean, sky, clean, calm | #0EA5E9 |
72
+ | navy, corporate, trust | #1E3A8A |
73
+ | forest, nature | #166534 |
74
+ | emerald, fresh, growth | #10B981 |
75
+ | coral, warm, friendly | #F97316 |
76
+ | violet, creative, innovative | #8B5CF6 |
77
+ | rose, playful, bold | #F43F5E |
78
+ | slate, minimal, neutral | #64748B |
79
+ | professional, modern, tech | #3B82F6 |
80
+ | luxury, premium, elegant | #7C3AED |
81
+ | earthy, natural, organic | #78716C |
82
+ | teal, balanced, health | #14B8A6 |
83
+ | indigo, deep, focused | #6366F1 |
84
+ | amber, energy, attention | #F59E0B |
85
+ | terminal, hacker, matrix | #00FF41 |
86
+ | cyberpunk, neon | #FF00FF |
87
+
88
+ ### Radii Reference
89
+
90
+ | Feel | sm | md | lg | xl | 2xl | default |
91
+ |------|-----|-----|-----|-----|------|---------|
92
+ | Sharp/pixel | 0 | 0 | 0 | 0 | 0 | none |
93
+ | Subtle | 0.125rem | 0.25rem | 0.375rem | 0.5rem | 0.75rem | sm |
94
+ | Rounded | 0.25rem | 0.375rem | 0.5rem | 0.75rem | 1rem | md |
95
+ | Pill/playful | 0.5rem | 0.75rem | 1rem | 1.5rem | 2rem | xl |
96
+
97
+ ### Shadow Reference
98
+
99
+ | Feel | sm | md | lg | glow |
100
+ |------|-----|-----|-----|------|
101
+ | Flat | none | none | none | none |
102
+ | Subtle | 0 1px 2px 0 rgb(0 0 0 / 0.05) | 0 4px 6px -1px rgb(0 0 0 / 0.1) | 0 10px 15px -3px rgb(0 0 0 / 0.1) | 0 0 10px rgb(0 0 0 / 0.1) |
103
+ | Pronounced | 0 2px 4px rgb(0 0 0 / 0.15) | 0 8px 12px rgb(0 0 0 / 0.2) | 0 20px 30px rgb(0 0 0 / 0.25) | 0 0 20px rgb(0 0 0 / 0.3) |
104
+
105
+ ### Typography Reference
106
+
107
+ **Heading Fonts:**
108
+ | Style | Font Stack |
109
+ |-------|------------|
110
+ | Geometric sans | `"Plus Jakarta Sans", "Outfit", sans-serif` |
111
+ | Humanist sans | `"Source Sans 3", "Nunito Sans", sans-serif` |
112
+ | Serif | `"Lora", "Merriweather", serif` |
113
+ | Monospace | `"JetBrains Mono", "Fira Code", monospace` |
114
+ | Terminal/retro | `"VT323", monospace` |
115
+
116
+ **Body Fonts:**
117
+ | Style | Font Stack |
118
+ |-------|------------|
119
+ | System stack | `ui-sans-serif, system-ui, -apple-system, sans-serif` |
120
+ | Clean sans | `"Inter var", "DM Sans", sans-serif` |
121
+
122
+ ### Color Scale Generation
123
+
124
+ From the base color, generate a 50-950 scale by adjusting lightness:
125
+
126
+ ```
127
+ 50: 97% lightness (very light tint)
128
+ 100: 94% lightness
129
+ 200: 86% lightness
130
+ 300: 76% lightness
131
+ 400: 62% lightness
132
+ 500: Base color lightness
133
+ 600: Base - 10% lightness
134
+ 700: Base - 20% lightness
135
+ 800: Base - 30% lightness
136
+ 900: Base - 40% lightness
137
+ 950: Base - 50% lightness (very dark shade)
138
+ ```
139
+
140
+ ### Color Resolution
141
+
142
+ **Light theme** (light backgrounds):
143
+ - `background` → gray.50
144
+ - `foreground` → gray.900
145
+ - `primary` → primary.600
146
+ - `primary-foreground` → gray.50
147
+ - `surface` → gray.100
148
+ - `muted` → gray.200
149
+ - `muted-foreground` → gray.500
150
+ - `border` → gray.200
151
+
152
+ **Dark theme** (dark backgrounds):
153
+ - `background` → gray.950
154
+ - `foreground` → gray.50
155
+ - `primary` → primary.500
156
+ - `primary-foreground` → gray.950
157
+ - `surface` → gray.900
158
+ - `muted` → gray.800
159
+ - `muted-foreground` → gray.400
160
+ - `border` → gray.700
161
+
162
+ 5. **Generate config and save theme**
163
+
164
+ Generate a `themeName` from the user's description (e.g., "ocean-minimal", "terminal-dark", "pastel-playful").
165
+
166
+ **Save to TWO locations:**
167
+ - `.claude/styling-config.json` - active config (full structure)
168
+ - `.claude/themes/{themeName}.json` - saved theme (for theme switcher)
169
+
170
+ Config structure:
28
171
 
29
- 3. **Generate `.claude/styling-config.json`** with structure:
30
172
  ```json
31
173
  {
32
- "aesthetic": "minimal",
174
+ "themeName": "<generated-from-prompt>",
33
175
  "tokens": {
34
176
  "colors": {
35
- "primary": "#0066FF",
36
- "primary-foreground": "#FFFFFF",
37
- "secondary": "#6C5CE7",
38
- "secondary-foreground": "#FFFFFF",
39
- "background": "#FFFFFF",
40
- "foreground": "#1A1A1A",
41
- "surface": "#F5F5F5",
42
- "muted": "#6B7280",
43
- "muted-foreground": "#9CA3AF",
44
- "border": "#E5E7EB",
45
- "destructive": "#EF4444",
46
- "destructive-foreground": "#FFFFFF"
177
+ "primary": "#...",
178
+ "primary-foreground": "#...",
179
+ "secondary": "#...",
180
+ "secondary-foreground": "#...",
181
+ "background": "#...",
182
+ "foreground": "#...",
183
+ "surface": "#...",
184
+ "muted": "#...",
185
+ "muted-foreground": "#...",
186
+ "border": "#...",
187
+ "destructive": "#dc2626",
188
+ "destructive-foreground": "#...",
189
+ "accent": "#...",
190
+ "accent-foreground": "#...",
191
+ "success": "#16a34a",
192
+ "success-foreground": "#...",
193
+ "warning": "#f59e0b",
194
+ "warning-foreground": "#..."
195
+ },
196
+ "radii": {
197
+ "none": "0",
198
+ "sm": "...",
199
+ "md": "...",
200
+ "lg": "...",
201
+ "xl": "...",
202
+ "2xl": "...",
203
+ "full": "9999px",
204
+ "default": "..."
205
+ },
206
+ "shadows": {
207
+ "none": "none",
208
+ "sm": "...",
209
+ "md": "...",
210
+ "lg": "...",
211
+ "xl": "...",
212
+ "glow": "..."
47
213
  },
48
- "radius": "rounded-lg",
49
- "shadow": "shadow-sm",
50
214
  "spacing": {
51
- "tight": "2",
52
- "normal": "4",
53
- "loose": "6"
215
+ "tight": "1",
216
+ "normal": "2",
217
+ "loose": "4"
54
218
  },
55
219
  "typography": {
56
- "family": "font-sans",
57
- "heading": "font-semibold tracking-tight",
58
- "body": "font-normal"
220
+ "families": {
221
+ "heading": { "name": "...", "stack": "...", "variable": "--font-heading" },
222
+ "body": { "name": "...", "stack": "...", "variable": "--font-body" },
223
+ "code": { "name": "JetBrains Mono", "stack": "'JetBrains Mono', ui-monospace, monospace", "variable": "--font-code" }
224
+ },
225
+ "scale": {
226
+ "xs": { "size": "0.75rem", "lineHeight": "1rem", "letterSpacing": "0.025em" },
227
+ "sm": { "size": "0.875rem", "lineHeight": "1.25rem", "letterSpacing": "0.015em" },
228
+ "base": { "size": "1rem", "lineHeight": "1.5rem", "letterSpacing": "0" },
229
+ "lg": { "size": "1.125rem", "lineHeight": "1.75rem", "letterSpacing": "-0.01em" },
230
+ "xl": { "size": "1.25rem", "lineHeight": "1.75rem", "letterSpacing": "-0.015em" },
231
+ "2xl": { "size": "1.5rem", "lineHeight": "2rem", "letterSpacing": "-0.02em" },
232
+ "3xl": { "size": "1.875rem", "lineHeight": "2.25rem", "letterSpacing": "-0.025em" },
233
+ "4xl": { "size": "2.25rem", "lineHeight": "2.5rem", "letterSpacing": "-0.03em" },
234
+ "5xl": { "size": "3rem", "lineHeight": "1", "letterSpacing": "-0.035em" },
235
+ "6xl": { "size": "3.75rem", "lineHeight": "1", "letterSpacing": "-0.04em" }
236
+ },
237
+ "weights": { "normal": "400", "medium": "500", "semibold": "600", "bold": "700" },
238
+ "tracking": { "tighter": "-0.05em", "tight": "-0.025em", "normal": "0", "wide": "0.025em", "wider": "0.05em", "widest": "0.1em" },
239
+ "leading": { "none": "1", "tight": "1.25", "snug": "1.375", "normal": "1.5", "relaxed": "1.625", "loose": "2" },
240
+ "googleFonts": { "url": "...", "preconnect": true },
241
+ "classes": {
242
+ "h1": "font-heading text-4xl font-bold tracking-tight",
243
+ "h2": "font-heading text-3xl font-semibold tracking-tight",
244
+ "h3": "font-heading text-2xl font-semibold",
245
+ "h4": "font-heading text-xl font-semibold",
246
+ "h5": "font-heading text-lg font-medium",
247
+ "h6": "font-heading text-base font-medium tracking-wide",
248
+ "body": "font-body text-base leading-relaxed",
249
+ "caption": "font-body text-xs text-muted-foreground tracking-wide",
250
+ "label": "font-body text-sm font-medium tracking-wide",
251
+ "code": "font-mono text-sm"
252
+ },
253
+ "accessibility": {
254
+ "minBodySize": "16px",
255
+ "minLineHeight": "1.5",
256
+ "preferredLineLength": "65ch"
257
+ }
59
258
  }
60
- },
61
- "personality": {
62
- "corners": "rounded",
63
- "depth": "subtle-shadows",
64
- "density": "comfortable"
65
259
  }
66
260
  }
67
261
  ```
68
262
 
69
- 4. **Generate `.claude/component-recipes/`** directory with recipes for each component type:
263
+ 6. **Generate `.claude/component-recipes/`** directory with recipes:
70
264
  - button.md, card.md, input.md, modal.md, select.md
71
265
  - checkbox.md, radio.md, badge.md, alert.md, avatar.md
72
266
  - tooltip.md, table.md, tabs.md, accordion.md, dialog.md, toast.md
73
267
 
74
- Each recipe should reference `{tokens.*}` from the config and follow the aesthetic choices.
268
+ Each recipe uses semantic tokens (bg-primary, text-foreground, border-border, etc.)
269
+
270
+ 7. **Validate the config**:
271
+ ```bash
272
+ npx validate-config
273
+ ```
274
+ If validation fails, fix the issues and re-run until it passes.
75
275
 
76
- 5. **Ask about component-harness**: "Want me to scaffold the visual component-harness for previewing?"
276
+ 8. **Ask about component-harness**: "Want me to scaffold the visual component-harness for previewing?"
77
277
 
78
278
  ## Recipe Template
79
279
 
80
- When generating each recipe, follow this structure:
81
280
  ```markdown
82
281
  # [Component] Component Recipe
83
282
 
@@ -88,24 +287,154 @@ When generating each recipe, follow this structure:
88
287
  - Required states (loading, disabled, etc.)
89
288
 
90
289
  ## Tailwind Classes
91
- - Base: [base classes that apply to all variants]
92
- - [Variant]: [classes for this variant using {tokens.*} references]
93
- - Sizes: [size-specific classes]
94
- - States: [hover, focus, disabled classes]
290
+ ### Base
291
+ [classes using semantic tokens: bg-background, text-foreground, border-border]
292
+
293
+ ### Variants
294
+ [variant-specific classes using semantic tokens]
295
+
296
+ ### Sizes
297
+ [size-specific classes]
298
+
299
+ ### States
300
+ [hover, focus, disabled using semantic tokens]
95
301
 
96
302
  ## Props Interface
97
- - variant: [list of variants]
98
- - size: [list of sizes]
99
- - [other props]
303
+ [TypeScript interface]
100
304
 
101
305
  ## Do
102
- - [best practices]
306
+ - Use semantic color tokens (bg-primary, not bg-blue-500)
307
+ - Include focus-visible states for accessibility
308
+ - Use cn() utility for class merging
103
309
 
104
310
  ## Don't
105
- - [anti-patterns]
311
+ - Hardcode colors (#hex or rgb values)
312
+ - Skip hover/focus states
313
+ - Forget cursor-pointer on interactive elements
106
314
 
107
315
  ## Example
108
- [code example]
316
+ [Complete code example using semantic tokens]
317
+ ```
318
+
319
+ ## CSS Variables
320
+
321
+ The harness maps design tokens to CSS variables:
322
+
323
+ ```css
324
+ :root {
325
+ /* Border Radius Scale */
326
+ --radius-none: 0;
327
+ --radius-sm: 0.125rem;
328
+ --radius-md: 0.375rem;
329
+ --radius-lg: 0.5rem;
330
+ --radius-xl: 0.75rem;
331
+ --radius-2xl: 1rem;
332
+ --radius-full: 9999px;
333
+ --radius: var(--radius-md); /* default radius */
334
+
335
+ /* Shadow/Elevation Scale */
336
+ --shadow-none: none;
337
+ --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
338
+ --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1);
339
+ --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1);
340
+ --shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.1);
341
+ --shadow-glow: 0 0 15px rgb(0 0 0 / 0.1);
342
+
343
+ /* Font Families */
344
+ --font-heading: "Plus Jakarta Sans", ui-sans-serif, system-ui, sans-serif;
345
+ --font-body: "Inter", ui-sans-serif, system-ui, sans-serif;
346
+ --font-code: "JetBrains Mono", ui-monospace, monospace;
347
+
348
+ /* Type Scale */
349
+ --text-xs: 0.75rem;
350
+ --text-sm: 0.875rem;
351
+ --text-base: 1rem;
352
+ --text-lg: 1.125rem;
353
+ --text-xl: 1.25rem;
354
+ --text-2xl: 1.5rem;
355
+ --text-3xl: 1.875rem;
356
+ --text-4xl: 2.25rem;
357
+ --text-5xl: 3rem;
358
+ --text-6xl: 3.75rem;
359
+
360
+ /* Semantic Colors (from tokens.colors) */
361
+ --color-background: #...;
362
+ --color-foreground: #...;
363
+ --color-primary: #...;
364
+ --color-primary-foreground: #...;
365
+ /* etc. */
366
+ }
367
+ ```
368
+
369
+ ## Tailwind Config Extension
370
+
371
+ Add design tokens to `tailwind.config.js`:
372
+
373
+ ```js
374
+ module.exports = {
375
+ theme: {
376
+ extend: {
377
+ borderRadius: {
378
+ none: 'var(--radius-none)',
379
+ sm: 'var(--radius-sm)',
380
+ DEFAULT: 'var(--radius)',
381
+ md: 'var(--radius-md)',
382
+ lg: 'var(--radius-lg)',
383
+ xl: 'var(--radius-xl)',
384
+ '2xl': 'var(--radius-2xl)',
385
+ full: 'var(--radius-full)',
386
+ },
387
+ boxShadow: {
388
+ none: 'var(--shadow-none)',
389
+ sm: 'var(--shadow-sm)',
390
+ DEFAULT: 'var(--shadow-md)',
391
+ md: 'var(--shadow-md)',
392
+ lg: 'var(--shadow-lg)',
393
+ xl: 'var(--shadow-xl)',
394
+ glow: 'var(--shadow-glow)',
395
+ },
396
+ colors: {
397
+ background: 'var(--color-background)',
398
+ foreground: 'var(--color-foreground)',
399
+ primary: {
400
+ DEFAULT: 'var(--color-primary)',
401
+ foreground: 'var(--color-primary-foreground)',
402
+ },
403
+ secondary: {
404
+ DEFAULT: 'var(--color-secondary)',
405
+ foreground: 'var(--color-secondary-foreground)',
406
+ },
407
+ muted: {
408
+ DEFAULT: 'var(--color-muted)',
409
+ foreground: 'var(--color-muted-foreground)',
410
+ },
411
+ accent: {
412
+ DEFAULT: 'var(--color-accent)',
413
+ foreground: 'var(--color-accent-foreground)',
414
+ },
415
+ destructive: {
416
+ DEFAULT: 'var(--color-destructive)',
417
+ foreground: 'var(--color-destructive-foreground)',
418
+ },
419
+ success: {
420
+ DEFAULT: 'var(--color-success)',
421
+ foreground: 'var(--color-success-foreground)',
422
+ },
423
+ warning: {
424
+ DEFAULT: 'var(--color-warning)',
425
+ foreground: 'var(--color-warning-foreground)',
426
+ },
427
+ border: 'var(--color-border)',
428
+ surface: 'var(--color-surface)',
429
+ },
430
+ fontFamily: {
431
+ heading: ['var(--font-heading)'],
432
+ body: ['var(--font-body)'],
433
+ mono: ['var(--font-code)'],
434
+ },
435
+ },
436
+ },
437
+ }
109
438
  ```
110
439
 
111
440
  $ARGUMENTS
@@ -17,7 +17,7 @@ border-b border-border
17
17
  ```
18
18
  flex flex-1 items-center justify-between py-4 text-sm font-medium
19
19
  transition-all hover:underline
20
- [&[data-state=open]>svg]:rotate-180
20
+ [&[data-open]>svg]:rotate-180
21
21
  ```
22
22
 
23
23
  ### Chevron Icon
@@ -28,8 +28,8 @@ h-4 w-4 shrink-0 text-muted-foreground transition-transform duration-200
28
28
  ### Content
29
29
  ```
30
30
  overflow-hidden text-sm
31
- data-[state=closed]:animate-accordion-up
32
- data-[state=open]:animate-accordion-down
31
+ data-closed:animate-accordion-up
32
+ data-open:animate-accordion-down
33
33
  ```
34
34
 
35
35
  ### Content Inner
@@ -42,10 +42,10 @@ pb-4 pt-0
42
42
  keyframes: {
43
43
  'accordion-down': {
44
44
  from: { height: '0' },
45
- to: { height: 'var(--radix-accordion-content-height)' },
45
+ to: { height: 'var(--accordion-panel-height)' },
46
46
  },
47
47
  'accordion-up': {
48
- from: { height: 'var(--radix-accordion-content-height)' },
48
+ from: { height: 'var(--accordion-panel-height)' },
49
49
  to: { height: '0' },
50
50
  },
51
51
  },
@@ -84,7 +84,7 @@ interface AccordionContentProps {
84
84
  ```
85
85
 
86
86
  ## Do
87
- - Use Radix Accordion for accessibility
87
+ - Use Base UI Accordion for accessibility
88
88
  - Animate height changes smoothly
89
89
  - Rotate chevron on open
90
90
  - Support both single and multiple modes
@@ -97,7 +97,7 @@ interface AccordionContentProps {
97
97
 
98
98
  ## Example
99
99
  ```tsx
100
- import * as AccordionPrimitive from '@radix-ui/react-accordion'
100
+ import { Accordion as AccordionPrimitive } from '@base-ui/react/accordion'
101
101
  import { ChevronDown } from 'lucide-react'
102
102
  import { cn } from '@/lib/utils'
103
103
 
@@ -115,7 +115,7 @@ const AccordionTrigger = ({ className, children, ...props }) => (
115
115
  <AccordionPrimitive.Trigger
116
116
  className={cn(
117
117
  'flex flex-1 items-center justify-between py-4 text-sm font-medium',
118
- 'transition-all hover:underline [&[data-state=open]>svg]:rotate-180',
118
+ 'transition-all hover:underline [&[data-open]>svg]:rotate-180',
119
119
  className
120
120
  )}
121
121
  {...props}
@@ -128,7 +128,7 @@ const AccordionTrigger = ({ className, children, ...props }) => (
128
128
 
129
129
  const AccordionContent = ({ className, children, ...props }) => (
130
130
  <AccordionPrimitive.Content
131
- className="overflow-hidden text-sm data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down"
131
+ className="overflow-hidden text-sm data-closed:animate-accordion-up data-open:animate-accordion-down"
132
132
  {...props}
133
133
  >
134
134
  <div className={cn('pb-4 pt-0', className)}>{children}</div>