@devmunna/agent-skillkit 0.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 (132) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +147 -0
  3. package/bin/ai-skills.js +5 -0
  4. package/dist/cli/commands/add.d.ts +2 -0
  5. package/dist/cli/commands/add.d.ts.map +1 -0
  6. package/dist/cli/commands/add.js +66 -0
  7. package/dist/cli/commands/add.js.map +1 -0
  8. package/dist/cli/commands/doctor.d.ts +2 -0
  9. package/dist/cli/commands/doctor.d.ts.map +1 -0
  10. package/dist/cli/commands/doctor.js +33 -0
  11. package/dist/cli/commands/doctor.js.map +1 -0
  12. package/dist/cli/commands/init.d.ts +10 -0
  13. package/dist/cli/commands/init.d.ts.map +1 -0
  14. package/dist/cli/commands/init.js +145 -0
  15. package/dist/cli/commands/init.js.map +1 -0
  16. package/dist/cli/commands/list.d.ts +5 -0
  17. package/dist/cli/commands/list.d.ts.map +1 -0
  18. package/dist/cli/commands/list.js +55 -0
  19. package/dist/cli/commands/list.js.map +1 -0
  20. package/dist/cli/commands/update.d.ts +2 -0
  21. package/dist/cli/commands/update.d.ts.map +1 -0
  22. package/dist/cli/commands/update.js +49 -0
  23. package/dist/cli/commands/update.js.map +1 -0
  24. package/dist/cli/commands/validate.d.ts +2 -0
  25. package/dist/cli/commands/validate.d.ts.map +1 -0
  26. package/dist/cli/commands/validate.js +22 -0
  27. package/dist/cli/commands/validate.js.map +1 -0
  28. package/dist/cli/index.d.ts +2 -0
  29. package/dist/cli/index.d.ts.map +1 -0
  30. package/dist/cli/index.js +49 -0
  31. package/dist/cli/index.js.map +1 -0
  32. package/dist/cli/prompts/agent-selector.d.ts +3 -0
  33. package/dist/cli/prompts/agent-selector.d.ts.map +1 -0
  34. package/dist/cli/prompts/agent-selector.js +23 -0
  35. package/dist/cli/prompts/agent-selector.js.map +1 -0
  36. package/dist/cli/prompts/stack-selector.d.ts +3 -0
  37. package/dist/cli/prompts/stack-selector.d.ts.map +1 -0
  38. package/dist/cli/prompts/stack-selector.js +60 -0
  39. package/dist/cli/prompts/stack-selector.js.map +1 -0
  40. package/dist/core/config-manager.d.ts +20 -0
  41. package/dist/core/config-manager.d.ts.map +1 -0
  42. package/dist/core/config-manager.js +107 -0
  43. package/dist/core/config-manager.js.map +1 -0
  44. package/dist/core/detector.d.ts +3 -0
  45. package/dist/core/detector.d.ts.map +1 -0
  46. package/dist/core/detector.js +50 -0
  47. package/dist/core/detector.js.map +1 -0
  48. package/dist/core/doctor.d.ts +12 -0
  49. package/dist/core/doctor.d.ts.map +1 -0
  50. package/dist/core/doctor.js +102 -0
  51. package/dist/core/doctor.js.map +1 -0
  52. package/dist/core/skill-registry.d.ts +11 -0
  53. package/dist/core/skill-registry.d.ts.map +1 -0
  54. package/dist/core/skill-registry.js +174 -0
  55. package/dist/core/skill-registry.js.map +1 -0
  56. package/dist/core/skill-resolver.d.ts +3 -0
  57. package/dist/core/skill-resolver.d.ts.map +1 -0
  58. package/dist/core/skill-resolver.js +36 -0
  59. package/dist/core/skill-resolver.js.map +1 -0
  60. package/dist/core/validator.d.ts +13 -0
  61. package/dist/core/validator.d.ts.map +1 -0
  62. package/dist/core/validator.js +99 -0
  63. package/dist/core/validator.js.map +1 -0
  64. package/dist/generators/agent-installer.d.ts +5 -0
  65. package/dist/generators/agent-installer.d.ts.map +1 -0
  66. package/dist/generators/agent-installer.js +20 -0
  67. package/dist/generators/agent-installer.js.map +1 -0
  68. package/dist/generators/agents-md.d.ts +3 -0
  69. package/dist/generators/agents-md.d.ts.map +1 -0
  70. package/dist/generators/agents-md.js +70 -0
  71. package/dist/generators/agents-md.js.map +1 -0
  72. package/dist/generators/claude-md.d.ts +3 -0
  73. package/dist/generators/claude-md.d.ts.map +1 -0
  74. package/dist/generators/claude-md.js +47 -0
  75. package/dist/generators/claude-md.js.map +1 -0
  76. package/dist/generators/skill-generator.d.ts +5 -0
  77. package/dist/generators/skill-generator.d.ts.map +1 -0
  78. package/dist/generators/skill-generator.js +34 -0
  79. package/dist/generators/skill-generator.js.map +1 -0
  80. package/dist/generators/workflows.d.ts +3 -0
  81. package/dist/generators/workflows.d.ts.map +1 -0
  82. package/dist/generators/workflows.js +57 -0
  83. package/dist/generators/workflows.js.map +1 -0
  84. package/dist/index.d.ts +13 -0
  85. package/dist/index.d.ts.map +1 -0
  86. package/dist/index.js +13 -0
  87. package/dist/index.js.map +1 -0
  88. package/dist/types/index.d.ts +55 -0
  89. package/dist/types/index.d.ts.map +1 -0
  90. package/dist/types/index.js +2 -0
  91. package/dist/types/index.js.map +1 -0
  92. package/dist/utils/file-utils.d.ts +12 -0
  93. package/dist/utils/file-utils.d.ts.map +1 -0
  94. package/dist/utils/file-utils.js +39 -0
  95. package/dist/utils/file-utils.js.map +1 -0
  96. package/dist/utils/logger.d.ts +10 -0
  97. package/dist/utils/logger.d.ts.map +1 -0
  98. package/dist/utils/logger.js +11 -0
  99. package/dist/utils/logger.js.map +1 -0
  100. package/package.json +73 -0
  101. package/skills/clean-architecture/SKILL.md +324 -0
  102. package/skills/express-mvc-prisma/SKILL.md +168 -0
  103. package/skills/express-mvc-prisma/references/auth.md +190 -0
  104. package/skills/express-mvc-prisma/references/boilerplate.md +196 -0
  105. package/skills/express-mvc-prisma/references/error-handling.md +121 -0
  106. package/skills/express-mvc-prisma/references/module-scaffold.md +253 -0
  107. package/skills/express-mvc-prisma/references/prisma-setup.md +97 -0
  108. package/skills/express-mvc-prisma/references/response-helpers.md +157 -0
  109. package/skills/express-mvc-prisma/references/zod-validation.md +157 -0
  110. package/skills/fastify-rest/SKILL.md +287 -0
  111. package/skills/mongoose-odm/SKILL.md +281 -0
  112. package/skills/nextjs-fullstack/SKILL.md +328 -0
  113. package/skills/nextjs-fullstack/references/auth.md +270 -0
  114. package/skills/nextjs-fullstack/references/caching.md +157 -0
  115. package/skills/nextjs-fullstack/references/route-handlers.md +194 -0
  116. package/skills/nextjs-fullstack/references/server-actions.md +214 -0
  117. package/skills/nextjs-fullstack/references/server-components.md +190 -0
  118. package/skills/node-base/SKILL.md +139 -0
  119. package/skills/prisma-orm/SKILL.md +334 -0
  120. package/skills/react-feature-arch/SKILL.md +208 -0
  121. package/skills/react-feature-arch/references/api-layer.md +110 -0
  122. package/skills/react-feature-arch/references/components.md +192 -0
  123. package/skills/react-feature-arch/references/data-fetching.md +198 -0
  124. package/skills/react-feature-arch/references/forms.md +194 -0
  125. package/skills/react-feature-arch/references/routing.md +148 -0
  126. package/skills/react-feature-arch/references/state-management.md +107 -0
  127. package/skills/tailwind-css/SKILL.md +236 -0
  128. package/skills/tailwind-css/references/components.md +340 -0
  129. package/skills/tailwind-css/references/design-tokens.md +230 -0
  130. package/skills/tailwind-css/references/patterns.md +375 -0
  131. package/skills/tailwind-css/references/setup.md +165 -0
  132. package/skills/zod-validation/SKILL.md +267 -0
@@ -0,0 +1,340 @@
1
+ # Component Patterns Reference
2
+
3
+ ---
4
+
5
+ ## cn() — Class Merging Helper
6
+
7
+ **Always create this file. Every component depends on it.**
8
+
9
+ ```ts
10
+ // src/lib/utils.ts
11
+ import { clsx, type ClassValue } from 'clsx';
12
+ import { twMerge } from 'tailwind-merge';
13
+
14
+ export function cn(...inputs: ClassValue[]) {
15
+ return twMerge(clsx(inputs));
16
+ }
17
+ ```
18
+
19
+ `clsx` handles conditional class logic. `twMerge` resolves Tailwind conflicts so caller-provided classes always win:
20
+ ```tsx
21
+ // Without cn: "rounded-md rounded-full" — broken, both apply
22
+ // With cn: "rounded-full" — tailwind-merge picks the last/winner
23
+ <Button className="rounded-full" />
24
+ ```
25
+
26
+ ---
27
+
28
+ ## Button — CVA Pattern
29
+
30
+ ```ts
31
+ // src/components/ui/Button.tsx
32
+ import { cva, type VariantProps } from 'class-variance-authority';
33
+ import { cn } from '@/lib/utils';
34
+
35
+ const buttonVariants = cva(
36
+ // Base styles — always applied
37
+ [
38
+ 'inline-flex items-center justify-center gap-2 rounded-md font-medium',
39
+ 'transition-colors select-none',
40
+ 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2',
41
+ 'disabled:pointer-events-none disabled:opacity-50',
42
+ ],
43
+ {
44
+ variants: {
45
+ variant: {
46
+ default: 'bg-primary text-white hover:bg-primary/90 focus-visible:ring-primary',
47
+ outline: 'border border-current bg-transparent hover:bg-primary/10 text-primary',
48
+ ghost: 'hover:bg-primary/10 hover:text-primary',
49
+ destructive: 'bg-danger text-white hover:bg-danger/90 focus-visible:ring-danger',
50
+ link: 'text-primary underline-offset-4 hover:underline p-0 h-auto',
51
+ },
52
+ size: {
53
+ sm: 'h-8 px-3 text-sm',
54
+ md: 'h-10 px-4',
55
+ lg: 'h-12 px-6 text-base',
56
+ icon: 'size-10 shrink-0',
57
+ },
58
+ },
59
+ defaultVariants: {
60
+ variant: 'default',
61
+ size: 'md',
62
+ },
63
+ },
64
+ );
65
+
66
+ export interface ButtonProps
67
+ extends React.ButtonHTMLAttributes<HTMLButtonElement>,
68
+ VariantProps<typeof buttonVariants> {
69
+ isLoading?: boolean;
70
+ }
71
+
72
+ export function Button({
73
+ className,
74
+ variant,
75
+ size,
76
+ isLoading,
77
+ children,
78
+ disabled,
79
+ ...props
80
+ }: ButtonProps) {
81
+ return (
82
+ <button
83
+ className={cn(buttonVariants({ variant, size }), className)}
84
+ disabled={disabled || isLoading}
85
+ {...props}
86
+ >
87
+ {isLoading && (
88
+ <svg className="size-4 animate-spin" viewBox="0 0 24 24" fill="none">
89
+ <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
90
+ <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8v8z" />
91
+ </svg>
92
+ )}
93
+ {children}
94
+ </button>
95
+ );
96
+ }
97
+ ```
98
+
99
+ Usage:
100
+ ```tsx
101
+ <Button>Default</Button>
102
+ <Button variant="outline">Outline</Button>
103
+ <Button variant="destructive" size="sm">Delete</Button>
104
+ <Button variant="ghost" size="icon"><TrashIcon /></Button>
105
+ <Button isLoading>Saving...</Button>
106
+ <Button className="w-full">Full Width</Button> {/* className always wins */}
107
+ ```
108
+
109
+ ---
110
+
111
+ ## Card
112
+
113
+ ```tsx
114
+ // src/components/ui/Card.tsx
115
+ import { cn } from '@/lib/utils';
116
+
117
+ type DivProps = React.HTMLAttributes<HTMLDivElement>;
118
+
119
+ export function Card({ className, ...props }: DivProps) {
120
+ return (
121
+ <div
122
+ className={cn('rounded-xl border border-border-col bg-card shadow-card', className)}
123
+ {...props}
124
+ />
125
+ );
126
+ }
127
+
128
+ export function CardHeader({ className, ...props }: DivProps) {
129
+ return (
130
+ <div
131
+ className={cn('flex flex-col gap-1.5 border-b border-border-col px-6 py-4', className)}
132
+ {...props}
133
+ />
134
+ );
135
+ }
136
+
137
+ export function CardTitle({ className, ...props }: React.HTMLAttributes<HTMLHeadingElement>) {
138
+ return (
139
+ <h3
140
+ className={cn('text-lg font-semibold leading-none tracking-tight text-fg', className)}
141
+ {...props}
142
+ />
143
+ );
144
+ }
145
+
146
+ export function CardDescription({ className, ...props }: React.HTMLAttributes<HTMLParagraphElement>) {
147
+ return (
148
+ <p className={cn('text-sm text-muted', className)} {...props} />
149
+ );
150
+ }
151
+
152
+ export function CardContent({ className, ...props }: DivProps) {
153
+ return <div className={cn('px-6 py-4', className)} {...props} />;
154
+ }
155
+
156
+ export function CardFooter({ className, ...props }: DivProps) {
157
+ return (
158
+ <div
159
+ className={cn('flex items-center border-t border-border-col px-6 py-4', className)}
160
+ {...props}
161
+ />
162
+ );
163
+ }
164
+ ```
165
+
166
+ Usage:
167
+ ```tsx
168
+ <Card>
169
+ <CardHeader>
170
+ <CardTitle>Users</CardTitle>
171
+ <CardDescription>Manage your team members</CardDescription>
172
+ </CardHeader>
173
+ <CardContent>
174
+ <UserList users={users} />
175
+ </CardContent>
176
+ <CardFooter className="justify-end gap-2">
177
+ <Button variant="outline">Cancel</Button>
178
+ <Button>Save</Button>
179
+ </CardFooter>
180
+ </Card>
181
+ ```
182
+
183
+ ---
184
+
185
+ ## Input
186
+
187
+ ```tsx
188
+ // src/components/ui/Input.tsx
189
+ import { cn } from '@/lib/utils';
190
+
191
+ export interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
192
+ error?: string;
193
+ label?: string;
194
+ }
195
+
196
+ export function Input({ className, error, label, id, ...props }: InputProps) {
197
+ return (
198
+ <div className="flex flex-col gap-1.5">
199
+ {label && (
200
+ <label htmlFor={id} className="text-sm font-medium text-fg">
201
+ {label}
202
+ </label>
203
+ )}
204
+ <input
205
+ id={id}
206
+ className={cn(
207
+ 'flex h-10 w-full rounded-md border bg-bg px-3 py-2 text-sm',
208
+ 'placeholder:text-muted',
209
+ 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary',
210
+ 'disabled:cursor-not-allowed disabled:opacity-50',
211
+ error
212
+ ? 'border-danger focus-visible:ring-danger'
213
+ : 'border-border-col',
214
+ className,
215
+ )}
216
+ {...props}
217
+ />
218
+ {error && <p className="text-xs text-danger">{error}</p>}
219
+ </div>
220
+ );
221
+ }
222
+ ```
223
+
224
+ ---
225
+
226
+ ## Badge
227
+
228
+ ```tsx
229
+ // src/components/ui/Badge.tsx
230
+ import { cva, type VariantProps } from 'class-variance-authority';
231
+ import { cn } from '@/lib/utils';
232
+
233
+ const badgeVariants = cva(
234
+ 'inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium transition-colors',
235
+ {
236
+ variants: {
237
+ variant: {
238
+ default: 'bg-primary text-white',
239
+ secondary: 'bg-primary/10 text-primary',
240
+ outline: 'border border-current text-fg',
241
+ success: 'bg-success/10 text-success',
242
+ warning: 'bg-warning/10 text-warning',
243
+ destructive: 'bg-danger/10 text-danger',
244
+ },
245
+ },
246
+ defaultVariants: { variant: 'default' },
247
+ },
248
+ );
249
+
250
+ interface BadgeProps
251
+ extends React.HTMLAttributes<HTMLSpanElement>,
252
+ VariantProps<typeof badgeVariants> {}
253
+
254
+ export function Badge({ className, variant, ...props }: BadgeProps) {
255
+ return <span className={cn(badgeVariants({ variant }), className)} {...props} />;
256
+ }
257
+ ```
258
+
259
+ ---
260
+
261
+ ## Skeleton (Loading Placeholder)
262
+
263
+ ```tsx
264
+ // src/components/ui/Skeleton.tsx
265
+ import { cn } from '@/lib/utils';
266
+
267
+ export function Skeleton({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
268
+ return (
269
+ <div
270
+ className={cn('animate-pulse rounded-md bg-border-col', className)}
271
+ {...props}
272
+ />
273
+ );
274
+ }
275
+
276
+ // Usage patterns
277
+ export function UserCardSkeleton() {
278
+ return (
279
+ <div className="flex items-center gap-3 p-4">
280
+ <Skeleton className="size-10 rounded-full" />
281
+ <div className="flex flex-col gap-2">
282
+ <Skeleton className="h-4 w-32" />
283
+ <Skeleton className="h-3 w-24" />
284
+ </div>
285
+ </div>
286
+ );
287
+ }
288
+ ```
289
+
290
+ ---
291
+
292
+ ## Modal / Dialog
293
+
294
+ ```tsx
295
+ // src/components/ui/Modal.tsx
296
+ 'use client'; // if Next.js
297
+
298
+ import { useEffect } from 'react';
299
+ import { cn } from '@/lib/utils';
300
+
301
+ interface ModalProps {
302
+ isOpen: boolean;
303
+ onClose: () => void;
304
+ children: React.ReactNode;
305
+ className?: string;
306
+ }
307
+
308
+ export function Modal({ isOpen, onClose, children, className }: ModalProps) {
309
+ // Close on Escape key
310
+ useEffect(() => {
311
+ const handler = (e: KeyboardEvent) => {
312
+ if (e.key === 'Escape') onClose();
313
+ };
314
+ document.addEventListener('keydown', handler);
315
+ return () => document.removeEventListener('keydown', handler);
316
+ }, [onClose]);
317
+
318
+ if (!isOpen) return null;
319
+
320
+ return (
321
+ <div className="fixed inset-0 z-50 flex items-center justify-center">
322
+ {/* Backdrop */}
323
+ <div
324
+ className="absolute inset-0 bg-black/50 backdrop-blur-sm"
325
+ onClick={onClose}
326
+ />
327
+ {/* Content */}
328
+ <div
329
+ className={cn(
330
+ 'relative z-10 w-full max-w-md rounded-xl bg-bg p-6 shadow-lg',
331
+ 'animate-scale-in',
332
+ className,
333
+ )}
334
+ >
335
+ {children}
336
+ </div>
337
+ </div>
338
+ );
339
+ }
340
+ ```
@@ -0,0 +1,230 @@
1
+ # Design Tokens Reference — @theme
2
+
3
+ All custom tokens go in `@theme` in your global CSS file. Tailwind generates utility classes automatically from the variable names.
4
+
5
+ ---
6
+
7
+ ## Colors — OKLCH (Preferred in v4)
8
+
9
+ OKLCH provides perceptually uniform lightness, making it easy to create consistent color scales.
10
+ Format: `oklch(lightness saturation hue)` — lightness 0–1, saturation 0–0.4, hue 0–360.
11
+
12
+ ```css
13
+ @import "tailwindcss";
14
+
15
+ @theme {
16
+ /* Primary brand color + scale */
17
+ --color-primary: oklch(0.55 0.25 262);
18
+ --color-primary-50: oklch(0.97 0.02 262);
19
+ --color-primary-100: oklch(0.93 0.05 262);
20
+ --color-primary-500: oklch(0.55 0.25 262);
21
+ --color-primary-600: oklch(0.48 0.25 262);
22
+ --color-primary-900: oklch(0.25 0.15 262);
23
+
24
+ /* Semantic colors */
25
+ --color-success: oklch(0.65 0.15 142);
26
+ --color-warning: oklch(0.75 0.17 80);
27
+ --color-danger: oklch(0.55 0.25 27);
28
+ --color-info: oklch(0.60 0.20 230);
29
+
30
+ /* Neutral surface colors — works well with dark mode */
31
+ --color-surface: white;
32
+ --color-surface-raised: oklch(0.98 0 0);
33
+ --color-border: oklch(0.90 0 0);
34
+ --color-muted: oklch(0.55 0 0);
35
+ }
36
+ ```
37
+
38
+ Generated utilities: `bg-primary`, `bg-primary-500`, `text-danger`, `border-success`, `text-muted`, etc.
39
+
40
+ ---
41
+
42
+ ## Dark Mode Color Tokens
43
+
44
+ Define light/dark values with CSS custom properties, then reference them in `@theme`:
45
+
46
+ ```css
47
+ @import "tailwindcss";
48
+
49
+ /* Light mode defaults */
50
+ :root {
51
+ --bg: white;
52
+ --fg: oklch(0.15 0 0);
53
+ --border-col: oklch(0.88 0 0);
54
+ --muted-col: oklch(0.55 0 0);
55
+ --card-col: oklch(0.97 0 0);
56
+ }
57
+
58
+ /* Dark mode overrides */
59
+ .dark {
60
+ --bg: oklch(0.12 0 0);
61
+ --fg: oklch(0.95 0 0);
62
+ --border-col: oklch(0.25 0 0);
63
+ --muted-col: oklch(0.55 0 0);
64
+ --card-col: oklch(0.16 0 0);
65
+ }
66
+
67
+ /* Expose to Tailwind */
68
+ @theme {
69
+ --color-bg: var(--bg);
70
+ --color-fg: var(--fg);
71
+ --color-border-col: var(--border-col);
72
+ --color-muted: var(--muted-col);
73
+ --color-card: var(--card-col);
74
+ }
75
+ ```
76
+
77
+ Usage:
78
+ ```html
79
+ <div class="bg-bg text-fg border border-border-col">
80
+ <div class="bg-card rounded-lg p-4">Card content</div>
81
+ </div>
82
+ ```
83
+
84
+ ---
85
+
86
+ ## Typography Tokens
87
+
88
+ ```css
89
+ @theme {
90
+ --font-sans: 'Inter', ui-sans-serif, system-ui, sans-serif;
91
+ --font-serif: 'Playfair Display', ui-serif, Georgia, serif;
92
+ --font-mono: 'JetBrains Mono', ui-monospace, 'Cascadia Code', monospace;
93
+
94
+ /* Font sizes with paired line-heights */
95
+ --text-xs: 0.75rem / 1rem;
96
+ --text-sm: 0.875rem / 1.25rem;
97
+ --text-base: 1rem / 1.5rem;
98
+ --text-lg: 1.125rem / 1.75rem;
99
+ --text-xl: 1.25rem / 1.75rem;
100
+ --text-2xl: 1.5rem / 2rem;
101
+ --text-3xl: 1.875rem / 2.25rem;
102
+ --text-4xl: 2.25rem / 2.5rem;
103
+ }
104
+ ```
105
+
106
+ Generated utilities: `font-sans`, `font-serif`, `font-mono`, `text-xs` through `text-4xl`.
107
+
108
+ ---
109
+
110
+ ## Spacing Tokens
111
+
112
+ Spacing tokens affect: `p-*`, `m-*`, `gap-*`, `w-*`, `h-*`, `top-*`, `left-*`, etc.
113
+
114
+ ```css
115
+ @theme {
116
+ /* Semantic spacing (for consistent page layout) */
117
+ --spacing-page: 2rem; /* px-page */
118
+ --spacing-section: 4rem; /* py-section */
119
+ --spacing-card: 1.5rem; /* p-card */
120
+ }
121
+ ```
122
+
123
+ ---
124
+
125
+ ## Border Radius Tokens
126
+
127
+ ```css
128
+ @theme {
129
+ --radius-sm: 0.25rem; /* rounded-sm */
130
+ --radius-md: 0.5rem; /* rounded-md */
131
+ --radius-lg: 0.75rem; /* rounded-lg */
132
+ --radius-xl: 1rem; /* rounded-xl */
133
+ --radius-card: 0.75rem; /* rounded-card */
134
+ --radius-pill: 9999px; /* rounded-pill */
135
+ }
136
+ ```
137
+
138
+ ---
139
+
140
+ ## Shadow Tokens
141
+
142
+ ```css
143
+ @theme {
144
+ --shadow-sm: 0 1px 2px 0 oklch(0 0 0 / 0.05);
145
+ --shadow-md: 0 4px 6px -1px oklch(0 0 0 / 0.1), 0 2px 4px -2px oklch(0 0 0 / 0.1);
146
+ --shadow-lg: 0 10px 15px -3px oklch(0 0 0 / 0.1), 0 4px 6px -4px oklch(0 0 0 / 0.1);
147
+ --shadow-card: 0 2px 8px oklch(0 0 0 / 0.08);
148
+ }
149
+ ```
150
+
151
+ ---
152
+
153
+ ## Animation Tokens
154
+
155
+ ```css
156
+ @theme {
157
+ --animate-fade-in: fade-in 0.2s ease-out;
158
+ --animate-slide-up: slide-up 0.3s ease-out;
159
+ --animate-slide-down: slide-down 0.3s ease-out;
160
+ --animate-scale-in: scale-in 0.2s ease-out;
161
+ }
162
+
163
+ @keyframes fade-in {
164
+ from { opacity: 0; }
165
+ to { opacity: 1; }
166
+ }
167
+
168
+ @keyframes slide-up {
169
+ from { transform: translateY(0.5rem); opacity: 0; }
170
+ to { transform: translateY(0); opacity: 1; }
171
+ }
172
+
173
+ @keyframes slide-down {
174
+ from { transform: translateY(-0.5rem); opacity: 0; }
175
+ to { transform: translateY(0); opacity: 1; }
176
+ }
177
+
178
+ @keyframes scale-in {
179
+ from { transform: scale(0.95); opacity: 0; }
180
+ to { transform: scale(1); opacity: 1; }
181
+ }
182
+ ```
183
+
184
+ Generated utilities: `animate-fade-in`, `animate-slide-up`, `animate-slide-down`, `animate-scale-in`.
185
+
186
+ ---
187
+
188
+ ## Custom Utilities — @utility
189
+
190
+ ```css
191
+ /* Static utility */
192
+ @utility center-flex {
193
+ display: flex;
194
+ align-items: center;
195
+ justify-content: center;
196
+ }
197
+
198
+ /* Truncate with line clamp */
199
+ @utility truncate-2 {
200
+ display: -webkit-box;
201
+ -webkit-line-clamp: 2;
202
+ -webkit-box-orient: vertical;
203
+ overflow: hidden;
204
+ }
205
+ ```
206
+
207
+ Usage: `<div class="center-flex truncate-2">`.
208
+
209
+ ---
210
+
211
+ ## Custom Variants — @custom-variant
212
+
213
+ ```css
214
+ /* Hover on mobile (touch devices long-press) */
215
+ @custom-variant touch-hover {
216
+ @media (hover: none) {
217
+ &:active;
218
+ }
219
+ }
220
+
221
+ /* Group peer variants are built-in; this shows the pattern */
222
+ @custom-variant data-active {
223
+ &[data-active="true"];
224
+ }
225
+ ```
226
+
227
+ Usage:
228
+ ```html
229
+ <button class="data-active:bg-primary" data-active="true">Active</button>
230
+ ```