@mizumi25/cli 0.1.0 → 0.1.3

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 (4) hide show
  1. package/docs-generator.js +1302 -536
  2. package/index.js +2557 -316
  3. package/package.json +1 -1
  4. package/watcher.js +153 -40
package/index.js CHANGED
@@ -1,416 +1,2657 @@
1
1
  #!/usr/bin/env node
2
2
  // packages/cli/index.js
3
3
 
4
- import { watch } from './watcher.js';
5
- import { DocsGenerator } from './docs-generator.js';
6
- import path from 'path';
7
- import fs from 'fs';
8
- import Mizumi from '../core/index.js';
9
- import { fileURLToPath, pathToFileURL } from 'url';
10
-
11
- // Get command from args
12
- const args = process.argv.slice(2);
13
- const command = args[0];
14
-
15
- // CLI commands
4
+ import { watch } from './watcher.js'
5
+ import { DocsGenerator } from './docs-generator.js'
6
+ import { MizuParser, loadMizuFiles, mergeMizuConfigs } from '../core/mizu-parser.js'
7
+ import { Validator } from '../core/validator.js'
8
+ import Mizumi from '../core/index.js'
9
+ import { generateDevToolsScript } from '../vite-plugin/devtools.js'
10
+
11
+ import path from 'node:path'
12
+ import fs from 'node:fs'
13
+ import { fileURLToPath, pathToFileURL } from 'node:url'
14
+ import { resolveClass } from '../core/class-resolver.js'
15
+
16
+
17
+ const args = process.argv.slice(2)
18
+ const command = args[0]
19
+
20
+ // ── Load config — supports mizumi.config.js AND .mizu files ──
21
+ async function loadConfig(configFile = 'mizumi.config.js') {
22
+ const cwd = process.cwd()
23
+ const configPath = path.resolve(cwd, configFile)
24
+ let config = {}
25
+
26
+ // Load JS config if exists
27
+ if (fs.existsSync(configPath)) {
28
+ const mod = await import(pathToFileURL(configPath).href + `?t=${Date.now()}`)
29
+ config = mod.default || mod
30
+ }
31
+
32
+ // Find and merge all .mizu files in src/
33
+ const srcDir = path.resolve(cwd, 'src')
34
+ const rootDir = cwd
35
+ const mizuDirs = [rootDir, srcDir].filter(fs.existsSync)
36
+
37
+ for (const dir of mizuDirs) {
38
+ const mizuConfig = loadMizuFiles(dir)
39
+ if (Object.keys(mizuConfig.tokens).length > 0 ||
40
+ Object.keys(mizuConfig.patterns).length > 0) {
41
+ config = mergeMizuConfigs(config, mizuConfig)
42
+ }
43
+ }
44
+
45
+ return config
46
+ }
47
+
48
+
49
+ function escapeCSSIdent(str) {
50
+ return str.replace(/([^a-zA-Z0-9_\-])/g, '\\$1')
51
+ }
52
+
53
+ const CLASS_RE = /(?:className|class)\s*=\s*(?:"([^"]*?)"|'([^']*?)'|`([^`]*?)`)/g
54
+
55
+ function extractTokens(source) {
56
+ const tokens = new Set()
57
+ for (const m of source.matchAll(CLASS_RE)) {
58
+ const raw = m[1] || m[2] || m[3] || ''
59
+ raw.split(/\s+/).filter(Boolean).forEach(t => tokens.add(t))
60
+ }
61
+ return tokens
62
+ }
63
+
64
+ function walkDir(dir, exts) {
65
+ const results = []
66
+ const extSet = new Set(exts)
67
+ if (!fs.existsSync(dir)) return results
68
+
69
+ function walk(current) {
70
+ let entries
71
+ try { entries = fs.readdirSync(current, { withFileTypes: true }) }
72
+ catch { return }
73
+ for (const entry of entries) {
74
+ const full = path.join(current, entry.name)
75
+ if (entry.isDirectory()) {
76
+ if (!entry.name.startsWith('.') && entry.name !== 'node_modules') walk(full)
77
+ } else if (entry.isFile()) {
78
+ const ext = entry.name.split('.').pop()
79
+ if (extSet.has(ext)) results.push(full)
80
+ }
81
+ }
82
+ }
83
+ walk(dir)
84
+ return results
85
+ }
86
+
87
+ function isNonCSSClass(token) {
88
+ const skip = ['animate-','hover-','active-','scroll-','stagger-','focus-','duration-','delay-','ease-']
89
+ const variants = ['sm:','md:','lg:','xl:','2xl:','dark:','hover:','focus:','active:','disabled:','motion-safe:','motion-reduce:','print:']
90
+ if (skip.some(p => token.startsWith(p))) return true
91
+ if (variants.some(p => token.startsWith(p))) return true
92
+ if (!token.includes(':') && !token.includes('{')) return true
93
+ return false
94
+ }
95
+
96
+ function scanAndGenerateCSS(root) {
97
+ const exts = ['html', 'htm', 'jsx', 'tsx', 'js', 'ts', 'vue', 'svelte']
98
+ const files = walkDir(root, exts)
99
+ const allToks = new Set()
100
+
101
+ for (const file of files) {
102
+ if (file.includes('node_modules') || file.includes('.mizumi')) continue
103
+ try {
104
+ extractTokens(fs.readFileSync(file, 'utf8')).forEach(t => allToks.add(t))
105
+ } catch { /* skip */ }
106
+ }
107
+
108
+ const lines = []
109
+ const seen = new Set()
110
+
111
+ for (const token of allToks) {
112
+ if (seen.has(token) || isNonCSSClass(token)) continue
113
+ seen.add(token)
114
+ const css = resolveClass(token)
115
+ if (css) lines.push(`.${escapeCSSIdent(token)} { ${css} }`)
116
+ }
117
+
118
+ console.log(` Scanned ${files.length} files, ${lines.length} arbitrary classes found`)
119
+ return lines.join('\n')
120
+ }
121
+
122
+
123
+
16
124
  const commands = {
17
125
 
18
- /**
19
- * Initialize Mizumi in current project
20
- * npx mizumi init
21
- */
126
+ // ── mizumi init ──
22
127
  init() {
23
- console.log('🌊 Initializing Mizumi...\n');
128
+ console.log('💮 Initializing Mizumi...\n')
129
+
130
+ const jsConfig = `// mizumi.config.js
131
+ // mizumi.config.js — FULL EXPANDED LIBRARY
132
+ // Tokens: ~2000+ | Patterns: ~400+ | Animations: ~800+ | Rules: complete
133
+ // ============================================================
134
+
135
+ export default {
24
136
 
25
- // Default config template
26
- const configTemplate = `// mizumi.config.js
27
- export {
137
+ // ============================================================
138
+ // TOKENS
139
+ // ============================================================
28
140
  tokens: {
141
+
142
+ // ── COLORS ──────────────────────────────────────────────────
29
143
  colors: {
144
+
145
+ // Primary — Blue
30
146
  primary: {
31
147
  DEFAULT: '#3B82F6',
32
- 50: '#EFF6FF',
148
+ 50: '#EFF6FF',
149
+ 100: '#DBEAFE',
150
+ 200: '#BFDBFE',
151
+ 300: '#93C5FD',
152
+ 400: '#60A5FA',
153
+ 500: '#3B82F6',
33
154
  600: '#2563EB',
34
- 900: '#1E3A8A'
155
+ 700: '#1D4ED8',
156
+ 800: '#1E40AF',
157
+ 900: '#1E3A8A',
158
+ 950: '#172554',
159
+ },
160
+
161
+ // Secondary — Violet
162
+ secondary: {
163
+ DEFAULT: '#8B5CF6',
164
+ 50: '#F5F3FF',
165
+ 100: '#EDE9FE',
166
+ 200: '#DDD6FE',
167
+ 300: '#C4B5FD',
168
+ 400: '#A78BFA',
169
+ 500: '#8B5CF6',
170
+ 600: '#7C3AED',
171
+ 700: '#6D28D9',
172
+ 800: '#5B21B6',
173
+ 900: '#4C1D95',
174
+ 950: '#2E1065',
175
+ },
176
+
177
+ // Accent — Fuchsia
178
+ accent: {
179
+ DEFAULT: '#D946EF',
180
+ 50: '#FDF4FF',
181
+ 100: '#FAE8FF',
182
+ 200: '#F5D0FE',
183
+ 300: '#F0ABFC',
184
+ 400: '#E879F9',
185
+ 500: '#D946EF',
186
+ 600: '#C026D3',
187
+ 700: '#A21CAF',
188
+ 800: '#86198F',
189
+ 900: '#701A75',
190
+ 950: '#4A044E',
35
191
  },
36
- secondary: '#8B5CF6',
192
+
193
+ // Neutral — Gray
37
194
  neutral: {
38
- 50: '#F9FAFB',
195
+ 0: '#FFFFFF',
196
+ 50: '#F9FAFB',
39
197
  100: '#F3F4F6',
198
+ 150: '#ECEEF1',
40
199
  200: '#E5E7EB',
200
+ 300: '#D1D5DB',
201
+ 400: '#9CA3AF',
41
202
  500: '#6B7280',
42
- 900: '#111827'
203
+ 600: '#4B5563',
204
+ 700: '#374151',
205
+ 800: '#1F2937',
206
+ 900: '#111827',
207
+ 950: '#030712',
208
+ },
209
+
210
+ // Slate
211
+ slate: {
212
+ 50: '#F8FAFC',
213
+ 100: '#F1F5F9',
214
+ 200: '#E2E8F0',
215
+ 300: '#CBD5E1',
216
+ 400: '#94A3B8',
217
+ 500: '#64748B',
218
+ 600: '#475569',
219
+ 700: '#334155',
220
+ 800: '#1E293B',
221
+ 900: '#0F172A',
222
+ 950: '#020617',
223
+ },
224
+
225
+ // Zinc
226
+ zinc: {
227
+ 50: '#FAFAFA',
228
+ 100: '#F4F4F5',
229
+ 200: '#E4E4E7',
230
+ 300: '#D4D4D8',
231
+ 400: '#A1A1AA',
232
+ 500: '#71717A',
233
+ 600: '#52525B',
234
+ 700: '#3F3F46',
235
+ 800: '#27272A',
236
+ 900: '#18181B',
237
+ 950: '#09090B',
238
+ },
239
+
240
+ // Stone
241
+ stone: {
242
+ 50: '#FAFAF9',
243
+ 100: '#F5F5F4',
244
+ 200: '#E7E5E4',
245
+ 300: '#D6D3D1',
246
+ 400: '#A8A29E',
247
+ 500: '#78716C',
248
+ 600: '#57534E',
249
+ 700: '#44403C',
250
+ 800: '#292524',
251
+ 900: '#1C1917',
252
+ 950: '#0C0A09',
253
+ },
254
+
255
+ // Red
256
+ red: {
257
+ DEFAULT: '#EF4444',
258
+ 50: '#FEF2F2',
259
+ 100: '#FEE2E2',
260
+ 200: '#FECACA',
261
+ 300: '#FCA5A5',
262
+ 400: '#F87171',
263
+ 500: '#EF4444',
264
+ 600: '#DC2626',
265
+ 700: '#B91C1C',
266
+ 800: '#991B1B',
267
+ 900: '#7F1D1D',
268
+ 950: '#450A0A',
269
+ },
270
+
271
+ // Orange
272
+ orange: {
273
+ DEFAULT: '#F97316',
274
+ 50: '#FFF7ED',
275
+ 100: '#FFEDD5',
276
+ 200: '#FED7AA',
277
+ 300: '#FDBA74',
278
+ 400: '#FB923C',
279
+ 500: '#F97316',
280
+ 600: '#EA580C',
281
+ 700: '#C2410C',
282
+ 800: '#9A3412',
283
+ 900: '#7C2D12',
284
+ 950: '#431407',
285
+ },
286
+
287
+ // Amber
288
+ amber: {
289
+ DEFAULT: '#F59E0B',
290
+ 50: '#FFFBEB',
291
+ 100: '#FEF3C7',
292
+ 200: '#FDE68A',
293
+ 300: '#FCD34D',
294
+ 400: '#FBBF24',
295
+ 500: '#F59E0B',
296
+ 600: '#D97706',
297
+ 700: '#B45309',
298
+ 800: '#92400E',
299
+ 900: '#78350F',
300
+ 950: '#451A03',
301
+ },
302
+
303
+ // Yellow
304
+ yellow: {
305
+ DEFAULT: '#EAB308',
306
+ 50: '#FEFCE8',
307
+ 100: '#FEF9C3',
308
+ 200: '#FEF08A',
309
+ 300: '#FDE047',
310
+ 400: '#FACC15',
311
+ 500: '#EAB308',
312
+ 600: '#CA8A04',
313
+ 700: '#A16207',
314
+ 800: '#854D0E',
315
+ 900: '#713F12',
316
+ 950: '#422006',
317
+ },
318
+
319
+ // Lime
320
+ lime: {
321
+ DEFAULT: '#84CC16',
322
+ 50: '#F7FEE7',
323
+ 100: '#ECFCCB',
324
+ 200: '#D9F99D',
325
+ 300: '#BEF264',
326
+ 400: '#A3E635',
327
+ 500: '#84CC16',
328
+ 600: '#65A30D',
329
+ 700: '#4D7C0F',
330
+ 800: '#3F6212',
331
+ 900: '#365314',
332
+ 950: '#1A2E05',
333
+ },
334
+
335
+ // Green
336
+ green: {
337
+ DEFAULT: '#22C55E',
338
+ 50: '#F0FDF4',
339
+ 100: '#DCFCE7',
340
+ 200: '#BBF7D0',
341
+ 300: '#86EFAC',
342
+ 400: '#4ADE80',
343
+ 500: '#22C55E',
344
+ 600: '#16A34A',
345
+ 700: '#15803D',
346
+ 800: '#166534',
347
+ 900: '#14532D',
348
+ 950: '#052E16',
349
+ },
350
+
351
+ // Emerald
352
+ emerald: {
353
+ DEFAULT: '#10B981',
354
+ 50: '#ECFDF5',
355
+ 100: '#D1FAE5',
356
+ 200: '#A7F3D0',
357
+ 300: '#6EE7B7',
358
+ 400: '#34D399',
359
+ 500: '#10B981',
360
+ 600: '#059669',
361
+ 700: '#047857',
362
+ 800: '#065F46',
363
+ 900: '#064E3B',
364
+ 950: '#022C22',
365
+ },
366
+
367
+ // Teal
368
+ teal: {
369
+ DEFAULT: '#14B8A6',
370
+ 50: '#F0FDFA',
371
+ 100: '#CCFBF1',
372
+ 200: '#99F6E4',
373
+ 300: '#5EEAD4',
374
+ 400: '#2DD4BF',
375
+ 500: '#14B8A6',
376
+ 600: '#0D9488',
377
+ 700: '#0F766E',
378
+ 800: '#115E59',
379
+ 900: '#134E4A',
380
+ 950: '#042F2E',
381
+ },
382
+
383
+ // Cyan
384
+ cyan: {
385
+ DEFAULT: '#06B6D4',
386
+ 50: '#ECFEFF',
387
+ 100: '#CFFAFE',
388
+ 200: '#A5F3FC',
389
+ 300: '#67E8F9',
390
+ 400: '#22D3EE',
391
+ 500: '#06B6D4',
392
+ 600: '#0891B2',
393
+ 700: '#0E7490',
394
+ 800: '#155E75',
395
+ 900: '#164E63',
396
+ 950: '#083344',
397
+ },
398
+
399
+ // Sky
400
+ sky: {
401
+ DEFAULT: '#0EA5E9',
402
+ 50: '#F0F9FF',
403
+ 100: '#E0F2FE',
404
+ 200: '#BAE6FD',
405
+ 300: '#7DD3FC',
406
+ 400: '#38BDF8',
407
+ 500: '#0EA5E9',
408
+ 600: '#0284C7',
409
+ 700: '#0369A1',
410
+ 800: '#075985',
411
+ 900: '#0C4A6E',
412
+ 950: '#082F49',
413
+ },
414
+
415
+ // Blue (alias/extended)
416
+ blue: {
417
+ DEFAULT: '#3B82F6',
418
+ 50: '#EFF6FF',
419
+ 100: '#DBEAFE',
420
+ 200: '#BFDBFE',
421
+ 300: '#93C5FD',
422
+ 400: '#60A5FA',
423
+ 500: '#3B82F6',
424
+ 600: '#2563EB',
425
+ 700: '#1D4ED8',
426
+ 800: '#1E40AF',
427
+ 900: '#1E3A8A',
428
+ 950: '#172554',
43
429
  },
44
- surface: '#FFFFFF',
45
- text: '#111827',
46
- success: '#10B981',
47
- error: '#EF4444'
430
+
431
+ // Indigo
432
+ indigo: {
433
+ DEFAULT: '#6366F1',
434
+ 50: '#EEF2FF',
435
+ 100: '#E0E7FF',
436
+ 200: '#C7D2FE',
437
+ 300: '#A5B4FC',
438
+ 400: '#818CF8',
439
+ 500: '#6366F1',
440
+ 600: '#4F46E5',
441
+ 700: '#4338CA',
442
+ 800: '#3730A3',
443
+ 900: '#312E81',
444
+ 950: '#1E1B4B',
445
+ },
446
+
447
+ // Violet
448
+ violet: {
449
+ DEFAULT: '#8B5CF6',
450
+ 50: '#F5F3FF',
451
+ 100: '#EDE9FE',
452
+ 200: '#DDD6FE',
453
+ 300: '#C4B5FD',
454
+ 400: '#A78BFA',
455
+ 500: '#8B5CF6',
456
+ 600: '#7C3AED',
457
+ 700: '#6D28D9',
458
+ 800: '#5B21B6',
459
+ 900: '#4C1D95',
460
+ 950: '#2E1065',
461
+ },
462
+
463
+ // Purple
464
+ purple: {
465
+ DEFAULT: '#A855F7',
466
+ 50: '#FAF5FF',
467
+ 100: '#F3E8FF',
468
+ 200: '#E9D5FF',
469
+ 300: '#D8B4FE',
470
+ 400: '#C084FC',
471
+ 500: '#A855F7',
472
+ 600: '#9333EA',
473
+ 700: '#7E22CE',
474
+ 800: '#6B21A8',
475
+ 900: '#581C87',
476
+ 950: '#3B0764',
477
+ },
478
+
479
+ // Pink
480
+ pink: {
481
+ DEFAULT: '#EC4899',
482
+ 50: '#FDF2F8',
483
+ 100: '#FCE7F3',
484
+ 200: '#FBCFE8',
485
+ 300: '#F9A8D4',
486
+ 400: '#F472B6',
487
+ 500: '#EC4899',
488
+ 600: '#DB2777',
489
+ 700: '#BE185D',
490
+ 800: '#9D174D',
491
+ 900: '#831843',
492
+ 950: '#500724',
493
+ },
494
+
495
+ // Rose
496
+ rose: {
497
+ DEFAULT: '#F43F5E',
498
+ 50: '#FFF1F2',
499
+ 100: '#FFE4E6',
500
+ 200: '#FECDD3',
501
+ 300: '#FDA4AF',
502
+ 400: '#FB7185',
503
+ 500: '#F43F5E',
504
+ 600: '#E11D48',
505
+ 700: '#BE123C',
506
+ 800: '#9F1239',
507
+ 900: '#881337',
508
+ 950: '#4C0519',
509
+ },
510
+
511
+ // Semantic
512
+ success: { DEFAULT: '#10B981', light: '#D1FAE5', dark: '#065F46' },
513
+ error: { DEFAULT: '#EF4444', light: '#FEE2E2', dark: '#7F1D1D' },
514
+ warning: { DEFAULT: '#F59E0B', light: '#FEF3C7', dark: '#78350F' },
515
+ info: { DEFAULT: '#3B82F6', light: '#DBEAFE', dark: '#1E3A8A' },
516
+
517
+ // Brand
518
+ surface: '#FFFFFF',
519
+ ink: '#111827',
520
+ white: '#FFFFFF',
521
+ black: '#000000',
522
+ inherit: 'inherit',
523
+ current: 'currentColor',
524
+ transparent: 'transparent',
48
525
  },
49
526
 
527
+ // ── SPACING ─────────────────────────────────────────────────
50
528
  spacing: {
51
- xs: '4px',
52
- sm: '8px',
53
- md: '16px',
54
- lg: '24px',
55
- xl: '32px',
529
+ 0: '0px',
530
+ px: '1px',
531
+ '0.5': '2px',
532
+ 1: '4px',
533
+ '1.5': '6px',
534
+ 2: '8px',
535
+ '2.5': '10px',
536
+ 3: '12px',
537
+ '3.5': '14px',
538
+ 4: '16px',
539
+ 5: '20px',
540
+ 6: '24px',
541
+ 7: '28px',
542
+ 8: '32px',
543
+ 9: '36px',
544
+ 10: '40px',
545
+ 11: '44px',
546
+ 12: '48px',
547
+ 14: '56px',
548
+ 16: '64px',
549
+ 20: '80px',
550
+ 24: '96px',
551
+ 28: '112px',
552
+ 32: '128px',
553
+ 36: '144px',
554
+ 40: '160px',
555
+ 44: '176px',
556
+ 48: '192px',
557
+ 52: '208px',
558
+ 56: '224px',
559
+ 60: '240px',
560
+ 64: '256px',
561
+ 72: '288px',
562
+ 80: '320px',
563
+ 96: '384px',
564
+ // Named
565
+ xs: '4px',
566
+ sm: '8px',
567
+ md: '16px',
568
+ lg: '24px',
569
+ xl: '32px',
56
570
  '2xl': '48px',
57
- '3xl': '64px'
571
+ '3xl': '64px',
572
+ '4xl': '96px',
573
+ '5xl': '128px',
574
+ '6xl': '192px',
575
+ '7xl': '256px',
576
+ // Fractional
577
+ 'half': '50%',
578
+ 'third': '33.333%',
579
+ 'quarter': '25%',
580
+ 'fifth': '20%',
581
+ 'sixth': '16.667%',
582
+ 'full': '100%',
583
+ // Special
584
+ auto: 'auto',
585
+ none: '0',
58
586
  },
59
587
 
588
+ // ── TYPOGRAPHY ──────────────────────────────────────────────
60
589
  typography: {
61
- h1: { size: '48px', weight: 700, line: 1.2 },
62
- h2: { size: '36px', weight: 600, line: 1.3 },
63
- h3: { size: '24px', weight: 600, line: 1.4 },
64
- body: { size: '16px', weight: 400, line: 1.6 },
65
- small: { size: '14px', weight: 400, line: 1.5 }
590
+ // Display sizes
591
+ display2xl: { size: '72px', weight: '800', line: '1.1', spacing: '-0.025em' },
592
+ displayXl: { size: '60px', weight: '800', line: '1.1', spacing: '-0.02em' },
593
+ displayLg: { size: '48px', weight: '700', line: '1.2', spacing: '-0.02em' },
594
+ displayMd: { size: '42px', weight: '700', line: '1.2', spacing: '-0.015em' },
595
+ displaySm: { size: '36px', weight: '700', line: '1.3', spacing: '-0.01em' },
596
+ // Headings
597
+ h1: { size: '48px', weight: '700', line: '1.2', spacing: '-0.02em' },
598
+ h2: { size: '36px', weight: '600', line: '1.3', spacing: '-0.015em' },
599
+ h3: { size: '28px', weight: '600', line: '1.4', spacing: '-0.01em' },
600
+ h4: { size: '22px', weight: '600', line: '1.4' },
601
+ h5: { size: '18px', weight: '600', line: '1.5' },
602
+ h6: { size: '16px', weight: '600', line: '1.5' },
603
+ // Body
604
+ xl: { size: '20px', weight: '400', line: '1.75' },
605
+ lg: { size: '18px', weight: '400', line: '1.75' },
606
+ body: { size: '16px', weight: '400', line: '1.6' },
607
+ md: { size: '16px', weight: '400', line: '1.6' },
608
+ sm: { size: '14px', weight: '400', line: '1.5' },
609
+ small:{ size: '14px', weight: '400', line: '1.5' },
610
+ xs: { size: '12px', weight: '400', line: '1.4' },
611
+ '2xs':{ size: '11px', weight: '400', line: '1.4' },
612
+ // Functional
613
+ label: { size: '12px', weight: '600', line: '1.0', spacing: '0.06em' },
614
+ caption: { size: '11px', weight: '400', line: '1.4' },
615
+ overline: { size: '11px', weight: '700', line: '1.0', spacing: '0.1em' },
616
+ code: { size: '14px', weight: '400', line: '1.6' },
617
+ mono: { size: '13px', weight: '400', line: '1.6' },
618
+ },
619
+
620
+ // ── FONTS ───────────────────────────────────────────────────
621
+ fonts: {
622
+ sans: 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
623
+ serif: 'Georgia, "Times New Roman", Times, serif',
624
+ mono: '"Fira Code", "JetBrains Mono", ui-monospace, "Cascadia Code", monospace',
625
+ inter: '"Inter", system-ui, sans-serif',
626
+ geist: '"Geist", system-ui, sans-serif',
627
+ display: '"Cal Sans", "Clash Display", system-ui, sans-serif',
628
+ heading: '"Plus Jakarta Sans", system-ui, sans-serif',
629
+ body: '"Instrument Sans", system-ui, sans-serif',
66
630
  },
67
631
 
632
+ // ── RADIUS ──────────────────────────────────────────────────
68
633
  radius: {
69
- none: '0',
70
- sm: '4px',
71
- md: '8px',
72
- lg: '16px',
73
- full: '9999px'
634
+ none: '0px',
635
+ xs: '2px',
636
+ sm: '4px',
637
+ md: '8px',
638
+ lg: '12px',
639
+ xl: '16px',
640
+ '2xl':'20px',
641
+ '3xl':'24px',
642
+ '4xl':'32px',
643
+ pill: '500px',
644
+ full: '9999px',
74
645
  },
75
646
 
647
+ // ── SHADOWS ─────────────────────────────────────────────────
76
648
  shadows: {
77
- none: 'none',
78
- sm: '0 1px 2px 0 rgba(0, 0, 0, 0.05)',
79
- md: '0 4px 6px -1px rgba(0, 0, 0, 0.1)',
80
- lg: '0 10px 15px -3px rgba(0, 0, 0, 0.1)',
81
- xl: '0 20px 25px -5px rgba(0, 0, 0, 0.1)'
649
+ none: 'none',
650
+ xs: '0 1px 2px 0 rgba(0,0,0,0.04)',
651
+ sm: '0 1px 3px 0 rgba(0,0,0,0.06), 0 1px 2px -1px rgba(0,0,0,0.04)',
652
+ md: '0 4px 6px -1px rgba(0,0,0,0.07), 0 2px 4px -2px rgba(0,0,0,0.05)',
653
+ lg: '0 10px 15px -3px rgba(0,0,0,0.08), 0 4px 6px -4px rgba(0,0,0,0.04)',
654
+ xl: '0 20px 25px -5px rgba(0,0,0,0.08), 0 8px 10px -6px rgba(0,0,0,0.04)',
655
+ '2xl': '0 25px 50px -12px rgba(0,0,0,0.15)',
656
+ '3xl': '0 35px 60px -15px rgba(0,0,0,0.2)',
657
+ inner: 'inset 0 2px 4px 0 rgba(0,0,0,0.05)',
658
+ 'inner-md': 'inset 0 4px 8px 0 rgba(0,0,0,0.08)',
659
+ // Colored
660
+ 'primary': '0 4px 14px 0 rgba(59,130,246,0.35)',
661
+ 'secondary': '0 4px 14px 0 rgba(139,92,246,0.35)',
662
+ 'accent': '0 4px 14px 0 rgba(217,70,239,0.35)',
663
+ 'success': '0 4px 14px 0 rgba(16,185,129,0.35)',
664
+ 'error': '0 4px 14px 0 rgba(239,68,68,0.35)',
665
+ 'warning': '0 4px 14px 0 rgba(245,158,11,0.35)',
666
+ // Glow
667
+ 'glow-sm': '0 0 10px rgba(59,130,246,0.3)',
668
+ 'glow-md': '0 0 20px rgba(59,130,246,0.4)',
669
+ 'glow-lg': '0 0 40px rgba(59,130,246,0.5)',
670
+ 'glow-xl': '0 0 60px rgba(59,130,246,0.6)',
671
+ // Dark
672
+ 'dark-sm': '0 1px 3px 0 rgba(0,0,0,0.3)',
673
+ 'dark-md': '0 4px 6px -1px rgba(0,0,0,0.4)',
674
+ 'dark-lg': '0 10px 15px -3px rgba(0,0,0,0.5)',
675
+ 'dark-xl': '0 20px 25px -5px rgba(0,0,0,0.6)',
82
676
  },
83
677
 
84
- animations: {
85
- duration: {
86
- fast: 150,
87
- normal: 300,
88
- slow: 500
89
- },
90
- easing: {
91
- smooth: 'power2.out',
92
- bouncy: 'elastic.out(1, 0.5)',
93
- sharp: 'power4.inOut'
94
- }
95
- }
96
- },
97
-
98
- patterns: {
99
- // Layout
100
- 'flex-center': 'flex items-center justify-center',
101
- 'flex-between': 'flex items-center justify-between',
102
- 'flex-col-center': 'flex flex-col items-center justify-center',
103
-
104
- // Containers
105
- container: 'max-w-6xl mx-auto pad-x-md',
106
- section: 'pad-y-2xl',
107
-
108
- // Cards
109
- card: 'bg-surface pad-md rounded-lg shadow-md',
110
- 'card-elevated': 'card shadow-xl',
111
- 'card-flat': 'card shadow-sm',
112
- 'card-hover': 'card transition cursor-pointer',
113
-
114
- // Buttons
115
- button: 'pad-sm pad-x-lg rounded-md cursor-pointer transition inline-flex items-center justify-center',
116
- 'btn-primary': 'button bg-primary color-white',
117
- 'btn-secondary': 'button bg-secondary color-white',
118
- 'btn-ghost': 'button bg-transparent color-primary',
119
- 'btn-outline': 'button border border-primary color-primary',
120
-
121
- // Inputs
122
- input: 'pad-sm rounded-md border border-neutral-200 transition',
123
-
124
- // Text
125
- heading: 'text-h1 color-text',
126
- subheading: 'text-h3 color-neutral-500',
127
- 'text-muted': 'color-neutral-500'
128
- },
678
+ // ── EASING ──────────────────────────────────────────────────
679
+ easing: {
680
+ // Standard
681
+ linear: 'linear',
682
+ smooth: 'cubic-bezier(0.4,0,0.2,1)',
683
+ ease: 'cubic-bezier(0.25,0.1,0.25,1)',
684
+ 'ease-in': 'cubic-bezier(0.4,0,1,1)',
685
+ 'ease-out': 'cubic-bezier(0,0,0.2,1)',
686
+ 'ease-in-out': 'cubic-bezier(0.4,0,0.2,1)',
687
+ // Expressive
688
+ bouncy: 'cubic-bezier(0.34,1.56,0.64,1)',
689
+ elastic: 'cubic-bezier(0.68,-0.55,0.265,1.55)',
690
+ spring: 'cubic-bezier(0.43,0.195,0.02,1.0)',
691
+ sharp: 'cubic-bezier(0.4,0,1,1)',
692
+ back: 'cubic-bezier(0.34,1.4,0.64,1)',
693
+ // Material
694
+ 'standard': 'cubic-bezier(0.2,0,0,1)',
695
+ 'emphasized': 'cubic-bezier(0.2,0,0,1)',
696
+ 'decelerate': 'cubic-bezier(0,0,0.2,1)',
697
+ 'accelerate': 'cubic-bezier(0.3,0,1,1)',
698
+ // Sine
699
+ 'sine-in': 'cubic-bezier(0.12,0,0.39,0)',
700
+ 'sine-out': 'cubic-bezier(0.61,1,0.88,1)',
701
+ 'sine-in-out': 'cubic-bezier(0.37,0,0.63,1)',
702
+ // Quad
703
+ 'quad-in': 'cubic-bezier(0.11,0,0.5,0)',
704
+ 'quad-out': 'cubic-bezier(0.5,1,0.89,1)',
705
+ 'quad-in-out': 'cubic-bezier(0.45,0,0.55,1)',
706
+ // Cubic
707
+ 'cubic-in': 'cubic-bezier(0.32,0,0.67,0)',
708
+ 'cubic-out': 'cubic-bezier(0.33,1,0.68,1)',
709
+ 'cubic-in-out': 'cubic-bezier(0.65,0,0.35,1)',
710
+ // Quart
711
+ 'quart-in': 'cubic-bezier(0.5,0,0.75,0)',
712
+ 'quart-out': 'cubic-bezier(0.25,1,0.5,1)',
713
+ 'quart-in-out': 'cubic-bezier(0.76,0,0.24,1)',
714
+ // Expo
715
+ 'expo-in': 'cubic-bezier(0.7,0,0.84,0)',
716
+ 'expo-out': 'cubic-bezier(0.16,1,0.3,1)',
717
+ 'expo-in-out': 'cubic-bezier(0.87,0,0.13,1)',
718
+ // Circ
719
+ 'circ-in': 'cubic-bezier(0.55,0,1,0.45)',
720
+ 'circ-out': 'cubic-bezier(0,0.55,0.45,1)',
721
+ 'circ-in-out': 'cubic-bezier(0.85,0,0.15,1)',
722
+ // Back
723
+ 'back-in': 'cubic-bezier(0.36,0,0.66,-0.56)',
724
+ 'back-out': 'cubic-bezier(0.34,1.56,0.64,1)',
725
+ 'back-in-out': 'cubic-bezier(0.68,-0.6,0.32,1.6)',
726
+ },
129
727
 
130
- animations: {
131
- // Entrance
132
- 'animate-fade-in': {
133
- from: { opacity: 0 },
134
- to: { opacity: 1 },
135
- duration: 300,
136
- ease: 'power2.out'
728
+ // ── DURATION ────────────────────────────────────────────────
729
+ duration: {
730
+ 0: '0ms',
731
+ 50: '50ms',
732
+ 75: '75ms',
733
+ 100: '100ms',
734
+ 150: '150ms',
735
+ 200: '200ms',
736
+ 250: '250ms',
737
+ 300: '300ms',
738
+ 350: '350ms',
739
+ 400: '400ms',
740
+ 500: '500ms',
741
+ 600: '600ms',
742
+ 700: '700ms',
743
+ 750: '750ms',
744
+ 800: '800ms',
745
+ 900: '900ms',
746
+ 1000: '1000ms',
747
+ 1200: '1200ms',
748
+ 1500: '1500ms',
749
+ 2000: '2000ms',
750
+ // Named
751
+ instant: '0ms',
752
+ snap: '75ms',
753
+ fast: '150ms',
754
+ quick: '200ms',
755
+ normal: '300ms',
756
+ moderate:'400ms',
757
+ slow: '500ms',
758
+ slower: '800ms',
759
+ sluggish:'1200ms',
760
+ lazy: '2000ms',
137
761
  },
138
- 'animate-slide-up': {
139
- from: { y: 100, opacity: 0 },
140
- to: { y: 0, opacity: 1 },
141
- duration: 300,
142
- ease: 'power2.out'
762
+
763
+ // ── BLUR ────────────────────────────────────────────────────
764
+ blur: {
765
+ none: '0',
766
+ xs: '2px',
767
+ sm: '4px',
768
+ md: '8px',
769
+ lg: '12px',
770
+ xl: '16px',
771
+ '2xl': '24px',
772
+ '3xl': '40px',
773
+ glass: '20px',
774
+ heavy: '48px',
775
+ ultra: '64px',
143
776
  },
144
- 'animate-scale-in': {
145
- from: { scale: 0, opacity: 0 },
146
- to: { scale: 1, opacity: 1 },
147
- duration: 300,
148
- ease: 'back.out'
777
+
778
+ // ── OPACITY ─────────────────────────────────────────────────
779
+ opacity: {
780
+ 0: '0',
781
+ 5: '0.05',
782
+ 10: '0.1',
783
+ 15: '0.15',
784
+ 20: '0.2',
785
+ 25: '0.25',
786
+ 30: '0.3',
787
+ 40: '0.4',
788
+ 50: '0.5',
789
+ 60: '0.6',
790
+ 70: '0.7',
791
+ 75: '0.75',
792
+ 80: '0.8',
793
+ 90: '0.9',
794
+ 95: '0.95',
795
+ 100: '1',
796
+ // Named
797
+ invisible: '0',
798
+ ghost: '0.05',
799
+ faint: '0.15',
800
+ muted: '0.4',
801
+ soft: '0.7',
802
+ strong: '0.85',
803
+ full: '1',
149
804
  },
150
805
 
151
- // Scroll
152
- 'scroll-trigger': {
153
- scrollTrigger: {
154
- trigger: 'self',
155
- start: 'top 80%',
156
- toggleActions: 'play none none reverse'
157
- }
806
+ // ── Z-INDEX ─────────────────────────────────────────────────
807
+ zIndex: {
808
+ 0: 0,
809
+ 10: 10,
810
+ 20: 20,
811
+ 30: 30,
812
+ 40: 40,
813
+ 50: 50,
814
+ 75: 75,
815
+ 100: 100,
816
+ 200: 200,
817
+ 300: 300,
818
+ 400: 400,
819
+ 500: 500,
820
+ 999: 999,
821
+ 9999: 9999,
822
+ // Named
823
+ auto: 'auto',
824
+ base: 0,
825
+ raised: 5,
826
+ float: 10,
827
+ overlay: 15,
828
+ sticky: 20,
829
+ fixed: 30,
830
+ drawer: 40,
831
+ modal: 100,
832
+ popover: 200,
833
+ toast: 300,
834
+ tooltip: 400,
835
+ top: 999,
836
+ crown: 9999,
158
837
  },
159
838
 
160
- // Hover
161
- 'hover-lift': {
162
- hover: { y: -8, duration: 150 }
839
+ // ── LEADING (line-height) ───────────────────────────────────
840
+ leading: {
841
+ none: '1',
842
+ tight: '1.25',
843
+ snug: '1.375',
844
+ normal: '1.5',
845
+ relaxed: '1.625',
846
+ loose: '2',
847
+ '3': '.75rem',
848
+ '4': '1rem',
849
+ '5': '1.25rem',
850
+ '6': '1.5rem',
851
+ '7': '1.75rem',
852
+ '8': '2rem',
853
+ '9': '2.25rem',
854
+ '10': '2.5rem',
163
855
  },
164
- 'hover-scale': {
165
- hover: { scale: 1.05, duration: 150 }
856
+
857
+ // ── TRACKING (letter-spacing) ───────────────────────────────
858
+ tracking: {
859
+ tightest: '-0.1em',
860
+ tighter: '-0.075em',
861
+ tight: '-0.05em',
862
+ snug: '-0.025em',
863
+ normal: '0em',
864
+ wide: '0.025em',
865
+ wider: '0.05em',
866
+ widest: '0.1em',
867
+ ultra: '0.2em',
868
+ spaced: '0.3em',
166
869
  },
167
- 'hover-glow': {
168
- hover: {
169
- boxShadow: '0 0 20px rgba(59, 130, 246, 0.5)',
170
- duration: 150
171
- }
870
+
871
+ // ── STROKES (border widths) ─────────────────────────────────
872
+ strokes: {
873
+ 0: '0px',
874
+ none: '0px',
875
+ px: '1px',
876
+ thin: '1px',
877
+ base: '2px',
878
+ md: '2px',
879
+ thick: '4px',
880
+ heavy: '8px',
881
+ bold: '12px',
172
882
  },
173
883
 
174
- // Click
175
- 'active-press': {
176
- active: { scale: 0.95, duration: 100 }
884
+ // ── SCREENS ─────────────────────────────────────────────────
885
+ screens: {
886
+ xs: '480px',
887
+ sm: '640px',
888
+ md: '768px',
889
+ lg: '1024px',
890
+ xl: '1280px',
891
+ '2xl': '1536px',
892
+ '3xl': '1920px',
177
893
  },
894
+ },
178
895
 
179
- // Stagger
180
- 'stagger-children-100': {
181
- targets: 'children',
182
- stagger: 0.1,
183
- from: { opacity: 0, y: 20 },
184
- to: { opacity: 1, y: 0 }
185
- }
896
+ // ============================================================
897
+ // PATTERNS
898
+ // ============================================================
899
+ patterns: {
900
+
901
+ // ── DISPLAY / LAYOUT PRIMITIVES ─────────────────────────────
902
+ 'flex': 'display:flex',
903
+ 'flex-inline': 'display:flex-inline',
904
+ 'grid': 'display:grid',
905
+ 'block': 'display:block',
906
+ 'inline': 'display:inline',
907
+ 'inline-block': 'display:block-inline',
908
+ 'hidden': 'display:none',
909
+ 'contents': 'display:contents',
910
+ 'flow-root': 'display:flow-root',
911
+
912
+ // ── FLEX LAYOUTS ────────────────────────────────────────────
913
+ 'flex-center': 'display:flex align-yi:center align-x:center',
914
+ 'flex-center-col': 'display:flex align-yi:center align-x:center flex-dir:col',
915
+ 'flex-between': 'display:flex align-yi:center align-x:between',
916
+ 'flex-between-col': 'display:flex align-x:between flex-dir:col',
917
+ 'flex-around': 'display:flex align-yi:center align-x:around',
918
+ 'flex-evenly': 'display:flex align-yi:center align-x:evenly',
919
+ 'flex-start': 'display:flex align-yi:start',
920
+ 'flex-end': 'display:flex align-yi:end',
921
+ 'flex-col': 'display:flex flex-dir:col',
922
+ 'flex-col-center': 'display:flex flex-dir:col align-yi:center align-x:center',
923
+ 'flex-col-between': 'display:flex flex-dir:col align-x:between',
924
+ 'flex-col-start': 'display:flex flex-dir:col align-yi:start',
925
+ 'flex-col-end': 'display:flex flex-dir:col align-yi:end',
926
+ 'flex-row': 'display:flex flex-dir:row align-yi:center',
927
+ 'flex-row-rev': 'display:flex flex-dir:row-rev align-yi:center',
928
+ 'flex-col-rev': 'display:flex flex-dir:col-rev',
929
+ 'flex-wrap': 'display:flex flex-wrap:yes',
930
+ 'flex-nowrap': 'display:flex flex-wrap:no',
931
+ 'flex-1': 'display:flex flex-grow:1',
932
+ 'flex-auto': 'display:flex',
933
+ 'flex-none': 'display:flex flex-grow:0',
934
+ 'stack': 'display:flex flex-dir:col',
935
+ 'stack-center': 'display:flex flex-dir:col align-yi:center',
936
+ 'row': 'display:flex flex-dir:row align-yi:center',
937
+ 'cluster': 'display:flex flex-wrap:yes gap:sm',
938
+ 'cluster-center': 'display:flex flex-wrap:yes gap:sm align-yi:center',
939
+ 'sidebar': 'display:flex gap:md',
940
+ 'cover': 'display:flex flex-dir:col canvas-h:full',
941
+ 'switcher': 'display:flex flex-wrap:yes gap:md',
942
+
943
+ // ── GRID LAYOUTS ─────────────────────────────────────────────
944
+ 'grid-auto': 'display:grid gap:md',
945
+ 'grid-center': 'display:grid place:center',
946
+ 'grid-1': 'display:grid grid-cols:repeat(1,1fr)',
947
+ 'grid-2': 'display:grid grid-cols:repeat(2,1fr) gap:md',
948
+ 'grid-3': 'display:grid grid-cols:repeat(3,1fr) gap:md',
949
+ 'grid-4': 'display:grid grid-cols:repeat(4,1fr) gap:md',
950
+ 'grid-5': 'display:grid grid-cols:repeat(5,1fr) gap:md',
951
+ 'grid-6': 'display:grid grid-cols:repeat(6,1fr) gap:md',
952
+ 'grid-12': 'display:grid grid-cols:repeat(12,1fr) gap:md',
953
+ 'grid-auto-sm': 'display:grid grid-cols:repeat(auto-fill,minmax(160px,1fr)) gap:sm',
954
+ 'grid-auto-md': 'display:grid grid-cols:repeat(auto-fill,minmax(220px,1fr)) gap:md',
955
+ 'grid-auto-lg': 'display:grid grid-cols:repeat(auto-fill,minmax(300px,1fr)) gap:lg',
956
+ 'grid-auto-xl': 'display:grid grid-cols:repeat(auto-fill,minmax(380px,1fr)) gap:xl',
957
+ 'grid-auto-fit': 'display:grid grid-cols:repeat(auto-fit,minmax(240px,1fr)) gap:md',
958
+ 'grid-dense': 'display:grid gap:sm',
959
+ 'repel': 'display:flex align-x:between align-yi:center',
960
+ 'frame': 'display:flex align-yi:center align-x:center overflow:hidden',
961
+
962
+ // ── CONTAINERS & PAGE LAYOUT ─────────────────────────────────
963
+ 'container': 'canvas-w:full mar-x:auto pad-x:md',
964
+ 'container-sm': 'canvas-w:full canvas-w-max:640px mar-x:auto pad-x:md',
965
+ 'container-md': 'canvas-w:full canvas-w-max:768px mar-x:auto pad-x:md',
966
+ 'container-lg': 'canvas-w:full canvas-w-max:1024px mar-x:auto pad-x:md',
967
+ 'container-xl': 'canvas-w:full canvas-w-max:1280px mar-x:auto pad-x:md',
968
+ 'container-2xl': 'canvas-w:full canvas-w-max:1536px mar-x:auto pad-x:md',
969
+ 'container-narrow': 'canvas-w:full canvas-w-max:640px mar-x:auto pad-x:lg',
970
+ 'container-wide': 'canvas-w:full canvas-w-max:1280px mar-x:auto pad-x:xl',
971
+ 'container-prose': 'canvas-w:full canvas-w-max:65ch mar-x:auto',
972
+ 'section': 'pad-y:2xl canvas-w:full',
973
+ 'section-sm': 'pad-y:lg canvas-w:full',
974
+ 'section-lg': 'pad-y:3xl canvas-w:full',
975
+ 'section-xl': 'pad-y:4xl canvas-w:full',
976
+ 'page': 'canvas-h:screen canvas-w:full',
977
+ 'hero': 'canvas-h:screen display:flex flex-dir:col align-yi:center align-x:center pad:xl',
978
+ 'hero-half': 'canvas-h:half display:flex flex-dir:col align-yi:center align-x:center pad:xl',
979
+ 'wrapper': 'canvas-w:full mar-x:auto pad-x:lg',
980
+ 'bleed': 'canvas-w:screen mar-x:auto',
981
+ 'inset': 'pad:md',
982
+ 'inset-sm': 'pad:sm',
983
+ 'inset-lg': 'pad:lg',
984
+ 'inset-xl': 'pad:xl',
985
+ 'inset-x': 'pad-x:md',
986
+ 'inset-y': 'pad-y:md',
987
+
988
+ // ── POSITIONING ─────────────────────────────────────────────
989
+ 'absolute-center': 'pos:absolute pos-top:50% pos-left:50%',
990
+ 'absolute-fill': 'pos:absolute pos-inset:0',
991
+ 'absolute-top': 'pos:absolute pos-top:0 pos-left:0 canvas-w:full',
992
+ 'absolute-bottom': 'pos:absolute pos-btm:0 pos-left:0 canvas-w:full',
993
+ 'fixed-top': 'pos:fixed pos-top:0 pos-left:0 canvas-w:full',
994
+ 'fixed-bottom': 'pos:fixed pos-btm:0 pos-left:0 canvas-w:full',
995
+ 'fixed-center': 'pos:fixed pos-top:50% pos-left:50%',
996
+ 'sticky-top': 'pos:sticky pos-top:0',
997
+ 'sticky-bottom': 'pos:sticky pos-btm:0',
998
+ 'overlay-fill': 'pos:absolute pos-inset:0 canvas-w:full canvas-h:full',
999
+
1000
+ // ── CARDS ────────────────────────────────────────────────────
1001
+ 'card': 'paint:surface pad:md curve:lg cast:md',
1002
+ 'card-sm': 'paint:surface pad:sm curve:md cast:sm',
1003
+ 'card-lg': 'paint:surface pad:lg curve:xl cast:lg',
1004
+ 'card-xl': 'paint:surface pad:xl curve:2xl cast:xl',
1005
+ 'card-elevated': 'paint:surface pad:md curve:lg cast:xl',
1006
+ 'card-flat': 'paint:surface pad:md curve:lg',
1007
+ 'card-hover': 'paint:surface pad:md curve:lg cast:md cursor:pointer',
1008
+ 'card-outline': 'pad:md curve:lg stroke-style:solid stroke-width:thin stroke-color:neutral-200',
1009
+ 'card-outline-hover': 'pad:md curve:lg stroke-style:solid stroke-width:thin stroke-color:neutral-300 cursor:pointer',
1010
+ 'card-ghost': 'pad:md curve:lg paint:neutral-50',
1011
+ 'card-glass': 'glass-blur:glass canvas-fade:soft curve:lg cast:md',
1012
+ 'card-dark': 'paint:neutral-900 pad:md curve:lg cast:dark-md',
1013
+ 'card-gradient': 'pad:md curve:lg cast:md overflow:hidden',
1014
+ 'card-feature': 'paint:surface pad:xl curve:2xl cast:lg display:flex flex-dir:col gap:lg',
1015
+ 'card-compact': 'paint:surface pad:sm curve:md cast:sm display:flex align-yi:center gap:md',
1016
+ 'card-media': 'paint:surface curve:lg cast:md overflow:hidden display:flex flex-dir:col',
1017
+ 'card-interactive': 'paint:surface pad:md curve:lg cast:md cursor:pointer select:none',
1018
+ 'card-pricing': 'paint:surface pad:xl curve:2xl cast:xl display:flex flex-dir:col gap:xl',
1019
+ 'card-stat': 'paint:surface pad:lg curve:xl cast:md display:flex flex-dir:col gap:sm',
1020
+ 'card-testimonial': 'paint:surface pad:xl curve:xl cast:md',
1021
+ 'card-profile': 'paint:surface pad:lg curve:xl cast:md display:flex flex-dir:col align-yi:center gap:md text-align:center',
1022
+ 'card-blog': 'paint:surface curve:xl cast:md overflow:hidden display:flex flex-dir:col',
1023
+ 'card-product': 'paint:surface curve:xl cast:md overflow:hidden display:flex flex-dir:col cursor:pointer',
1024
+ 'card-job': 'paint:surface pad:lg curve:xl cast:md display:flex gap:lg align-yi:start',
1025
+ 'card-notification': 'paint:surface pad:md curve:lg cast:sm display:flex gap:md align-yi:start',
1026
+ 'card-empty': 'paint:surface pad:2xl curve:xl cast:sm display:flex flex-dir:col align-yi:center align-x:center gap:lg text-align:center',
1027
+ 'card-success': 'paint:success-light pad:md curve:lg cast:sm',
1028
+ 'card-error': 'paint:error-light pad:md curve:lg cast:sm',
1029
+ 'card-warning': 'paint:warning-light pad:md curve:lg cast:sm',
1030
+ 'card-info': 'paint:info-light pad:md curve:lg cast:sm',
1031
+ 'panel': 'paint:surface cast:md curve:xl pad:lg',
1032
+ 'panel-sm': 'paint:surface cast:sm curve:lg pad:md',
1033
+ 'panel-lg': 'paint:surface cast:xl curve:2xl pad:xl',
1034
+
1035
+ // ── BUTTONS ──────────────────────────────────────────────────
1036
+ 'button': [
1037
+ 'display:flex-inline align-yi:center align-x:center',
1038
+ 'pad-y:sm pad-x:lg',
1039
+ 'curve:md cursor:pointer',
1040
+ 'type-weight:semi text:body',
1041
+ 'select:none',
1042
+ ].join(' '),
1043
+ 'btn-sm': 'button pad-y:xs pad-x:md text:sm',
1044
+ 'btn-md': 'button',
1045
+ 'btn-lg': 'button pad-y:md pad-x:xl text:lg',
1046
+ 'btn-xl': 'button pad-y:lg pad-x:2xl text:xl',
1047
+ 'btn-icon': 'display:flex-inline align-yi:center align-x:center pad:sm curve:md cursor:pointer select:none',
1048
+ 'btn-icon-sm': 'display:flex-inline align-yi:center align-x:center pad:xs curve:sm cursor:pointer select:none',
1049
+ 'btn-icon-lg': 'display:flex-inline align-yi:center align-x:center pad:md curve:lg cursor:pointer select:none',
1050
+ 'btn-icon-round': 'display:flex-inline align-yi:center align-x:center pad:sm curve:full cursor:pointer select:none',
1051
+ 'btn-full': 'button canvas-w:full',
1052
+ 'btn-primary': 'button paint:primary ink:white',
1053
+ 'btn-primary-sm': 'btn-sm paint:primary ink:white',
1054
+ 'btn-primary-lg': 'btn-lg paint:primary ink:white',
1055
+ 'btn-secondary': 'button paint:secondary ink:white',
1056
+ 'btn-accent': 'button paint:accent ink:white',
1057
+ 'btn-success': 'button paint:success ink:white',
1058
+ 'btn-error': 'button paint:error ink:white',
1059
+ 'btn-danger': 'button paint:error ink:white',
1060
+ 'btn-warning': 'button paint:warning ink:white',
1061
+ 'btn-info': 'button paint:info ink:white',
1062
+ 'btn-ghost': 'button stroke-style:solid stroke-width:thin stroke-color:primary ink:primary',
1063
+ 'btn-ghost-sm': 'btn-sm stroke-style:solid stroke-width:thin stroke-color:primary ink:primary',
1064
+ 'btn-ghost-secondary': 'button stroke-style:solid stroke-width:thin stroke-color:secondary ink:secondary',
1065
+ 'btn-ghost-neutral': 'button stroke-style:solid stroke-width:thin stroke-color:neutral-300 ink:neutral-700',
1066
+ 'btn-ghost-white': 'button stroke-style:solid stroke-width:thin stroke-color:white ink:white',
1067
+ 'btn-text': 'button ink:primary',
1068
+ 'btn-text-sm': 'btn-sm ink:primary',
1069
+ 'btn-text-neutral':'button ink:neutral-600',
1070
+ 'btn-neutral': 'button paint:neutral-100 ink:neutral-900',
1071
+ 'btn-neutral-sm': 'btn-sm paint:neutral-100 ink:neutral-900',
1072
+ 'btn-dark': 'button paint:neutral-900 ink:white',
1073
+ 'btn-white': 'button paint:white ink:neutral-900',
1074
+ 'btn-glass': 'button glass-blur:md canvas-fade:soft',
1075
+ 'btn-gradient': 'button ink:white',
1076
+ 'btn-link': 'ink:primary cursor:pointer type-weight:semi',
1077
+ 'btn-pill': 'button curve:full',
1078
+ 'btn-pill-primary':'button paint:primary ink:white curve:full',
1079
+ 'btn-square': 'button curve:none',
1080
+ 'btn-loading': 'button events:none canvas-fade:muted cursor:not-allowed',
1081
+ 'btn-disabled': 'button events:none canvas-fade:muted cursor:not-allowed',
1082
+
1083
+ // ── INPUTS & FORMS ───────────────────────────────────────────
1084
+ 'input': [
1085
+ 'pad:sm curve:md canvas-w:full',
1086
+ 'stroke-color:neutral-200 stroke-width:thin stroke-style:solid',
1087
+ 'type-face:sans text:body ink:neutral-900',
1088
+ 'paint:surface',
1089
+ ].join(' '),
1090
+ 'input-sm': 'input text:sm pad:xs',
1091
+ 'input-lg': 'input text:lg pad:md',
1092
+ 'input-ghost': 'pad:sm canvas-w:full type-face:sans text:body ink:neutral-900',
1093
+ 'input-flush': 'pad-y:sm canvas-w:full type-face:sans text:body stroke-y-end:neutral-200 stroke-style:solid stroke-width:thin',
1094
+ 'input-error': 'input stroke-color:error',
1095
+ 'input-success': 'input stroke-color:success',
1096
+ 'input-disabled': 'input events:none canvas-fade:muted paint:neutral-50 cursor:not-allowed',
1097
+ 'textarea': 'input canvas-h:auto leading:relaxed',
1098
+ 'textarea-sm': 'input-sm canvas-h:auto leading:relaxed',
1099
+ 'textarea-lg': 'input-lg canvas-h:auto leading:relaxed',
1100
+ 'select': 'input cursor:pointer',
1101
+ 'checkbox': 'cursor:pointer select:none',
1102
+ 'radio': 'cursor:pointer select:none',
1103
+ 'toggle': 'cursor:pointer select:none',
1104
+ 'label': 'text:label type-weight:semi ink:neutral-700',
1105
+ 'label-sm': 'text:xs type-weight:semi ink:neutral-600',
1106
+ 'label-error': 'text:xs ink:error',
1107
+ 'label-success': 'text:xs ink:success',
1108
+ 'field': 'display:flex flex-dir:col gap:xs',
1109
+ 'field-row': 'display:flex gap:md align-yi:center',
1110
+ 'field-group': 'display:flex flex-dir:col gap:md',
1111
+ 'input-group': 'display:flex align-yi:center',
1112
+ 'input-addon': 'display:flex-inline align-yi:center pad-x:sm paint:neutral-50 stroke-style:solid stroke-width:thin stroke-color:neutral-200',
1113
+ 'form': 'display:flex flex-dir:col gap:lg',
1114
+ 'form-sm': 'display:flex flex-dir:col gap:md',
1115
+ 'form-row': 'display:grid grid-cols:repeat(2,1fr) gap:md',
1116
+ 'form-actions': 'display:flex gap:sm align-yi:center align-x:end',
1117
+
1118
+ // ── NAVIGATION ───────────────────────────────────────────────
1119
+ 'nav': 'display:flex align-yi:center gap:md',
1120
+ 'nav-bar': 'display:flex align-yi:center align-x:between pad-x:xl pad-y:md paint:surface cast:sm',
1121
+ 'nav-bar-dark': 'display:flex align-yi:center align-x:between pad-x:xl pad-y:md paint:neutral-900',
1122
+ 'nav-bar-glass': 'display:flex align-yi:center align-x:between pad-x:xl pad-y:md glass-blur:md',
1123
+ 'nav-item': 'display:flex-inline align-yi:center pad-x:md pad-y:sm curve:md ink:neutral-600 cursor:pointer type-weight:medium text:sm',
1124
+ 'nav-item-active':'nav-item paint:primary-50 ink:primary-600',
1125
+ 'nav-link': 'ink:neutral-600 cursor:pointer type-weight:medium text:sm',
1126
+ 'nav-link-active':'ink:primary-600 type-weight:semi',
1127
+ 'nav-brand': 'display:flex-inline align-yi:center gap:sm type-weight:bold text:lg ink:neutral-900',
1128
+ 'nav-section': 'display:flex align-yi:center gap:xs',
1129
+ 'sidebar-nav': 'display:flex flex-dir:col gap:xs',
1130
+ 'sidebar-item': 'display:flex align-yi:center gap:md pad:sm curve:md ink:neutral-600 cursor:pointer type-weight:medium text:sm',
1131
+ 'sidebar-item-active': 'sidebar-item paint:primary-50 ink:primary-600',
1132
+ 'sidebar-section':'text:xs type-weight:bold tracking:widest text-case:upper ink:neutral-400 pad-x:sm pad-y:xs',
1133
+ 'breadcrumb': 'display:flex align-yi:center gap:xs text:sm ink:neutral-500',
1134
+ 'breadcrumb-item':'ink:neutral-500',
1135
+ 'breadcrumb-active': 'ink:neutral-900 type-weight:medium',
1136
+ 'tab-list': 'display:flex gap:xs stroke-y-end:neutral-200 stroke-style:solid stroke-width:thin',
1137
+ 'tab': 'pad-x:md pad-y:sm ink:neutral-500 cursor:pointer type-weight:medium text:sm',
1138
+ 'tab-active': 'ink:primary-600 type-weight:semi',
1139
+ 'tab-panel': 'pad:lg',
1140
+ 'tabs-pill': 'display:flex gap:xs paint:neutral-100 pad:xs curve:lg',
1141
+ 'tab-pill': 'pad-x:md pad-y:xs curve:md ink:neutral-600 cursor:pointer type-weight:medium text:sm',
1142
+ 'tab-pill-active':'pad-x:md pad-y:xs curve:md paint:white ink:neutral-900 cast:sm cursor:pointer type-weight:medium text:sm',
1143
+ 'menu': 'display:flex flex-dir:col pad:xs curve:md cast:lg paint:surface',
1144
+ 'menu-item': 'display:flex align-yi:center gap:sm pad-x:md pad-y:sm curve:md ink:neutral-700 cursor:pointer text:sm',
1145
+ 'menu-item-danger':'menu-item ink:error',
1146
+ 'menu-divider': 'stroke-y-start:neutral-100 stroke-style:solid stroke-width:thin mar-y:xs',
1147
+
1148
+ // ── TYPOGRAPHY PATTERNS ──────────────────────────────────────
1149
+ 'heading': 'text:h1 ink:ink type-face:sans type-weight:bold',
1150
+ 'heading-display':'text:display-xl ink:ink type-face:display type-weight:black tracking:tight',
1151
+ 'heading-lg': 'text:h1 ink:ink type-face:sans type-weight:bold',
1152
+ 'heading-md': 'text:h2 ink:ink type-face:sans type-weight:semi',
1153
+ 'heading-sm': 'text:h3 ink:ink type-face:sans type-weight:semi',
1154
+ 'heading-xs': 'text:h4 ink:ink type-face:sans type-weight:semi',
1155
+ 'subheading': 'text:h4 ink:neutral-500 type-face:sans',
1156
+ 'eyebrow': 'text:label type-weight:bold tracking:widest text-case:upper ink:primary',
1157
+ 'overline': 'text:xs type-weight:bold tracking:widest text-case:upper ink:neutral-400',
1158
+ 'caption': 'text:xs ink:neutral-500 leading:normal',
1159
+ 'text-muted': 'ink:neutral-500 text:small',
1160
+ 'text-subtle': 'ink:neutral-400 text:sm',
1161
+ 'text-faint': 'ink:neutral-300 text:xs',
1162
+ 'text-label': 'text:label type-weight:semi tracking:wide text-case:upper ink:neutral-500',
1163
+ 'text-link': 'ink:primary type-weight:medium cursor:pointer',
1164
+ 'text-link-muted':'ink:neutral-500 cursor:pointer',
1165
+ 'text-mono': 'type-face:mono text:code',
1166
+ 'text-code': 'type-face:mono text:xs paint:neutral-100 pad-x:xs pad-y:0 curve:sm ink:neutral-800',
1167
+ 'prose': 'text:body ink:ink leading:relaxed type-face:sans canvas-w-max:65ch',
1168
+ 'prose-sm': 'text:sm ink:ink leading:relaxed type-face:sans',
1169
+ 'prose-lg': 'text:lg ink:ink leading:relaxed type-face:sans',
1170
+ 'lead': 'text:xl ink:neutral-600 leading:relaxed',
1171
+ 'quote': 'text:xl ink:neutral-700 type-style:italic leading:relaxed',
1172
+ 'code-block': 'type-face:mono text:sm paint:neutral-900 ink:neutral-100 pad:lg curve:lg overflow:auto',
1173
+ 'kbd': 'type-face:mono text:xs paint:neutral-100 pad-x:xs curve:sm stroke-style:solid stroke-width:thin stroke-color:neutral-300 ink:neutral-700 cast:xs',
1174
+ 'strike': 'text-decor:strike',
1175
+ 'underline': 'text-decor:under',
1176
+ 'no-underline': 'text-decor:none',
1177
+ 'italic': 'type-style:italic',
1178
+ 'bold': 'type-weight:bold',
1179
+ 'truncate': 'overflow:hidden text-overflow:dots wrap:no',
1180
+ 'clamp-1': 'overflow:hidden text-overflow:dots wrap:no',
1181
+ 'clamp-2': 'overflow:hidden',
1182
+ 'clamp-3': 'overflow:hidden',
1183
+
1184
+ // ── BADGES & TAGS ────────────────────────────────────────────
1185
+ 'badge': 'display:flex-inline align-yi:center pad-y:0 pad-x:sm curve:full text:xs type-weight:semi',
1186
+ 'badge-sm': 'display:flex-inline align-yi:center pad-y:0 pad-x:xs curve:full text:2xs type-weight:semi',
1187
+ 'badge-lg': 'display:flex-inline align-yi:center pad-y:xs pad-x:md curve:full text:sm type-weight:semi',
1188
+ 'badge-primary': 'badge paint:primary-100 ink:primary-700',
1189
+ 'badge-secondary':'badge paint:secondary-100 ink:secondary-700',
1190
+ 'badge-accent': 'badge paint:accent-100 ink:accent-700',
1191
+ 'badge-success': 'badge paint:success-light ink:emerald-700',
1192
+ 'badge-error': 'badge paint:error-light ink:red-700',
1193
+ 'badge-warning': 'badge paint:warning-light ink:amber-700',
1194
+ 'badge-info': 'badge paint:info-light ink:blue-700',
1195
+ 'badge-neutral': 'badge paint:neutral-100 ink:neutral-700',
1196
+ 'badge-dark': 'badge paint:neutral-800 ink:white',
1197
+ 'badge-outline': 'badge stroke-style:solid stroke-width:thin stroke-color:primary ink:primary',
1198
+ 'badge-dot': 'display:flex-inline align-yi:center gap:xs pad-y:0 pad-x:sm curve:full text:xs type-weight:semi',
1199
+ 'tag': 'display:flex-inline align-yi:center gap:xs pad-y:xs pad-x:sm curve:md paint:neutral-100 ink:neutral-700 text:xs type-weight:medium cursor:pointer',
1200
+ 'tag-removable': 'tag gap:sm',
1201
+ 'pill': 'display:flex-inline align-yi:center pad-y:xs pad-x:md curve:full text:sm type-weight:medium',
1202
+ 'chip': 'display:flex-inline align-yi:center gap:sm pad-y:xs pad-x:md curve:full paint:neutral-100 ink:neutral-700 text:sm type-weight:medium cursor:pointer',
1203
+ 'chip-active': 'chip paint:primary-100 ink:primary-700',
1204
+
1205
+ // ── AVATAR & MEDIA ───────────────────────────────────────────
1206
+ 'avatar': 'canvas-w:md canvas-h:md curve:full overflow:hidden canvas-fit:cover display:flex-inline align-yi:center align-x:center',
1207
+ 'avatar-xs': 'canvas-w:sm canvas-h:sm curve:full overflow:hidden canvas-fit:cover',
1208
+ 'avatar-sm': 'canvas-w:md canvas-h:md curve:full overflow:hidden canvas-fit:cover',
1209
+ 'avatar-md': 'canvas-w:lg canvas-h:lg curve:full overflow:hidden canvas-fit:cover',
1210
+ 'avatar-lg': 'canvas-w:xl canvas-h:xl curve:full overflow:hidden canvas-fit:cover',
1211
+ 'avatar-xl': 'canvas-w:2xl canvas-h:2xl curve:full overflow:hidden canvas-fit:cover',
1212
+ 'avatar-square': 'canvas-w:md canvas-h:md curve:md overflow:hidden canvas-fit:cover',
1213
+ 'avatar-group': 'display:flex',
1214
+ 'avatar-initials':'canvas-w:md canvas-h:md curve:full display:flex align-yi:center align-x:center type-weight:semi text:sm',
1215
+ 'media': 'canvas-w:full overflow:hidden curve:lg',
1216
+ 'media-16-9': 'canvas-ratio:16_9 overflow:hidden',
1217
+ 'media-4-3': 'canvas-ratio:4_3 overflow:hidden',
1218
+ 'media-1-1': 'canvas-ratio:1_1 overflow:hidden',
1219
+ 'media-3-2': 'canvas-ratio:3_2 overflow:hidden',
1220
+ 'media-21-9': 'canvas-ratio:21_9 overflow:hidden',
1221
+ 'cover': 'canvas-w:full canvas-h:full canvas-fit:cover',
1222
+ 'contain': 'canvas-w:full canvas-h:full canvas-fit:contain',
1223
+ 'thumbnail': 'canvas-w:md canvas-h:md canvas-fit:cover curve:md overflow:hidden',
1224
+ 'thumbnail-lg': 'canvas-w:xl canvas-h:xl canvas-fit:cover curve:lg overflow:hidden',
1225
+ 'icon': 'canvas-w:md canvas-h:md display:flex-inline align-yi:center align-x:center',
1226
+ 'icon-sm': 'canvas-w:sm canvas-h:sm display:flex-inline align-yi:center align-x:center',
1227
+ 'icon-lg': 'canvas-w:lg canvas-h:lg display:flex-inline align-yi:center align-x:center',
1228
+ 'icon-xl': 'canvas-w:xl canvas-h:xl display:flex-inline align-yi:center align-x:center',
1229
+
1230
+ // ── MODALS & OVERLAYS ────────────────────────────────────────
1231
+ 'modal-backdrop': 'pos:fixed pos-inset:0 paint:black canvas-fade:muted display:flex align-yi:center align-x:center',
1232
+ 'modal': 'paint:surface cast:2xl curve:2xl pad:2xl canvas-w:full pos:relative',
1233
+ 'modal-sm': 'modal canvas-w-max:400px',
1234
+ 'modal-md': 'modal canvas-w-max:560px',
1235
+ 'modal-lg': 'modal canvas-w-max:720px',
1236
+ 'modal-xl': 'modal canvas-w-max:900px',
1237
+ 'modal-full': 'modal canvas-w:full canvas-h:screen curve:none',
1238
+ 'modal-header': 'display:flex align-yi:center align-x:between pad-btm:lg',
1239
+ 'modal-body': 'display:flex flex-dir:col gap:md',
1240
+ 'modal-footer': 'display:flex gap:sm align-yi:center align-x:end pad-top:lg',
1241
+ 'drawer': 'pos:fixed pos-top:0 pos-right:0 canvas-h:screen canvas-w:full paint:surface cast:2xl display:flex flex-dir:col',
1242
+ 'drawer-sm': 'drawer canvas-w-max:320px',
1243
+ 'drawer-md': 'drawer canvas-w-max:420px',
1244
+ 'drawer-lg': 'drawer canvas-w-max:560px',
1245
+ 'drawer-header': 'display:flex align-yi:center align-x:between pad:lg stroke-y-end:neutral-100 stroke-style:solid stroke-width:thin',
1246
+ 'drawer-body': 'display:flex flex-dir:col gap:md pad:lg overflow-y:auto',
1247
+ 'drawer-footer': 'display:flex gap:sm align-x:end pad:lg stroke-y-start:neutral-100 stroke-style:solid stroke-width:thin',
1248
+ 'popup': 'paint:surface cast:xl curve:xl pad:md pos:absolute display:flex flex-dir:col gap:sm',
1249
+ 'tooltip': 'paint:neutral-900 ink:white pad-y:xs pad-x:sm curve:md text:xs type-weight:medium',
1250
+ 'tooltip-light': 'paint:white cast:lg ink:neutral-800 pad-y:xs pad-x:sm curve:md text:xs type-weight:medium',
1251
+ 'popover': 'paint:surface cast:xl curve:xl pad:md pos:absolute canvas-w-max:320px display:flex flex-dir:col gap:sm',
1252
+ 'sheet': 'paint:surface cast:2xl pad:2xl display:flex flex-dir:col gap:lg',
1253
+ 'overlay': 'pos:absolute pos-inset:0 paint:black canvas-fade:muted',
1254
+ 'overlay-light': 'pos:absolute pos-inset:0 paint:white canvas-fade:ghost',
1255
+ 'overlay-blur': 'pos:absolute pos-inset:0 glass-blur:md',
1256
+ 'overlay-gradient': 'pos:absolute pos-inset:0',
1257
+ 'scrim': 'pos:fixed pos-inset:0 paint:black canvas-fade:muted events:none',
1258
+
1259
+ // ── ALERTS & FEEDBACK ────────────────────────────────────────
1260
+ 'alert': 'display:flex gap:md pad:md curve:lg stroke-style:solid stroke-width:thin',
1261
+ 'alert-info': 'alert paint:info-light stroke-color:info ink:info-dark',
1262
+ 'alert-success': 'alert paint:success-light stroke-color:success ink:success-dark',
1263
+ 'alert-error': 'alert paint:error-light stroke-color:error ink:error-dark',
1264
+ 'alert-warning': 'alert paint:warning-light stroke-color:warning ink:warning-dark',
1265
+ 'alert-neutral': 'alert paint:neutral-50 stroke-color:neutral-200 ink:neutral-800',
1266
+ 'alert-dark': 'alert paint:neutral-900 stroke-color:neutral-700 ink:white',
1267
+ 'toast': 'paint:surface cast:xl curve:xl pad:md display:flex gap:md align-yi:start canvas-w-max:400px',
1268
+ 'toast-success': 'toast stroke-style:solid stroke-width:base stroke-color:success',
1269
+ 'toast-error': 'toast stroke-style:solid stroke-width:base stroke-color:error',
1270
+ 'toast-warning': 'toast stroke-style:solid stroke-width:base stroke-color:warning',
1271
+ 'toast-info': 'toast stroke-style:solid stroke-width:base stroke-color:info',
1272
+ 'banner': 'canvas-w:full pad:md display:flex align-yi:center align-x:between',
1273
+ 'banner-primary': 'banner paint:primary ink:white',
1274
+ 'banner-warning': 'banner paint:warning ink:white',
1275
+ 'banner-error': 'banner paint:error ink:white',
1276
+ 'callout': 'pad:lg curve:xl stroke-style:solid stroke-width:base',
1277
+ 'callout-info': 'callout paint:info-light stroke-color:info-300',
1278
+ 'callout-warning':'callout paint:warning-light stroke-color:amber-300',
1279
+ 'callout-tip': 'callout paint:emerald-50 stroke-color:emerald-300',
1280
+ 'notice': 'pad:sm curve:md text:sm',
1281
+ 'notice-info': 'notice paint:info-light ink:blue-700',
1282
+ 'notice-warning': 'notice paint:warning-light ink:amber-700',
1283
+ 'empty-state': 'display:flex flex-dir:col align-yi:center align-x:center gap:md pad:2xl text-align:center',
1284
+ 'error-state': 'display:flex flex-dir:col align-yi:center align-x:center gap:sm pad:2xl text-align:center',
1285
+ 'loading-state': 'display:flex align-yi:center align-x:center pad:2xl',
1286
+
1287
+ // ── PROGRESS & LOADING ───────────────────────────────────────
1288
+ 'progress-bar': 'canvas-w:full canvas-h:2 paint:neutral-100 curve:full overflow:hidden',
1289
+ 'progress-fill': 'canvas-h:full paint:primary curve:full',
1290
+ 'progress-sm': 'canvas-w:full canvas-h:1 paint:neutral-100 curve:full overflow:hidden',
1291
+ 'progress-lg': 'canvas-w:full canvas-h:3 paint:neutral-100 curve:full overflow:hidden',
1292
+ 'spinner': 'canvas-w:md canvas-h:md curve:full stroke-style:solid stroke-width:base stroke-color:primary',
1293
+ 'spinner-sm': 'canvas-w:sm canvas-h:sm curve:full stroke-style:solid stroke-width:thin stroke-color:primary',
1294
+ 'spinner-lg': 'canvas-w:lg canvas-h:lg curve:full stroke-style:solid stroke-width:thick stroke-color:primary',
1295
+ 'skeleton': 'paint:neutral-200 curve:md overflow:hidden pos:relative',
1296
+ 'skeleton-text': 'canvas-h:3 paint:neutral-200 curve:full',
1297
+ 'skeleton-title': 'canvas-h:5 paint:neutral-200 curve:full',
1298
+ 'skeleton-avatar':'canvas-w:md canvas-h:md paint:neutral-200 curve:full',
1299
+ 'skeleton-card': 'paint:neutral-200 curve:lg canvas-h:2xl',
1300
+ 'loader': 'display:flex align-yi:center align-x:center gap:sm',
1301
+ 'dot-loader': 'display:flex align-yi:center gap:xs',
1302
+ 'dot': 'canvas-w:2 canvas-h:2 curve:full paint:current',
1303
+ 'pulse': 'paint:neutral-200 curve:md',
1304
+
1305
+ // ── SURFACE VARIANTS ─────────────────────────────────────────
1306
+ 'surface': 'paint:surface cast:sm curve:md',
1307
+ 'surface-sm': 'paint:surface cast:xs curve:sm',
1308
+ 'surface-lg': 'paint:surface cast:lg curve:xl',
1309
+ 'surface-raised': 'paint:surface cast:xl curve:xl',
1310
+ 'surface-sunken': 'paint:neutral-50 curve:md',
1311
+ 'surface-tinted': 'paint:primary-50 curve:md',
1312
+ 'surface-dark': 'paint:neutral-900 curve:md',
1313
+ 'surface-glass': 'glass-blur:md canvas-fade:soft curve:md',
1314
+ 'glass': 'glass-blur:md canvas-fade:soft',
1315
+ 'glass-sm': 'glass-blur:sm canvas-fade:soft',
1316
+ 'glass-lg': 'glass-blur:xl canvas-fade:soft',
1317
+ 'glass-card': 'glass-blur:glass canvas-fade:soft curve:lg cast:md',
1318
+ 'glass-dark': 'glass-blur:md canvas-fade:strong paint:neutral-900',
1319
+ 'frosted': 'glass-blur:heavy canvas-fade:soft',
1320
+ 'matte': 'paint:white canvas-fade:muted',
1321
+ 'mirror': 'paint:white canvas-fade:ghost',
1322
+
1323
+ // ── LISTS & DATA ─────────────────────────────────────────────
1324
+ 'list': 'display:flex flex-dir:col',
1325
+ 'list-sm': 'display:flex flex-dir:col gap:xs',
1326
+ 'list-md': 'display:flex flex-dir:col gap:sm',
1327
+ 'list-lg': 'display:flex flex-dir:col gap:md',
1328
+ 'list-divided': 'display:flex flex-dir:col',
1329
+ 'list-item': 'display:flex align-yi:center gap:md pad-y:sm',
1330
+ 'list-item-divided': 'list-item stroke-y-end:neutral-100 stroke-style:solid stroke-width:thin',
1331
+ 'list-item-action': 'list-item cursor:pointer',
1332
+ 'list-item-sm': 'display:flex align-yi:center gap:sm pad-y:xs text:sm',
1333
+ 'list-ordered': 'display:flex flex-dir:col gap:xs',
1334
+ 'data-list': 'display:flex flex-dir:col gap:sm',
1335
+ 'data-item': 'display:flex align-x:between align-yi:baseline gap:md',
1336
+ 'data-label': 'text:sm ink:neutral-500',
1337
+ 'data-value': 'text:sm ink:neutral-900 type-weight:medium',
1338
+ 'dl-term': 'text:sm type-weight:semi ink:neutral-500',
1339
+ 'dl-def': 'text:sm ink:neutral-900',
1340
+
1341
+ // ── TABLES ───────────────────────────────────────────────────
1342
+ 'table': 'canvas-w:full cast:sm curve:lg overflow:hidden',
1343
+ 'table-header': 'paint:neutral-50 stroke-y-end:neutral-200 stroke-style:solid stroke-width:thin',
1344
+ 'table-th': 'pad:sm text:xs type-weight:bold tracking:wide text-case:upper ink:neutral-500 text-align:left',
1345
+ 'table-row': 'stroke-y-end:neutral-100 stroke-style:solid stroke-width:thin',
1346
+ 'table-row-hover':'stroke-y-end:neutral-100 stroke-style:solid stroke-width:thin cursor:pointer',
1347
+ 'table-td': 'pad:sm text:sm ink:neutral-800',
1348
+ 'table-td-action':'pad:sm display:flex align-yi:center gap:sm',
1349
+ 'table-foot': 'paint:neutral-50 stroke-y-start:neutral-200 stroke-style:solid stroke-width:thin',
1350
+
1351
+ // ── DIVIDERS & SEPARATORS ────────────────────────────────────
1352
+ 'divider': 'stroke-y-start:neutral-200 stroke-style:solid stroke-width:thin',
1353
+ 'divider-strong': 'stroke-y-start:neutral-400 stroke-style:solid stroke-width:thin',
1354
+ 'divider-subtle': 'stroke-y-start:neutral-100 stroke-style:solid stroke-width:thin',
1355
+ 'divider-dark': 'stroke-y-start:neutral-700 stroke-style:solid stroke-width:thin',
1356
+ 'divider-x': 'stroke-x-start:neutral-200 stroke-style:solid stroke-width:thin',
1357
+ 'divider-label': 'display:flex align-yi:center gap:md text:xs ink:neutral-400 type-weight:semi',
1358
+ 'hr': 'canvas-w:full stroke-y-start:neutral-200 stroke-style:solid stroke-width:thin',
1359
+ 'rule': 'paint:neutral-200 canvas-h:px canvas-w:full',
1360
+ 'spacer': 'display:block',
1361
+
1362
+ // ── UTILITIES ────────────────────────────────────────────────
1363
+ 'sr-only': 'pos:absolute canvas-w:1px canvas-h:1px overflow:hidden events:none',
1364
+ 'not-sr-only': 'pos:static canvas-w:auto canvas-h:auto overflow:visible',
1365
+ 'clearfix': 'display:flow-root',
1366
+ 'isolate': 'pos:relative',
1367
+ 'reset': 'mar:0 pad:0',
1368
+ 'box-border': 'canvas-box:border',
1369
+ 'box-content': 'canvas-box:content',
1370
+ 'select-none': 'select:none',
1371
+ 'select-all': 'select:all',
1372
+ 'select-text': 'select:text',
1373
+ 'pointer': 'cursor:pointer',
1374
+ 'not-allowed': 'cursor:not-allowed events:none',
1375
+ 'no-events': 'events:none',
1376
+ 'no-wrap': 'wrap:no',
1377
+ 'break-word': 'word-break:break-word',
1378
+ 'antialiased': 'type-smooth:anti',
1379
+ 'subpixel': 'type-smooth:sub',
1380
+
1381
+ // ── INTERACTIVE STATES ───────────────────────────────────────
1382
+ 'interactive': 'cursor:pointer select:none',
1383
+ 'hoverable': 'cursor:pointer',
1384
+ 'pressable': 'cursor:pointer select:none',
1385
+ 'draggable': 'cursor:grab select:none',
1386
+ 'dragging': 'cursor:grabbing',
1387
+ 'disabled': 'events:none canvas-fade:muted cursor:not-allowed',
1388
+ 'clickable': 'cursor:pointer',
1389
+
1390
+ // ── GRADIENT HELPERS ─────────────────────────────────────────
1391
+ 'gradient-primary': 'ink:transparent',
1392
+ 'gradient-sunset': 'ink:transparent',
1393
+ 'gradient-ocean': 'ink:transparent',
1394
+ 'gradient-forest': 'ink:transparent',
1395
+ 'gradient-midnight': 'ink:transparent',
1396
+ 'gradient-aurora': 'ink:transparent',
1397
+ 'gradient-candy': 'ink:transparent',
1398
+ 'gradient-fire': 'ink:transparent',
1399
+
1400
+ // ── SPECIAL EFFECTS ──────────────────────────────────────────
1401
+ 'glow': 'cast:glow-md',
1402
+ 'glow-sm': 'cast:glow-sm',
1403
+ 'glow-lg': 'cast:glow-lg',
1404
+ 'glow-primary': 'cast:primary',
1405
+ 'glow-secondary': 'cast:secondary',
1406
+ 'glow-success': 'cast:success',
1407
+ 'glow-error': 'cast:error',
1408
+ 'ring': 'stroke-style:solid stroke-width:base stroke-color:primary',
1409
+ 'ring-sm': 'stroke-style:solid stroke-width:thin stroke-color:primary',
1410
+ 'ring-thick': 'stroke-style:solid stroke-width:thick stroke-color:primary',
1411
+ 'ring-focus': 'stroke-style:solid stroke-width:base stroke-color:primary',
1412
+ 'ring-error': 'stroke-style:solid stroke-width:base stroke-color:error',
1413
+ 'ring-success': 'stroke-style:solid stroke-width:base stroke-color:success',
1414
+ 'inset-ring': 'cast:inner',
1415
+ 'shadow-none': 'cast:none',
1416
+ 'shadow-sm': 'cast:sm',
1417
+ 'shadow-md': 'cast:md',
1418
+ 'shadow-lg': 'cast:lg',
1419
+ 'shadow-xl': 'cast:xl',
1420
+ 'shadow-2xl': 'cast:2xl',
1421
+
1422
+ // ── MISC COMPONENTS ──────────────────────────────────────────
1423
+ 'kpi': 'display:flex flex-dir:col gap:xs',
1424
+ 'kpi-value': 'text:h2 type-weight:bold ink:neutral-900',
1425
+ 'kpi-label': 'text:sm ink:neutral-500',
1426
+ 'kpi-change': 'display:flex-inline align-yi:center gap:xs text:xs type-weight:semi',
1427
+ 'kpi-up': 'kpi-change ink:success',
1428
+ 'kpi-down': 'kpi-change ink:error',
1429
+ 'stat': 'display:flex flex-dir:col gap:xs',
1430
+ 'stat-value': 'text:h3 type-weight:bold ink:neutral-900',
1431
+ 'stat-label': 'text:xs ink:neutral-500 type-weight:medium',
1432
+ 'feature': 'display:flex flex-dir:col gap:md',
1433
+ 'feature-icon': 'display:flex align-yi:center align-x:center canvas-w:xl canvas-h:xl curve:xl paint:primary-50 ink:primary',
1434
+ 'feature-title': 'text:h5 type-weight:semi ink:neutral-900',
1435
+ 'feature-desc': 'text:body ink:neutral-600 leading:relaxed',
1436
+ 'testimonial': 'display:flex flex-dir:col gap:lg',
1437
+ 'testimonial-body':'text:lg ink:neutral-700 type-style:italic leading:relaxed',
1438
+ 'testimonial-author': 'display:flex align-yi:center gap:md',
1439
+ 'pricing-tier': 'display:flex flex-dir:col gap:lg',
1440
+ 'pricing-header': 'display:flex flex-dir:col gap:sm',
1441
+ 'pricing-amount': 'display:flex align-yi:end gap:xs',
1442
+ 'pricing-price': 'text:h1 type-weight:bold ink:neutral-900',
1443
+ 'pricing-period': 'text:body ink:neutral-500',
1444
+ 'pricing-features': 'display:flex flex-dir:col gap:sm',
1445
+ 'pricing-feature': 'display:flex align-yi:start gap:sm text:sm ink:neutral-700',
1446
+ 'timeline': 'display:flex flex-dir:col gap:md pos:relative',
1447
+ 'timeline-item': 'display:flex gap:md pos:relative',
1448
+ 'timeline-dot': 'canvas-w:sm canvas-h:sm curve:full paint:primary pos:relative',
1449
+ 'timeline-line': 'pos:absolute',
1450
+ 'faq': 'display:flex flex-dir:col gap:0',
1451
+ 'faq-item': 'stroke-y-end:neutral-200 stroke-style:solid stroke-width:thin pad-y:md',
1452
+ 'faq-question': 'display:flex align-x:between align-yi:center cursor:pointer text:body type-weight:semi ink:neutral-900',
1453
+ 'faq-answer': 'text:body ink:neutral-600 leading:relaxed',
1454
+ 'step': 'display:flex gap:md',
1455
+ 'step-number': 'canvas-w:md canvas-h:md curve:full paint:primary ink:white display:flex-inline align-yi:center align-x:center type-weight:bold text:sm',
1456
+ 'step-content': 'display:flex flex-dir:col gap:xs flex-grow:1',
1457
+ },
1458
+
1459
+ // ============================================================
1460
+ // ANIMATIONS
1461
+ // ============================================================
1462
+ animations: {
1463
+
1464
+ // ── ENTRANCE — FADE ──────────────────────────────────────────
1465
+ 'animate-fade-in': { from: { opacity: 0 }, to: { opacity: 1 }, duration: 0.5, ease: 'power2.out' },
1466
+ 'animate-fade-out': { from: { opacity: 1 }, to: { opacity: 0 }, duration: 0.4, ease: 'power2.in' },
1467
+ 'animate-fade-in-fast': { from: { opacity: 0 }, to: { opacity: 1 }, duration: 0.15, ease: 'power2.out' },
1468
+ 'animate-fade-in-slow': { from: { opacity: 0 }, to: { opacity: 1 }, duration: 1.0, ease: 'power2.out' },
1469
+ 'animate-fade-in-down': { from: { opacity: 0, y: -20 }, to: { opacity: 1, y: 0 }, duration: 0.5, ease: 'power2.out' },
1470
+ 'animate-fade-in-up': { from: { opacity: 0, y: 20 }, to: { opacity: 1, y: 0 }, duration: 0.5, ease: 'power2.out' },
1471
+ 'animate-fade-in-left': { from: { opacity: 0, x: -20 }, to: { opacity: 1, x: 0 }, duration: 0.5, ease: 'power2.out' },
1472
+ 'animate-fade-in-right': { from: { opacity: 0, x: 20 }, to: { opacity: 1, x: 0 }, duration: 0.5, ease: 'power2.out' },
1473
+
1474
+ // ── ENTRANCE — SLIDE ─────────────────────────────────────────
1475
+ 'animate-slide-up': { from: { y: 60, opacity: 0 }, to: { y: 0, opacity: 1 }, duration: 0.4, ease: 'power2.out' },
1476
+ 'animate-slide-up-sm': { from: { y: 20, opacity: 0 }, to: { y: 0, opacity: 1 }, duration: 0.3, ease: 'power2.out' },
1477
+ 'animate-slide-up-lg': { from: { y: 120, opacity: 0 }, to: { y: 0, opacity: 1 }, duration: 0.6, ease: 'power3.out' },
1478
+ 'animate-slide-down': { from: { y: -60, opacity: 0 }, to: { y: 0, opacity: 1 }, duration: 0.4, ease: 'power2.out' },
1479
+ 'animate-slide-down-sm': { from: { y: -20, opacity: 0 }, to: { y: 0, opacity: 1 }, duration: 0.3, ease: 'power2.out' },
1480
+ 'animate-slide-left': { from: { x: 80, opacity: 0 }, to: { x: 0, opacity: 1 }, duration: 0.4, ease: 'power2.out' },
1481
+ 'animate-slide-left-sm': { from: { x: 30, opacity: 0 }, to: { x: 0, opacity: 1 }, duration: 0.3, ease: 'power2.out' },
1482
+ 'animate-slide-right': { from: { x: -80, opacity: 0 }, to: { x: 0, opacity: 1 }, duration: 0.4, ease: 'power2.out' },
1483
+ 'animate-slide-right-sm': { from: { x: -30, opacity: 0 }, to: { x: 0, opacity: 1 }, duration: 0.3, ease: 'power2.out' },
1484
+ 'animate-slide-in-top': { from: { y: '-100%', opacity: 0 }, to: { y: '0%', opacity: 1 }, duration: 0.5, ease: 'power3.out' },
1485
+ 'animate-slide-in-bottom': { from: { y: '100%', opacity: 0 }, to: { y: '0%', opacity: 1 }, duration: 0.5, ease: 'power3.out' },
1486
+ 'animate-slide-in-left': { from: { x: '-100%', opacity: 0 }, to: { x: '0%', opacity: 1 }, duration: 0.5, ease: 'power3.out' },
1487
+ 'animate-slide-in-right': { from: { x: '100%', opacity: 0 }, to: { x: '0%', opacity: 1 }, duration: 0.5, ease: 'power3.out' },
1488
+
1489
+ // ── ENTRANCE — SCALE ─────────────────────────────────────────
1490
+ 'animate-scale-in': { from: { scale: 0, opacity: 0 }, to: { scale: 1, opacity: 1 }, duration: 0.4, ease: 'back.out(1.7)' },
1491
+ 'animate-scale-in-sm': { from: { scale: 0.8, opacity: 0 }, to: { scale: 1, opacity: 1 }, duration: 0.3, ease: 'power2.out' },
1492
+ 'animate-scale-in-lg': { from: { scale: 0.5, opacity: 0 }, to: { scale: 1, opacity: 1 }, duration: 0.5, ease: 'back.out(1.4)' },
1493
+ 'animate-scale-out': { from: { scale: 1, opacity: 1 }, to: { scale: 0, opacity: 0 }, duration: 0.3, ease: 'power2.in' },
1494
+ 'animate-scale-out-sm': { from: { scale: 1, opacity: 1 }, to: { scale: 0.8, opacity: 0 }, duration: 0.2, ease: 'power2.in' },
1495
+ 'animate-scale-x-in': { from: { scaleX: 0, opacity: 0 }, to: { scaleX: 1, opacity: 1 }, duration: 0.4, ease: 'power2.out' },
1496
+ 'animate-scale-y-in': { from: { scaleY: 0, opacity: 0 }, to: { scaleY: 1, opacity: 1 }, duration: 0.4, ease: 'power2.out' },
1497
+ 'animate-zoom-in': { from: { scale: 1.2, opacity: 0 }, to: { scale: 1, opacity: 1 }, duration: 0.5, ease: 'power2.out' },
1498
+ 'animate-zoom-out': { from: { scale: 0.8, opacity: 0 }, to: { scale: 1, opacity: 1 }, duration: 0.5, ease: 'power2.out' },
1499
+ 'animate-pop': { from: { scale: 0.5, opacity: 0 }, to: { scale: 1, opacity: 1 }, duration: 0.5, ease: 'elastic.out(1,0.5)' },
1500
+ 'animate-pop-sm': { from: { scale: 0.8, opacity: 0 }, to: { scale: 1, opacity: 1 }, duration: 0.4, ease: 'elastic.out(1,0.6)' },
1501
+ 'animate-balloon': { from: { scale: 0, opacity: 0 }, to: { scale: 1, opacity: 1 }, duration: 0.7, ease: 'elastic.out(1,0.4)' },
1502
+ 'animate-shrink-in': { from: { scale: 1.5, opacity: 0 }, to: { scale: 1, opacity: 1 }, duration: 0.5, ease: 'power3.out' },
1503
+
1504
+ // ── ENTRANCE — ROTATE & FLIP ──────────────────────────────────
1505
+ 'animate-flip-in': { from: { rotationY: -90, opacity: 0 }, to: { rotationY: 0, opacity: 1 }, duration: 0.5, ease: 'back.out(1.4)' },
1506
+ 'animate-flip-in-x': { from: { rotationX: -90, opacity: 0 }, to: { rotationX: 0, opacity: 1 }, duration: 0.5, ease: 'back.out(1.4)' },
1507
+ 'animate-flip-in-y': { from: { rotationY: -90, opacity: 0 }, to: { rotationY: 0, opacity: 1 }, duration: 0.5, ease: 'back.out(1.4)' },
1508
+ 'animate-flip-down': { from: { rotationX: 90, opacity: 0 }, to: { rotationX: 0, opacity: 1 }, duration: 0.5, ease: 'power3.out' },
1509
+ 'animate-spin-in': { from: { rotation: -180, scale: 0, opacity: 0 }, to: { rotation: 0, scale: 1, opacity: 1 }, duration: 0.6, ease: 'back.out(1.4)' },
1510
+ 'animate-spin-in-fast': { from: { rotation: -90, opacity: 0 }, to: { rotation: 0, opacity: 1 }, duration: 0.4, ease: 'power3.out' },
1511
+ 'animate-roll-in': { from: { rotation: -20, x: -60, opacity: 0 }, to: { rotation: 0, x: 0, opacity: 1 }, duration: 0.5, ease: 'power2.out' },
1512
+ 'animate-tilt-in': { from: { rotationZ: -10, opacity: 0 }, to: { rotationZ: 0, opacity: 1 }, duration: 0.5, ease: 'back.out(1.2)' },
1513
+ 'animate-tilt-in-right': { from: { rotationZ: 10, opacity: 0 }, to: { rotationZ: 0, opacity: 1 }, duration: 0.5, ease: 'back.out(1.2)' },
1514
+
1515
+ // ── ENTRANCE — BLUR ───────────────────────────────────────────
1516
+ 'animate-blur-in': { from: { filter: 'blur(12px)', opacity: 0 }, to: { filter: 'blur(0px)', opacity: 1 }, duration: 0.6, ease: 'power2.out' },
1517
+ 'animate-blur-in-sm': { from: { filter: 'blur(6px)', opacity: 0 }, to: { filter: 'blur(0px)', opacity: 1 }, duration: 0.4, ease: 'power2.out' },
1518
+ 'animate-blur-in-lg': { from: { filter: 'blur(24px)', opacity: 0 }, to: { filter: 'blur(0px)', opacity: 1 }, duration: 0.8, ease: 'power2.out' },
1519
+ 'animate-blur-out': { from: { filter: 'blur(0px)', opacity: 1 }, to: { filter: 'blur(12px)', opacity: 0 }, duration: 0.4, ease: 'power2.in' },
1520
+ 'animate-sharpen': { from: { filter: 'blur(20px) saturate(0)', opacity: 0 }, to: { filter: 'blur(0) saturate(1)', opacity: 1 }, duration: 0.8, ease: 'power2.out' },
1521
+ 'animate-unblur': { from: { filter: 'blur(8px)', opacity: 0.5 }, to: { filter: 'blur(0)', opacity: 1 }, duration: 0.5, ease: 'power2.out' },
1522
+
1523
+ // ── ENTRANCE — CLIP & REVEAL ──────────────────────────────────
1524
+ 'animate-clip-up': { from: { clipPath: 'inset(100% 0 0 0)', opacity: 1 }, to: { clipPath: 'inset(0% 0 0 0)', opacity: 1 }, duration: 0.6, ease: 'power3.out' },
1525
+ 'animate-clip-down': { from: { clipPath: 'inset(0 0 100% 0)', opacity: 1 }, to: { clipPath: 'inset(0% 0 0 0)', opacity: 1 }, duration: 0.6, ease: 'power3.out' },
1526
+ 'animate-clip-left': { from: { clipPath: 'inset(0 100% 0 0)', opacity: 1 }, to: { clipPath: 'inset(0% 0 0 0)', opacity: 1 }, duration: 0.6, ease: 'power3.out' },
1527
+ 'animate-clip-right': { from: { clipPath: 'inset(0 0 0 100%)', opacity: 1 }, to: { clipPath: 'inset(0% 0 0 0)', opacity: 1 }, duration: 0.6, ease: 'power3.out' },
1528
+ 'animate-wipe-in': { from: { scaleX: 0, transformOrigin: 'left' }, to: { scaleX: 1 }, duration: 0.5, ease: 'power3.out' },
1529
+ 'animate-wipe-in-right': { from: { scaleX: 0, transformOrigin: 'right' }, to: { scaleX: 1 }, duration: 0.5, ease: 'power3.out' },
1530
+ 'animate-curtain': { from: { scaleY: 0, transformOrigin: 'top' }, to: { scaleY: 1 }, duration: 0.5, ease: 'power3.out' },
1531
+ 'animate-curtain-up': { from: { scaleY: 0, transformOrigin: 'bottom' }, to: { scaleY: 1 }, duration: 0.5, ease: 'power3.out' },
1532
+
1533
+ // ── ENTRANCE — BOUNCE & SPRING ────────────────────────────────
1534
+ 'animate-bounce-in': { from: { y: -60, opacity: 0 }, to: { y: 0, opacity: 1 }, duration: 0.8, ease: 'bounce.out' },
1535
+ 'animate-bounce-in-up': { from: { y: 60, opacity: 0 }, to: { y: 0, opacity: 1 }, duration: 0.8, ease: 'bounce.out' },
1536
+ 'animate-bounce-in-left': { from: { x: -80, opacity: 0 }, to: { x: 0, opacity: 1 }, duration: 0.8, ease: 'bounce.out' },
1537
+ 'animate-bounce-in-right': { from: { x: 80, opacity: 0 }, to: { x: 0, opacity: 1 }, duration: 0.8, ease: 'bounce.out' },
1538
+ 'animate-bounce-in-scale': { from: { scale: 0.3, opacity: 0 }, to: { scale: 1, opacity: 1 }, duration: 0.8, ease: 'bounce.out' },
1539
+ 'animate-spring-in': { from: { scale: 0.5, opacity: 0 }, to: { scale: 1, opacity: 1 }, duration: 0.7, ease: 'elastic.out(1,0.4)' },
1540
+ 'animate-spring-up': { from: { y: 80, opacity: 0 }, to: { y: 0, opacity: 1 }, duration: 0.7, ease: 'elastic.out(1,0.5)' },
1541
+ 'animate-spring-down': { from: { y: -80, opacity: 0 }, to: { y: 0, opacity: 1 }, duration: 0.7, ease: 'elastic.out(1,0.5)' },
1542
+ 'animate-elastic-in': { from: { scaleX: 1.4, scaleY: 0.6, opacity: 0 }, to: { scaleX: 1, scaleY: 1, opacity: 1 }, duration: 0.6, ease: 'elastic.out(1,0.5)' },
1543
+
1544
+ // ── ENTRANCE — SPECIAL ────────────────────────────────────────
1545
+ 'animate-typewriter': { from: { width: '0%' }, to: { width: '100%' }, duration: 1.5, ease: 'none' },
1546
+ 'animate-draw': { from: { strokeDashoffset: '100%' }, to: { strokeDashoffset: '0%' }, duration: 1.0, ease: 'power2.inOut' },
1547
+ 'animate-morph-in': { from: { borderRadius: '50%', scale: 0.3, opacity: 0 }, to: { borderRadius: '0%', scale: 1, opacity: 1 }, duration: 0.6, ease: 'power3.out' },
1548
+ 'animate-glitch-in': { from: { skewX: -10, opacity: 0, x: -10 }, to: { skewX: 0, opacity: 1, x: 0 }, duration: 0.4, ease: 'power4.out' },
1549
+ 'animate-spotlight': { from: { clipPath: 'circle(0% at 50% 50%)', opacity: 0 }, to: { clipPath: 'circle(100% at 50% 50%)', opacity: 1 }, duration: 0.7, ease: 'power2.out' },
1550
+ 'animate-rise': { from: { y: 40, opacity: 0, scale: 0.95 }, to: { y: 0, opacity: 1, scale: 1 }, duration: 0.6, ease: 'power3.out' },
1551
+ 'animate-drop': { from: { y: -40, opacity: 0, scale: 0.95 }, to: { y: 0, opacity: 1, scale: 1 }, duration: 0.6, ease: 'power3.out' },
1552
+ 'animate-materialize': { from: { opacity: 0, scale: 0.9, filter: 'blur(8px)' }, to: { opacity: 1, scale: 1, filter: 'blur(0px)' }, duration: 0.7, ease: 'power2.out' },
1553
+ 'animate-dissolve-in': { from: { opacity: 0, filter: 'blur(4px) saturate(0)' }, to: { opacity: 1, filter: 'blur(0) saturate(1)' }, duration: 0.8, ease: 'power2.out' },
1554
+ 'animate-perspective-in': { from: { rotationX: 40, opacity: 0, z: -200 }, to: { rotationX: 0, opacity: 1, z: 0 }, duration: 0.7, ease: 'power3.out' },
1555
+ 'animate-swoop-in': { from: { y: 100, rotation: 5, opacity: 0 }, to: { y: 0, rotation: 0, opacity: 1 }, duration: 0.6, ease: 'power3.out' },
1556
+ 'animate-swoop-left': { from: { x: 100, rotation: -5, opacity: 0 }, to: { x: 0, rotation: 0, opacity: 1 }, duration: 0.6, ease: 'power3.out' },
1557
+ 'animate-swoosh': { from: { x: -120, skewX: 15, opacity: 0 }, to: { x: 0, skewX: 0, opacity: 1 }, duration: 0.5, ease: 'power3.out' },
1558
+ 'animate-slam': { from: { y: -80, scale: 1.1, opacity: 0 }, to: { y: 0, scale: 1, opacity: 1 }, duration: 0.4, ease: 'power4.out' },
1559
+ 'animate-unfurl': { from: { scaleX: 0, opacity: 0 }, to: { scaleX: 1, opacity: 1 }, duration: 0.5, ease: 'power2.out' },
1560
+ 'animate-unfurl-y': { from: { scaleY: 0, opacity: 0 }, to: { scaleY: 1, opacity: 1 }, duration: 0.5, ease: 'power2.out' },
1561
+ 'animate-levitate': { from: { y: 30, opacity: 0, scale: 0.97 }, to: { y: 0, opacity: 1, scale: 1 }, duration: 0.8, ease: 'power2.out' },
1562
+
1563
+ // ── HOVER ANIMATIONS ─────────────────────────────────────────
1564
+ 'hover-lift': { hover: { y: -8, duration: 0.2, ease: 'power2.out' } },
1565
+ 'hover-lift-sm': { hover: { y: -4, duration: 0.15, ease: 'power2.out' } },
1566
+ 'hover-lift-lg': { hover: { y: -12, duration: 0.25, ease: 'power2.out' } },
1567
+ 'hover-sink': { hover: { y: 4, duration: 0.15, ease: 'power2.out' } },
1568
+ 'hover-float': { hover: { y: -6, duration: 0.3, ease: 'power1.inOut' } },
1569
+ 'hover-scale': { hover: { scale: 1.05, duration: 0.2, ease: 'power2.out' } },
1570
+ 'hover-scale-sm': { hover: { scale: 1.02, duration: 0.15, ease: 'power2.out' } },
1571
+ 'hover-scale-lg': { hover: { scale: 1.1, duration: 0.25, ease: 'back.out(1.5)' } },
1572
+ 'hover-scale-xl': { hover: { scale: 1.15, duration: 0.3, ease: 'back.out(1.7)' } },
1573
+ 'hover-shrink': { hover: { scale: 0.97, duration: 0.15, ease: 'power2.out' } },
1574
+ 'hover-grow': { hover: { scale: 1.08, duration: 0.2, ease: 'back.out(1.5)' } },
1575
+ 'hover-glow': { hover: { boxShadow: '0 0 24px rgba(59,130,246,0.5)', duration: 0.2 } },
1576
+ 'hover-glow-sm': { hover: { boxShadow: '0 0 12px rgba(59,130,246,0.3)', duration: 0.15 } },
1577
+ 'hover-glow-lg': { hover: { boxShadow: '0 0 48px rgba(59,130,246,0.6)', duration: 0.25 } },
1578
+ 'hover-glow-primary': { hover: { boxShadow: '0 0 24px rgba(59,130,246,0.5)', duration: 0.2 } },
1579
+ 'hover-glow-secondary': { hover: { boxShadow: '0 0 24px rgba(139,92,246,0.5)', duration: 0.2 } },
1580
+ 'hover-glow-accent': { hover: { boxShadow: '0 0 24px rgba(217,70,239,0.5)', duration: 0.2 } },
1581
+ 'hover-glow-success': { hover: { boxShadow: '0 0 24px rgba(16,185,129,0.5)', duration: 0.2 } },
1582
+ 'hover-glow-error': { hover: { boxShadow: '0 0 24px rgba(239,68,68,0.5)', duration: 0.2 } },
1583
+ 'hover-shadow-lg': { hover: { boxShadow: '0 20px 40px rgba(0,0,0,0.15)', y: -4, duration: 0.25, ease: 'power2.out' } },
1584
+ 'hover-bright': { hover: { filter: 'brightness(1.08)', duration: 0.15 } },
1585
+ 'hover-dim': { hover: { filter: 'brightness(0.9)', duration: 0.15 } },
1586
+ 'hover-saturate': { hover: { filter: 'saturate(1.3)', duration: 0.2 } },
1587
+ 'hover-rotate': { hover: { rotation: 5, duration: 0.2, ease: 'power2.out' } },
1588
+ 'hover-rotate-sm': { hover: { rotation: 2, duration: 0.15, ease: 'power2.out' } },
1589
+ 'hover-rotate-lg': { hover: { rotation: 15, duration: 0.25, ease: 'back.out' } },
1590
+ 'hover-tilt': { hover: { rotationY: 10, duration: 0.3, ease: 'power2.out' } },
1591
+ 'hover-tilt-left': { hover: { rotationY: -10, duration: 0.3, ease: 'power2.out' } },
1592
+ 'hover-skew': { hover: { skewX: 5, duration: 0.2, ease: 'power2.out' } },
1593
+ 'hover-blur': { hover: { filter: 'blur(2px)', duration: 0.15 } },
1594
+ 'hover-unblur': { hover: { filter: 'blur(0px)', duration: 0.15 } },
1595
+ 'hover-spin': { hover: { rotation: 360, duration: 0.6, ease: 'power2.out' } },
1596
+ 'hover-bob': { hover: { y: -4, duration: 0.3, ease: 'power1.inOut', yoyo: true, repeat: 1 } },
1597
+ 'hover-pulse': { hover: { scale: 1.05, duration: 0.2, ease: 'power1.inOut', yoyo: true, repeat: 1 } },
1598
+ 'hover-shake': { hover: { x: 3, duration: 0.05, ease: 'none', yoyo: true, repeat: 6 } },
1599
+ 'hover-wobble': { hover: { rotation: 5, duration: 0.1, ease: 'none', yoyo: true, repeat: 5 } },
1600
+ 'hover-jello': { hover: { scaleX: 1.15, scaleY: 0.85, duration: 0.1, ease: 'power2.out', yoyo: true, repeat: 3 } },
1601
+ 'hover-heartbeat': { hover: { scale: 1.15, duration: 0.1, ease: 'power2.out', yoyo: true, repeat: 3 } },
1602
+ 'hover-underline': { hover: { textDecorationLine: 'underline', duration: 0.1 } },
1603
+ 'hover-fade': { hover: { opacity: 0.7, duration: 0.2 } },
1604
+ 'hover-fade-strong': { hover: { opacity: 0.4, duration: 0.2 } },
1605
+ 'hover-x': { hover: { x: 4, duration: 0.2, ease: 'power2.out' } },
1606
+ 'hover-x-sm': { hover: { x: 2, duration: 0.15, ease: 'power2.out' } },
1607
+ 'hover-x-lg': { hover: { x: 8, duration: 0.25, ease: 'power2.out' } },
1608
+ 'hover-x-neg': { hover: { x: -4, duration: 0.2, ease: 'power2.out' } },
1609
+
1610
+ // ── ACTIVE ANIMATIONS ─────────────────────────────────────────
1611
+ 'active-press': { active: { scale: 0.95, duration: 0.08, ease: 'power2.inOut' } },
1612
+ 'active-press-sm': { active: { scale: 0.97, duration: 0.07, ease: 'power2.inOut' } },
1613
+ 'active-press-lg': { active: { scale: 0.9, duration: 0.1, ease: 'power2.inOut' } },
1614
+ 'active-press-xl': { active: { scale: 0.85, duration: 0.1, ease: 'power3.inOut' } },
1615
+ 'active-bounce': { active: { scale: 0.9, duration: 0.1, ease: 'back.out(2)' } },
1616
+ 'active-bounce-sm': { active: { scale: 0.95, duration: 0.08, ease: 'back.out(2)' } },
1617
+ 'active-push': { active: { y: 2, duration: 0.08, ease: 'power2.inOut' } },
1618
+ 'active-push-sm': { active: { y: 1, duration: 0.06, ease: 'power2.inOut' } },
1619
+ 'active-push-lg': { active: { y: 4, duration: 0.1, ease: 'power2.inOut' } },
1620
+ 'active-inset': { active: { scale: 0.92, boxShadow: 'inset 0 3px 8px rgba(0,0,0,0.2)', duration: 0.1 } },
1621
+ 'active-dim': { active: { opacity: 0.8, duration: 0.08 } },
1622
+ 'active-dim-strong': { active: { opacity: 0.6, duration: 0.08 } },
1623
+ 'active-highlight': { active: { filter: 'brightness(1.1)', duration: 0.08 } },
1624
+ 'active-darken': { active: { filter: 'brightness(0.85)', duration: 0.08 } },
1625
+ 'active-rotate': { active: { rotation: 90, duration: 0.15, ease: 'power2.out' } },
1626
+ 'active-spin': { active: { rotation: 180, duration: 0.2, ease: 'power2.out' } },
1627
+ 'active-shake': { active: { x: 3, duration: 0.05, ease: 'none', yoyo: true, repeat: 4 } },
1628
+ 'active-click': { active: { scale: 0.93, duration: 0.05, ease: 'power4.inOut', yoyo: true, repeat: 1 } },
1629
+
1630
+ // ── SCROLL TRIGGER ANIMATIONS ─────────────────────────────────
1631
+ 'scroll-trigger': { scrollTrigger: { trigger: 'self', start: 'top 80%', toggleActions: 'play none none reverse' } },
1632
+ 'scroll-trigger-top': { scrollTrigger: { trigger: 'self', start: 'top 90%', toggleActions: 'play none none none' } },
1633
+ 'scroll-trigger-mid': { scrollTrigger: { trigger: 'self', start: 'top 60%', toggleActions: 'play none none reverse' } },
1634
+ 'scroll-trigger-late':{ scrollTrigger: { trigger: 'self', start: 'top 40%', toggleActions: 'play none none reverse' } },
1635
+
1636
+ 'scroll-fade-in': { from: { opacity: 0, y: 30 }, to: { opacity: 1, y: 0 }, duration: 0.7, ease: 'power2.out', scrollTrigger: { trigger: 'self', start: 'top 85%' } },
1637
+ 'scroll-fade-up': { from: { opacity: 0, y: 50 }, to: { opacity: 1, y: 0 }, duration: 0.7, ease: 'power3.out', scrollTrigger: { trigger: 'self', start: 'top 85%' } },
1638
+ 'scroll-fade-down': { from: { opacity: 0, y: -50 }, to: { opacity: 1, y: 0 }, duration: 0.7, ease: 'power3.out', scrollTrigger: { trigger: 'self', start: 'top 85%' } },
1639
+ 'scroll-fade-left': { from: { opacity: 0, x: 60 }, to: { opacity: 1, x: 0 }, duration: 0.7, ease: 'power3.out', scrollTrigger: { trigger: 'self', start: 'top 85%' } },
1640
+ 'scroll-fade-right': { from: { opacity: 0, x: -60 }, to: { opacity: 1, x: 0 }, duration: 0.7, ease: 'power3.out', scrollTrigger: { trigger: 'self', start: 'top 85%' } },
1641
+ 'scroll-fade-in-sm': { from: { opacity: 0, y: 15 }, to: { opacity: 1, y: 0 }, duration: 0.5, ease: 'power2.out', scrollTrigger: { trigger: 'self', start: 'top 88%' } },
1642
+ 'scroll-fade-in-lg': { from: { opacity: 0, y: 80 }, to: { opacity: 1, y: 0 }, duration: 0.9, ease: 'power3.out', scrollTrigger: { trigger: 'self', start: 'top 80%' } },
1643
+
1644
+ 'scroll-slide-up': { from: { y: 80, opacity: 0 }, to: { y: 0, opacity: 1 }, duration: 0.7, ease: 'power3.out', scrollTrigger: { trigger: 'self', start: 'top 85%' } },
1645
+ 'scroll-slide-down': { from: { y: -80, opacity: 0 }, to: { y: 0, opacity: 1 }, duration: 0.7, ease: 'power3.out', scrollTrigger: { trigger: 'self', start: 'top 85%' } },
1646
+ 'scroll-slide-left': { from: { x: 80, opacity: 0 }, to: { x: 0, opacity: 1 }, duration: 0.7, ease: 'power3.out', scrollTrigger: { trigger: 'self', start: 'top 85%' } },
1647
+ 'scroll-slide-right': { from: { x: -80, opacity: 0 }, to: { x: 0, opacity: 1 }, duration: 0.7, ease: 'power3.out', scrollTrigger: { trigger: 'self', start: 'top 85%' } },
1648
+ 'scroll-slide-up-lg': { from: { y: 150, opacity: 0 }, to: { y: 0, opacity: 1 }, duration: 1.0, ease: 'power3.out', scrollTrigger: { trigger: 'self', start: 'top 80%' } },
1649
+
1650
+ 'scroll-scale-in': { from: { scale: 0.85, opacity: 0 }, to: { scale: 1, opacity: 1 }, duration: 0.7, ease: 'power2.out', scrollTrigger: { trigger: 'self', start: 'top 85%' } },
1651
+ 'scroll-scale-in-sm': { from: { scale: 0.95, opacity: 0 }, to: { scale: 1, opacity: 1 }, duration: 0.5, ease: 'power2.out', scrollTrigger: { trigger: 'self', start: 'top 88%' } },
1652
+ 'scroll-scale-out': { from: { scale: 1.1, opacity: 0 }, to: { scale: 1, opacity: 1 }, duration: 0.6, ease: 'power2.out', scrollTrigger: { trigger: 'self', start: 'top 85%' } },
1653
+ 'scroll-pop': { from: { scale: 0.5, opacity: 0 }, to: { scale: 1, opacity: 1 }, duration: 0.7, ease: 'back.out(1.7)', scrollTrigger: { trigger: 'self', start: 'top 85%' } },
1654
+ 'scroll-spring': { from: { scale: 0.7, opacity: 0 }, to: { scale: 1, opacity: 1 }, duration: 0.8, ease: 'elastic.out(1,0.5)', scrollTrigger: { trigger: 'self', start: 'top 85%' } },
1655
+
1656
+ 'scroll-blur-in': { from: { filter: 'blur(12px)', opacity: 0 }, to: { filter: 'blur(0)', opacity: 1 }, duration: 0.8, ease: 'power2.out', scrollTrigger: { trigger: 'self', start: 'top 85%' } },
1657
+ 'scroll-rise': { from: { y: 40, opacity: 0, scale: 0.95 }, to: { y: 0, opacity: 1, scale: 1 }, duration: 0.8, ease: 'power3.out', scrollTrigger: { trigger: 'self', start: 'top 85%' } },
1658
+ 'scroll-flip-in': { from: { rotationX: 60, opacity: 0, z: -100 }, to: { rotationX: 0, opacity: 1, z: 0 }, duration: 0.8, ease: 'power3.out', scrollTrigger: { trigger: 'self', start: 'top 85%' } },
1659
+ 'scroll-clip-up': { from: { clipPath: 'inset(100% 0 0 0)' }, to: { clipPath: 'inset(0%)' }, duration: 0.7, ease: 'power3.out', scrollTrigger: { trigger: 'self', start: 'top 85%' } },
1660
+ 'scroll-materialize': { from: { opacity: 0, scale: 0.9, filter: 'blur(8px)' }, to: { opacity: 1, scale: 1, filter: 'blur(0)' }, duration: 0.9, ease: 'power2.out', scrollTrigger: { trigger: 'self', start: 'top 85%' } },
1661
+
1662
+ // ── SCROLL SCRUB (parallax) ────────────────────────────────────
1663
+ 'scroll-scrub': { scrollTrigger: { trigger: 'self', start: 'top bottom', end: 'bottom top', scrub: true } },
1664
+ 'scroll-scrub-fast': { scrollTrigger: { trigger: 'self', start: 'top bottom', end: 'bottom top', scrub: 0.3 } },
1665
+ 'scroll-scrub-slow': { scrollTrigger: { trigger: 'self', start: 'top bottom', end: 'bottom top', scrub: 2 } },
1666
+ 'scroll-parallax-y': { from: { y: '-20%' }, to: { y: '20%' }, scrollTrigger: { trigger: 'self', start: 'top bottom', end: 'bottom top', scrub: true } },
1667
+ 'scroll-parallax-up': { from: { y: '0%' }, to: { y: '-30%' }, scrollTrigger: { trigger: 'self', start: 'top bottom', end: 'bottom top', scrub: true } },
1668
+ 'scroll-parallax-dn': { from: { y: '0%' }, to: { y: '30%' }, scrollTrigger: { trigger: 'self', start: 'top bottom', end: 'bottom top', scrub: true } },
1669
+ 'scroll-parallax-x': { from: { x: '-10%' }, to: { x: '10%' }, scrollTrigger: { trigger: 'self', start: 'top bottom', end: 'bottom top', scrub: true } },
1670
+ 'scroll-parallax-scale': { from: { scale: 1.0 }, to: { scale: 1.2 }, scrollTrigger: { trigger: 'self', start: 'top bottom', end: 'bottom top', scrub: true } },
1671
+ 'scroll-parallax-rotate': { from: { rotation: 0 }, to: { rotation: 30 }, scrollTrigger: { trigger: 'self', start: 'top bottom', end: 'bottom top', scrub: true } },
1672
+ 'scroll-parallax-fade': { from: { opacity: 1 }, to: { opacity: 0 }, scrollTrigger: { trigger: 'self', start: 'top 30%', end: 'bottom 0%', scrub: true } },
1673
+ 'scroll-pin': { scrollTrigger: { trigger: 'self', start: 'top top', end: '+=300%', pin: true, scrub: true } },
1674
+ 'scroll-pin-sm': { scrollTrigger: { trigger: 'self', start: 'top top', end: '+=100%', pin: true, scrub: true } },
1675
+ 'scroll-zoom': { from: { scale: 1 }, to: { scale: 1.3 }, scrollTrigger: { trigger: 'self', start: 'top center', end: 'bottom top', scrub: true } },
1676
+ 'scroll-zoom-out': { from: { scale: 1.3 }, to: { scale: 1 }, scrollTrigger: { trigger: 'self', start: 'top bottom', end: 'center center', scrub: true } },
1677
+ 'scroll-rotate-scrub':{ from: { rotation: -10 }, to: { rotation: 10 }, scrollTrigger: { trigger: 'self', start: 'top bottom', end: 'bottom top', scrub: true } },
1678
+ 'scroll-unblur': { from: { filter: 'blur(10px)', opacity: 0 }, to: { filter: 'blur(0)', opacity: 1 }, scrollTrigger: { trigger: 'self', start: 'top 80%', end: 'top 40%', scrub: true } },
1679
+ 'scroll-brightness': { from: { filter: 'brightness(0.5)' }, to: { filter: 'brightness(1)' }, scrollTrigger: { trigger: 'self', start: 'top bottom', end: 'center center', scrub: true } },
1680
+
1681
+ // ── STAGGER ANIMATIONS ────────────────────────────────────────
1682
+ 'stagger-fade': { targets: 'children', stagger: 0.08, from: { opacity: 0 }, to: { opacity: 1 } },
1683
+ 'stagger-fade-fast': { targets: 'children', stagger: 0.04, from: { opacity: 0 }, to: { opacity: 1 } },
1684
+ 'stagger-fade-slow': { targets: 'children', stagger: 0.15, from: { opacity: 0 }, to: { opacity: 1 } },
1685
+ 'stagger-up': { targets: 'children', stagger: 0.08, from: { opacity: 0, y: 20 }, to: { opacity: 1, y: 0 } },
1686
+ 'stagger-up-sm': { targets: 'children', stagger: 0.05, from: { opacity: 0, y: 10 }, to: { opacity: 1, y: 0 } },
1687
+ 'stagger-up-lg': { targets: 'children', stagger: 0.12, from: { opacity: 0, y: 40 }, to: { opacity: 1, y: 0 } },
1688
+ 'stagger-down': { targets: 'children', stagger: 0.08, from: { opacity: 0, y: -20 }, to: { opacity: 1, y: 0 } },
1689
+ 'stagger-left': { targets: 'children', stagger: 0.08, from: { opacity: 0, x: 20 }, to: { opacity: 1, x: 0 } },
1690
+ 'stagger-right': { targets: 'children', stagger: 0.08, from: { opacity: 0, x: -20 }, to: { opacity: 1, x: 0 } },
1691
+ 'stagger-scale': { targets: 'children', stagger: 0.08, from: { opacity: 0, scale: 0.8 }, to: { opacity: 1, scale: 1 } },
1692
+ 'stagger-scale-fast': { targets: 'children', stagger: 0.04, from: { opacity: 0, scale: 0.9 }, to: { opacity: 1, scale: 1 } },
1693
+ 'stagger-pop': { targets: 'children', stagger: 0.08, from: { opacity: 0, scale: 0.5 }, to: { opacity: 1, scale: 1 }, ease: 'back.out(1.7)' },
1694
+ 'stagger-blur': { targets: 'children', stagger: 0.08, from: { opacity: 0, filter: 'blur(8px)' }, to: { opacity: 1, filter: 'blur(0)' } },
1695
+ 'stagger-flip': { targets: 'children', stagger: 0.08, from: { opacity: 0, rotationY: -60 }, to: { opacity: 1, rotationY: 0 } },
1696
+ 'stagger-rise': { targets: 'children', stagger: 0.1, from: { opacity: 0, y: 30, scale: 0.95 }, to: { opacity: 1, y: 0, scale: 1 } },
1697
+ 'stagger-children-50': { targets: 'children', stagger: 0.05, from: { opacity: 0, y: 10 }, to: { opacity: 1, y: 0 } },
1698
+ 'stagger-children-100': { targets: 'children', stagger: 0.1, from: { opacity: 0, y: 20 }, to: { opacity: 1, y: 0 } },
1699
+ 'stagger-children-150': { targets: 'children', stagger: 0.15, from: { opacity: 0, y: 20 }, to: { opacity: 1, y: 0 } },
1700
+ 'stagger-children-200': { targets: 'children', stagger: 0.2, from: { opacity: 0, y: 30 }, to: { opacity: 1, y: 0 } },
1701
+
1702
+ // ── STAGGER + SCROLL ──────────────────────────────────────────
1703
+ 'scroll-stagger-up': { targets: 'children', stagger: 0.1, from: { opacity: 0, y: 30 }, to: { opacity: 1, y: 0 }, scrollTrigger: { trigger: 'self', start: 'top 80%' } },
1704
+ 'scroll-stagger-fade': { targets: 'children', stagger: 0.08, from: { opacity: 0 }, to: { opacity: 1 }, scrollTrigger: { trigger: 'self', start: 'top 80%' } },
1705
+ 'scroll-stagger-left': { targets: 'children', stagger: 0.1, from: { opacity: 0, x: 40 }, to: { opacity: 1, x: 0 }, scrollTrigger: { trigger: 'self', start: 'top 80%' } },
1706
+ 'scroll-stagger-right': { targets: 'children', stagger: 0.1, from: { opacity: 0, x: -40 }, to: { opacity: 1, x: 0 }, scrollTrigger: { trigger: 'self', start: 'top 80%' } },
1707
+ 'scroll-stagger-scale': { targets: 'children', stagger: 0.1, from: { opacity: 0, scale: 0.8 }, to: { opacity: 1, scale: 1 }, scrollTrigger: { trigger: 'self', start: 'top 80%' } },
1708
+ 'scroll-stagger-pop': { targets: 'children', stagger: 0.1, from: { opacity: 0, scale: 0.5 }, to: { opacity: 1, scale: 1 }, ease: 'back.out(1.7)', scrollTrigger: { trigger: 'self', start: 'top 80%' } },
1709
+ 'scroll-stagger-flip': { targets: 'children', stagger: 0.1, from: { opacity: 0, rotationY: -60 }, to: { opacity: 1, rotationY: 0 }, scrollTrigger: { trigger: 'self', start: 'top 80%' } },
1710
+ 'scroll-stagger-blur': { targets: 'children', stagger: 0.08, from: { opacity: 0, filter: 'blur(8px)' }, to: { opacity: 1, filter: 'blur(0)' }, scrollTrigger: { trigger: 'self', start: 'top 80%' } },
1711
+
1712
+ // ── GESTURE ANIMATIONS ────────────────────────────────────────
1713
+ 'gesture-press': { active: { scale: 0.94, duration: 0.08, ease: 'power2.out' } },
1714
+ 'gesture-press-hard': { active: { scale: 0.88, duration: 0.06, ease: 'power3.out' } },
1715
+ 'gesture-press-light': { active: { scale: 0.97, duration: 0.07, ease: 'power2.out' } },
1716
+ 'gesture-push': { active: { y: 2, scale: 0.98, duration: 0.08, ease: 'power2.out' } },
1717
+ 'gesture-push-sm': { active: { y: 1, scale: 0.99, duration: 0.06, ease: 'power2.out' } },
1718
+ 'gesture-push-lg': { active: { y: 4, scale: 0.95, duration: 0.1, ease: 'power2.out' } },
1719
+ 'gesture-click': { active: { scale: 0.92, boxShadow: 'inset 0 4px 8px rgba(0,0,0,0.15)', duration: 0.06, ease: 'power3.out' } },
1720
+ 'gesture-click-bounce': { active: { scale: 0.9, duration: 0.08, ease: 'back.out(3)' } },
1721
+ 'gesture-tap': { active: { opacity: 0.7, scale: 0.96, duration: 0.05, ease: 'power2.inOut' } },
1722
+ 'gesture-tap-ripple': { active: { scale: 0.95, duration: 0.08 } },
1723
+ 'gesture-hold': { active: { scale: 1.0, boxShadow: '0 0 0 3px rgba(59,130,246,0.4)', duration: 0.3, ease: 'power2.out' } },
1724
+ 'gesture-hold-grow': { active: { scale: 1.05, duration: 0.5, ease: 'power1.out' } },
1725
+
1726
+ // Drag
1727
+ 'gesture-drag': { active: { scale: 1.05, boxShadow: '0 20px 40px rgba(0,0,0,0.2)', rotation: 3, duration: 0.15, ease: 'power2.out' } },
1728
+ 'gesture-drag-flat': { active: { scale: 1.02, boxShadow: '0 8px 20px rgba(0,0,0,0.15)', duration: 0.12 } },
1729
+ 'gesture-drag-ghost': { active: { opacity: 0.6, scale: 1.05, duration: 0.12 } },
1730
+ 'gesture-drag-snap': { active: { scale: 1.08, rotation: 2, boxShadow: '0 24px 48px rgba(0,0,0,0.2)', duration: 0.15 } },
1731
+ 'gesture-drag-rotate': { active: { rotation: 5, scale: 1.05, duration: 0.15, ease: 'power2.out' } },
1732
+
1733
+ // Swipe
1734
+ 'gesture-swipe-left': { active: { x: -6, opacity: 0.8, duration: 0.1, ease: 'power2.out' } },
1735
+ 'gesture-swipe-right': { active: { x: 6, opacity: 0.8, duration: 0.1, ease: 'power2.out' } },
1736
+ 'gesture-swipe-up': { active: { y: -6, opacity: 0.8, duration: 0.1, ease: 'power2.out' } },
1737
+ 'gesture-swipe-down': { active: { y: 6, opacity: 0.8, duration: 0.1, ease: 'power2.out' } },
1738
+ 'gesture-swipe-dismiss': { active: { x: 100, opacity: 0, duration: 0.3, ease: 'power3.in' } },
1739
+ 'gesture-swipe-dismiss-left': { active: { x: -100, opacity: 0, duration: 0.3, ease: 'power3.in' } },
1740
+ 'gesture-swipe-reveal': { active: { x: 80, duration: 0.25, ease: 'power2.out' } },
1741
+
1742
+ // Pinch
1743
+ 'gesture-pinch-in': { active: { scale: 0.85, duration: 0.2, ease: 'power2.out' } },
1744
+ 'gesture-pinch-out': { active: { scale: 1.15, duration: 0.2, ease: 'power2.out' } },
1745
+ 'gesture-pinch-zoom': { active: { scale: 1.2, duration: 0.3, ease: 'power2.out' } },
1746
+ 'gesture-pinch-close': { active: { scale: 0.8, opacity: 0, duration: 0.3, ease: 'power2.in' } },
1747
+
1748
+ // Pull
1749
+ 'gesture-pull-down': { active: { y: 12, scale: 0.98, duration: 0.15, ease: 'power1.out' } },
1750
+ 'gesture-pull-up': { active: { y: -12, scale: 0.98, duration: 0.15, ease: 'power1.out' } },
1751
+ 'gesture-pull-left': { active: { x: -12, scale: 0.98, duration: 0.15, ease: 'power1.out' } },
1752
+ 'gesture-pull-right': { active: { x: 12, scale: 0.98, duration: 0.15, ease: 'power1.out' } },
1753
+ 'gesture-pull-to-refresh': { active: { y: 40, scale: 0.95, duration: 0.3, ease: 'power2.out' } },
1754
+ 'gesture-pull-stretch': { active: { scaleY: 1.08, duration: 0.2, ease: 'power1.out' } },
1755
+ 'gesture-pull-rubber': { active: { y: 20, scaleY: 1.05, duration: 0.2, ease: 'power1.out' } },
1756
+
1757
+ // Long press
1758
+ 'gesture-longpress': { active: { scale: 0.96, duration: 0.5, ease: 'power1.in' } },
1759
+ 'gesture-longpress-shake': { active: { x: 2, duration: 0.08, ease: 'none', yoyo: true, repeat: 8 } },
1760
+ 'gesture-longpress-glow': { active: { boxShadow: '0 0 20px rgba(59,130,246,0.6)', scale: 1.02, duration: 0.5 } },
1761
+ 'gesture-longpress-pulse': { active: { scale: 1.04, duration: 0.4, ease: 'power1.inOut', yoyo: true, repeat: 3 } },
1762
+
1763
+ // Focus
1764
+ 'gesture-focus': { hover: { boxShadow: '0 0 0 3px rgba(59,130,246,0.4)', duration: 0.15 } },
1765
+ 'gesture-focus-outline': { hover: { boxShadow: '0 0 0 4px rgba(59,130,246,0.3)', outline: 'none', duration: 0.15 } },
1766
+ 'gesture-focus-glow': { hover: { boxShadow: '0 0 0 3px rgba(59,130,246,0.5), 0 0 12px rgba(59,130,246,0.3)', duration: 0.15 } },
1767
+ 'gesture-focus-lift': { hover: { y: -2, boxShadow: '0 0 0 3px rgba(59,130,246,0.4), 0 8px 16px rgba(0,0,0,0.1)', duration: 0.2 } },
1768
+
1769
+ // Hover — pointer-specific
1770
+ 'gesture-hover-lift': { hover: { y: -6, boxShadow: '0 12px 24px rgba(0,0,0,0.12)', duration: 0.2, ease: 'power2.out' } },
1771
+ 'gesture-hover-sink': { hover: { y: 3, duration: 0.15, ease: 'power2.out' } },
1772
+ 'gesture-hover-scale': { hover: { scale: 1.04, duration: 0.2, ease: 'power2.out' } },
1773
+ 'gesture-hover-tilt': { hover: { rotationX: 8, rotationY: 8, duration: 0.3, ease: 'power2.out' } },
1774
+ 'gesture-hover-glow': { hover: { boxShadow: '0 0 30px rgba(59,130,246,0.4)', duration: 0.2 } },
1775
+ 'gesture-hover-reveal': { hover: { opacity: 1, duration: 0.15, ease: 'power2.out' } },
1776
+ 'gesture-hover-hide': { hover: { opacity: 0, duration: 0.15, ease: 'power2.out' } },
1777
+ 'gesture-hover-x': { hover: { x: 4, duration: 0.2, ease: 'power2.out' } },
1778
+ 'gesture-hover-x-neg': { hover: { x: -4, duration: 0.2, ease: 'power2.out' } },
1779
+ 'gesture-hover-bob': { hover: { y: -4, duration: 0.4, ease: 'sine.inOut', yoyo: true, repeat: -1 } },
1780
+ 'gesture-hover-spin': { hover: { rotation: 360, duration: 0.6, ease: 'power2.out' } },
1781
+ 'gesture-hover-flip': { hover: { rotationY: 180, duration: 0.4, ease: 'power2.inOut' } },
1782
+ 'gesture-hover-wiggle': { hover: { rotation: 5, duration: 0.1, ease: 'none', yoyo: true, repeat: 5 } },
1783
+ 'gesture-hover-pulse': { hover: { scale: 1.06, duration: 0.3, ease: 'power1.inOut', yoyo: true, repeat: -1 } },
1784
+ 'gesture-hover-breathe': { hover: { scale: 1.03, duration: 0.8, ease: 'sine.inOut', yoyo: true, repeat: -1 } },
1785
+ 'gesture-hover-shake': { hover: { x: 4, duration: 0.06, ease: 'none', yoyo: true, repeat: 8 } },
1786
+
1787
+ // Keyboard
1788
+ 'gesture-key-press': { active: { y: 2, scale: 0.97, duration: 0.05 } },
1789
+ 'gesture-key-return': { active: { y: 0, scale: 1.0, duration: 0.15, ease: 'back.out(2)' } },
1790
+
1791
+ // Scroll gesture
1792
+ 'gesture-scroll-highlight': { scrollTrigger: { trigger: 'self', start: 'top 70%', end: 'top 30%', scrub: true }, from: { opacity: 0.3 }, to: { opacity: 1 } },
1793
+ 'gesture-scroll-dim': { scrollTrigger: { trigger: 'self', start: 'bottom 70%', end: 'bottom 30%', scrub: true }, from: { opacity: 1 }, to: { opacity: 0.3 } },
1794
+ 'gesture-scroll-rise': { scrollTrigger: { trigger: 'self', start: 'top 80%', end: 'top 20%', scrub: true }, from: { y: 30, opacity: 0 }, to: { y: 0, opacity: 1 } },
1795
+
1796
+ // Magnetic
1797
+ 'gesture-magnetic': { hover: { scale: 1.06, duration: 0.3, ease: 'power2.out' } },
1798
+ 'gesture-magnetic-strong': { hover: { scale: 1.12, duration: 0.3, ease: 'power2.out' } },
1799
+ 'gesture-magnetic-text': { hover: { y: -2, duration: 0.2, ease: 'power2.out' } },
1800
+
1801
+ // Ripple-style
1802
+ 'gesture-ripple': { active: { scale: 0.95, opacity: 0.9, duration: 0.1 } },
1803
+ 'gesture-ripple-out': { active: { scale: 1.1, opacity: 0, duration: 0.4, ease: 'power2.out' } },
1804
+
1805
+ // Spring / elastic
1806
+ 'gesture-spring-press': { active: { scale: 0.88, duration: 0.1, ease: 'power4.inOut' } },
1807
+ 'gesture-spring-release': { hover: { scale: 1, duration: 0.5, ease: 'elastic.out(1,0.4)' } },
1808
+ 'gesture-bounce-press': { active: { scale: 0.85, duration: 0.08 } },
1809
+ 'gesture-bounce-release': { hover: { scale: 1, duration: 0.6, ease: 'elastic.out(1,0.5)' } },
1810
+ 'gesture-elastic-x': { active: { scaleX: 0.9, duration: 0.08 } },
1811
+ 'gesture-elastic-y': { active: { scaleY: 0.9, duration: 0.08 } },
1812
+
1813
+ // Haptic-like
1814
+ 'gesture-haptic': { active: { x: 2, duration: 0.04, ease: 'none', yoyo: true, repeat: 4 } },
1815
+ 'gesture-haptic-hard': { active: { x: 4, duration: 0.04, ease: 'none', yoyo: true, repeat: 6 } },
1816
+ 'gesture-haptic-soft': { active: { x: 1, duration: 0.05, ease: 'none', yoyo: true, repeat: 2 } },
1817
+ 'gesture-haptic-y': { active: { y: 2, duration: 0.04, ease: 'none', yoyo: true, repeat: 4 } },
1818
+
1819
+ // Selection
1820
+ 'gesture-select': { active: { scale: 1.02, boxShadow: '0 0 0 2px rgba(59,130,246,0.5)', duration: 0.15 } },
1821
+ 'gesture-deselect': { active: { scale: 1, boxShadow: '0 0 0 0px rgba(59,130,246,0)', duration: 0.15 } },
1822
+ 'gesture-check': { active: { scale: 1.1, rotation: 5, duration: 0.2, ease: 'back.out(2)' } },
1823
+ 'gesture-uncheck': { active: { scale: 0.9, duration: 0.15 } },
1824
+
1825
+ // Drop / accept
1826
+ 'gesture-drop-accept': { active: { scale: 1.05, boxShadow: '0 0 0 3px rgba(16,185,129,0.5)', duration: 0.15 } },
1827
+ 'gesture-drop-reject': { active: { x: 4, duration: 0.05, ease: 'none', yoyo: true, repeat: 4, boxShadow: '0 0 0 3px rgba(239,68,68,0.5)' } },
1828
+ 'gesture-drop-zone': { hover: { scale: 1.02, boxShadow: '0 0 0 2px rgba(59,130,246,0.4), 0 0 20px rgba(59,130,246,0.15)', duration: 0.2 } },
1829
+
1830
+ // Context menu / right click
1831
+ 'gesture-context': { active: { scale: 0.97, duration: 0.08 } },
1832
+
1833
+ // Double tap
1834
+ 'gesture-doubletap': { active: { scale: 1.2, opacity: 0, duration: 0.3, ease: 'power2.out' } },
1835
+ 'gesture-doubletap-like': { active: { scale: 1.4, rotation: -10, duration: 0.25, ease: 'back.out(2)' } },
1836
+
1837
+ // Rotate gesture
1838
+ 'gesture-rotate-cw': { active: { rotation: 15, duration: 0.2, ease: 'power2.out' } },
1839
+ 'gesture-rotate-ccw': { active: { rotation: -15, duration: 0.2, ease: 'power2.out' } },
1840
+ 'gesture-rotate-snap': { active: { rotation: 90, duration: 0.3, ease: 'back.out(1.5)' } },
1841
+
1842
+ // Momentum
1843
+ 'gesture-momentum-x': { active: { x: 20, opacity: 0.8, duration: 0.4, ease: 'power4.out' } },
1844
+ 'gesture-momentum-y': { active: { y: 20, opacity: 0.8, duration: 0.4, ease: 'power4.out' } },
1845
+
1846
+ // Pan
1847
+ 'gesture-pan-start': { active: { scale: 1.02, duration: 0.1 } },
1848
+ 'gesture-pan-end': { active: { scale: 1, duration: 0.2, ease: 'power2.out' } },
1849
+
1850
+ // ── LOOPING / CONTINUOUS ──────────────────────────────────────
1851
+ 'animate-pulse': { from: { opacity: 1 }, to: { opacity: 0.4 }, duration: 1.0, ease: 'sine.inOut', yoyo: true, repeat: -1 },
1852
+ 'animate-pulse-sm': { from: { opacity: 1 }, to: { opacity: 0.6 }, duration: 0.8, ease: 'sine.inOut', yoyo: true, repeat: -1 },
1853
+ 'animate-pulse-scale':{ from: { scale: 1 }, to: { scale: 1.06 }, duration: 1.0, ease: 'sine.inOut', yoyo: true, repeat: -1 },
1854
+ 'animate-ping': { from: { scale: 1, opacity: 1 }, to: { scale: 2, opacity: 0 }, duration: 1.0, ease: 'power2.out', repeat: -1 },
1855
+ 'animate-ping-sm': { from: { scale: 1, opacity: 1 }, to: { scale: 1.5, opacity: 0 }, duration: 0.8, ease: 'power2.out', repeat: -1 },
1856
+ 'animate-bounce': { from: { y: 0 }, to: { y: -12 }, duration: 0.5, ease: 'power1.inOut', yoyo: true, repeat: -1 },
1857
+ 'animate-bounce-sm': { from: { y: 0 }, to: { y: -6 }, duration: 0.4, ease: 'power1.inOut', yoyo: true, repeat: -1 },
1858
+ 'animate-bounce-lg': { from: { y: 0 }, to: { y: -20 }, duration: 0.6, ease: 'power1.inOut', yoyo: true, repeat: -1 },
1859
+ 'animate-float': { from: { y: 0 }, to: { y: -10 }, duration: 2.0, ease: 'sine.inOut', yoyo: true, repeat: -1 },
1860
+ 'animate-float-sm': { from: { y: 0 }, to: { y: -5 }, duration: 1.5, ease: 'sine.inOut', yoyo: true, repeat: -1 },
1861
+ 'animate-float-lg': { from: { y: 0 }, to: { y: -16 }, duration: 2.5, ease: 'sine.inOut', yoyo: true, repeat: -1 },
1862
+ 'animate-spin': { to: { rotation: 360 }, duration: 1.0, ease: 'none', repeat: -1 },
1863
+ 'animate-spin-slow': { to: { rotation: 360 }, duration: 3.0, ease: 'none', repeat: -1 },
1864
+ 'animate-spin-fast': { to: { rotation: 360 }, duration: 0.4, ease: 'none', repeat: -1 },
1865
+ 'animate-spin-rev': { to: { rotation: -360 }, duration: 1.5, ease: 'none', repeat: -1 },
1866
+ 'animate-wiggle': { from: { rotation: 0 }, to: { rotation: 5 }, duration: 0.15, ease: 'none', yoyo: true, repeat: 5 },
1867
+ 'animate-wiggle-lg': { from: { rotation: 0 }, to: { rotation: 10 }, duration: 0.12, ease: 'none', yoyo: true, repeat: 7 },
1868
+ 'animate-shake': { from: { x: 0 }, to: { x: 6 }, duration: 0.08, ease: 'none', yoyo: true, repeat: 8 },
1869
+ 'animate-shake-sm': { from: { x: 0 }, to: { x: 3 }, duration: 0.06, ease: 'none', yoyo: true, repeat: 6 },
1870
+ 'animate-shake-y': { from: { y: 0 }, to: { y: 5 }, duration: 0.08, ease: 'none', yoyo: true, repeat: 8 },
1871
+ 'animate-breathe': { from: { scale: 1 }, to: { scale: 1.04 }, duration: 1.5, ease: 'sine.inOut', yoyo: true, repeat: -1 },
1872
+ 'animate-heartbeat': { from: { scale: 1 }, to: { scale: 1.15 }, duration: 0.2, ease: 'power2.out', yoyo: true, repeat: -1, repeatDelay: 0.8 },
1873
+ 'animate-flicker': { from: { opacity: 1 }, to: { opacity: 0 }, duration: 0.1, ease: 'none', yoyo: true, repeat: -1, repeatDelay: 1.5 },
1874
+ 'animate-blink': { from: { opacity: 1 }, to: { opacity: 0 }, duration: 0.5, ease: 'none', yoyo: true, repeat: -1, repeatDelay: 0.5 },
1875
+ 'animate-sway': { from: { rotation: -3 }, to: { rotation: 3 }, duration: 2.5, ease: 'sine.inOut', yoyo: true, repeat: -1 },
1876
+ 'animate-rock': { from: { rotation: -8 }, to: { rotation: 8 }, duration: 0.8, ease: 'sine.inOut', yoyo: true, repeat: -1 },
1877
+ 'animate-jello': { from: { scaleX: 1.25, scaleY: 0.75 }, to: { scaleX: 1, scaleY: 1 }, duration: 0.5, ease: 'elastic.out(1,0.4)' },
1878
+ 'animate-rubber': { from: { scaleX: 1.3, scaleY: 0.7 }, to: { scaleX: 1, scaleY: 1 }, duration: 0.6, ease: 'elastic.out(1,0.3)' },
1879
+ 'animate-orbit': { to: { rotation: 360 }, duration: 4.0, ease: 'none', repeat: -1, transformOrigin: 'center 60px' },
1880
+ 'animate-drift': { from: { x: 0, y: 0 }, to: { x: 8, y: -5 }, duration: 3.0, ease: 'sine.inOut', yoyo: true, repeat: -1 },
1881
+ 'animate-shimmer': { from: { backgroundPosition: '-200% 0' }, to: { backgroundPosition: '200% 0' }, duration: 1.5, ease: 'none', repeat: -1 },
1882
+ 'animate-morph': { from: { borderRadius: '30% 70% 70% 30% / 30% 30% 70% 70%' }, to: { borderRadius: '70% 30% 30% 70% / 70% 70% 30% 30%' }, duration: 4, ease: 'sine.inOut', yoyo: true, repeat: -1 },
1883
+ 'animate-wave': { from: { y: 0 }, to: { y: -8 }, duration: 1.0, ease: 'sine.inOut', yoyo: true, repeat: -1, stagger: 0.1 },
1884
+ 'animate-ripple': { from: { scale: 0.8, opacity: 1 }, to: { scale: 2, opacity: 0 }, duration: 1.5, ease: 'power2.out', repeat: -1 },
1885
+
1886
+ // ── TRANSITION OUT / EXIT ─────────────────────────────────────
1887
+ 'exit-fade': { from: { opacity: 1 }, to: { opacity: 0 }, duration: 0.3, ease: 'power2.in' },
1888
+ 'exit-fade-up': { from: { opacity: 1, y: 0 }, to: { opacity: 0, y: -20 }, duration: 0.3, ease: 'power2.in' },
1889
+ 'exit-fade-down': { from: { opacity: 1, y: 0 }, to: { opacity: 0, y: 20 }, duration: 0.3, ease: 'power2.in' },
1890
+ 'exit-fade-left': { from: { opacity: 1, x: 0 }, to: { opacity: 0, x: -20 }, duration: 0.3, ease: 'power2.in' },
1891
+ 'exit-fade-right': { from: { opacity: 1, x: 0 }, to: { opacity: 0, x: 20 }, duration: 0.3, ease: 'power2.in' },
1892
+ 'exit-scale': { from: { opacity: 1, scale: 1 }, to: { opacity: 0, scale: 0.8 }, duration: 0.3, ease: 'power2.in' },
1893
+ 'exit-scale-up': { from: { opacity: 1, scale: 1 }, to: { opacity: 0, scale: 1.2 }, duration: 0.3, ease: 'power2.in' },
1894
+ 'exit-slide-up': { from: { y: '0%' }, to: { y: '-100%', opacity: 0 }, duration: 0.4, ease: 'power3.in' },
1895
+ 'exit-slide-down': { from: { y: '0%' }, to: { y: '100%', opacity: 0 }, duration: 0.4, ease: 'power3.in' },
1896
+ 'exit-slide-left': { from: { x: '0%' }, to: { x: '-100%', opacity: 0 }, duration: 0.4, ease: 'power3.in' },
1897
+ 'exit-slide-right': { from: { x: '0%' }, to: { x: '100%', opacity: 0 }, duration: 0.4, ease: 'power3.in' },
1898
+ 'exit-blur': { from: { opacity: 1, filter: 'blur(0)' }, to: { opacity: 0, filter: 'blur(12px)' }, duration: 0.4, ease: 'power2.in' },
1899
+ 'exit-flip': { from: { rotationY: 0, opacity: 1 }, to: { rotationY: 90, opacity: 0 }, duration: 0.4, ease: 'power2.in' },
1900
+ 'exit-collapse': { from: { scaleY: 1, opacity: 1 }, to: { scaleY: 0, opacity: 0 }, duration: 0.3, ease: 'power2.in' },
1901
+ 'exit-squeeze': { from: { scaleX: 1, opacity: 1 }, to: { scaleX: 0, opacity: 0 }, duration: 0.3, ease: 'power2.in' },
1902
+ 'exit-dissolve': { from: { opacity: 1, filter: 'blur(0) saturate(1)' }, to: { opacity: 0, filter: 'blur(8px) saturate(0)' }, duration: 0.5, ease: 'power2.in' },
1903
+ 'exit-implode': { from: { scale: 1, opacity: 1 }, to: { scale: 0, opacity: 0 }, duration: 0.4, ease: 'back.in(2)' },
186
1904
  },
187
1905
 
1906
+ // ============================================================
1907
+ // RULES
1908
+ // ============================================================
188
1909
  rules: {
189
- darkMode: false,
190
- responsive: true,
1910
+ responsive: true,
1911
+ darkMode: 'class',
1912
+ print: true,
1913
+ motion: true,
1914
+ orientation: true,
1915
+ states: true,
1916
+
191
1917
  breakpoints: {
192
- sm: '640px',
193
- md: '768px',
194
- lg: '1024px',
195
- xl: '1280px'
196
- }
1918
+ xs: '480px',
1919
+ sm: '640px',
1920
+ md: '768px',
1921
+ lg: '1024px',
1922
+ xl: '1280px',
1923
+ '2xl': '1536px',
1924
+ '3xl': '1920px',
1925
+ },
1926
+
1927
+ containers: {
1928
+ card: { sm: '300px', md: '500px', lg: '700px' },
1929
+ sidebar: { collapsed: '200px', expanded: '320px' },
1930
+ panel: { sm: '240px', md: '400px', lg: '600px' },
1931
+ dialog: { sm: '320px', md: '480px', lg: '640px' },
1932
+ header: { sm: '400px', md: '768px', lg: '1024px' },
1933
+ article: { sm: '400px', md: '640px', lg: '800px' },
1934
+ widget: { sm: '200px', md: '340px', lg: '480px' },
1935
+ hero: { sm: '480px', md: '768px', lg: '1100px' },
1936
+ gallery: { sm: '300px', md: '600px', lg: '900px' },
1937
+ form: { sm: '300px', md: '480px', lg: '640px' },
1938
+ nav: { sm: '480px', md: '768px' },
1939
+ aside: { sm: '220px', md: '300px', lg: '400px' },
1940
+ section: { sm: '480px', md: '768px', lg: '1200px' },
1941
+ list: { sm: '300px', md: '500px' },
1942
+ toolbar: { sm: '360px', md: '600px' },
1943
+ drawer: { sm: '260px', md: '380px' },
1944
+ popover: { sm: '200px', md: '320px' },
1945
+ banner: { sm: '480px', md: '768px' },
1946
+ pricing: { sm: '260px', md: '360px', lg: '480px' },
1947
+ },
1948
+ },
1949
+
1950
+ // ============================================================
1951
+ // DEPTH
1952
+ // ============================================================
1953
+ depth: {
1954
+ strength: 0.4,
1955
+ perspective: 1000,
1956
+ perspectiveOrigin: '20% 50%',
1957
+ light: { x: 0, y: -1 },
1958
+ layers: 6,
1959
+ effects: {
1960
+ shadow: true,
1961
+ scale: true,
1962
+ brightness: true,
1963
+ blur: false,
1964
+ saturate: false,
1965
+ },
1966
+ zMap: {
1967
+ 0: 0,
1968
+ 5: 0.5,
1969
+ 10: 1,
1970
+ 20: 2,
1971
+ 30: 2.5,
1972
+ 40: 3,
1973
+ 50: 3.5,
1974
+ 100: 4,
1975
+ 200: 4.5,
1976
+ 300: 5,
1977
+ 999: 5.5,
1978
+ 9999: 6,
1979
+ },
1980
+ dimension: {
1981
+ tiltStrength: 15,
1982
+ perspective: 800,
1983
+ scrollZoom: 20,
1984
+ shine: true,
1985
+ parallaxLayers: true,
1986
+ }
1987
+ },
1988
+ }
1989
+ `
1990
+
1991
+ const mimuExample = `/* styles.mizu — CSS-style alternative to mizumi.config.js */
1992
+ /* Both files are supported — they get merged automatically */
1993
+
1994
+ @token {
1995
+ colors {
1996
+ brand: #6366f1;
1997
+ }
1998
+ spacing {
1999
+ section: 80px;
2000
+ hero: 120px;
197
2001
  }
198
- };
199
- `;
2002
+ }
2003
+
2004
+ @pattern hero {
2005
+ pad-y: hero;
2006
+ display: flex;
2007
+ flex-dir: col;
2008
+ align-yi: center;
2009
+ align-x: center;
2010
+ text-align: center;
2011
+ }
200
2012
 
201
- // Check if config already exists
202
- const configPath = path.join(process.cwd(), 'mizumi.config.js');
2013
+ @pattern section {
2014
+ pad-y: section;
2015
+ canvas-w: full;
2016
+ }
2017
+ `
203
2018
 
204
- if (fs.existsSync(configPath)) {
205
- console.log('⚠️ mizumi.config.js already exists, skipping...');
2019
+ if (!fs.existsSync('mizumi.config.js')) {
2020
+ fs.writeFileSync('mizumi.config.js', jsConfig)
2021
+ console.log('✅ Created mizumi.config.js')
206
2022
  } else {
207
- fs.writeFileSync(configPath, configTemplate);
208
- console.log('✅ Created: mizumi.config.js');
2023
+ console.log('⏭️ mizumi.config.js already exists — skipping')
209
2024
  }
210
2025
 
211
- // Create .mizumi directory
212
- const mizumiDir = path.join(process.cwd(), '.mizumi');
213
- if (!fs.existsSync(mizumiDir)) {
214
- fs.mkdirSync(mizumiDir);
2026
+ if (!fs.existsSync('styles.mizu')) {
2027
+ fs.writeFileSync('styles.mizu', mimuExample)
2028
+ console.log('✅ Created styles.mizu')
215
2029
  }
216
2030
 
217
- // Create .gitignore entry
218
- const gitignorePath = path.join(process.cwd(), '.gitignore');
219
- if (fs.existsSync(gitignorePath)) {
220
- const gitignore = fs.readFileSync(gitignorePath, 'utf8');
221
- if (!gitignore.includes('.mizumi')) {
222
- fs.appendFileSync(gitignorePath, '\n# Mizumi generated files\n.mizumi/\n');
223
- console.log('✅ Updated: .gitignore');
2031
+ console.log('\n💮 Run: npx mizumi build\n')
2032
+ },
2033
+
2034
+ // ── mizumi build ──
2035
+ async build() {
2036
+ console.log('💮 Mizumi: Building...\n')
2037
+ try {
2038
+ const cwd = process.cwd()
2039
+ const config = await loadConfig()
2040
+ const mizumi = new Mizumi(config)
2041
+ const outDir = '.mizumi'
2042
+
2043
+ // Generate base CSS from tokens/patterns
2044
+ let css = mizumi.generateCSS()
2045
+
2046
+ // Scan source files and append arbitrary classes
2047
+ const scanned = scanAndGenerateCSS(cwd)
2048
+ if (scanned) {
2049
+ css += '\n\n/* ===== SCANNED ARBITRARY CLASSES ===== */\n' + scanned
224
2050
  }
225
- } else {
226
- fs.writeFileSync(gitignorePath, '# Mizumi generated files\n.mizumi/\n');
227
- console.log('✅ Created: .gitignore');
2051
+
2052
+ // Write all outputs
2053
+ if (!fs.existsSync(outDir)) fs.mkdirSync(outDir, { recursive: true })
2054
+
2055
+ fs.writeFileSync(path.join(outDir, 'mizumi.css'), css)
2056
+ console.log(`✅ CSS: ${path.join(outDir, 'mizumi.css')} (${(Buffer.byteLength(css)/1024).toFixed(2)} KB)`)
2057
+
2058
+ const js = mizumi.generateRuntimeScript()
2059
+ fs.writeFileSync(path.join(outDir, 'mizumi-runtime.js'), js)
2060
+ console.log(`✅ Runtime: ${path.join(outDir, 'mizumi-runtime.js')} (${(Buffer.byteLength(js)/1024).toFixed(2)} KB)`)
2061
+
2062
+ const depthJs = mizumi.depthEngine.generateRuntimeScript()
2063
+ fs.writeFileSync(path.join(outDir, 'mizumi-depth-runtime.js'), depthJs)
2064
+ console.log(`✅ Depth: ${path.join(outDir, 'mizumi-depth-runtime.js')} (${(Buffer.byteLength(depthJs)/1024).toFixed(2)} KB)`)
2065
+
2066
+ const dts = mizumi.typesGenerator.generateDTS()
2067
+ fs.writeFileSync(path.join(outDir, 'mizumi.d.ts'), dts)
2068
+ console.log(`✅ Types: ${path.join(outDir, 'mizumi.d.ts')} (${(Buffer.byteLength(dts)/1024).toFixed(2)} KB)`)
2069
+
2070
+ const helpers = mizumi.typesGenerator.generateHelpers()
2071
+ fs.writeFileSync(path.join(outDir, 'mizumi-helpers.js'), helpers)
2072
+ console.log(`✅ Helpers: ${path.join(outDir, 'mizumi-helpers.js')} (${(Buffer.byteLength(helpers)/1024).toFixed(2)} KB)`)
2073
+
2074
+ const metaObj = {
2075
+ tokens: config.tokens,
2076
+ patterns: config.patterns,
2077
+ animations:config.animations,
2078
+ rules: config.rules,
2079
+ generated: new Date().toISOString()
2080
+ }
2081
+ const meta = JSON.stringify(metaObj, null, 2)
2082
+ fs.writeFileSync(path.join(outDir, 'mizumi.meta.json'), meta)
2083
+ console.log(`✅ Meta: ${path.join(outDir, 'mizumi.meta.json')} (${(Buffer.byteLength(meta)/1024).toFixed(2)} KB)`)
2084
+
2085
+ // Always write devtools — inactive until mizumi-devtools.js is loaded
2086
+ const devtools = generateDevToolsScript({ tokens: metaObj.tokens, patterns: metaObj.patterns, animations: metaObj.animations })
2087
+ fs.writeFileSync(path.join(outDir, 'mizumi-devtools.js'), devtools)
2088
+ console.log(`✅ DevTools:${path.join(outDir, 'mizumi-devtools.js')} (${(Buffer.byteLength(devtools)/1024).toFixed(2)} KB)`)
2089
+
2090
+ console.log('\n✅ Build complete')
2091
+ console.log(' 💡 Add to HTML for DevTools: <script src=".mizumi/mizumi-devtools.js"></script>')
2092
+ } catch (err) {
2093
+ console.error('❌ Build failed:', err.message)
2094
+ process.exit(1)
228
2095
  }
2096
+ },
229
2097
 
230
- console.log('\n🎉 Mizumi initialized successfully!');
231
- console.log('\nNext steps:');
232
- console.log(' 1. Edit mizumi.config.js to customize your tokens');
233
- console.log(' 2. Run: node mizumi build');
234
- console.log(' 3. Import .mizumi/mizumi.css in your project');
2098
+ // ── mizumi watch ──
2099
+ async watch() {
2100
+ console.log('💮 Mizumi: Watching...\n')
2101
+ await commands.build()
2102
+ watch(loadConfig, Mizumi, generateDevToolsScript)
235
2103
  },
236
2104
 
237
- /**
238
- * Build CSS from config
239
- * npx mizumi build
240
- */
241
- build: async function() {
242
- console.log('🌊 Building Mizumi CSS...\n');
243
-
244
- // Find config file
245
- const configPath = path.join(process.cwd(), 'mizumi.config.js');
246
- if (!fs.existsSync(configPath)) {
247
- console.error('❌ mizumi.config.js not found!');
248
- console.error(' Run: node mizumi init');
249
- process.exit(1);
250
- }
2105
+ // ── mizumi validate ──
2106
+ async validate() {
2107
+ console.log('💮 Mizumi: Validating config...\n')
2108
+ try {
2109
+ const config = await loadConfig()
2110
+ const validator = new Validator(config)
2111
+ const result = validator.validate()
251
2112
 
252
- // Load config
253
- const configModule = await import(pathToFileURL(configPath).href);
254
- const config = configModule.default || configModule; // ← handles both ESM and CommonJS
2113
+ if (result.valid && result.warnings.length === 0) {
2114
+ console.log('✅ Config is valid — no issues found\n')
2115
+ return
2116
+ }
255
2117
 
256
- // Generate CSS + Runtime JS
257
- const mizumi = new Mizumi(config);
258
-
2118
+ if (result.errors.length > 0) {
2119
+ console.log(`❌ ${result.errors.length} error(s):\n`)
2120
+ result.errors.forEach(e => console.log(e + '\n'))
2121
+ }
2122
+
2123
+ if (result.warnings.length > 0) {
2124
+ console.log(`⚠️ ${result.warnings.length} warning(s):\n`)
2125
+ result.warnings.forEach(w => console.log(w + '\n'))
2126
+ }
2127
+
2128
+ if (!result.valid) process.exit(1)
2129
+
2130
+ } catch (err) {
2131
+ console.error('❌ Validation failed:', err.message)
2132
+ process.exit(1)
2133
+ }
2134
+ },
2135
+
2136
+ // ── mizumi analyze ──
2137
+ async analyze() {
2138
+ console.log('💮 Mizumi: Analyzing design system...\n')
2139
+ try {
2140
+ const config = await loadConfig()
2141
+ const mizumi = new Mizumi(config)
2142
+
2143
+ // Token stats
2144
+ const tokens = config.tokens || {}
2145
+ const patterns = config.patterns || {}
2146
+ const anims = config.animations || {}
2147
+
2148
+ console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━')
2149
+ console.log(' MIZUMI DESIGN SYSTEM ANALYSIS')
2150
+ console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n')
259
2151
 
260
- const outDir = path.join(process.cwd(), '.mizumi');
261
- mizumi.build(outDir); // ← now passes directory, not file path
2152
+ // Token summary
2153
+ console.log('📦 TOKENS')
2154
+ for (const [category, values] of Object.entries(tokens)) {
2155
+ const count = typeof values === 'object'
2156
+ ? Object.keys(values).length
2157
+ : 1
2158
+ console.log(` ${category.padEnd(16)} ${count} values`)
2159
+ }
262
2160
 
263
- console.log('\n🎉 Build complete!');
264
- console.log(' Add to your HTML:');
265
- console.log(' <link rel="stylesheet" href=".mizumi/mizumi.css">');
266
- console.log(' <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script>');
267
- console.log(' <script src=".mizumi/mizumi-runtime.js"></script>');
268
- },
2161
+ // Pattern summary
2162
+ console.log(`\n🎨 PATTERNS (${Object.keys(patterns).length} total)`)
2163
+ for (const [name, value] of Object.entries(patterns)) {
2164
+ const classes = value.split(/\s+/).filter(Boolean)
2165
+ console.log(` .${name.padEnd(20)} ${classes.length} utilities`)
2166
+ }
269
2167
 
2168
+ // Animation summary
2169
+ console.log(`\n✨ ANIMATIONS (${Object.keys(anims).length} total)`)
2170
+ for (const [name] of Object.entries(anims)) {
2171
+ console.log(` ${name}`)
2172
+ }
270
2173
 
2174
+ // CSS output size estimate
2175
+ const css = mizumi.generateCSS()
2176
+ const kb = (Buffer.byteLength(css) / 1024).toFixed(2)
2177
+ console.log(`\n📄 ESTIMATED OUTPUT`)
2178
+ console.log(` CSS size: ${kb} KB`)
2179
+ console.log(` Utilities generated: ${css.match(/\./g)?.length || 0}`)
2180
+
2181
+ // Unused token check — only warn for tokens expected in patterns
2182
+ // easing/duration/blur/zIndex/leading/tracking are utility tokens
2183
+ // used inline in HTML, not required in patterns
2184
+ const PATTERN_TOKEN_CATEGORIES = ['colors', 'spacing', 'typography', 'radius', 'shadows', 'fonts']
2185
+ console.log('\n🔍 TOKEN USAGE IN PATTERNS')
2186
+ const allPatternText = Object.values(patterns).join(' ')
2187
+ let unusedCount = 0
2188
+ for (const [category, values] of Object.entries(tokens)) {
2189
+ if (!PATTERN_TOKEN_CATEGORIES.includes(category)) continue
2190
+ if (typeof values !== 'object') continue
2191
+ for (const key of Object.keys(values)) {
2192
+ const used = allPatternText.includes(`:${key}`)
2193
+ if (!used) {
2194
+ console.log(` ⚠️ ${category}.${key} — defined but not used in any pattern`)
2195
+ unusedCount++
2196
+ }
2197
+ }
2198
+ }
2199
+ if (unusedCount === 0) {
2200
+ console.log(' ✅ All pattern tokens are in use')
2201
+ }
2202
+ console.log('\n ℹ️ easing/duration/blur/opacity/zIndex/leading/tracking')
2203
+ console.log(' are utility tokens — use inline in HTML/JSX as needed')
271
2204
 
2205
+ console.log('\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n')
272
2206
 
273
- /**
274
- * List all patterns
275
- * npx mizumi list
276
- */
277
- list: async function() {
278
- const configPath = path.join(process.cwd(), 'mizumi.config.js');
2207
+ } catch (err) {
2208
+ console.error('❌ Analysis failed:', err.message)
2209
+ }
2210
+ },
279
2211
 
280
- if (!fs.existsSync(configPath)) {
281
- console.error('❌ mizumi.config.js not found! Run: node mizumi init');
282
- process.exit(1);
2212
+ // ── mizumi convert ──
2213
+ // Converts Tailwind class strings to Mizumi equivalents
2214
+ convert() {
2215
+ const input = args[1]
2216
+ if (!input) {
2217
+ console.log('Usage: mizumi convert "p-4 bg-blue-500 rounded-lg text-white"')
2218
+ return
283
2219
  }
284
2220
 
285
-
286
- const configModule = await import(pathToFileURL(configPath).href);
287
- const config = configModule.default || configModule; // ← handles both ESM and CommonJS
2221
+ const TAILWIND_MAP = {
2222
+ 'flex': 'display:flex',
2223
+ 'grid': 'display:grid',
2224
+ 'block': 'display:block',
2225
+ 'inline': 'display:inline',
2226
+ 'hidden': 'display:none',
2227
+ 'relative': 'pos:relative',
2228
+ 'absolute': 'pos:absolute',
2229
+ 'fixed': 'pos:fixed',
2230
+ 'sticky': 'pos:sticky',
2231
+ 'w-full': 'canvas-w:full',
2232
+ 'h-full': 'canvas-h:full',
2233
+ 'w-screen': 'canvas-w:screen',
2234
+ 'h-screen': 'canvas-h:screen',
2235
+ 'mx-auto': 'mar-x:auto',
2236
+ 'items-center': 'align-yi:center',
2237
+ 'items-start': 'align-yi:start',
2238
+ 'items-end': 'align-yi:end',
2239
+ 'justify-center': 'align-x:center',
2240
+ 'justify-between': 'align-x:between',
2241
+ 'justify-start': 'align-x:start',
2242
+ 'justify-end': 'align-x:end',
2243
+ 'flex-col': 'flex-dir:col',
2244
+ 'flex-row': 'flex-dir:row',
2245
+ 'flex-wrap': 'flex-wrap:yes',
2246
+ 'flex-1': 'flex:1',
2247
+ 'font-bold': 'type-weight:bold',
2248
+ 'font-semibold': 'type-weight:semi',
2249
+ 'font-medium': 'type-weight:medium',
2250
+ 'font-normal': 'type-weight:normal',
2251
+ 'font-light': 'type-weight:light',
2252
+ 'italic': 'type-style:italic',
2253
+ 'uppercase': 'text-case:upper',
2254
+ 'lowercase': 'text-case:lower',
2255
+ 'capitalize': 'text-case:capital',
2256
+ 'text-center': 'text-align:center',
2257
+ 'text-left': 'text-align:left',
2258
+ 'text-right': 'text-align:right',
2259
+ 'overflow-hidden': 'overflow:hidden',
2260
+ 'overflow-auto': 'overflow:auto',
2261
+ 'overflow-scroll': 'overflow:scroll',
2262
+ 'cursor-pointer': 'cursor:pointer',
2263
+ 'cursor-default': 'cursor:default',
2264
+ 'select-none': 'select:none',
2265
+ 'pointer-events-none': 'events:none',
2266
+ 'truncate': 'overflow:hidden text-overflow:dots wrap:no',
2267
+ 'border': 'stroke-width:1px stroke-style:solid',
2268
+ 'border-none': 'stroke-style:none',
2269
+ 'list-none': 'list:none',
2270
+ }
288
2271
 
289
- // Generate CSS + Runtime JS
290
- const mizumi = new Mizumi(config);
291
-
292
- console.log('\n🌊 Mizumi Patterns:\n');
2272
+ const classes = input.split(/\s+/).filter(Boolean)
2273
+ const converted = []
2274
+ const unknown = []
293
2275
 
294
- for (const [name, value] of Object.entries(config.patterns || {})) {
295
- const expanded = mizumi.expandClassName(name);
296
- console.log(` .${name}`);
297
- console.log(` ${expanded}`);
298
- console.log('');
2276
+ for (const cls of classes) {
2277
+ if (TAILWIND_MAP[cls]) {
2278
+ converted.push(TAILWIND_MAP[cls])
2279
+ } else if (/^p-(\d+)$/.exec(cls)) { converted.push(`pad:your-spacing-token /* was ${cls} */`) }
2280
+ else if (/^px-(\d+)$/.exec(cls)) { converted.push(`pad-x:your-spacing-token /* was ${cls} */`) }
2281
+ else if (/^py-(\d+)$/.exec(cls)) { converted.push(`pad-y:your-spacing-token /* was ${cls} */`) }
2282
+ else if (/^m-(\d+)$/.exec(cls)) { converted.push(`mar:your-spacing-token /* was ${cls} */`) }
2283
+ else if (/^mx-(\d+)$/.exec(cls)) { converted.push(`mar-x:your-spacing-token /* was ${cls} */`) }
2284
+ else if (/^my-(\d+)$/.exec(cls)) { converted.push(`mar-y:your-spacing-token /* was ${cls} */`) }
2285
+ else if (/^gap-(\d+)$/.exec(cls)) { converted.push(`gap:your-spacing-token /* was ${cls} */`) }
2286
+ else if (/^rounded/.exec(cls)) { converted.push(`curve:your-radius-token /* was ${cls} */`) }
2287
+ else if (/^shadow/.exec(cls)) { converted.push(`cast:your-shadow-token /* was ${cls} */`) }
2288
+ else if (/^bg-/.exec(cls)) { converted.push(`paint:your-color-token /* was ${cls} */`) }
2289
+ else if (/^text-/.exec(cls)) { converted.push(`text:your-type-token /* was ${cls} */`) }
2290
+ else if (/^text-\[/.exec(cls)) { converted.push(`type-size:your-size-token /* was ${cls} */`) }
2291
+ else if (/^border-/.exec(cls)) { converted.push(`stroke-color:your-color /* was ${cls} */`) }
2292
+ else if (/^text-(white|black)/.exec(cls)) { converted.push(`ink:your-color-token /* was ${cls} */`) }
2293
+ else { unknown.push(cls) }
299
2294
  }
300
2295
 
301
- console.log('\n🌊 Mizumi Animations:\n');
2296
+ console.log('\n💮 Mizumi equivalent:\n')
2297
+ console.log(converted.join('\n'))
302
2298
 
303
- for (const [name, value] of Object.entries(config.animations || {})) {
304
- console.log(` .${name}`);
305
- console.log(` → GSAP: ${JSON.stringify(value).slice(0, 60)}...`);
306
- console.log('');
2299
+ if (unknown.length > 0) {
2300
+ console.log(`\n⚠️ Could not convert (no direct equivalent):\n ${unknown.join(', ')}`)
2301
+ console.log(' Check: https://github.com/Mizumi25/MizumiPackage')
307
2302
  }
2303
+
2304
+ console.log('')
308
2305
  },
309
2306
 
310
- /**
311
- * Explain what a class does
312
- * npx mizumi explain "card"
313
- */
314
- explain: async function() {
315
- const className = args[1];
316
-
317
- if (!className) {
318
- console.error('❌ Please provide a class name');
319
- console.error(' Usage: node mizumi explain "card"');
320
- process.exit(1);
2307
+ // ── mizumi docs ──
2308
+ async docs() {
2309
+ console.log('💮 Mizumi: Generating docs...\n')
2310
+ try {
2311
+ const config = await loadConfig()
2312
+ const docs = new DocsGenerator(config)
2313
+ docs.generate('.mizumi/docs')
2314
+ console.log('✅ Docs generated in .mizumi/docs/')
2315
+ } catch (err) {
2316
+ console.error(' Docs failed:', err.message)
321
2317
  }
2318
+ },
322
2319
 
323
- const configPath = path.join(process.cwd(), 'mizumi.config.js');
324
-
325
- const configModule = await import(pathToFileURL(configPath).href);
326
- const config = configModule.default || configModule;
2320
+ // ── mizumi help ──
2321
+ help() {
2322
+ console.log(`
2323
+ 💮 Mizumi CLI
327
2324
 
328
- const mizumi = new Mizumi(config);
2325
+ COMMANDS:
2326
+ init Create mizumi.config.js and styles.mizu starter files
2327
+ build Build CSS, runtime, types and meta from your config
2328
+ watch Build then watch for config changes
2329
+ validate Check your config for errors and Tailwind/raw CSS usage
2330
+ analyze Design system health report — tokens, patterns, usage
2331
+ convert Convert Tailwind class string to Mizumi vocabulary
2332
+ docs Generate HTML documentation from your config
2333
+ help Show this help
329
2334
 
330
- console.log(`\n🌊 Explaining: "${className}"\n`);
2335
+ EXAMPLES:
2336
+ npx mizumi init
2337
+ npx mizumi build
2338
+ npx mizumi validate
2339
+ npx mizumi analyze
2340
+ npx mizumi convert "p-4 bg-blue-500 flex items-center rounded-lg"
331
2341
 
332
- const classes = className.split(' ');
2342
+ FILES:
2343
+ mizumi.config.js JS config (for JS developers)
2344
+ *.mizu CSS-style config (for CSS developers)
2345
+ Both are auto-detected and merged.
333
2346
 
334
- for (const cls of classes) {
335
- // Check if it's a pattern
336
- if (config.patterns?.[cls]) {
337
- const expanded = mizumi.expandClassName(cls);
338
- console.log(` Pattern: .${cls}`);
339
- console.log(` Expands to: ${expanded}`);
340
- }
341
- // Check if it's an animation
342
- else if (config.animations?.[cls]) {
343
- console.log(` Animation: .${cls}`);
344
- console.log(` Config: ${JSON.stringify(config.animations[cls], null, 4)}`);
2347
+ OUTPUT (.mizumi/):
2348
+ mizumi.css All generated CSS
2349
+ mizumi-runtime.js GSAP animation runtime
2350
+ mizumi.d.ts TypeScript types
2351
+ mizumi-helpers.js JS class name helpers
2352
+ mizumi.meta.json Config metadata
2353
+ `)
2354
+ },
2355
+
2356
+
2357
+
2358
+
2359
+ // ── ADD THESE TO THE commands OBJECT IN packages/cli/index.js ──
2360
+
2361
+
2362
+ // ── mizumi sync:defaults ──
2363
+ // Reads packages/core/defaults.js and syncs into pattern-expander.js,
2364
+ // parser.js, animation-engine parent (index.js), variant-generator.js
2365
+ async ['sync:defaults']() {
2366
+ console.log('💮 Mizumi: Syncing defaults...\n')
2367
+
2368
+ const __dirname = path.dirname(fileURLToPath(import.meta.url))
2369
+ const coreDir = path.resolve(__dirname, '../core')
2370
+ const defaultsPath = path.resolve(coreDir, 'defaults.js')
2371
+
2372
+ if (!fs.existsSync(defaultsPath)) {
2373
+ console.error('❌ packages/core/defaults.js not found')
2374
+ process.exit(1)
2375
+ }
2376
+
2377
+ const { DEFAULT_TOKENS, DEFAULT_PATTERNS, DEFAULT_ANIMATIONS, DEFAULT_RULES } =
2378
+ await import(pathToFileURL(defaultsPath).href + `?t=${Date.now()}`)
2379
+
2380
+ // ── 1. Sync patterns into pattern-expander.js ──
2381
+ const peFile = path.resolve(coreDir, 'pattern-expander.js')
2382
+ let peSrc = fs.readFileSync(peFile, 'utf8')
2383
+
2384
+ const patternsJSON = JSON.stringify(DEFAULT_PATTERNS, null, 4)
2385
+ .replace(/"([^"]+)":/g, "'$1':") // use single quotes for keys
2386
+ .replace(/"/g, "'") // use single quotes for values
2387
+
2388
+ const peMarkerStart = '// <<<DEFAULTS:PATTERNS:START>>>'
2389
+ const peMarkerEnd = '// <<<DEFAULTS:PATTERNS:END>>>'
2390
+
2391
+ if (peSrc.includes(peMarkerStart)) {
2392
+ // Replace existing block
2393
+ const re = new RegExp(`${peMarkerStart}[\\s\\S]*?${peMarkerEnd}`)
2394
+ peSrc = peSrc.replace(re,
2395
+ `${peMarkerStart}\n ...${patternsJSON},\n ${peMarkerEnd}`)
2396
+ } else {
2397
+ // Inject into constructor — find: this.patterns = {
2398
+ peSrc = peSrc.replace(
2399
+ 'this.patterns = {',
2400
+ `this.patterns = {\n ${peMarkerStart}\n ...${patternsJSON},\n ${peMarkerEnd}`
2401
+ )
2402
+ }
2403
+ fs.writeFileSync(peFile, peSrc)
2404
+ console.log(`✅ Patterns synced → pattern-expander.js (${Object.keys(DEFAULT_PATTERNS).length} patterns)`)
2405
+
2406
+ // ── 2. Sync tokens into parser.js ──
2407
+ const parserFile = path.resolve(coreDir, 'parser.js')
2408
+ let parserSrc = fs.readFileSync(parserFile, 'utf8')
2409
+
2410
+ const tokensJSON = JSON.stringify(DEFAULT_TOKENS, null, 4)
2411
+
2412
+ const tokMarkerStart = '// <<<DEFAULTS:TOKENS:START>>>'
2413
+ const tokMarkerEnd = '// <<<DEFAULTS:TOKENS:END>>>'
2414
+
2415
+ if (parserSrc.includes(tokMarkerStart)) {
2416
+ const re = new RegExp(`${tokMarkerStart}[\\s\\S]*?${tokMarkerEnd}`)
2417
+ parserSrc = parserSrc.replace(re,
2418
+ `${tokMarkerStart}\n const DEFAULT_TOKENS = ${tokensJSON}\n c = this._mergeDeep(DEFAULT_TOKENS, c)\n ${tokMarkerEnd}`)
2419
+ } else {
2420
+ // Inject at start of parse() method, after: const c = this.config
2421
+ parserSrc = parserSrc.replace(
2422
+ 'parse() {\n const vars = {}\n const c = this.config',
2423
+ `parse() {\n const vars = {}\n let c = this.config\n ${tokMarkerStart}\n const DEFAULT_TOKENS = ${tokensJSON}\n c = this._mergeDeep(DEFAULT_TOKENS, c)\n ${tokMarkerEnd}`
2424
+ )
2425
+
2426
+ // Add _mergeDeep helper if not present
2427
+ if (!parserSrc.includes('_mergeDeep')) {
2428
+ parserSrc = parserSrc.replace(
2429
+ 'export class TokenParser {',
2430
+ `export class TokenParser {
2431
+ _mergeDeep(target, source) {
2432
+ const out = { ...target }
2433
+ for (const key of Object.keys(source || {})) {
2434
+ if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])) {
2435
+ out[key] = this._mergeDeep(target[key] || {}, source[key])
2436
+ } else {
2437
+ out[key] = source[key]
345
2438
  }
346
- // Check if it's a utility
347
- else {
348
- console.log(` Utility: .${cls}`);
349
- console.log(` (Built-in utility class)`);
2439
+ }
2440
+ return out
2441
+ }
2442
+ `
2443
+ )
350
2444
  }
351
- console.log('');
352
2445
  }
2446
+ fs.writeFileSync(parserFile, parserSrc)
2447
+ console.log(`✅ Tokens synced → parser.js`)
2448
+
2449
+ // ── 3. Sync animations into core/index.js ──
2450
+ const indexFile = path.resolve(coreDir, 'index.js')
2451
+ let indexSrc = fs.readFileSync(indexFile, 'utf8')
2452
+
2453
+ const animJSON = JSON.stringify(DEFAULT_ANIMATIONS, null, 4)
2454
+ const animMarkerStart = '// <<<DEFAULTS:ANIMATIONS:START>>>'
2455
+ const animMarkerEnd = '// <<<DEFAULTS:ANIMATIONS:END>>>'
2456
+
2457
+ if (indexSrc.includes(animMarkerStart)) {
2458
+ const re = new RegExp(`${animMarkerStart}[\\s\\S]*?${animMarkerEnd}`)
2459
+ indexSrc = indexSrc.replace(re,
2460
+ `${animMarkerStart}\n const DEFAULT_ANIMATIONS = ${animJSON}\n ${animMarkerEnd}`)
2461
+ } else {
2462
+ // Find AnimationEngine constructor call and inject defaults merge
2463
+ indexSrc = indexSrc.replace(
2464
+ 'this.animationEngine = new AnimationEngine(',
2465
+ `${animMarkerStart}\n const DEFAULT_ANIMATIONS = ${animJSON}\n ${animMarkerEnd}\n this.animationEngine = new AnimationEngine(`
2466
+ )
2467
+ // Now fix the actual merge — find the animations arg
2468
+ indexSrc = indexSrc.replace(
2469
+ 'new AnimationEngine(\n config.animations',
2470
+ 'new AnimationEngine(\n { ...DEFAULT_ANIMATIONS, ...config.animations }'
2471
+ )
2472
+ // Handle single-line version too
2473
+ indexSrc = indexSrc.replace(
2474
+ /new AnimationEngine\(\s*config\.animations\s*,/g,
2475
+ 'new AnimationEngine({ ...DEFAULT_ANIMATIONS, ...config.animations },'
2476
+ )
2477
+ }
2478
+ fs.writeFileSync(indexFile, indexSrc)
2479
+ console.log(`✅ Animations synced → index.js (${Object.keys(DEFAULT_ANIMATIONS).length} animations)`)
2480
+
2481
+ console.log('\n✅ Sync complete — rebuild to apply: npx mizumi build')
353
2482
  },
354
-
355
- watch() {
356
- watch();
2483
+
2484
+
2485
+ // ── mizumi add:pattern <name> "<utilities>" ──
2486
+ async ['add:pattern']() {
2487
+ const name = args[1]
2488
+ const value = args[2]
2489
+
2490
+ if (!name || !value) {
2491
+ console.log('Usage: node cli/index.js add:pattern <name> "<utilities>"')
2492
+ console.log('Example: node cli/index.js add:pattern flex-center "display:flex align-x:center align-yi:center"')
2493
+ return
2494
+ }
2495
+
2496
+ const __dirname = path.dirname(fileURLToPath(import.meta.url))
2497
+ const defaultsPath = path.resolve(__dirname, '../core/defaults.js')
2498
+
2499
+ if (!fs.existsSync(defaultsPath)) {
2500
+ console.error('❌ packages/core/defaults.js not found')
2501
+ process.exit(1)
2502
+ }
2503
+
2504
+ let src = fs.readFileSync(defaultsPath, 'utf8')
2505
+
2506
+ // Find the closing of DEFAULT_PATTERNS and inject before it
2507
+ const insertBefore = '\n}\n\nexport const DEFAULT_ANIMATIONS'
2508
+ if (!src.includes(insertBefore)) {
2509
+ console.error('❌ Could not find insertion point in defaults.js')
2510
+ process.exit(1)
2511
+ }
2512
+
2513
+ const line = ` '${name}': '${value}',`
2514
+
2515
+ // Check if already exists
2516
+ if (src.includes(`'${name}':`)) {
2517
+ // Update existing
2518
+ src = src.replace(
2519
+ new RegExp(`'${name}':\\s*'[^']*'`),
2520
+ `'${name}': '${value}'`
2521
+ )
2522
+ console.log(`✏️ Updated pattern: ${name}`)
2523
+ } else {
2524
+ // Insert before closing brace of DEFAULT_PATTERNS
2525
+ src = src.replace(insertBefore, `\n${line}${insertBefore}`)
2526
+ console.log(`✅ Added pattern: ${name}`)
2527
+ }
2528
+
2529
+ fs.writeFileSync(defaultsPath, src)
2530
+ console.log(` Run sync:defaults to apply → node packages/cli/index.js sync:defaults`)
357
2531
  },
358
2532
 
359
- /**
360
- * Show help
361
- */
362
- help() {
363
- console.log(`
364
- 🌊 Mizumi CSS Framework v0.1.0
365
-
366
- Commands:
367
- init Initialize Mizumi in project
368
- build Generate CSS + runtime JS
369
- watch Watch config and auto-rebuild
370
- docs Generate documentation page
371
- list List all patterns & animations
372
- explain <class> Explain what a class does
373
- help Show help
374
-
375
- Examples:
376
- node mizumi init
377
- node mizumi build
378
- node mizumi watch
379
- node mizumi list
380
- node mizumi explain "card animate-fade-in"
381
- `);
382
- },
383
-
384
-
385
-
386
- docs: async function() {
387
- console.log('🌊 Generating Mizumi Docs...\n');
388
- const cfgPath = path.join(process.cwd(), 'mizumi.config.js');
389
- if (!fs.existsSync(cfgPath)) {
390
- console.error('❌ mizumi.config.js not found!');
391
- process.exit(1);
2533
+
2534
+ // ── mizumi add:token <category> <name> <value> ──
2535
+ async ['add:token']() {
2536
+ const category = args[1]
2537
+ const name = args[2]
2538
+ const value = args[3]
2539
+
2540
+ if (!category || !name || !value) {
2541
+ console.log('Usage: node cli/index.js add:token <category> <name> <value>')
2542
+ console.log('Example: node cli/index.js add:token colors brand "#ff6b6b"')
2543
+ console.log('Example: node cli/index.js add:token spacing hero "120px"')
2544
+ return
2545
+ }
2546
+
2547
+ const __dirname = path.dirname(fileURLToPath(import.meta.url))
2548
+ const defaultsPath = path.resolve(__dirname, '../core/defaults.js')
2549
+
2550
+ if (!fs.existsSync(defaultsPath)) {
2551
+ console.error('❌ packages/core/defaults.js not found')
2552
+ process.exit(1)
2553
+ }
2554
+
2555
+ let src = fs.readFileSync(defaultsPath, 'utf8')
2556
+
2557
+ // Check if already exists
2558
+ if (src.includes(`${name}:`) ) {
2559
+ src = src.replace(
2560
+ new RegExp(`(${name}:\\s*)(['"\`][^'"\`]*['"\`]|\\d+)`),
2561
+ `$1'${value}'`
2562
+ )
2563
+ console.log(`✏️ Updated token: ${category}.${name} = ${value}`)
2564
+ } else {
2565
+ // Find the category block and inject
2566
+ const catMarker = ` ${category}: {`
2567
+ if (!src.includes(catMarker)) {
2568
+ console.error(`❌ Token category "${category}" not found in defaults.js`)
2569
+ console.log(` Valid categories: colors, spacing, typography, fonts, radius, shadows, easing, duration, blur, opacity, zIndex, leading, tracking`)
2570
+ process.exit(1)
2571
+ }
2572
+ src = src.replace(catMarker, `${catMarker}\n ${name}: '${value}',`)
2573
+ console.log(`✅ Added token: ${category}.${name} = ${value}`)
392
2574
  }
393
-
394
- const configModule = await import(pathToFileURL(cfgPath).href);
395
- const config = configModule.default || configModule;
396
-
397
- const generator = new DocsGenerator(config);
398
- const html = generator.generate();
399
- const outDir = path.join(process.cwd(), '.mizumi');
400
- const outPath = path.join(outDir, 'docs.html');
401
- if (!fs.existsSync(outDir)) fs.mkdirSync(outDir);
402
- fs.writeFileSync(outPath, html);
403
- console.log(`✅ Docs generated: ${outPath}`);
404
- console.log('\n🎉 Open in browser:');
405
- console.log(` .mizumi/docs.html`);
2575
+
2576
+ fs.writeFileSync(defaultsPath, src)
2577
+ console.log(` Run sync:defaults to apply → node packages/cli/index.js sync:defaults`)
406
2578
  },
407
2579
 
408
- };
2580
+
2581
+ // ── mizumi add:animation <name> ──
2582
+ // Opens a prompt-style flow (just prints the template for now)
2583
+ async ['add:animation']() {
2584
+ const name = args[1]
2585
+
2586
+ if (!name) {
2587
+ console.log('Usage: node cli/index.js add:animation <name>')
2588
+ console.log('Example: node cli/index.js add:animation hover-glow')
2589
+ return
2590
+ }
2591
+
2592
+ const __dirname = path.dirname(fileURLToPath(import.meta.url))
2593
+ const defaultsPath = path.resolve(__dirname, '../core/defaults.js')
2594
+
2595
+ if (!fs.existsSync(defaultsPath)) {
2596
+ console.error('❌ packages/core/defaults.js not found')
2597
+ process.exit(1)
2598
+ }
2599
+
2600
+ let src = fs.readFileSync(defaultsPath, 'utf8')
2601
+
2602
+ if (src.includes(`'${name}':`)) {
2603
+ console.log(`⚠️ Animation "${name}" already exists in defaults.js`)
2604
+ console.log(' Edit it directly in packages/core/defaults.js')
2605
+ return
2606
+ }
2607
+
2608
+ // Detect type from name
2609
+ let template
2610
+ if (name.startsWith('hover-')) {
2611
+ template = ` '${name}': {\n hover: { y: -6, duration: 0.15, ease: 'power2.out' },\n },`
2612
+ } else if (name.startsWith('active-')) {
2613
+ template = ` '${name}': {\n active: { scale: 0.95, duration: 0.1 },\n },`
2614
+ } else if (name.startsWith('scroll-')) {
2615
+ template = ` '${name}': {\n from: { opacity: 0, y: 30 },\n to: { opacity: 1, y: 0 },\n duration: 0.6,\n ease: 'power2.out',\n scrollTrigger: { trigger: 'self', start: 'top 85%' },\n },`
2616
+ } else if (name.startsWith('stagger-')) {
2617
+ template = ` '${name}': {\n targets: 'children',\n stagger: 0.1,\n from: { opacity: 0, y: 20 },\n to: { opacity: 1, y: 0 },\n },`
2618
+ } else {
2619
+ template = ` '${name}': {\n from: { opacity: 0, y: 40 },\n to: { opacity: 1, y: 0 },\n duration: 0.3,\n ease: 'power2.out',\n },`
2620
+ }
2621
+
2622
+ // Inject before closing of DEFAULT_ANIMATIONS
2623
+ const insertBefore = '\n}\n\nexport const DEFAULT_RULES'
2624
+ src = src.replace(insertBefore, `\n${template}${insertBefore}`)
2625
+
2626
+ fs.writeFileSync(defaultsPath, src)
2627
+ console.log(`✅ Added animation: ${name}`)
2628
+ console.log(` Edit the config in packages/core/defaults.js if needed`)
2629
+ console.log(` Run sync:defaults to apply → node packages/cli/index.js sync:defaults`)
2630
+ },
2631
+
2632
+
2633
+
2634
+ }
409
2635
 
410
2636
  // Run command
411
- if (commands[command]) {
412
- await commands[command](); // top-level await is allowed in ESM
413
- } else {
414
- console.error(`❌ Unknown command: ${command}`);
415
- commands.help();
2637
+ if (!command || command === 'help') {
2638
+ commands.help()
2639
+ } else if (commands[command]) {
2640
+ Promise.resolve(commands[command]()).catch(err => {
2641
+ console.error('❌', err.message)
2642
+ process.exit(1)
2643
+ })
2644
+ } else if (command === 'sync:defaults') {
2645
+ Promise.resolve(commands['sync:defaults']()).catch(err => { console.error('❌', err.message); process.exit(1) })
2646
+ } else if (command === 'add:pattern') {
2647
+ Promise.resolve(commands['add:pattern']()).catch(err => { console.error('❌', err.message); process.exit(1) })
2648
+ } else if (command === 'add:token') {
2649
+ Promise.resolve(commands['add:token']()).catch(err => { console.error('❌', err.message); process.exit(1) })
2650
+ } else if (command === 'add:animation') {
2651
+ Promise.resolve(commands['add:animation']()).catch(err => { console.error('❌', err.message); process.exit(1) })
416
2652
  }
2653
+ else {
2654
+ console.error(`❌ Unknown command: ${command}`)
2655
+ console.log('Run: npx mizumi help')
2656
+ process.exit(1)
2657
+ }