@0xsown/vibe-code-fe 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 (189) hide show
  1. package/bin/index.js +181 -0
  2. package/package.json +32 -0
  3. package/skills/claude-md-improver/SKILL.md +179 -0
  4. package/skills/claude-md-improver/references/quality-criteria.md +109 -0
  5. package/skills/claude-md-improver/references/templates.md +253 -0
  6. package/skills/claude-md-improver/references/update-guidelines.md +150 -0
  7. package/skills/find-skills/SKILL.md +133 -0
  8. package/skills/frontend-design/LICENSE.txt +177 -0
  9. package/skills/frontend-design/SKILL.md +42 -0
  10. package/skills/next-best-practices/SKILL.md +153 -0
  11. package/skills/next-best-practices/async-patterns.md +87 -0
  12. package/skills/next-best-practices/bundling.md +180 -0
  13. package/skills/next-best-practices/data-patterns.md +297 -0
  14. package/skills/next-best-practices/debug-tricks.md +105 -0
  15. package/skills/next-best-practices/directives.md +73 -0
  16. package/skills/next-best-practices/error-handling.md +227 -0
  17. package/skills/next-best-practices/file-conventions.md +140 -0
  18. package/skills/next-best-practices/font.md +245 -0
  19. package/skills/next-best-practices/functions.md +108 -0
  20. package/skills/next-best-practices/hydration-error.md +91 -0
  21. package/skills/next-best-practices/image.md +173 -0
  22. package/skills/next-best-practices/metadata.md +301 -0
  23. package/skills/next-best-practices/parallel-routes.md +287 -0
  24. package/skills/next-best-practices/route-handlers.md +146 -0
  25. package/skills/next-best-practices/rsc-boundaries.md +159 -0
  26. package/skills/next-best-practices/runtime-selection.md +39 -0
  27. package/skills/next-best-practices/scripts.md +141 -0
  28. package/skills/next-best-practices/self-hosting.md +371 -0
  29. package/skills/next-best-practices/suspense-boundaries.md +67 -0
  30. package/skills/next-cache-components/SKILL.md +411 -0
  31. package/skills/shadcn-ui/README.md +248 -0
  32. package/skills/shadcn-ui/SKILL.md +326 -0
  33. package/skills/shadcn-ui/examples/auth-layout.tsx +177 -0
  34. package/skills/shadcn-ui/examples/data-table.tsx +313 -0
  35. package/skills/shadcn-ui/examples/form-pattern.tsx +177 -0
  36. package/skills/shadcn-ui/resources/component-catalog.md +481 -0
  37. package/skills/shadcn-ui/resources/customization-guide.md +516 -0
  38. package/skills/shadcn-ui/resources/migration-guide.md +463 -0
  39. package/skills/shadcn-ui/resources/setup-guide.md +412 -0
  40. package/skills/shadcn-ui/scripts/verify-setup.sh +134 -0
  41. package/skills/supabase-postgres-best-practices/AGENTS.md +68 -0
  42. package/skills/supabase-postgres-best-practices/CLAUDE.md +68 -0
  43. package/skills/supabase-postgres-best-practices/README.md +116 -0
  44. package/skills/supabase-postgres-best-practices/SKILL.md +64 -0
  45. package/skills/supabase-postgres-best-practices/references/advanced-full-text-search.md +55 -0
  46. package/skills/supabase-postgres-best-practices/references/advanced-jsonb-indexing.md +49 -0
  47. package/skills/supabase-postgres-best-practices/references/conn-idle-timeout.md +46 -0
  48. package/skills/supabase-postgres-best-practices/references/conn-limits.md +44 -0
  49. package/skills/supabase-postgres-best-practices/references/conn-pooling.md +41 -0
  50. package/skills/supabase-postgres-best-practices/references/conn-prepared-statements.md +46 -0
  51. package/skills/supabase-postgres-best-practices/references/data-batch-inserts.md +54 -0
  52. package/skills/supabase-postgres-best-practices/references/data-n-plus-one.md +53 -0
  53. package/skills/supabase-postgres-best-practices/references/data-pagination.md +50 -0
  54. package/skills/supabase-postgres-best-practices/references/data-upsert.md +50 -0
  55. package/skills/supabase-postgres-best-practices/references/lock-advisory.md +56 -0
  56. package/skills/supabase-postgres-best-practices/references/lock-deadlock-prevention.md +68 -0
  57. package/skills/supabase-postgres-best-practices/references/lock-short-transactions.md +50 -0
  58. package/skills/supabase-postgres-best-practices/references/lock-skip-locked.md +54 -0
  59. package/skills/supabase-postgres-best-practices/references/monitor-explain-analyze.md +45 -0
  60. package/skills/supabase-postgres-best-practices/references/monitor-pg-stat-statements.md +55 -0
  61. package/skills/supabase-postgres-best-practices/references/monitor-vacuum-analyze.md +55 -0
  62. package/skills/supabase-postgres-best-practices/references/query-composite-indexes.md +44 -0
  63. package/skills/supabase-postgres-best-practices/references/query-covering-indexes.md +40 -0
  64. package/skills/supabase-postgres-best-practices/references/query-index-types.md +48 -0
  65. package/skills/supabase-postgres-best-practices/references/query-missing-indexes.md +43 -0
  66. package/skills/supabase-postgres-best-practices/references/query-partial-indexes.md +45 -0
  67. package/skills/supabase-postgres-best-practices/references/schema-constraints.md +80 -0
  68. package/skills/supabase-postgres-best-practices/references/schema-data-types.md +46 -0
  69. package/skills/supabase-postgres-best-practices/references/schema-foreign-key-indexes.md +59 -0
  70. package/skills/supabase-postgres-best-practices/references/schema-lowercase-identifiers.md +55 -0
  71. package/skills/supabase-postgres-best-practices/references/schema-partitioning.md +55 -0
  72. package/skills/supabase-postgres-best-practices/references/schema-primary-keys.md +61 -0
  73. package/skills/supabase-postgres-best-practices/references/security-privileges.md +54 -0
  74. package/skills/supabase-postgres-best-practices/references/security-rls-basics.md +50 -0
  75. package/skills/supabase-postgres-best-practices/references/security-rls-performance.md +57 -0
  76. package/skills/tailwind-design-system/SKILL.md +874 -0
  77. package/skills/vercel-composition-patterns/AGENTS.md +946 -0
  78. package/skills/vercel-composition-patterns/README.md +60 -0
  79. package/skills/vercel-composition-patterns/SKILL.md +89 -0
  80. package/skills/vercel-composition-patterns/rules/architecture-avoid-boolean-props.md +100 -0
  81. package/skills/vercel-composition-patterns/rules/architecture-compound-components.md +112 -0
  82. package/skills/vercel-composition-patterns/rules/patterns-children-over-render-props.md +87 -0
  83. package/skills/vercel-composition-patterns/rules/patterns-explicit-variants.md +100 -0
  84. package/skills/vercel-composition-patterns/rules/react19-no-forwardref.md +42 -0
  85. package/skills/vercel-composition-patterns/rules/state-context-interface.md +191 -0
  86. package/skills/vercel-composition-patterns/rules/state-decouple-implementation.md +113 -0
  87. package/skills/vercel-composition-patterns/rules/state-lift-state.md +125 -0
  88. package/skills/vercel-react-best-practices/AGENTS.md +2934 -0
  89. package/skills/vercel-react-best-practices/README.md +123 -0
  90. package/skills/vercel-react-best-practices/SKILL.md +136 -0
  91. package/skills/vercel-react-best-practices/rules/advanced-event-handler-refs.md +55 -0
  92. package/skills/vercel-react-best-practices/rules/advanced-init-once.md +42 -0
  93. package/skills/vercel-react-best-practices/rules/advanced-use-latest.md +39 -0
  94. package/skills/vercel-react-best-practices/rules/async-api-routes.md +38 -0
  95. package/skills/vercel-react-best-practices/rules/async-defer-await.md +80 -0
  96. package/skills/vercel-react-best-practices/rules/async-dependencies.md +51 -0
  97. package/skills/vercel-react-best-practices/rules/async-parallel.md +28 -0
  98. package/skills/vercel-react-best-practices/rules/async-suspense-boundaries.md +99 -0
  99. package/skills/vercel-react-best-practices/rules/bundle-barrel-imports.md +59 -0
  100. package/skills/vercel-react-best-practices/rules/bundle-conditional.md +31 -0
  101. package/skills/vercel-react-best-practices/rules/bundle-defer-third-party.md +49 -0
  102. package/skills/vercel-react-best-practices/rules/bundle-dynamic-imports.md +35 -0
  103. package/skills/vercel-react-best-practices/rules/bundle-preload.md +50 -0
  104. package/skills/vercel-react-best-practices/rules/client-event-listeners.md +74 -0
  105. package/skills/vercel-react-best-practices/rules/client-localstorage-schema.md +71 -0
  106. package/skills/vercel-react-best-practices/rules/client-passive-event-listeners.md +48 -0
  107. package/skills/vercel-react-best-practices/rules/client-swr-dedup.md +56 -0
  108. package/skills/vercel-react-best-practices/rules/js-batch-dom-css.md +107 -0
  109. package/skills/vercel-react-best-practices/rules/js-cache-function-results.md +80 -0
  110. package/skills/vercel-react-best-practices/rules/js-cache-property-access.md +28 -0
  111. package/skills/vercel-react-best-practices/rules/js-cache-storage.md +70 -0
  112. package/skills/vercel-react-best-practices/rules/js-combine-iterations.md +32 -0
  113. package/skills/vercel-react-best-practices/rules/js-early-exit.md +50 -0
  114. package/skills/vercel-react-best-practices/rules/js-hoist-regexp.md +45 -0
  115. package/skills/vercel-react-best-practices/rules/js-index-maps.md +37 -0
  116. package/skills/vercel-react-best-practices/rules/js-length-check-first.md +49 -0
  117. package/skills/vercel-react-best-practices/rules/js-min-max-loop.md +82 -0
  118. package/skills/vercel-react-best-practices/rules/js-set-map-lookups.md +24 -0
  119. package/skills/vercel-react-best-practices/rules/js-tosorted-immutable.md +57 -0
  120. package/skills/vercel-react-best-practices/rules/rendering-activity.md +26 -0
  121. package/skills/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
  122. package/skills/vercel-react-best-practices/rules/rendering-conditional-render.md +40 -0
  123. package/skills/vercel-react-best-practices/rules/rendering-content-visibility.md +38 -0
  124. package/skills/vercel-react-best-practices/rules/rendering-hoist-jsx.md +46 -0
  125. package/skills/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
  126. package/skills/vercel-react-best-practices/rules/rendering-hydration-suppress-warning.md +30 -0
  127. package/skills/vercel-react-best-practices/rules/rendering-svg-precision.md +28 -0
  128. package/skills/vercel-react-best-practices/rules/rendering-usetransition-loading.md +75 -0
  129. package/skills/vercel-react-best-practices/rules/rerender-defer-reads.md +39 -0
  130. package/skills/vercel-react-best-practices/rules/rerender-dependencies.md +45 -0
  131. package/skills/vercel-react-best-practices/rules/rerender-derived-state-no-effect.md +40 -0
  132. package/skills/vercel-react-best-practices/rules/rerender-derived-state.md +29 -0
  133. package/skills/vercel-react-best-practices/rules/rerender-functional-setstate.md +74 -0
  134. package/skills/vercel-react-best-practices/rules/rerender-lazy-state-init.md +58 -0
  135. package/skills/vercel-react-best-practices/rules/rerender-memo-with-default-value.md +38 -0
  136. package/skills/vercel-react-best-practices/rules/rerender-memo.md +44 -0
  137. package/skills/vercel-react-best-practices/rules/rerender-move-effect-to-event.md +45 -0
  138. package/skills/vercel-react-best-practices/rules/rerender-simple-expression-in-memo.md +35 -0
  139. package/skills/vercel-react-best-practices/rules/rerender-transitions.md +40 -0
  140. package/skills/vercel-react-best-practices/rules/rerender-use-ref-transient-values.md +73 -0
  141. package/skills/vercel-react-best-practices/rules/server-after-nonblocking.md +73 -0
  142. package/skills/vercel-react-best-practices/rules/server-auth-actions.md +96 -0
  143. package/skills/vercel-react-best-practices/rules/server-cache-lru.md +41 -0
  144. package/skills/vercel-react-best-practices/rules/server-cache-react.md +76 -0
  145. package/skills/vercel-react-best-practices/rules/server-dedup-props.md +65 -0
  146. package/skills/vercel-react-best-practices/rules/server-parallel-fetching.md +83 -0
  147. package/skills/vercel-react-best-practices/rules/server-serialization.md +38 -0
  148. package/skills/vercel-react-native-skills/AGENTS.md +2897 -0
  149. package/skills/vercel-react-native-skills/README.md +165 -0
  150. package/skills/vercel-react-native-skills/SKILL.md +121 -0
  151. package/skills/vercel-react-native-skills/rules/animation-derived-value.md +53 -0
  152. package/skills/vercel-react-native-skills/rules/animation-gesture-detector-press.md +95 -0
  153. package/skills/vercel-react-native-skills/rules/animation-gpu-properties.md +65 -0
  154. package/skills/vercel-react-native-skills/rules/design-system-compound-components.md +66 -0
  155. package/skills/vercel-react-native-skills/rules/fonts-config-plugin.md +71 -0
  156. package/skills/vercel-react-native-skills/rules/imports-design-system-folder.md +68 -0
  157. package/skills/vercel-react-native-skills/rules/js-hoist-intl.md +61 -0
  158. package/skills/vercel-react-native-skills/rules/list-performance-callbacks.md +44 -0
  159. package/skills/vercel-react-native-skills/rules/list-performance-function-references.md +132 -0
  160. package/skills/vercel-react-native-skills/rules/list-performance-images.md +53 -0
  161. package/skills/vercel-react-native-skills/rules/list-performance-inline-objects.md +97 -0
  162. package/skills/vercel-react-native-skills/rules/list-performance-item-expensive.md +94 -0
  163. package/skills/vercel-react-native-skills/rules/list-performance-item-memo.md +82 -0
  164. package/skills/vercel-react-native-skills/rules/list-performance-item-types.md +104 -0
  165. package/skills/vercel-react-native-skills/rules/list-performance-virtualize.md +67 -0
  166. package/skills/vercel-react-native-skills/rules/monorepo-native-deps-in-app.md +46 -0
  167. package/skills/vercel-react-native-skills/rules/monorepo-single-dependency-versions.md +63 -0
  168. package/skills/vercel-react-native-skills/rules/navigation-native-navigators.md +188 -0
  169. package/skills/vercel-react-native-skills/rules/react-compiler-destructure-functions.md +50 -0
  170. package/skills/vercel-react-native-skills/rules/react-compiler-reanimated-shared-values.md +48 -0
  171. package/skills/vercel-react-native-skills/rules/react-state-dispatcher.md +91 -0
  172. package/skills/vercel-react-native-skills/rules/react-state-fallback.md +56 -0
  173. package/skills/vercel-react-native-skills/rules/react-state-minimize.md +65 -0
  174. package/skills/vercel-react-native-skills/rules/rendering-no-falsy-and.md +74 -0
  175. package/skills/vercel-react-native-skills/rules/rendering-text-in-text-component.md +36 -0
  176. package/skills/vercel-react-native-skills/rules/scroll-position-no-state.md +82 -0
  177. package/skills/vercel-react-native-skills/rules/state-ground-truth.md +80 -0
  178. package/skills/vercel-react-native-skills/rules/ui-expo-image.md +66 -0
  179. package/skills/vercel-react-native-skills/rules/ui-image-gallery.md +104 -0
  180. package/skills/vercel-react-native-skills/rules/ui-measure-views.md +78 -0
  181. package/skills/vercel-react-native-skills/rules/ui-menus.md +174 -0
  182. package/skills/vercel-react-native-skills/rules/ui-native-modals.md +77 -0
  183. package/skills/vercel-react-native-skills/rules/ui-pressable.md +61 -0
  184. package/skills/vercel-react-native-skills/rules/ui-safe-area-scroll.md +65 -0
  185. package/skills/vercel-react-native-skills/rules/ui-scrollview-content-inset.md +45 -0
  186. package/skills/vercel-react-native-skills/rules/ui-styling.md +87 -0
  187. package/skills/web-design-guidelines/SKILL.md +39 -0
  188. package/templates/AGENTS.md +31 -0
  189. package/templates/CLAUDE.md +31 -0
@@ -0,0 +1,874 @@
1
+ ---
2
+ name: tailwind-design-system
3
+ description: Build scalable design systems with Tailwind CSS v4, design tokens, component libraries, and responsive patterns. Use when creating component libraries, implementing design systems, or standardizing UI patterns.
4
+ ---
5
+
6
+ # Tailwind Design System (v4)
7
+
8
+ Build production-ready design systems with Tailwind CSS v4, including CSS-first configuration, design tokens, component variants, responsive patterns, and accessibility.
9
+
10
+ > **Note**: This skill targets Tailwind CSS v4 (2024+). For v3 projects, refer to the [upgrade guide](https://tailwindcss.com/docs/upgrade-guide).
11
+
12
+ ## When to Use This Skill
13
+
14
+ - Creating a component library with Tailwind v4
15
+ - Implementing design tokens and theming with CSS-first configuration
16
+ - Building responsive and accessible components
17
+ - Standardizing UI patterns across a codebase
18
+ - Migrating from Tailwind v3 to v4
19
+ - Setting up dark mode with native CSS features
20
+
21
+ ## Key v4 Changes
22
+
23
+ | v3 Pattern | v4 Pattern |
24
+ | ------------------------------------- | --------------------------------------------------------------------- |
25
+ | `tailwind.config.ts` | `@theme` in CSS |
26
+ | `@tailwind base/components/utilities` | `@import "tailwindcss"` |
27
+ | `darkMode: "class"` | `@custom-variant dark (&:where(.dark, .dark *))` |
28
+ | `theme.extend.colors` | `@theme { --color-*: value }` |
29
+ | `require("tailwindcss-animate")` | CSS `@keyframes` in `@theme` + `@starting-style` for entry animations |
30
+
31
+ ## Quick Start
32
+
33
+ ```css
34
+ /* app.css - Tailwind v4 CSS-first configuration */
35
+ @import "tailwindcss";
36
+
37
+ /* Define your theme with @theme */
38
+ @theme {
39
+ /* Semantic color tokens using OKLCH for better color perception */
40
+ --color-background: oklch(100% 0 0);
41
+ --color-foreground: oklch(14.5% 0.025 264);
42
+
43
+ --color-primary: oklch(14.5% 0.025 264);
44
+ --color-primary-foreground: oklch(98% 0.01 264);
45
+
46
+ --color-secondary: oklch(96% 0.01 264);
47
+ --color-secondary-foreground: oklch(14.5% 0.025 264);
48
+
49
+ --color-muted: oklch(96% 0.01 264);
50
+ --color-muted-foreground: oklch(46% 0.02 264);
51
+
52
+ --color-accent: oklch(96% 0.01 264);
53
+ --color-accent-foreground: oklch(14.5% 0.025 264);
54
+
55
+ --color-destructive: oklch(53% 0.22 27);
56
+ --color-destructive-foreground: oklch(98% 0.01 264);
57
+
58
+ --color-border: oklch(91% 0.01 264);
59
+ --color-ring: oklch(14.5% 0.025 264);
60
+
61
+ --color-card: oklch(100% 0 0);
62
+ --color-card-foreground: oklch(14.5% 0.025 264);
63
+
64
+ /* Ring offset for focus states */
65
+ --color-ring-offset: oklch(100% 0 0);
66
+
67
+ /* Radius tokens */
68
+ --radius-sm: 0.25rem;
69
+ --radius-md: 0.375rem;
70
+ --radius-lg: 0.5rem;
71
+ --radius-xl: 0.75rem;
72
+
73
+ /* Animation tokens - keyframes inside @theme are output when referenced by --animate-* variables */
74
+ --animate-fade-in: fade-in 0.2s ease-out;
75
+ --animate-fade-out: fade-out 0.2s ease-in;
76
+ --animate-slide-in: slide-in 0.3s ease-out;
77
+ --animate-slide-out: slide-out 0.3s ease-in;
78
+
79
+ @keyframes fade-in {
80
+ from {
81
+ opacity: 0;
82
+ }
83
+ to {
84
+ opacity: 1;
85
+ }
86
+ }
87
+
88
+ @keyframes fade-out {
89
+ from {
90
+ opacity: 1;
91
+ }
92
+ to {
93
+ opacity: 0;
94
+ }
95
+ }
96
+
97
+ @keyframes slide-in {
98
+ from {
99
+ transform: translateY(-0.5rem);
100
+ opacity: 0;
101
+ }
102
+ to {
103
+ transform: translateY(0);
104
+ opacity: 1;
105
+ }
106
+ }
107
+
108
+ @keyframes slide-out {
109
+ from {
110
+ transform: translateY(0);
111
+ opacity: 1;
112
+ }
113
+ to {
114
+ transform: translateY(-0.5rem);
115
+ opacity: 0;
116
+ }
117
+ }
118
+ }
119
+
120
+ /* Dark mode variant - use @custom-variant for class-based dark mode */
121
+ @custom-variant dark (&:where(.dark, .dark *));
122
+
123
+ /* Dark mode theme overrides */
124
+ .dark {
125
+ --color-background: oklch(14.5% 0.025 264);
126
+ --color-foreground: oklch(98% 0.01 264);
127
+
128
+ --color-primary: oklch(98% 0.01 264);
129
+ --color-primary-foreground: oklch(14.5% 0.025 264);
130
+
131
+ --color-secondary: oklch(22% 0.02 264);
132
+ --color-secondary-foreground: oklch(98% 0.01 264);
133
+
134
+ --color-muted: oklch(22% 0.02 264);
135
+ --color-muted-foreground: oklch(65% 0.02 264);
136
+
137
+ --color-accent: oklch(22% 0.02 264);
138
+ --color-accent-foreground: oklch(98% 0.01 264);
139
+
140
+ --color-destructive: oklch(42% 0.15 27);
141
+ --color-destructive-foreground: oklch(98% 0.01 264);
142
+
143
+ --color-border: oklch(22% 0.02 264);
144
+ --color-ring: oklch(83% 0.02 264);
145
+
146
+ --color-card: oklch(14.5% 0.025 264);
147
+ --color-card-foreground: oklch(98% 0.01 264);
148
+
149
+ --color-ring-offset: oklch(14.5% 0.025 264);
150
+ }
151
+
152
+ /* Base styles */
153
+ @layer base {
154
+ * {
155
+ @apply border-border;
156
+ }
157
+
158
+ body {
159
+ @apply bg-background text-foreground antialiased;
160
+ }
161
+ }
162
+ ```
163
+
164
+ ## Core Concepts
165
+
166
+ ### 1. Design Token Hierarchy
167
+
168
+ ```
169
+ Brand Tokens (abstract)
170
+ └── Semantic Tokens (purpose)
171
+ └── Component Tokens (specific)
172
+
173
+ Example:
174
+ oklch(45% 0.2 260) → --color-primary → bg-primary
175
+ ```
176
+
177
+ ### 2. Component Architecture
178
+
179
+ ```
180
+ Base styles → Variants → Sizes → States → Overrides
181
+ ```
182
+
183
+ ## Patterns
184
+
185
+ ### Pattern 1: CVA (Class Variance Authority) Components
186
+
187
+ ```typescript
188
+ // components/ui/button.tsx
189
+ import { Slot } from '@radix-ui/react-slot'
190
+ import { cva, type VariantProps } from 'class-variance-authority'
191
+ import { cn } from '@/lib/utils'
192
+
193
+ const buttonVariants = cva(
194
+ // Base styles - v4 uses native CSS variables
195
+ 'inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50',
196
+ {
197
+ variants: {
198
+ variant: {
199
+ default: 'bg-primary text-primary-foreground hover:bg-primary/90',
200
+ destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/90',
201
+ outline: 'border border-border bg-background hover:bg-accent hover:text-accent-foreground',
202
+ secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',
203
+ ghost: 'hover:bg-accent hover:text-accent-foreground',
204
+ link: 'text-primary underline-offset-4 hover:underline',
205
+ },
206
+ size: {
207
+ default: 'h-10 px-4 py-2',
208
+ sm: 'h-9 rounded-md px-3',
209
+ lg: 'h-11 rounded-md px-8',
210
+ icon: 'size-10',
211
+ },
212
+ },
213
+ defaultVariants: {
214
+ variant: 'default',
215
+ size: 'default',
216
+ },
217
+ }
218
+ )
219
+
220
+ export interface ButtonProps
221
+ extends React.ButtonHTMLAttributes<HTMLButtonElement>,
222
+ VariantProps<typeof buttonVariants> {
223
+ asChild?: boolean
224
+ }
225
+
226
+ // React 19: No forwardRef needed
227
+ export function Button({
228
+ className,
229
+ variant,
230
+ size,
231
+ asChild = false,
232
+ ref,
233
+ ...props
234
+ }: ButtonProps & { ref?: React.Ref<HTMLButtonElement> }) {
235
+ const Comp = asChild ? Slot : 'button'
236
+ return (
237
+ <Comp
238
+ className={cn(buttonVariants({ variant, size, className }))}
239
+ ref={ref}
240
+ {...props}
241
+ />
242
+ )
243
+ }
244
+
245
+ // Usage
246
+ <Button variant="destructive" size="lg">Delete</Button>
247
+ <Button variant="outline">Cancel</Button>
248
+ <Button asChild><Link href="/home">Home</Link></Button>
249
+ ```
250
+
251
+ ### Pattern 2: Compound Components (React 19)
252
+
253
+ ```typescript
254
+ // components/ui/card.tsx
255
+ import { cn } from '@/lib/utils'
256
+
257
+ // React 19: ref is a regular prop, no forwardRef
258
+ export function Card({
259
+ className,
260
+ ref,
261
+ ...props
262
+ }: React.HTMLAttributes<HTMLDivElement> & { ref?: React.Ref<HTMLDivElement> }) {
263
+ return (
264
+ <div
265
+ ref={ref}
266
+ className={cn(
267
+ 'rounded-lg border border-border bg-card text-card-foreground shadow-sm',
268
+ className
269
+ )}
270
+ {...props}
271
+ />
272
+ )
273
+ }
274
+
275
+ export function CardHeader({
276
+ className,
277
+ ref,
278
+ ...props
279
+ }: React.HTMLAttributes<HTMLDivElement> & { ref?: React.Ref<HTMLDivElement> }) {
280
+ return (
281
+ <div
282
+ ref={ref}
283
+ className={cn('flex flex-col space-y-1.5 p-6', className)}
284
+ {...props}
285
+ />
286
+ )
287
+ }
288
+
289
+ export function CardTitle({
290
+ className,
291
+ ref,
292
+ ...props
293
+ }: React.HTMLAttributes<HTMLHeadingElement> & { ref?: React.Ref<HTMLHeadingElement> }) {
294
+ return (
295
+ <h3
296
+ ref={ref}
297
+ className={cn('text-2xl font-semibold leading-none tracking-tight', className)}
298
+ {...props}
299
+ />
300
+ )
301
+ }
302
+
303
+ export function CardDescription({
304
+ className,
305
+ ref,
306
+ ...props
307
+ }: React.HTMLAttributes<HTMLParagraphElement> & { ref?: React.Ref<HTMLParagraphElement> }) {
308
+ return (
309
+ <p
310
+ ref={ref}
311
+ className={cn('text-sm text-muted-foreground', className)}
312
+ {...props}
313
+ />
314
+ )
315
+ }
316
+
317
+ export function CardContent({
318
+ className,
319
+ ref,
320
+ ...props
321
+ }: React.HTMLAttributes<HTMLDivElement> & { ref?: React.Ref<HTMLDivElement> }) {
322
+ return (
323
+ <div ref={ref} className={cn('p-6 pt-0', className)} {...props} />
324
+ )
325
+ }
326
+
327
+ export function CardFooter({
328
+ className,
329
+ ref,
330
+ ...props
331
+ }: React.HTMLAttributes<HTMLDivElement> & { ref?: React.Ref<HTMLDivElement> }) {
332
+ return (
333
+ <div
334
+ ref={ref}
335
+ className={cn('flex items-center p-6 pt-0', className)}
336
+ {...props}
337
+ />
338
+ )
339
+ }
340
+
341
+ // Usage
342
+ <Card>
343
+ <CardHeader>
344
+ <CardTitle>Account</CardTitle>
345
+ <CardDescription>Manage your account settings</CardDescription>
346
+ </CardHeader>
347
+ <CardContent>
348
+ <form>...</form>
349
+ </CardContent>
350
+ <CardFooter>
351
+ <Button>Save</Button>
352
+ </CardFooter>
353
+ </Card>
354
+ ```
355
+
356
+ ### Pattern 3: Form Components
357
+
358
+ ```typescript
359
+ // components/ui/input.tsx
360
+ import { cn } from '@/lib/utils'
361
+
362
+ export interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
363
+ error?: string
364
+ ref?: React.Ref<HTMLInputElement>
365
+ }
366
+
367
+ export function Input({ className, type, error, ref, ...props }: InputProps) {
368
+ return (
369
+ <div className="relative">
370
+ <input
371
+ type={type}
372
+ className={cn(
373
+ 'flex h-10 w-full rounded-md border border-border bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',
374
+ error && 'border-destructive focus-visible:ring-destructive',
375
+ className
376
+ )}
377
+ ref={ref}
378
+ aria-invalid={!!error}
379
+ aria-describedby={error ? `${props.id}-error` : undefined}
380
+ {...props}
381
+ />
382
+ {error && (
383
+ <p
384
+ id={`${props.id}-error`}
385
+ className="mt-1 text-sm text-destructive"
386
+ role="alert"
387
+ >
388
+ {error}
389
+ </p>
390
+ )}
391
+ </div>
392
+ )
393
+ }
394
+
395
+ // components/ui/label.tsx
396
+ import { cva, type VariantProps } from 'class-variance-authority'
397
+
398
+ const labelVariants = cva(
399
+ 'text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70'
400
+ )
401
+
402
+ export function Label({
403
+ className,
404
+ ref,
405
+ ...props
406
+ }: React.LabelHTMLAttributes<HTMLLabelElement> & { ref?: React.Ref<HTMLLabelElement> }) {
407
+ return (
408
+ <label ref={ref} className={cn(labelVariants(), className)} {...props} />
409
+ )
410
+ }
411
+
412
+ // Usage with React Hook Form + Zod
413
+ import { useForm } from 'react-hook-form'
414
+ import { zodResolver } from '@hookform/resolvers/zod'
415
+ import { z } from 'zod'
416
+
417
+ const schema = z.object({
418
+ email: z.string().email('Invalid email address'),
419
+ password: z.string().min(8, 'Password must be at least 8 characters'),
420
+ })
421
+
422
+ function LoginForm() {
423
+ const { register, handleSubmit, formState: { errors } } = useForm({
424
+ resolver: zodResolver(schema),
425
+ })
426
+
427
+ return (
428
+ <form onSubmit={handleSubmit(onSubmit)} className="space-y-4">
429
+ <div className="space-y-2">
430
+ <Label htmlFor="email">Email</Label>
431
+ <Input
432
+ id="email"
433
+ type="email"
434
+ {...register('email')}
435
+ error={errors.email?.message}
436
+ />
437
+ </div>
438
+ <div className="space-y-2">
439
+ <Label htmlFor="password">Password</Label>
440
+ <Input
441
+ id="password"
442
+ type="password"
443
+ {...register('password')}
444
+ error={errors.password?.message}
445
+ />
446
+ </div>
447
+ <Button type="submit" className="w-full">Sign In</Button>
448
+ </form>
449
+ )
450
+ }
451
+ ```
452
+
453
+ ### Pattern 4: Responsive Grid System
454
+
455
+ ```typescript
456
+ // components/ui/grid.tsx
457
+ import { cn } from '@/lib/utils'
458
+ import { cva, type VariantProps } from 'class-variance-authority'
459
+
460
+ const gridVariants = cva('grid', {
461
+ variants: {
462
+ cols: {
463
+ 1: 'grid-cols-1',
464
+ 2: 'grid-cols-1 sm:grid-cols-2',
465
+ 3: 'grid-cols-1 sm:grid-cols-2 lg:grid-cols-3',
466
+ 4: 'grid-cols-1 sm:grid-cols-2 lg:grid-cols-4',
467
+ 5: 'grid-cols-2 sm:grid-cols-3 lg:grid-cols-5',
468
+ 6: 'grid-cols-2 sm:grid-cols-3 lg:grid-cols-6',
469
+ },
470
+ gap: {
471
+ none: 'gap-0',
472
+ sm: 'gap-2',
473
+ md: 'gap-4',
474
+ lg: 'gap-6',
475
+ xl: 'gap-8',
476
+ },
477
+ },
478
+ defaultVariants: {
479
+ cols: 3,
480
+ gap: 'md',
481
+ },
482
+ })
483
+
484
+ interface GridProps
485
+ extends React.HTMLAttributes<HTMLDivElement>,
486
+ VariantProps<typeof gridVariants> {}
487
+
488
+ export function Grid({ className, cols, gap, ...props }: GridProps) {
489
+ return (
490
+ <div className={cn(gridVariants({ cols, gap, className }))} {...props} />
491
+ )
492
+ }
493
+
494
+ // Container component
495
+ const containerVariants = cva('mx-auto w-full px-4 sm:px-6 lg:px-8', {
496
+ variants: {
497
+ size: {
498
+ sm: 'max-w-screen-sm',
499
+ md: 'max-w-screen-md',
500
+ lg: 'max-w-screen-lg',
501
+ xl: 'max-w-screen-xl',
502
+ '2xl': 'max-w-screen-2xl',
503
+ full: 'max-w-full',
504
+ },
505
+ },
506
+ defaultVariants: {
507
+ size: 'xl',
508
+ },
509
+ })
510
+
511
+ interface ContainerProps
512
+ extends React.HTMLAttributes<HTMLDivElement>,
513
+ VariantProps<typeof containerVariants> {}
514
+
515
+ export function Container({ className, size, ...props }: ContainerProps) {
516
+ return (
517
+ <div className={cn(containerVariants({ size, className }))} {...props} />
518
+ )
519
+ }
520
+
521
+ // Usage
522
+ <Container>
523
+ <Grid cols={4} gap="lg">
524
+ {products.map((product) => (
525
+ <ProductCard key={product.id} product={product} />
526
+ ))}
527
+ </Grid>
528
+ </Container>
529
+ ```
530
+
531
+ ### Pattern 5: Native CSS Animations (v4)
532
+
533
+ ```css
534
+ /* In your CSS file - native @starting-style for entry animations */
535
+ @theme {
536
+ --animate-dialog-in: dialog-fade-in 0.2s ease-out;
537
+ --animate-dialog-out: dialog-fade-out 0.15s ease-in;
538
+ }
539
+
540
+ @keyframes dialog-fade-in {
541
+ from {
542
+ opacity: 0;
543
+ transform: scale(0.95) translateY(-0.5rem);
544
+ }
545
+ to {
546
+ opacity: 1;
547
+ transform: scale(1) translateY(0);
548
+ }
549
+ }
550
+
551
+ @keyframes dialog-fade-out {
552
+ from {
553
+ opacity: 1;
554
+ transform: scale(1) translateY(0);
555
+ }
556
+ to {
557
+ opacity: 0;
558
+ transform: scale(0.95) translateY(-0.5rem);
559
+ }
560
+ }
561
+
562
+ /* Native popover animations using @starting-style */
563
+ [popover] {
564
+ transition:
565
+ opacity 0.2s,
566
+ transform 0.2s,
567
+ display 0.2s allow-discrete;
568
+ opacity: 0;
569
+ transform: scale(0.95);
570
+ }
571
+
572
+ [popover]:popover-open {
573
+ opacity: 1;
574
+ transform: scale(1);
575
+ }
576
+
577
+ @starting-style {
578
+ [popover]:popover-open {
579
+ opacity: 0;
580
+ transform: scale(0.95);
581
+ }
582
+ }
583
+ ```
584
+
585
+ ```typescript
586
+ // components/ui/dialog.tsx - Using native popover API
587
+ import * as DialogPrimitive from '@radix-ui/react-dialog'
588
+ import { cn } from '@/lib/utils'
589
+
590
+ const DialogPortal = DialogPrimitive.Portal
591
+
592
+ export function DialogOverlay({
593
+ className,
594
+ ref,
595
+ ...props
596
+ }: React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay> & {
597
+ ref?: React.Ref<HTMLDivElement>
598
+ }) {
599
+ return (
600
+ <DialogPrimitive.Overlay
601
+ ref={ref}
602
+ className={cn(
603
+ 'fixed inset-0 z-50 bg-black/80',
604
+ 'data-[state=open]:animate-fade-in data-[state=closed]:animate-fade-out',
605
+ className
606
+ )}
607
+ {...props}
608
+ />
609
+ )
610
+ }
611
+
612
+ export function DialogContent({
613
+ className,
614
+ children,
615
+ ref,
616
+ ...props
617
+ }: React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content> & {
618
+ ref?: React.Ref<HTMLDivElement>
619
+ }) {
620
+ return (
621
+ <DialogPortal>
622
+ <DialogOverlay />
623
+ <DialogPrimitive.Content
624
+ ref={ref}
625
+ className={cn(
626
+ 'fixed left-1/2 top-1/2 z-50 grid w-full max-w-lg -translate-x-1/2 -translate-y-1/2 gap-4 border border-border bg-background p-6 shadow-lg sm:rounded-lg',
627
+ 'data-[state=open]:animate-dialog-in data-[state=closed]:animate-dialog-out',
628
+ className
629
+ )}
630
+ {...props}
631
+ >
632
+ {children}
633
+ </DialogPrimitive.Content>
634
+ </DialogPortal>
635
+ )
636
+ }
637
+ ```
638
+
639
+ ### Pattern 6: Dark Mode with CSS (v4)
640
+
641
+ ```typescript
642
+ // providers/ThemeProvider.tsx - Simplified for v4
643
+ 'use client'
644
+
645
+ import { createContext, useContext, useEffect, useState } from 'react'
646
+
647
+ type Theme = 'dark' | 'light' | 'system'
648
+
649
+ interface ThemeContextType {
650
+ theme: Theme
651
+ setTheme: (theme: Theme) => void
652
+ resolvedTheme: 'dark' | 'light'
653
+ }
654
+
655
+ const ThemeContext = createContext<ThemeContextType | undefined>(undefined)
656
+
657
+ export function ThemeProvider({
658
+ children,
659
+ defaultTheme = 'system',
660
+ storageKey = 'theme',
661
+ }: {
662
+ children: React.ReactNode
663
+ defaultTheme?: Theme
664
+ storageKey?: string
665
+ }) {
666
+ const [theme, setTheme] = useState<Theme>(defaultTheme)
667
+ const [resolvedTheme, setResolvedTheme] = useState<'dark' | 'light'>('light')
668
+
669
+ useEffect(() => {
670
+ const stored = localStorage.getItem(storageKey) as Theme | null
671
+ if (stored) setTheme(stored)
672
+ }, [storageKey])
673
+
674
+ useEffect(() => {
675
+ const root = document.documentElement
676
+ root.classList.remove('light', 'dark')
677
+
678
+ const resolved = theme === 'system'
679
+ ? (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light')
680
+ : theme
681
+
682
+ root.classList.add(resolved)
683
+ setResolvedTheme(resolved)
684
+
685
+ // Update meta theme-color for mobile browsers
686
+ const metaThemeColor = document.querySelector('meta[name="theme-color"]')
687
+ if (metaThemeColor) {
688
+ metaThemeColor.setAttribute('content', resolved === 'dark' ? '#09090b' : '#ffffff')
689
+ }
690
+ }, [theme])
691
+
692
+ return (
693
+ <ThemeContext.Provider value={{
694
+ theme,
695
+ setTheme: (newTheme) => {
696
+ localStorage.setItem(storageKey, newTheme)
697
+ setTheme(newTheme)
698
+ },
699
+ resolvedTheme,
700
+ }}>
701
+ {children}
702
+ </ThemeContext.Provider>
703
+ )
704
+ }
705
+
706
+ export const useTheme = () => {
707
+ const context = useContext(ThemeContext)
708
+ if (!context) throw new Error('useTheme must be used within ThemeProvider')
709
+ return context
710
+ }
711
+
712
+ // components/ThemeToggle.tsx
713
+ import { Moon, Sun } from 'lucide-react'
714
+ import { useTheme } from '@/providers/ThemeProvider'
715
+
716
+ export function ThemeToggle() {
717
+ const { resolvedTheme, setTheme } = useTheme()
718
+
719
+ return (
720
+ <Button
721
+ variant="ghost"
722
+ size="icon"
723
+ onClick={() => setTheme(resolvedTheme === 'dark' ? 'light' : 'dark')}
724
+ >
725
+ <Sun className="size-5 rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
726
+ <Moon className="absolute size-5 rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
727
+ <span className="sr-only">Toggle theme</span>
728
+ </Button>
729
+ )
730
+ }
731
+ ```
732
+
733
+ ## Utility Functions
734
+
735
+ ```typescript
736
+ // lib/utils.ts
737
+ import { type ClassValue, clsx } from "clsx";
738
+ import { twMerge } from "tailwind-merge";
739
+
740
+ export function cn(...inputs: ClassValue[]) {
741
+ return twMerge(clsx(inputs));
742
+ }
743
+
744
+ // Focus ring utility
745
+ export const focusRing = cn(
746
+ "focus-visible:outline-none focus-visible:ring-2",
747
+ "focus-visible:ring-ring focus-visible:ring-offset-2",
748
+ );
749
+
750
+ // Disabled utility
751
+ export const disabled = "disabled:pointer-events-none disabled:opacity-50";
752
+ ```
753
+
754
+ ## Advanced v4 Patterns
755
+
756
+ ### Custom Utilities with `@utility`
757
+
758
+ Define reusable custom utilities:
759
+
760
+ ```css
761
+ /* Custom utility for decorative lines */
762
+ @utility line-t {
763
+ @apply relative before:absolute before:top-0 before:-left-[100vw] before:h-px before:w-[200vw] before:bg-gray-950/5 dark:before:bg-white/10;
764
+ }
765
+
766
+ /* Custom utility for text gradients */
767
+ @utility text-gradient {
768
+ @apply bg-gradient-to-r from-primary to-accent bg-clip-text text-transparent;
769
+ }
770
+ ```
771
+
772
+ ### Theme Modifiers
773
+
774
+ ```css
775
+ /* Use @theme inline when referencing other CSS variables */
776
+ @theme inline {
777
+ --font-sans: var(--font-inter), system-ui;
778
+ }
779
+
780
+ /* Use @theme static to always generate CSS variables (even when unused) */
781
+ @theme static {
782
+ --color-brand: oklch(65% 0.15 240);
783
+ }
784
+
785
+ /* Import with theme options */
786
+ @import "tailwindcss" theme(static);
787
+ ```
788
+
789
+ ### Namespace Overrides
790
+
791
+ ```css
792
+ @theme {
793
+ /* Clear all default colors and define your own */
794
+ --color-*: initial;
795
+ --color-white: #fff;
796
+ --color-black: #000;
797
+ --color-primary: oklch(45% 0.2 260);
798
+ --color-secondary: oklch(65% 0.15 200);
799
+
800
+ /* Clear ALL defaults for a minimal setup */
801
+ /* --*: initial; */
802
+ }
803
+ ```
804
+
805
+ ### Semi-transparent Color Variants
806
+
807
+ ```css
808
+ @theme {
809
+ /* Use color-mix() for alpha variants */
810
+ --color-primary-50: color-mix(in oklab, var(--color-primary) 5%, transparent);
811
+ --color-primary-100: color-mix(
812
+ in oklab,
813
+ var(--color-primary) 10%,
814
+ transparent
815
+ );
816
+ --color-primary-200: color-mix(
817
+ in oklab,
818
+ var(--color-primary) 20%,
819
+ transparent
820
+ );
821
+ }
822
+ ```
823
+
824
+ ### Container Queries
825
+
826
+ ```css
827
+ @theme {
828
+ --container-xs: 20rem;
829
+ --container-sm: 24rem;
830
+ --container-md: 28rem;
831
+ --container-lg: 32rem;
832
+ }
833
+ ```
834
+
835
+ ## v3 to v4 Migration Checklist
836
+
837
+ - [ ] Replace `tailwind.config.ts` with CSS `@theme` block
838
+ - [ ] Change `@tailwind base/components/utilities` to `@import "tailwindcss"`
839
+ - [ ] Move color definitions to `@theme { --color-*: value }`
840
+ - [ ] Replace `darkMode: "class"` with `@custom-variant dark`
841
+ - [ ] Move `@keyframes` inside `@theme` blocks (ensures keyframes output with theme)
842
+ - [ ] Replace `require("tailwindcss-animate")` with native CSS animations
843
+ - [ ] Update `h-10 w-10` to `size-10` (new utility)
844
+ - [ ] Remove `forwardRef` (React 19 passes ref as prop)
845
+ - [ ] Consider OKLCH colors for better color perception
846
+ - [ ] Replace custom plugins with `@utility` directives
847
+
848
+ ## Best Practices
849
+
850
+ ### Do's
851
+
852
+ - **Use `@theme` blocks** - CSS-first configuration is v4's core pattern
853
+ - **Use OKLCH colors** - Better perceptual uniformity than HSL
854
+ - **Compose with CVA** - Type-safe variants
855
+ - **Use semantic tokens** - `bg-primary` not `bg-blue-500`
856
+ - **Use `size-*`** - New shorthand for `w-* h-*`
857
+ - **Add accessibility** - ARIA attributes, focus states
858
+
859
+ ### Don'ts
860
+
861
+ - **Don't use `tailwind.config.ts`** - Use CSS `@theme` instead
862
+ - **Don't use `@tailwind` directives** - Use `@import "tailwindcss"`
863
+ - **Don't use `forwardRef`** - React 19 passes ref as prop
864
+ - **Don't use arbitrary values** - Extend `@theme` instead
865
+ - **Don't hardcode colors** - Use semantic tokens
866
+ - **Don't forget dark mode** - Test both themes
867
+
868
+ ## Resources
869
+
870
+ - [Tailwind CSS v4 Documentation](https://tailwindcss.com/docs)
871
+ - [Tailwind v4 Beta Announcement](https://tailwindcss.com/blog/tailwindcss-v4-beta)
872
+ - [CVA Documentation](https://cva.style/docs)
873
+ - [shadcn/ui](https://ui.shadcn.com/)
874
+ - [Radix Primitives](https://www.radix-ui.com/primitives)