omgkit 2.1.0 → 2.2.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 (56) hide show
  1. package/package.json +1 -1
  2. package/plugin/skills/SKILL_STANDARDS.md +743 -0
  3. package/plugin/skills/databases/mongodb/SKILL.md +797 -28
  4. package/plugin/skills/databases/postgresql/SKILL.md +494 -18
  5. package/plugin/skills/databases/prisma/SKILL.md +776 -30
  6. package/plugin/skills/databases/redis/SKILL.md +885 -25
  7. package/plugin/skills/devops/aws/SKILL.md +686 -28
  8. package/plugin/skills/devops/docker/SKILL.md +466 -18
  9. package/plugin/skills/devops/github-actions/SKILL.md +684 -29
  10. package/plugin/skills/devops/kubernetes/SKILL.md +621 -24
  11. package/plugin/skills/frameworks/django/SKILL.md +920 -20
  12. package/plugin/skills/frameworks/express/SKILL.md +1361 -35
  13. package/plugin/skills/frameworks/fastapi/SKILL.md +1260 -33
  14. package/plugin/skills/frameworks/laravel/SKILL.md +1244 -31
  15. package/plugin/skills/frameworks/nestjs/SKILL.md +1005 -26
  16. package/plugin/skills/frameworks/nextjs/SKILL.md +407 -44
  17. package/plugin/skills/frameworks/rails/SKILL.md +594 -28
  18. package/plugin/skills/frameworks/react/SKILL.md +1006 -32
  19. package/plugin/skills/frameworks/spring/SKILL.md +528 -35
  20. package/plugin/skills/frameworks/vue/SKILL.md +1296 -27
  21. package/plugin/skills/frontend/accessibility/SKILL.md +1108 -34
  22. package/plugin/skills/frontend/frontend-design/SKILL.md +1304 -26
  23. package/plugin/skills/frontend/responsive/SKILL.md +847 -21
  24. package/plugin/skills/frontend/shadcn-ui/SKILL.md +976 -38
  25. package/plugin/skills/frontend/tailwindcss/SKILL.md +831 -35
  26. package/plugin/skills/frontend/threejs/SKILL.md +1298 -29
  27. package/plugin/skills/languages/javascript/SKILL.md +935 -31
  28. package/plugin/skills/languages/python/SKILL.md +489 -25
  29. package/plugin/skills/languages/typescript/SKILL.md +379 -30
  30. package/plugin/skills/methodology/brainstorming/SKILL.md +597 -23
  31. package/plugin/skills/methodology/defense-in-depth/SKILL.md +832 -34
  32. package/plugin/skills/methodology/dispatching-parallel-agents/SKILL.md +665 -31
  33. package/plugin/skills/methodology/executing-plans/SKILL.md +556 -24
  34. package/plugin/skills/methodology/finishing-development-branch/SKILL.md +595 -25
  35. package/plugin/skills/methodology/problem-solving/SKILL.md +429 -61
  36. package/plugin/skills/methodology/receiving-code-review/SKILL.md +536 -24
  37. package/plugin/skills/methodology/requesting-code-review/SKILL.md +632 -21
  38. package/plugin/skills/methodology/root-cause-tracing/SKILL.md +641 -30
  39. package/plugin/skills/methodology/sequential-thinking/SKILL.md +262 -3
  40. package/plugin/skills/methodology/systematic-debugging/SKILL.md +571 -32
  41. package/plugin/skills/methodology/test-driven-development/SKILL.md +779 -24
  42. package/plugin/skills/methodology/testing-anti-patterns/SKILL.md +691 -29
  43. package/plugin/skills/methodology/token-optimization/SKILL.md +598 -29
  44. package/plugin/skills/methodology/verification-before-completion/SKILL.md +543 -22
  45. package/plugin/skills/methodology/writing-plans/SKILL.md +590 -18
  46. package/plugin/skills/omega/omega-architecture/SKILL.md +838 -39
  47. package/plugin/skills/omega/omega-coding/SKILL.md +636 -39
  48. package/plugin/skills/omega/omega-sprint/SKILL.md +855 -48
  49. package/plugin/skills/omega/omega-testing/SKILL.md +940 -41
  50. package/plugin/skills/omega/omega-thinking/SKILL.md +703 -50
  51. package/plugin/skills/security/better-auth/SKILL.md +1065 -28
  52. package/plugin/skills/security/oauth/SKILL.md +968 -31
  53. package/plugin/skills/security/owasp/SKILL.md +894 -33
  54. package/plugin/skills/testing/playwright/SKILL.md +764 -38
  55. package/plugin/skills/testing/pytest/SKILL.md +873 -36
  56. package/plugin/skills/testing/vitest/SKILL.md +980 -35
@@ -1,52 +1,848 @@
1
1
  ---
2
2
  name: tailwindcss
3
- description: Tailwind CSS styling. Use when styling with utility classes.
3
+ description: Tailwind CSS utility-first styling with responsive design, dark mode, animations, and component patterns
4
+ category: frontend
5
+ triggers:
6
+ - tailwind
7
+ - tailwindcss
8
+ - utility classes
9
+ - css framework
10
+ - styling
4
11
  ---
5
12
 
6
- # Tailwind CSS Skill
13
+ # Tailwind CSS
7
14
 
8
- ## Core Utilities
9
- ```html
10
- <!-- Spacing -->
11
- <div class="p-4 m-2 space-y-4">
15
+ Enterprise-grade **utility-first CSS framework** following industry best practices. This skill covers responsive design, dark mode, custom configurations, animations, component patterns, and optimization strategies used by top engineering teams.
12
16
 
13
- <!-- Flexbox -->
14
- <div class="flex items-center justify-between gap-4">
17
+ ## Purpose
15
18
 
16
- <!-- Grid -->
17
- <div class="grid grid-cols-3 gap-4">
19
+ Build beautiful, responsive UIs efficiently:
18
20
 
19
- <!-- Typography -->
20
- <p class="text-lg font-bold text-gray-900">
21
+ - Write utility-first CSS
22
+ - Implement responsive designs
23
+ - Configure dark mode theming
24
+ - Create reusable component patterns
25
+ - Customize design tokens
26
+ - Optimize for production
27
+ - Build accessible interfaces
28
+
29
+ ## Features
30
+
31
+ ### 1. Configuration Setup
32
+
33
+ ```javascript
34
+ // tailwind.config.js
35
+ /** @type {import('tailwindcss').Config} */
36
+ module.exports = {
37
+ content: [
38
+ "./src/**/*.{js,ts,jsx,tsx,mdx}",
39
+ "./components/**/*.{js,ts,jsx,tsx}",
40
+ "./app/**/*.{js,ts,jsx,tsx}",
41
+ ],
42
+ darkMode: "class", // or 'media'
43
+ theme: {
44
+ extend: {
45
+ // Custom colors
46
+ colors: {
47
+ primary: {
48
+ 50: "#eff6ff",
49
+ 100: "#dbeafe",
50
+ 200: "#bfdbfe",
51
+ 300: "#93c5fd",
52
+ 400: "#60a5fa",
53
+ 500: "#3b82f6",
54
+ 600: "#2563eb",
55
+ 700: "#1d4ed8",
56
+ 800: "#1e40af",
57
+ 900: "#1e3a8a",
58
+ 950: "#172554",
59
+ },
60
+ secondary: {
61
+ 50: "#f8fafc",
62
+ // ... other shades
63
+ },
64
+ },
65
+ // Custom spacing
66
+ spacing: {
67
+ "18": "4.5rem",
68
+ "88": "22rem",
69
+ "128": "32rem",
70
+ },
71
+ // Custom fonts
72
+ fontFamily: {
73
+ sans: ["Inter", "system-ui", "sans-serif"],
74
+ mono: ["JetBrains Mono", "monospace"],
75
+ },
76
+ // Custom font sizes
77
+ fontSize: {
78
+ "2xs": ["0.625rem", { lineHeight: "0.75rem" }],
79
+ },
80
+ // Custom border radius
81
+ borderRadius: {
82
+ "4xl": "2rem",
83
+ },
84
+ // Custom animations
85
+ animation: {
86
+ "fade-in": "fadeIn 0.3s ease-in-out",
87
+ "slide-up": "slideUp 0.3s ease-out",
88
+ "spin-slow": "spin 3s linear infinite",
89
+ "pulse-slow": "pulse 3s cubic-bezier(0.4, 0, 0.6, 1) infinite",
90
+ },
91
+ keyframes: {
92
+ fadeIn: {
93
+ "0%": { opacity: "0" },
94
+ "100%": { opacity: "1" },
95
+ },
96
+ slideUp: {
97
+ "0%": { transform: "translateY(10px)", opacity: "0" },
98
+ "100%": { transform: "translateY(0)", opacity: "1" },
99
+ },
100
+ },
101
+ // Custom box shadows
102
+ boxShadow: {
103
+ "soft": "0 2px 15px -3px rgba(0, 0, 0, 0.07), 0 10px 20px -2px rgba(0, 0, 0, 0.04)",
104
+ "inner-soft": "inset 0 2px 4px 0 rgba(0, 0, 0, 0.05)",
105
+ },
106
+ // Custom breakpoints
107
+ screens: {
108
+ "xs": "475px",
109
+ "3xl": "1920px",
110
+ },
111
+ },
112
+ },
113
+ plugins: [
114
+ require("@tailwindcss/forms"),
115
+ require("@tailwindcss/typography"),
116
+ require("@tailwindcss/aspect-ratio"),
117
+ require("@tailwindcss/container-queries"),
118
+ ],
119
+ };
21
120
  ```
22
121
 
23
- ## Responsive
24
- ```html
25
- <div class="text-sm md:text-base lg:text-lg">
26
- <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3">
122
+ ```css
123
+ /* globals.css */
124
+ @tailwind base;
125
+ @tailwind components;
126
+ @tailwind utilities;
127
+
128
+ @layer base {
129
+ :root {
130
+ --background: 0 0% 100%;
131
+ --foreground: 222.2 84% 4.9%;
132
+ --primary: 221.2 83.2% 53.3%;
133
+ --primary-foreground: 210 40% 98%;
134
+ --secondary: 210 40% 96.1%;
135
+ --secondary-foreground: 222.2 47.4% 11.2%;
136
+ --muted: 210 40% 96.1%;
137
+ --muted-foreground: 215.4 16.3% 46.9%;
138
+ --accent: 210 40% 96.1%;
139
+ --accent-foreground: 222.2 47.4% 11.2%;
140
+ --destructive: 0 84.2% 60.2%;
141
+ --destructive-foreground: 210 40% 98%;
142
+ --border: 214.3 31.8% 91.4%;
143
+ --input: 214.3 31.8% 91.4%;
144
+ --ring: 221.2 83.2% 53.3%;
145
+ --radius: 0.5rem;
146
+ }
147
+
148
+ .dark {
149
+ --background: 222.2 84% 4.9%;
150
+ --foreground: 210 40% 98%;
151
+ --primary: 217.2 91.2% 59.8%;
152
+ --primary-foreground: 222.2 47.4% 11.2%;
153
+ --secondary: 217.2 32.6% 17.5%;
154
+ --secondary-foreground: 210 40% 98%;
155
+ --muted: 217.2 32.6% 17.5%;
156
+ --muted-foreground: 215 20.2% 65.1%;
157
+ --accent: 217.2 32.6% 17.5%;
158
+ --accent-foreground: 210 40% 98%;
159
+ --destructive: 0 62.8% 30.6%;
160
+ --destructive-foreground: 210 40% 98%;
161
+ --border: 217.2 32.6% 17.5%;
162
+ --input: 217.2 32.6% 17.5%;
163
+ --ring: 224.3 76.3% 48%;
164
+ }
165
+ }
166
+
167
+ @layer base {
168
+ * {
169
+ @apply border-border;
170
+ }
171
+ body {
172
+ @apply bg-background text-foreground;
173
+ }
174
+ }
27
175
  ```
28
176
 
29
- ## Component Pattern
30
- ```html
31
- <button class="
32
- px-4 py-2
33
- bg-blue-500 hover:bg-blue-600
34
- text-white font-medium
35
- rounded-lg
36
- transition-colors
37
- focus:outline-none focus:ring-2 focus:ring-blue-500
38
- ">
39
- Click me
40
- </button>
177
+ ### 2. Component Patterns
178
+
179
+ ```tsx
180
+ // Button component with variants
181
+ interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
182
+ variant?: "primary" | "secondary" | "outline" | "ghost" | "destructive";
183
+ size?: "sm" | "md" | "lg";
184
+ loading?: boolean;
185
+ }
186
+
187
+ export function Button({
188
+ variant = "primary",
189
+ size = "md",
190
+ loading,
191
+ className,
192
+ children,
193
+ disabled,
194
+ ...props
195
+ }: ButtonProps) {
196
+ const baseStyles = `
197
+ inline-flex items-center justify-center
198
+ font-medium rounded-lg
199
+ transition-colors duration-200
200
+ focus:outline-none focus:ring-2 focus:ring-offset-2
201
+ disabled:opacity-50 disabled:cursor-not-allowed
202
+ `;
203
+
204
+ const variants = {
205
+ primary: `
206
+ bg-primary-600 text-white
207
+ hover:bg-primary-700
208
+ focus:ring-primary-500
209
+ `,
210
+ secondary: `
211
+ bg-secondary-100 text-secondary-900
212
+ hover:bg-secondary-200
213
+ focus:ring-secondary-500
214
+ dark:bg-secondary-800 dark:text-secondary-100
215
+ `,
216
+ outline: `
217
+ border-2 border-primary-600 text-primary-600
218
+ hover:bg-primary-50
219
+ focus:ring-primary-500
220
+ dark:border-primary-400 dark:text-primary-400
221
+ `,
222
+ ghost: `
223
+ text-gray-700 hover:bg-gray-100
224
+ focus:ring-gray-500
225
+ dark:text-gray-300 dark:hover:bg-gray-800
226
+ `,
227
+ destructive: `
228
+ bg-red-600 text-white
229
+ hover:bg-red-700
230
+ focus:ring-red-500
231
+ `,
232
+ };
233
+
234
+ const sizes = {
235
+ sm: "px-3 py-1.5 text-sm gap-1.5",
236
+ md: "px-4 py-2 text-base gap-2",
237
+ lg: "px-6 py-3 text-lg gap-2.5",
238
+ };
239
+
240
+ return (
241
+ <button
242
+ className={`${baseStyles} ${variants[variant]} ${sizes[size]} ${className}`}
243
+ disabled={disabled || loading}
244
+ {...props}
245
+ >
246
+ {loading && (
247
+ <svg
248
+ className="animate-spin h-4 w-4"
249
+ xmlns="http://www.w3.org/2000/svg"
250
+ fill="none"
251
+ viewBox="0 0 24 24"
252
+ >
253
+ <circle
254
+ className="opacity-25"
255
+ cx="12"
256
+ cy="12"
257
+ r="10"
258
+ stroke="currentColor"
259
+ strokeWidth="4"
260
+ />
261
+ <path
262
+ className="opacity-75"
263
+ fill="currentColor"
264
+ d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"
265
+ />
266
+ </svg>
267
+ )}
268
+ {children}
269
+ </button>
270
+ );
271
+ }
272
+
273
+ // Card component
274
+ interface CardProps {
275
+ children: React.ReactNode;
276
+ className?: string;
277
+ hoverable?: boolean;
278
+ }
279
+
280
+ export function Card({ children, className, hoverable }: CardProps) {
281
+ return (
282
+ <div
283
+ className={`
284
+ bg-white dark:bg-gray-800
285
+ rounded-xl shadow-soft
286
+ border border-gray-200 dark:border-gray-700
287
+ ${hoverable ? "hover:shadow-lg hover:-translate-y-1 transition-all duration-200" : ""}
288
+ ${className}
289
+ `}
290
+ >
291
+ {children}
292
+ </div>
293
+ );
294
+ }
295
+
296
+ export function CardHeader({ children, className }: { children: React.ReactNode; className?: string }) {
297
+ return (
298
+ <div className={`px-6 py-4 border-b border-gray-200 dark:border-gray-700 ${className}`}>
299
+ {children}
300
+ </div>
301
+ );
302
+ }
303
+
304
+ export function CardContent({ children, className }: { children: React.ReactNode; className?: string }) {
305
+ return <div className={`px-6 py-4 ${className}`}>{children}</div>;
306
+ }
307
+
308
+ export function CardFooter({ children, className }: { children: React.ReactNode; className?: string }) {
309
+ return (
310
+ <div className={`px-6 py-4 border-t border-gray-200 dark:border-gray-700 ${className}`}>
311
+ {children}
312
+ </div>
313
+ );
314
+ }
315
+
316
+ // Input component
317
+ interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
318
+ label?: string;
319
+ error?: string;
320
+ hint?: string;
321
+ }
322
+
323
+ export function Input({ label, error, hint, className, id, ...props }: InputProps) {
324
+ const inputId = id || label?.toLowerCase().replace(/\s/g, "-");
325
+
326
+ return (
327
+ <div className="space-y-1">
328
+ {label && (
329
+ <label
330
+ htmlFor={inputId}
331
+ className="block text-sm font-medium text-gray-700 dark:text-gray-300"
332
+ >
333
+ {label}
334
+ {props.required && <span className="text-red-500 ml-1">*</span>}
335
+ </label>
336
+ )}
337
+ <input
338
+ id={inputId}
339
+ className={`
340
+ w-full px-4 py-2
341
+ border rounded-lg
342
+ bg-white dark:bg-gray-800
343
+ text-gray-900 dark:text-gray-100
344
+ placeholder-gray-400 dark:placeholder-gray-500
345
+ transition-colors duration-200
346
+ focus:outline-none focus:ring-2 focus:ring-primary-500 focus:border-transparent
347
+ disabled:bg-gray-100 disabled:cursor-not-allowed
348
+ ${error
349
+ ? "border-red-500 focus:ring-red-500"
350
+ : "border-gray-300 dark:border-gray-600"
351
+ }
352
+ ${className}
353
+ `}
354
+ {...props}
355
+ />
356
+ {hint && !error && (
357
+ <p className="text-sm text-gray-500 dark:text-gray-400">{hint}</p>
358
+ )}
359
+ {error && (
360
+ <p className="text-sm text-red-500 dark:text-red-400">{error}</p>
361
+ )}
362
+ </div>
363
+ );
364
+ }
41
365
  ```
42
366
 
43
- ## Dark Mode
44
- ```html
45
- <div class="bg-white dark:bg-gray-900 text-black dark:text-white">
367
+ ### 3. Responsive Design
368
+
369
+ ```tsx
370
+ // Responsive layout patterns
371
+ export function ResponsiveGrid({ children }: { children: React.ReactNode }) {
372
+ return (
373
+ <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4 md:gap-6">
374
+ {children}
375
+ </div>
376
+ );
377
+ }
378
+
379
+ // Responsive navigation
380
+ export function Navigation() {
381
+ return (
382
+ <nav className="bg-white dark:bg-gray-900 shadow-sm">
383
+ <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
384
+ <div className="flex justify-between h-16">
385
+ {/* Logo */}
386
+ <div className="flex-shrink-0 flex items-center">
387
+ <Logo className="h-8 w-auto" />
388
+ </div>
389
+
390
+ {/* Desktop navigation */}
391
+ <div className="hidden md:flex md:items-center md:space-x-8">
392
+ <NavLink href="/">Home</NavLink>
393
+ <NavLink href="/products">Products</NavLink>
394
+ <NavLink href="/about">About</NavLink>
395
+ <NavLink href="/contact">Contact</NavLink>
396
+ </div>
397
+
398
+ {/* Mobile menu button */}
399
+ <div className="flex items-center md:hidden">
400
+ <button
401
+ className="
402
+ inline-flex items-center justify-center
403
+ p-2 rounded-md
404
+ text-gray-400 hover:text-gray-500 hover:bg-gray-100
405
+ focus:outline-none focus:ring-2 focus:ring-inset focus:ring-primary-500
406
+ "
407
+ >
408
+ <span className="sr-only">Open main menu</span>
409
+ <MenuIcon className="h-6 w-6" />
410
+ </button>
411
+ </div>
412
+ </div>
413
+ </div>
414
+
415
+ {/* Mobile menu */}
416
+ <div className="md:hidden">
417
+ <div className="px-2 pt-2 pb-3 space-y-1">
418
+ <MobileNavLink href="/">Home</MobileNavLink>
419
+ <MobileNavLink href="/products">Products</MobileNavLink>
420
+ <MobileNavLink href="/about">About</MobileNavLink>
421
+ <MobileNavLink href="/contact">Contact</MobileNavLink>
422
+ </div>
423
+ </div>
424
+ </nav>
425
+ );
426
+ }
427
+
428
+ // Responsive hero section
429
+ export function Hero() {
430
+ return (
431
+ <section className="relative bg-gray-900 overflow-hidden">
432
+ {/* Background pattern */}
433
+ <div className="absolute inset-0 bg-gradient-to-br from-primary-600 to-primary-900 opacity-90" />
434
+
435
+ <div className="relative max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-24 sm:py-32 lg:py-40">
436
+ <div className="text-center lg:text-left lg:max-w-2xl">
437
+ {/* Responsive typography */}
438
+ <h1 className="text-3xl sm:text-4xl md:text-5xl lg:text-6xl font-bold text-white tracking-tight">
439
+ Build amazing products
440
+ <span className="block text-primary-300 mt-2">with confidence</span>
441
+ </h1>
442
+
443
+ <p className="mt-6 text-lg sm:text-xl text-gray-300 max-w-xl mx-auto lg:mx-0">
444
+ Start building your next project with our comprehensive component
445
+ library and design system.
446
+ </p>
447
+
448
+ {/* Responsive button layout */}
449
+ <div className="mt-10 flex flex-col sm:flex-row gap-4 justify-center lg:justify-start">
450
+ <Button size="lg" className="w-full sm:w-auto">
451
+ Get Started
452
+ </Button>
453
+ <Button variant="outline" size="lg" className="w-full sm:w-auto">
454
+ Learn More
455
+ </Button>
456
+ </div>
457
+ </div>
458
+ </div>
459
+ </section>
460
+ );
461
+ }
462
+ ```
463
+
464
+ ### 4. Dark Mode
465
+
466
+ ```tsx
467
+ // Dark mode toggle
468
+ import { useEffect, useState } from "react";
469
+
470
+ export function DarkModeToggle() {
471
+ const [isDark, setIsDark] = useState(false);
472
+
473
+ useEffect(() => {
474
+ // Check initial preference
475
+ const isDarkMode =
476
+ localStorage.getItem("theme") === "dark" ||
477
+ (!localStorage.getItem("theme") &&
478
+ window.matchMedia("(prefers-color-scheme: dark)").matches);
479
+ setIsDark(isDarkMode);
480
+ document.documentElement.classList.toggle("dark", isDarkMode);
481
+ }, []);
482
+
483
+ const toggleDarkMode = () => {
484
+ const newIsDark = !isDark;
485
+ setIsDark(newIsDark);
486
+ document.documentElement.classList.toggle("dark", newIsDark);
487
+ localStorage.setItem("theme", newIsDark ? "dark" : "light");
488
+ };
489
+
490
+ return (
491
+ <button
492
+ onClick={toggleDarkMode}
493
+ className="
494
+ p-2 rounded-lg
495
+ text-gray-500 hover:text-gray-700
496
+ dark:text-gray-400 dark:hover:text-gray-200
497
+ hover:bg-gray-100 dark:hover:bg-gray-800
498
+ transition-colors duration-200
499
+ "
500
+ aria-label={isDark ? "Switch to light mode" : "Switch to dark mode"}
501
+ >
502
+ {isDark ? (
503
+ <SunIcon className="h-5 w-5" />
504
+ ) : (
505
+ <MoonIcon className="h-5 w-5" />
506
+ )}
507
+ </button>
508
+ );
509
+ }
510
+
511
+ // Dark mode aware components
512
+ export function DarkModeCard({ title, description }: { title: string; description: string }) {
513
+ return (
514
+ <div
515
+ className="
516
+ p-6 rounded-xl
517
+ bg-white dark:bg-gray-800
518
+ border border-gray-200 dark:border-gray-700
519
+ shadow-sm hover:shadow-md
520
+ transition-shadow duration-200
521
+ "
522
+ >
523
+ <h3 className="text-lg font-semibold text-gray-900 dark:text-white">
524
+ {title}
525
+ </h3>
526
+ <p className="mt-2 text-gray-600 dark:text-gray-300">
527
+ {description}
528
+ </p>
529
+ </div>
530
+ );
531
+ }
532
+ ```
533
+
534
+ ### 5. Animation Patterns
535
+
536
+ ```tsx
537
+ // Animated components
538
+ export function AnimatedCard({ children, delay = 0 }: { children: React.ReactNode; delay?: number }) {
539
+ return (
540
+ <div
541
+ className="animate-slide-up opacity-0"
542
+ style={{
543
+ animationDelay: `${delay}ms`,
544
+ animationFillMode: "forwards",
545
+ }}
546
+ >
547
+ {children}
548
+ </div>
549
+ );
550
+ }
551
+
552
+ // Hover animations
553
+ export function HoverCard({ children }: { children: React.ReactNode }) {
554
+ return (
555
+ <div
556
+ className="
557
+ group
558
+ relative
559
+ bg-white dark:bg-gray-800
560
+ rounded-xl shadow-sm
561
+ transition-all duration-300
562
+ hover:shadow-xl hover:-translate-y-2
563
+ cursor-pointer
564
+ "
565
+ >
566
+ {/* Gradient overlay on hover */}
567
+ <div
568
+ className="
569
+ absolute inset-0 rounded-xl
570
+ bg-gradient-to-br from-primary-500/0 to-primary-500/0
571
+ group-hover:from-primary-500/5 group-hover:to-primary-500/10
572
+ transition-all duration-300
573
+ "
574
+ />
575
+ <div className="relative z-10">{children}</div>
576
+ </div>
577
+ );
578
+ }
579
+
580
+ // Loading skeleton
581
+ export function Skeleton({ className }: { className?: string }) {
582
+ return (
583
+ <div
584
+ className={`
585
+ animate-pulse
586
+ bg-gray-200 dark:bg-gray-700
587
+ rounded
588
+ ${className}
589
+ `}
590
+ />
591
+ );
592
+ }
593
+
594
+ export function CardSkeleton() {
595
+ return (
596
+ <div className="p-6 bg-white dark:bg-gray-800 rounded-xl">
597
+ <Skeleton className="h-6 w-3/4 mb-4" />
598
+ <Skeleton className="h-4 w-full mb-2" />
599
+ <Skeleton className="h-4 w-5/6 mb-2" />
600
+ <Skeleton className="h-4 w-4/6" />
601
+ <div className="mt-6 flex gap-2">
602
+ <Skeleton className="h-10 w-24" />
603
+ <Skeleton className="h-10 w-24" />
604
+ </div>
605
+ </div>
606
+ );
607
+ }
608
+
609
+ // Transition group
610
+ export function FadeTransition({ show, children }: { show: boolean; children: React.ReactNode }) {
611
+ return (
612
+ <div
613
+ className={`
614
+ transition-all duration-300 ease-in-out
615
+ ${show ? "opacity-100 translate-y-0" : "opacity-0 -translate-y-4 pointer-events-none"}
616
+ `}
617
+ >
618
+ {children}
619
+ </div>
620
+ );
621
+ }
622
+ ```
623
+
624
+ ### 6. Utility Class Patterns
625
+
626
+ ```tsx
627
+ // Using clsx/cn for conditional classes
628
+ import { clsx, type ClassValue } from "clsx";
629
+ import { twMerge } from "tailwind-merge";
630
+
631
+ export function cn(...inputs: ClassValue[]) {
632
+ return twMerge(clsx(inputs));
633
+ }
634
+
635
+ // Usage
636
+ interface BadgeProps {
637
+ variant?: "default" | "success" | "warning" | "error";
638
+ children: React.ReactNode;
639
+ className?: string;
640
+ }
641
+
642
+ export function Badge({ variant = "default", children, className }: BadgeProps) {
643
+ return (
644
+ <span
645
+ className={cn(
646
+ "inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium",
647
+ {
648
+ "bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-200":
649
+ variant === "default",
650
+ "bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200":
651
+ variant === "success",
652
+ "bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200":
653
+ variant === "warning",
654
+ "bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200":
655
+ variant === "error",
656
+ },
657
+ className
658
+ )}
659
+ >
660
+ {children}
661
+ </span>
662
+ );
663
+ }
664
+
665
+ // Responsive spacing utility
666
+ export function Stack({
667
+ children,
668
+ spacing = "md",
669
+ direction = "vertical",
670
+ }: {
671
+ children: React.ReactNode;
672
+ spacing?: "sm" | "md" | "lg";
673
+ direction?: "vertical" | "horizontal";
674
+ }) {
675
+ const spacingClasses = {
676
+ sm: direction === "vertical" ? "space-y-2" : "space-x-2",
677
+ md: direction === "vertical" ? "space-y-4" : "space-x-4",
678
+ lg: direction === "vertical" ? "space-y-6" : "space-x-6",
679
+ };
680
+
681
+ return (
682
+ <div
683
+ className={cn(
684
+ direction === "horizontal" && "flex items-center",
685
+ spacingClasses[spacing]
686
+ )}
687
+ >
688
+ {children}
689
+ </div>
690
+ );
691
+ }
692
+ ```
693
+
694
+ ### 7. Form Patterns
695
+
696
+ ```tsx
697
+ // Complete form example
698
+ export function ContactForm() {
699
+ return (
700
+ <form className="space-y-6">
701
+ <div className="grid grid-cols-1 gap-6 sm:grid-cols-2">
702
+ <Input
703
+ label="First Name"
704
+ name="firstName"
705
+ placeholder="John"
706
+ required
707
+ />
708
+ <Input
709
+ label="Last Name"
710
+ name="lastName"
711
+ placeholder="Doe"
712
+ required
713
+ />
714
+ </div>
715
+
716
+ <Input
717
+ label="Email"
718
+ name="email"
719
+ type="email"
720
+ placeholder="john@example.com"
721
+ required
722
+ />
723
+
724
+ <div className="space-y-1">
725
+ <label
726
+ htmlFor="message"
727
+ className="block text-sm font-medium text-gray-700 dark:text-gray-300"
728
+ >
729
+ Message
730
+ </label>
731
+ <textarea
732
+ id="message"
733
+ name="message"
734
+ rows={4}
735
+ className="
736
+ w-full px-4 py-2
737
+ border border-gray-300 dark:border-gray-600
738
+ rounded-lg
739
+ bg-white dark:bg-gray-800
740
+ text-gray-900 dark:text-gray-100
741
+ placeholder-gray-400 dark:placeholder-gray-500
742
+ focus:outline-none focus:ring-2 focus:ring-primary-500 focus:border-transparent
743
+ resize-none
744
+ "
745
+ placeholder="Your message..."
746
+ />
747
+ </div>
748
+
749
+ <div className="flex items-center">
750
+ <input
751
+ id="terms"
752
+ name="terms"
753
+ type="checkbox"
754
+ className="
755
+ h-4 w-4
756
+ rounded
757
+ border-gray-300
758
+ text-primary-600
759
+ focus:ring-primary-500
760
+ "
761
+ />
762
+ <label
763
+ htmlFor="terms"
764
+ className="ml-2 text-sm text-gray-600 dark:text-gray-400"
765
+ >
766
+ I agree to the{" "}
767
+ <a href="/terms" className="text-primary-600 hover:underline">
768
+ terms and conditions
769
+ </a>
770
+ </label>
771
+ </div>
772
+
773
+ <Button type="submit" className="w-full sm:w-auto">
774
+ Send Message
775
+ </Button>
776
+ </form>
777
+ );
778
+ }
779
+ ```
780
+
781
+ ## Use Cases
782
+
783
+ ### Responsive Dashboard Layout
784
+
785
+ ```tsx
786
+ export function DashboardLayout({ children }: { children: React.ReactNode }) {
787
+ return (
788
+ <div className="min-h-screen bg-gray-50 dark:bg-gray-900">
789
+ {/* Sidebar */}
790
+ <aside
791
+ className="
792
+ fixed inset-y-0 left-0
793
+ z-50 w-64
794
+ bg-white dark:bg-gray-800
795
+ border-r border-gray-200 dark:border-gray-700
796
+ transform -translate-x-full lg:translate-x-0
797
+ transition-transform duration-300
798
+ "
799
+ >
800
+ {/* Sidebar content */}
801
+ </aside>
802
+
803
+ {/* Main content */}
804
+ <main className="lg:pl-64">
805
+ <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
806
+ {children}
807
+ </div>
808
+ </main>
809
+ </div>
810
+ );
811
+ }
46
812
  ```
47
813
 
48
814
  ## Best Practices
49
- - Use consistent spacing
50
- - Mobile-first responsive
51
- - Extract common patterns
52
- - Use @apply sparingly
815
+
816
+ ### Do's
817
+
818
+ - Use mobile-first responsive design
819
+ - Leverage utility composition
820
+ - Create reusable component patterns
821
+ - Use CSS variables for theming
822
+ - Implement dark mode properly
823
+ - Use the cn() utility for conditional classes
824
+ - Configure purge/content correctly
825
+ - Use semantic class grouping
826
+ - Optimize for production build
827
+ - Follow consistent spacing scales
828
+
829
+ ### Don'ts
830
+
831
+ - Don't overuse @apply
832
+ - Don't create overly specific utilities
833
+ - Don't ignore accessibility
834
+ - Don't repeat complex class combinations
835
+ - Don't hardcode colors outside theme
836
+ - Don't skip responsive testing
837
+ - Don't forget dark mode variants
838
+ - Don't use arbitrary values excessively
839
+ - Don't ignore the configuration file
840
+ - Don't mix styling paradigms
841
+
842
+ ## References
843
+
844
+ - [Tailwind CSS Documentation](https://tailwindcss.com/docs)
845
+ - [Tailwind UI](https://tailwindui.com/)
846
+ - [Headless UI](https://headlessui.com/)
847
+ - [Tailwind CSS Best Practices](https://tailwindcss.com/docs/reusing-styles)
848
+ - [Tailwind CSS Plugins](https://tailwindcss.com/docs/plugins)