@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,375 @@
1
+ # Patterns Reference — Responsive, Dark Mode, Animations, Typography
2
+
3
+ ---
4
+
5
+ ## Responsive Design — Mobile-First
6
+
7
+ Always style the mobile base first, then add breakpoint prefixes for larger screens:
8
+
9
+ ```html
10
+ <!-- Typography -->
11
+ <h1 class="text-2xl font-bold sm:text-3xl lg:text-4xl">Title</h1>
12
+
13
+ <!-- Grid layout -->
14
+ <div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4">
15
+
16
+ <!-- Stack on mobile, side-by-side on desktop -->
17
+ <div class="flex flex-col sm:flex-row gap-4">
18
+
19
+ <!-- Full width on mobile, auto on desktop -->
20
+ <button class="w-full sm:w-auto">Submit</button>
21
+
22
+ <!-- Show/hide at breakpoints -->
23
+ <nav class="hidden md:flex">Desktop nav</nav>
24
+ <button class="md:hidden">Mobile menu</button>
25
+
26
+ <!-- Padding scales -->
27
+ <div class="px-4 sm:px-6 lg:px-8">Page content</div>
28
+ ```
29
+
30
+ **Built-in breakpoints:**
31
+ | Prefix | Min-width |
32
+ |--------|-----------|
33
+ | `sm:` | 640px |
34
+ | `md:` | 768px |
35
+ | `lg:` | 1024px |
36
+ | `xl:` | 1280px |
37
+ | `2xl:` | 1536px |
38
+
39
+ ---
40
+
41
+ ## Container Queries (v4 Built-In)
42
+
43
+ Container queries let components respond to their parent's size, not the viewport. Essential for reusable components in varying layouts.
44
+
45
+ ```html
46
+ <!-- Mark the container -->
47
+ <div class="@container">
48
+ <!-- Card adapts to container width, not screen width -->
49
+ <div class="flex flex-col @md:flex-row gap-4">
50
+ <img class="w-full @md:w-48 @md:shrink-0 rounded-lg" src="..." />
51
+ <div class="@md:flex @md:flex-col @md:justify-center">
52
+ <h2 class="text-lg @md:text-xl font-semibold">Title</h2>
53
+ <p class="text-sm text-muted">Description</p>
54
+ </div>
55
+ </div>
56
+ </div>
57
+ ```
58
+
59
+ **Container breakpoints (based on container width):**
60
+ | Prefix | Min-width |
61
+ |--------|-----------|
62
+ | `@sm:` | 384px |
63
+ | `@md:` | 448px |
64
+ | `@lg:` | 512px |
65
+ | `@xl:` | 576px |
66
+ | `@2xl:`| 672px |
67
+
68
+ **Named containers (for nested scenarios):**
69
+ ```html
70
+ <aside class="@container/sidebar">
71
+ <main class="@container/content">
72
+ <!-- Respond to different ancestor containers -->
73
+ <div class="@lg/sidebar:hidden @lg/content:block">
74
+ Only visible when content container is large
75
+ </div>
76
+ </main>
77
+ </aside>
78
+ ```
79
+
80
+ ---
81
+
82
+ ## Dark Mode
83
+
84
+ ### Setup — Class-Based (Recommended)
85
+
86
+ ```css
87
+ /* globals.css — define the dark variant */
88
+ @import "tailwindcss";
89
+
90
+ @custom-variant dark (&:where(.dark, .dark *));
91
+ ```
92
+
93
+ ```ts
94
+ // Zustand store or simple util
95
+ export function setTheme(theme: 'light' | 'dark') {
96
+ document.documentElement.classList.toggle('dark', theme === 'dark');
97
+ localStorage.setItem('theme', theme);
98
+ }
99
+
100
+ // On app startup — read persisted preference
101
+ const saved = localStorage.getItem('theme') as 'light' | 'dark' | null;
102
+ const system = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
103
+ setTheme(saved ?? system);
104
+ ```
105
+
106
+ ### Usage
107
+
108
+ ```html
109
+ <!-- Colors -->
110
+ <div class="bg-white dark:bg-slate-900">
111
+ <div class="text-slate-900 dark:text-slate-100">
112
+ <div class="border-slate-200 dark:border-slate-700">
113
+
114
+ <!-- With CSS variable tokens (cleaner) -->
115
+ <div class="bg-bg text-fg border-border-col">
116
+
117
+ <!-- Images / icons -->
118
+ <img class="opacity-100 dark:opacity-80" />
119
+ <svg class="fill-slate-900 dark:fill-white" />
120
+
121
+ <!-- Shadows -->
122
+ <div class="shadow-md dark:shadow-slate-900/50">
123
+ ```
124
+
125
+ ### Theme Toggle Component
126
+
127
+ ```tsx
128
+ 'use client'; // if Next.js
129
+
130
+ import { useState, useEffect } from 'react';
131
+
132
+ export function ThemeToggle() {
133
+ const [isDark, setIsDark] = useState(false);
134
+
135
+ useEffect(() => {
136
+ setIsDark(document.documentElement.classList.contains('dark'));
137
+ }, []);
138
+
139
+ const toggle = () => {
140
+ const next = !isDark;
141
+ setIsDark(next);
142
+ document.documentElement.classList.toggle('dark', next);
143
+ localStorage.setItem('theme', next ? 'dark' : 'light');
144
+ };
145
+
146
+ return (
147
+ <button
148
+ onClick={toggle}
149
+ className="rounded-md p-2 hover:bg-primary/10 transition-colors"
150
+ aria-label="Toggle theme"
151
+ >
152
+ {isDark ? '☀️' : '🌙'}
153
+ </button>
154
+ );
155
+ }
156
+ ```
157
+
158
+ ---
159
+
160
+ ## Animations
161
+
162
+ ### CSS Transitions (Hover, Focus)
163
+
164
+ ```html
165
+ <!-- Color transition -->
166
+ <button class="bg-primary hover:bg-primary/80 transition-colors duration-200">
167
+
168
+ <!-- Scale on hover -->
169
+ <div class="hover:scale-105 transition-transform duration-200">
170
+
171
+ <!-- Multiple properties -->
172
+ <div class="hover:shadow-lg hover:-translate-y-1 transition-all duration-200">
173
+
174
+ <!-- Opacity + transform combined -->
175
+ <div class="hover:opacity-80 active:scale-95 transition-all duration-150">
176
+ ```
177
+
178
+ ### Enter Animations — starting: Variant (v4)
179
+
180
+ The `starting:` variant applies `@starting-style` — defines the element's initial state before it renders, so it transitions in on mount.
181
+
182
+ ```html
183
+ <!-- Fade in on mount -->
184
+ <div class="opacity-100 transition-opacity duration-300 starting:opacity-0">
185
+ Fades in when added to DOM
186
+ </div>
187
+
188
+ <!-- Slide up on mount -->
189
+ <div class="translate-y-0 opacity-100 transition-all duration-300 starting:translate-y-4 starting:opacity-0">
190
+ Slides up from below
191
+ </div>
192
+
193
+ <!-- Scale in on mount -->
194
+ <div class="scale-100 opacity-100 transition-all duration-200 starting:scale-95 starting:opacity-0">
195
+ Scales in
196
+ </div>
197
+ ```
198
+
199
+ ### Custom Animation Classes (via @theme)
200
+
201
+ After defining animations in `@theme` (see design-tokens.md):
202
+
203
+ ```html
204
+ <div class="animate-fade-in">Fades in</div>
205
+ <div class="animate-slide-up">Slides up</div>
206
+ <div class="animate-scale-in">Scales in</div>
207
+
208
+ <!-- Built-in loading animations -->
209
+ <div class="animate-spin">Spinner</div>
210
+ <div class="animate-pulse">Skeleton</div>
211
+ <div class="animate-bounce">Bounce indicator</div>
212
+ <div class="animate-ping">Notification ping</div>
213
+ ```
214
+
215
+ ### Conditional Animation (React)
216
+
217
+ ```tsx
218
+ export function Notification({ show }: { show: boolean }) {
219
+ return (
220
+ <div
221
+ className={cn(
222
+ 'rounded-lg bg-success/10 px-4 py-3 text-success',
223
+ 'transition-all duration-300',
224
+ show
225
+ ? 'translate-y-0 opacity-100'
226
+ : '-translate-y-4 opacity-0 pointer-events-none',
227
+ )}
228
+ >
229
+ Saved successfully!
230
+ </div>
231
+ );
232
+ }
233
+ ```
234
+
235
+ ---
236
+
237
+ ## Typography — @tailwindcss/typography
238
+
239
+ Install: `npm install -D @tailwindcss/typography`
240
+
241
+ In globals.css: `@plugin "@tailwindcss/typography";`
242
+
243
+ ### Usage
244
+
245
+ ```html
246
+ <!-- Blog post, markdown output, rich text editor content -->
247
+ <article class="prose lg:prose-lg dark:prose-invert max-w-none">
248
+ <h1>Article Title</h1>
249
+ <p>Content is auto-styled — links, headings, lists, code, blockquotes.</p>
250
+ <code>code snippets</code>
251
+ <pre><code>code blocks</code></pre>
252
+ </article>
253
+ ```
254
+
255
+ ### Prose Modifiers
256
+
257
+ ```html
258
+ <!-- Size -->
259
+ <article class="prose prose-sm"> Small (14px) </article>
260
+ <article class="prose"> Base (16px) </article>
261
+ <article class="prose prose-lg"> Large (18px) </article>
262
+ <article class="prose prose-xl"> XL (20px) </article>
263
+
264
+ <!-- Dark mode -->
265
+ <article class="prose dark:prose-invert">
266
+
267
+ <!-- Responsive size -->
268
+ <article class="prose md:prose-lg lg:prose-xl">
269
+
270
+ <!-- Element overrides -->
271
+ <article class="prose prose-a:text-primary prose-a:no-underline hover:prose-a:underline prose-code:rounded prose-code:bg-muted/20 prose-code:px-1 prose-img:rounded-xl">
272
+ ```
273
+
274
+ ---
275
+
276
+ ## Layout Patterns
277
+
278
+ ### Page Layout
279
+
280
+ ```tsx
281
+ export function PageLayout({ children }: { children: React.ReactNode }) {
282
+ return (
283
+ <div className="min-h-screen bg-bg text-fg">
284
+ <header className="sticky top-0 z-40 border-b border-border-col bg-bg/80 backdrop-blur">
285
+ <div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
286
+ <div className="flex h-16 items-center justify-between">
287
+ <Logo />
288
+ <nav className="hidden md:flex items-center gap-4">
289
+ <NavLinks />
290
+ </nav>
291
+ <ThemeToggle />
292
+ </div>
293
+ </div>
294
+ </header>
295
+ <main className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8 py-8">
296
+ {children}
297
+ </main>
298
+ </div>
299
+ );
300
+ }
301
+ ```
302
+
303
+ ### Sidebar Layout
304
+
305
+ ```tsx
306
+ export function DashboardLayout({ children }: { children: React.ReactNode }) {
307
+ return (
308
+ <div className="flex min-h-screen bg-bg">
309
+ {/* Sidebar */}
310
+ <aside className="hidden w-64 shrink-0 border-r border-border-col lg:block">
311
+ <nav className="sticky top-0 h-screen overflow-y-auto p-4">
312
+ <SidebarNav />
313
+ </nav>
314
+ </aside>
315
+ {/* Content */}
316
+ <div className="flex flex-1 flex-col">
317
+ <header className="flex h-16 items-center border-b border-border-col px-6">
318
+ <h1 className="text-lg font-semibold">Dashboard</h1>
319
+ </header>
320
+ <main className="flex-1 overflow-auto p-6">{children}</main>
321
+ </div>
322
+ </div>
323
+ );
324
+ }
325
+ ```
326
+
327
+ ### Data Table
328
+
329
+ ```tsx
330
+ export function DataTable<T>({ columns, rows }: TableProps<T>) {
331
+ return (
332
+ <div className="overflow-hidden rounded-xl border border-border-col">
333
+ <table className="w-full text-sm">
334
+ <thead className="border-b border-border-col bg-card">
335
+ <tr>
336
+ {columns.map((col) => (
337
+ <th key={col.key} className="px-4 py-3 text-left font-medium text-muted">
338
+ {col.label}
339
+ </th>
340
+ ))}
341
+ </tr>
342
+ </thead>
343
+ <tbody className="divide-y divide-border-col bg-bg">
344
+ {rows.map((row, i) => (
345
+ <tr key={i} className="hover:bg-card transition-colors">
346
+ {columns.map((col) => (
347
+ <td key={col.key} className="px-4 py-3">
348
+ {col.render ? col.render(row) : String((row as any)[col.key])}
349
+ </td>
350
+ ))}
351
+ </tr>
352
+ ))}
353
+ </tbody>
354
+ </table>
355
+ </div>
356
+ );
357
+ }
358
+ ```
359
+
360
+ ### Empty State
361
+
362
+ ```tsx
363
+ export function EmptyState({ icon: Icon, title, description, action }: EmptyStateProps) {
364
+ return (
365
+ <div className="flex flex-col items-center justify-center rounded-xl border border-dashed border-border-col py-16 text-center">
366
+ <div className="mb-4 rounded-full bg-primary/10 p-4">
367
+ <Icon className="size-8 text-primary" />
368
+ </div>
369
+ <h3 className="text-lg font-semibold text-fg">{title}</h3>
370
+ <p className="mt-1 text-sm text-muted">{description}</p>
371
+ {action && <div className="mt-6">{action}</div>}
372
+ </div>
373
+ );
374
+ }
375
+ ```
@@ -0,0 +1,165 @@
1
+ # Setup Reference — Tailwind CSS v4
2
+
3
+ ---
4
+
5
+ ## Vite + React
6
+
7
+ ```bash
8
+ npm create vite@latest my-app -- --template react-ts
9
+ cd my-app
10
+ npm install tailwindcss @tailwindcss/vite clsx tailwind-merge class-variance-authority
11
+ ```
12
+
13
+ **vite.config.ts:**
14
+ ```ts
15
+ import { defineConfig } from 'vite';
16
+ import react from '@vitejs/plugin-react';
17
+ import tailwindcss from '@tailwindcss/vite';
18
+
19
+ export default defineConfig({
20
+ plugins: [react(), tailwindcss()],
21
+ resolve: {
22
+ alias: { '@': '/src' },
23
+ },
24
+ });
25
+ ```
26
+
27
+ **src/index.css:**
28
+ ```css
29
+ @import "tailwindcss";
30
+
31
+ /* All @theme customizations go here */
32
+ @theme {
33
+ --font-sans: 'Inter', sans-serif;
34
+ --color-primary: oklch(0.55 0.25 262);
35
+ }
36
+ ```
37
+
38
+ **main.tsx:**
39
+ ```tsx
40
+ import './index.css';
41
+ import ReactDOM from 'react-dom/client';
42
+ import App from './App';
43
+
44
+ ReactDOM.createRoot(document.getElementById('root')!).render(<App />);
45
+ ```
46
+
47
+ ---
48
+
49
+ ## Next.js 15
50
+
51
+ ```bash
52
+ npx create-next-app@latest my-app --typescript --app --src-dir --import-alias "@/*"
53
+ cd my-app
54
+ npm install tailwindcss @tailwindcss/postcss postcss clsx tailwind-merge class-variance-authority
55
+ ```
56
+
57
+ **postcss.config.mjs:**
58
+ ```js
59
+ export default { plugins: { '@tailwindcss/postcss': {} } };
60
+ ```
61
+
62
+ **src/app/globals.css:**
63
+ ```css
64
+ @import "tailwindcss";
65
+
66
+ @theme {
67
+ --font-sans: 'Inter', sans-serif;
68
+ --color-primary: oklch(0.55 0.25 262);
69
+ }
70
+ ```
71
+
72
+ **src/app/layout.tsx:**
73
+ ```tsx
74
+ import './globals.css';
75
+ import type { Metadata } from 'next';
76
+
77
+ export const metadata: Metadata = { title: 'My App' };
78
+
79
+ export default function RootLayout({ children }: { children: React.ReactNode }) {
80
+ return (
81
+ <html lang="en">
82
+ <body>{children}</body>
83
+ </html>
84
+ );
85
+ }
86
+ ```
87
+
88
+ ---
89
+
90
+ ## @tailwindcss/typography Plugin
91
+
92
+ ```bash
93
+ npm install -D @tailwindcss/typography
94
+ ```
95
+
96
+ **In globals.css — add plugin import after tailwindcss:**
97
+ ```css
98
+ @import "tailwindcss";
99
+ @plugin "@tailwindcss/typography";
100
+ ```
101
+
102
+ Usage:
103
+ ```html
104
+ <article class="prose lg:prose-lg dark:prose-invert max-w-none">
105
+ <!-- Rich text content, markdown output, blog posts -->
106
+ </article>
107
+ ```
108
+
109
+ ---
110
+
111
+ ## shadcn/ui Setup (Tailwind v4)
112
+
113
+ shadcn/ui components ship ready for Tailwind v4 with CSS variable–based theming.
114
+
115
+ ```bash
116
+ npx shadcn@latest init
117
+ ```
118
+
119
+ The CLI will:
120
+ 1. Create `src/lib/utils.ts` with the `cn()` helper
121
+ 2. Add CSS variables to `globals.css` under `:root` and `.dark`
122
+ 3. Wire up `@theme` to expose variables as Tailwind utilities
123
+
124
+ Install components individually:
125
+ ```bash
126
+ npx shadcn@latest add button
127
+ npx shadcn@latest add card
128
+ npx shadcn@latest add input
129
+ npx shadcn@latest add dialog
130
+ npx shadcn@latest add table
131
+ npx shadcn@latest add form # includes react-hook-form integration
132
+ ```
133
+
134
+ Components land in `src/components/ui/` — they are source files you own and customize.
135
+
136
+ ---
137
+
138
+ ## cn() Helper — Always Create This File
139
+
140
+ ```ts
141
+ // src/lib/utils.ts
142
+ import { clsx, type ClassValue } from 'clsx';
143
+ import { twMerge } from 'tailwind-merge';
144
+
145
+ export function cn(...inputs: ClassValue[]) {
146
+ return twMerge(clsx(inputs));
147
+ }
148
+ ```
149
+
150
+ ---
151
+
152
+ ## TypeScript Path Aliases (tsconfig.json)
153
+
154
+ ```json
155
+ {
156
+ "compilerOptions": {
157
+ "baseUrl": ".",
158
+ "paths": {
159
+ "@/*": ["./src/*"]
160
+ }
161
+ }
162
+ }
163
+ ```
164
+
165
+ Vite also needs the alias in `vite.config.ts` (shown above). Next.js handles it automatically when using `--import-alias "@/*"` flag.