@kbach/react 0.5.15 → 0.5.16

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.
@@ -0,0 +1,3458 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/vite-plugin.ts
21
+ var vite_plugin_exports = {};
22
+ __export(vite_plugin_exports, {
23
+ VIRTUAL_ID: () => VIRTUAL_ID,
24
+ kbach: () => kbach
25
+ });
26
+ module.exports = __toCommonJS(vite_plugin_exports);
27
+ var import_fs = require("fs");
28
+ var import_path = require("path");
29
+
30
+ // src/core/theme.ts
31
+ var defaultColors = {
32
+ transparent: "transparent",
33
+ current: "currentColor",
34
+ black: "#000000",
35
+ white: "#ffffff",
36
+ slate: {
37
+ 1: "#f8fafc",
38
+ 2: "#f1f5f9",
39
+ 3: "#e2e8f0",
40
+ 4: "#cbd5e1",
41
+ 5: "#94a3b8",
42
+ 6: "#64748b",
43
+ 7: "#475569",
44
+ 8: "#334155",
45
+ 9: "#1e293b",
46
+ 10: "#0f172a",
47
+ 11: "#020617",
48
+ 12: "#01020a"
49
+ },
50
+ gray: {
51
+ 1: "#f9fafb",
52
+ 2: "#f3f4f6",
53
+ 3: "#e5e7eb",
54
+ 4: "#d1d5db",
55
+ 5: "#9ca3af",
56
+ 6: "#6b7280",
57
+ 7: "#4b5563",
58
+ 8: "#374151",
59
+ 9: "#1f2937",
60
+ 10: "#111827",
61
+ 11: "#030712",
62
+ 12: "#020409"
63
+ },
64
+ zinc: {
65
+ 1: "#fafafa",
66
+ 2: "#f4f4f5",
67
+ 3: "#e4e4e7",
68
+ 4: "#d4d4d8",
69
+ 5: "#a1a1aa",
70
+ 6: "#71717a",
71
+ 7: "#52525b",
72
+ 8: "#3f3f46",
73
+ 9: "#27272a",
74
+ 10: "#18181b",
75
+ 11: "#09090b",
76
+ 12: "#050506"
77
+ },
78
+ neutral: {
79
+ 1: "#fafafa",
80
+ 2: "#f5f5f5",
81
+ 3: "#e5e5e5",
82
+ 4: "#d4d4d4",
83
+ 5: "#a3a3a3",
84
+ 6: "#737373",
85
+ 7: "#525252",
86
+ 8: "#404040",
87
+ 9: "#262626",
88
+ 10: "#171717",
89
+ 11: "#0a0a0a",
90
+ 12: "#050505"
91
+ },
92
+ stone: {
93
+ 1: "#fafaf9",
94
+ 2: "#f5f5f4",
95
+ 3: "#e7e5e4",
96
+ 4: "#d6d3d1",
97
+ 5: "#a8a29e",
98
+ 6: "#78716c",
99
+ 7: "#57534e",
100
+ 8: "#44403c",
101
+ 9: "#292524",
102
+ 10: "#1c1917",
103
+ 11: "#0c0a09",
104
+ 12: "#070605"
105
+ },
106
+ red: {
107
+ 1: "#fef2f2",
108
+ 2: "#fee2e2",
109
+ 3: "#fecaca",
110
+ 4: "#fca5a5",
111
+ 5: "#f87171",
112
+ 6: "#ef4444",
113
+ 7: "#dc2626",
114
+ 8: "#b91c1c",
115
+ 9: "#991b1b",
116
+ 10: "#7f1d1d",
117
+ 11: "#450a0a",
118
+ 12: "#280606"
119
+ },
120
+ orange: {
121
+ 1: "#fff7ed",
122
+ 2: "#ffedd5",
123
+ 3: "#fed7aa",
124
+ 4: "#fdba74",
125
+ 5: "#fb923c",
126
+ 6: "#f97316",
127
+ 7: "#ea580c",
128
+ 8: "#c2410c",
129
+ 9: "#9a3412",
130
+ 10: "#7c2d12",
131
+ 11: "#431407",
132
+ 12: "#270c04"
133
+ },
134
+ amber: {
135
+ 1: "#fffbeb",
136
+ 2: "#fef3c7",
137
+ 3: "#fde68a",
138
+ 4: "#fcd34d",
139
+ 5: "#fbbf24",
140
+ 6: "#f59e0b",
141
+ 7: "#d97706",
142
+ 8: "#b45309",
143
+ 9: "#92400e",
144
+ 10: "#78350f",
145
+ 11: "#451a03",
146
+ 12: "#291002"
147
+ },
148
+ yellow: {
149
+ 1: "#fefce8",
150
+ 2: "#fef9c3",
151
+ 3: "#fef08a",
152
+ 4: "#fde047",
153
+ 5: "#facc15",
154
+ 6: "#eab308",
155
+ 7: "#ca8a04",
156
+ 8: "#a16207",
157
+ 9: "#854d0e",
158
+ 10: "#713f12",
159
+ 11: "#422006",
160
+ 12: "#271304"
161
+ },
162
+ lime: {
163
+ 1: "#f7fee7",
164
+ 2: "#ecfccb",
165
+ 3: "#d9f99d",
166
+ 4: "#bef264",
167
+ 5: "#a3e635",
168
+ 6: "#84cc16",
169
+ 7: "#65a30d",
170
+ 8: "#4d7c0f",
171
+ 9: "#3f6212",
172
+ 10: "#365314",
173
+ 11: "#1a2e05",
174
+ 12: "#0f1b03"
175
+ },
176
+ green: {
177
+ 1: "#f0fdf4",
178
+ 2: "#dcfce7",
179
+ 3: "#bbf7d0",
180
+ 4: "#86efac",
181
+ 5: "#4ade80",
182
+ 6: "#22c55e",
183
+ 7: "#16a34a",
184
+ 8: "#15803d",
185
+ 9: "#166534",
186
+ 10: "#14532d",
187
+ 11: "#052e16",
188
+ 12: "#031b0d"
189
+ },
190
+ emerald: {
191
+ 1: "#ecfdf5",
192
+ 2: "#d1fae5",
193
+ 3: "#a7f3d0",
194
+ 4: "#6ee7b7",
195
+ 5: "#34d399",
196
+ 6: "#10b981",
197
+ 7: "#059669",
198
+ 8: "#047857",
199
+ 9: "#065f46",
200
+ 10: "#064e3b",
201
+ 11: "#022c22",
202
+ 12: "#011a14"
203
+ },
204
+ teal: {
205
+ 1: "#f0fdfa",
206
+ 2: "#ccfbf1",
207
+ 3: "#99f6e4",
208
+ 4: "#5eead4",
209
+ 5: "#2dd4bf",
210
+ 6: "#14b8a6",
211
+ 7: "#0d9488",
212
+ 8: "#0f766e",
213
+ 9: "#115e59",
214
+ 10: "#134e4a",
215
+ 11: "#042f2e",
216
+ 12: "#021c1b"
217
+ },
218
+ cyan: {
219
+ 1: "#ecfeff",
220
+ 2: "#cffafe",
221
+ 3: "#a5f3fc",
222
+ 4: "#67e8f9",
223
+ 5: "#22d3ee",
224
+ 6: "#06b6d4",
225
+ 7: "#0891b2",
226
+ 8: "#0e7490",
227
+ 9: "#155e75",
228
+ 10: "#164e63",
229
+ 11: "#083344",
230
+ 12: "#041e28"
231
+ },
232
+ sky: {
233
+ 1: "#f0f9ff",
234
+ 2: "#e0f2fe",
235
+ 3: "#bae6fd",
236
+ 4: "#7dd3fc",
237
+ 5: "#38bdf8",
238
+ 6: "#0ea5e9",
239
+ 7: "#0284c7",
240
+ 8: "#0369a1",
241
+ 9: "#075985",
242
+ 10: "#0c4a6e",
243
+ 11: "#082f49",
244
+ 12: "#041b2b"
245
+ },
246
+ blue: {
247
+ 1: "#eff6ff",
248
+ 2: "#dbeafe",
249
+ 3: "#bfdbfe",
250
+ 4: "#93c5fd",
251
+ 5: "#60a5fa",
252
+ 6: "#3b82f6",
253
+ 7: "#2563eb",
254
+ 8: "#1d4ed8",
255
+ 9: "#1e40af",
256
+ 10: "#1e3a8a",
257
+ 11: "#172554",
258
+ 12: "#0d1633"
259
+ },
260
+ indigo: {
261
+ 1: "#eef2ff",
262
+ 2: "#e0e7ff",
263
+ 3: "#c7d2fe",
264
+ 4: "#a5b4fc",
265
+ 5: "#818cf8",
266
+ 6: "#6366f1",
267
+ 7: "#4f46e5",
268
+ 8: "#4338ca",
269
+ 9: "#3730a3",
270
+ 10: "#312e81",
271
+ 11: "#1e1b4b",
272
+ 12: "#12102d"
273
+ },
274
+ violet: {
275
+ 1: "#f5f3ff",
276
+ 2: "#ede9fe",
277
+ 3: "#ddd6fe",
278
+ 4: "#c4b5fd",
279
+ 5: "#a78bfa",
280
+ 6: "#8b5cf6",
281
+ 7: "#7c3aed",
282
+ 8: "#6d28d9",
283
+ 9: "#5b21b6",
284
+ 10: "#4c1d95",
285
+ 11: "#2e1065",
286
+ 12: "#1c0a3d"
287
+ },
288
+ purple: {
289
+ 1: "#faf5ff",
290
+ 2: "#f3e8ff",
291
+ 3: "#e9d5ff",
292
+ 4: "#d8b4fe",
293
+ 5: "#c084fc",
294
+ 6: "#a855f7",
295
+ 7: "#9333ea",
296
+ 8: "#7e22ce",
297
+ 9: "#6b21a8",
298
+ 10: "#581c87",
299
+ 11: "#3b0764",
300
+ 12: "#23043c"
301
+ },
302
+ fuchsia: {
303
+ 1: "#fdf4ff",
304
+ 2: "#fae8ff",
305
+ 3: "#f5d0fe",
306
+ 4: "#f0abfc",
307
+ 5: "#e879f9",
308
+ 6: "#d946ef",
309
+ 7: "#c026d3",
310
+ 8: "#a21caf",
311
+ 9: "#86198f",
312
+ 10: "#701a75",
313
+ 11: "#4a044e",
314
+ 12: "#2d022f"
315
+ },
316
+ pink: {
317
+ 1: "#fdf2f8",
318
+ 2: "#fce7f3",
319
+ 3: "#fbcfe8",
320
+ 4: "#f9a8d4",
321
+ 5: "#f472b6",
322
+ 6: "#ec4899",
323
+ 7: "#db2777",
324
+ 8: "#be185d",
325
+ 9: "#9d174d",
326
+ 10: "#831843",
327
+ 11: "#500724",
328
+ 12: "#300415"
329
+ },
330
+ rose: {
331
+ 1: "#fff1f2",
332
+ 2: "#ffe4e6",
333
+ 3: "#fecdd3",
334
+ 4: "#fda4af",
335
+ 5: "#fb7185",
336
+ 6: "#f43f5e",
337
+ 7: "#e11d48",
338
+ 8: "#be123c",
339
+ 9: "#9f1239",
340
+ 10: "#881337",
341
+ 11: "#4c0519",
342
+ 12: "#2d030e"
343
+ }
344
+ };
345
+ var defaultTheme = {
346
+ colors: defaultColors,
347
+ // 1 unit = 4px
348
+ spacing: {
349
+ px: 1,
350
+ 0: 0,
351
+ "0.5": 2,
352
+ 1: 4,
353
+ "1.5": 6,
354
+ 2: 8,
355
+ "2.5": 10,
356
+ 3: 12,
357
+ "3.5": 14,
358
+ 4: 16,
359
+ 5: 20,
360
+ 6: 24,
361
+ 7: 28,
362
+ 8: 32,
363
+ 9: 36,
364
+ 10: 40,
365
+ 11: 44,
366
+ 12: 48,
367
+ 14: 56,
368
+ 16: 64,
369
+ 20: 80,
370
+ 24: 96,
371
+ 28: 112,
372
+ 32: 128,
373
+ 36: 144,
374
+ 40: 160,
375
+ 44: 176,
376
+ 48: 192,
377
+ 52: 208,
378
+ 56: 224,
379
+ 60: 240,
380
+ 64: 256,
381
+ 72: 288,
382
+ 80: 320,
383
+ 96: 384,
384
+ auto: "auto",
385
+ full: "100%",
386
+ "1/2": "50%",
387
+ "1/3": "33.333333%",
388
+ "2/3": "66.666667%",
389
+ "1/4": "25%",
390
+ "3/4": "75%",
391
+ screen: "100vh",
392
+ min: "min-content",
393
+ max: "max-content",
394
+ fit: "fit-content"
395
+ },
396
+ fontSize: {
397
+ xs: 12,
398
+ sm: 14,
399
+ base: 16,
400
+ lg: 18,
401
+ xl: 20,
402
+ "2xl": 24,
403
+ "3xl": 30,
404
+ "4xl": 36,
405
+ "5xl": 48,
406
+ "6xl": 60,
407
+ "7xl": 72,
408
+ "8xl": 96,
409
+ "9xl": 128
410
+ },
411
+ fontFamily: {
412
+ sans: "System",
413
+ mono: "Courier New",
414
+ serif: "Georgia"
415
+ },
416
+ fontWeight: {
417
+ thin: "100",
418
+ extralight: "200",
419
+ light: "300",
420
+ normal: "400",
421
+ medium: "500",
422
+ semibold: "600",
423
+ bold: "700",
424
+ extrabold: "800",
425
+ black: "900"
426
+ },
427
+ borderRadius: {
428
+ none: 0,
429
+ sm: 2,
430
+ DEFAULT: 4,
431
+ md: 6,
432
+ lg: 8,
433
+ xl: 12,
434
+ "2xl": 16,
435
+ "3xl": 24,
436
+ full: 9999
437
+ },
438
+ borderWidth: {
439
+ DEFAULT: 1,
440
+ 0: 0,
441
+ 2: 2,
442
+ 4: 4,
443
+ 8: 8
444
+ },
445
+ opacity: {
446
+ 0: 0,
447
+ 5: 0.05,
448
+ 10: 0.1,
449
+ 15: 0.15,
450
+ 20: 0.2,
451
+ 25: 0.25,
452
+ 30: 0.3,
453
+ 40: 0.4,
454
+ 50: 0.5,
455
+ 60: 0.6,
456
+ 70: 0.7,
457
+ 75: 0.75,
458
+ 80: 0.8,
459
+ 90: 0.9,
460
+ 95: 0.95,
461
+ 100: 1
462
+ },
463
+ lineHeight: {
464
+ none: 1,
465
+ tight: 1.25,
466
+ snug: 1.375,
467
+ normal: 1.5,
468
+ relaxed: 1.625,
469
+ loose: 2,
470
+ 3: 12,
471
+ 4: 16,
472
+ 5: 20,
473
+ 6: 24,
474
+ 7: 28,
475
+ 8: 32,
476
+ 9: 36,
477
+ 10: 40
478
+ },
479
+ letterSpacing: {
480
+ tighter: -0.8,
481
+ tight: -0.4,
482
+ normal: 0,
483
+ wide: 0.4,
484
+ wider: 0.8,
485
+ widest: 1.6
486
+ },
487
+ zIndex: {
488
+ auto: "auto",
489
+ 0: 0,
490
+ 10: 10,
491
+ 20: 20,
492
+ 30: 30,
493
+ 40: 40,
494
+ 50: 50
495
+ },
496
+ flex: {
497
+ 1: 1,
498
+ auto: 1,
499
+ initial: 0,
500
+ none: 0
501
+ },
502
+ shadow: {
503
+ sm: {
504
+ shadowColor: "#000",
505
+ shadowOffset: { width: 0, height: 1 },
506
+ shadowOpacity: 0.05,
507
+ shadowRadius: 2,
508
+ elevation: 1
509
+ },
510
+ DEFAULT: {
511
+ shadowColor: "#000",
512
+ shadowOffset: { width: 0, height: 2 },
513
+ shadowOpacity: 0.1,
514
+ shadowRadius: 4,
515
+ elevation: 2
516
+ },
517
+ md: {
518
+ shadowColor: "#000",
519
+ shadowOffset: { width: 0, height: 4 },
520
+ shadowOpacity: 0.1,
521
+ shadowRadius: 8,
522
+ elevation: 3
523
+ },
524
+ lg: {
525
+ shadowColor: "#000",
526
+ shadowOffset: { width: 0, height: 8 },
527
+ shadowOpacity: 0.1,
528
+ shadowRadius: 15,
529
+ elevation: 4
530
+ },
531
+ xl: {
532
+ shadowColor: "#000",
533
+ shadowOffset: { width: 0, height: 16 },
534
+ shadowOpacity: 0.1,
535
+ shadowRadius: 24,
536
+ elevation: 6
537
+ },
538
+ "2xl": {
539
+ shadowColor: "#000",
540
+ shadowOffset: { width: 0, height: 24 },
541
+ shadowOpacity: 0.25,
542
+ shadowRadius: 48,
543
+ elevation: 8
544
+ },
545
+ none: {
546
+ shadowColor: "transparent",
547
+ shadowOffset: { width: 0, height: 0 },
548
+ shadowOpacity: 0,
549
+ shadowRadius: 0,
550
+ elevation: 0
551
+ }
552
+ },
553
+ screens: {
554
+ sm: 576,
555
+ // small tablets / large phones (landscape)
556
+ md: 768,
557
+ // tablets (iPad and up)
558
+ lg: 1024,
559
+ // large tablets (iPad Pro)
560
+ xl: 1280,
561
+ // desktop
562
+ "2xl": 1536
563
+ }
564
+ };
565
+
566
+ // src/core/platform.ts
567
+ var isWeb = typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined";
568
+ function toNativeValue(raw) {
569
+ if (/^-?\d+(\.\d+)?px$/.test(raw)) return parseFloat(raw);
570
+ if (/^-?\d+(\.\d+)?rem$/.test(raw)) return parseFloat(raw) * 16;
571
+ if (/^-?\d+(\.\d+)?em$/.test(raw)) return parseFloat(raw) * 16;
572
+ if (/^-?\d+(\.\d+)?$/.test(raw)) return parseFloat(raw);
573
+ return raw;
574
+ }
575
+ function escapeCSSSelector(cls) {
576
+ return cls.replace(/[!"#$%&'()*+,./:;<=>?@[\\\]^`{|}~]/g, "\\$&");
577
+ }
578
+
579
+ // src/core/utilities.ts
580
+ function resolveColor(value, colors, isArbitrary) {
581
+ if (isArbitrary) return value;
582
+ const slashIdx = value.indexOf("/");
583
+ const colorPart = slashIdx > 0 ? value.slice(0, slashIdx) : value;
584
+ const opacityPart = slashIdx > 0 ? value.slice(slashIdx + 1) : null;
585
+ let hex = null;
586
+ if (colorPart in colors) {
587
+ const entry = colors[colorPart];
588
+ if (typeof entry === "string") hex = entry;
589
+ else if (typeof entry === "object" && "6" in entry) hex = entry["6"];
590
+ } else {
591
+ const lastDash = colorPart.lastIndexOf("-");
592
+ if (lastDash > 0) {
593
+ const colorName = colorPart.slice(0, lastDash);
594
+ const shade = colorPart.slice(lastDash + 1);
595
+ const scale = colors[colorName];
596
+ if (scale && typeof scale === "object" && shade in scale) {
597
+ hex = scale[shade] ?? null;
598
+ }
599
+ }
600
+ }
601
+ if (hex && !hex.startsWith("#") && !hex.startsWith("rgb") && hex !== "transparent" && hex !== "currentColor") {
602
+ if (hex in colors) {
603
+ const alias = colors[hex];
604
+ if (typeof alias === "string") hex = alias;
605
+ else if (typeof alias === "object" && "6" in alias) hex = alias["6"] ?? hex;
606
+ } else {
607
+ const aliasLastDash = hex.lastIndexOf("-");
608
+ if (aliasLastDash > 0) {
609
+ const aliasColorName = hex.slice(0, aliasLastDash);
610
+ const aliasShade = hex.slice(aliasLastDash + 1);
611
+ const aliasScale = colors[aliasColorName];
612
+ if (aliasScale && typeof aliasScale === "object") {
613
+ hex = aliasScale[aliasShade] ?? null;
614
+ } else if (typeof aliasScale === "string") {
615
+ hex = aliasScale;
616
+ }
617
+ }
618
+ }
619
+ }
620
+ if (!hex) return null;
621
+ if (!opacityPart) return hex;
622
+ let alpha;
623
+ if (opacityPart.startsWith("[") && opacityPart.endsWith("]")) {
624
+ const v = parseFloat(opacityPart.slice(1, -1));
625
+ alpha = v > 1 ? v / 100 : v;
626
+ } else {
627
+ alpha = parseFloat(opacityPart) / 100;
628
+ }
629
+ if (isNaN(alpha)) return hex;
630
+ return hexToRgba(hex, alpha);
631
+ }
632
+ function hexToRgba(hex, alpha) {
633
+ const h = hex.replace("#", "");
634
+ let r, g, b;
635
+ if (h.length === 3) {
636
+ r = parseInt(h[0] + h[0], 16);
637
+ g = parseInt(h[1] + h[1], 16);
638
+ b = parseInt(h[2] + h[2], 16);
639
+ } else {
640
+ r = parseInt(h.slice(0, 2), 16);
641
+ g = parseInt(h.slice(2, 4), 16);
642
+ b = parseInt(h.slice(4, 6), 16);
643
+ }
644
+ return `rgba(${r},${g},${b},${alpha})`;
645
+ }
646
+ function resolveSpacing(value, negative, spacing, isArbitrary) {
647
+ if (isArbitrary) {
648
+ const resolved = isWeb ? value : toNativeValue(value);
649
+ return negative && typeof resolved === "number" ? -resolved : resolved;
650
+ }
651
+ const raw = spacing[value];
652
+ if (raw === void 0) return null;
653
+ if (typeof raw === "number") return negative ? -raw : raw;
654
+ if (raw === "auto") return "auto";
655
+ if (negative && typeof raw === "string" && raw.endsWith("%")) {
656
+ return `-${raw}`;
657
+ }
658
+ return raw;
659
+ }
660
+ function resolveSizing(value, spacing, isArbitrary) {
661
+ if (isArbitrary) return isWeb ? value : toNativeValue(value);
662
+ const raw = spacing[value];
663
+ if (raw !== void 0) return raw;
664
+ if (/^\d+\/\d+$/.test(value)) {
665
+ const [num, den] = value.split("/").map(Number);
666
+ return `${(num / den * 100).toFixed(6)}%`;
667
+ }
668
+ return null;
669
+ }
670
+ function resolveRadius(value, radii, isArbitrary) {
671
+ if (isArbitrary) return isWeb ? value : toNativeValue(value);
672
+ const key = value === "" ? "DEFAULT" : value;
673
+ return radii[key] ?? null;
674
+ }
675
+ function resolveFontSize(value, fontSizes, isArbitrary) {
676
+ if (isArbitrary) return isWeb ? value : toNativeValue(value);
677
+ return fontSizes[value] ?? null;
678
+ }
679
+ var FILTER_COMPOSE = "var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)";
680
+ var BACKDROP_FILTER_COMPOSE = "var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)";
681
+ var STANDALONE = {
682
+ // Display
683
+ // React Native only supports display:'flex'|'none'. Setting 'flex' explicitly is
684
+ // a no-op normally, but is needed to re-show an element that was hidden via `hidden`.
685
+ // `grid`, `inline-*`, `contents`, `flow-root` have no native equivalent.
686
+ flex: { display: "flex" },
687
+ block: isWeb ? { display: "block" } : null,
688
+ "inline-block": isWeb ? { display: "inline-block" } : null,
689
+ inline: isWeb ? { display: "inline" } : null,
690
+ grid: isWeb ? { display: "grid" } : null,
691
+ grd: isWeb ? { display: "grid" } : null,
692
+ "inline-flex": { display: isWeb ? "inline-flex" : "flex" },
693
+ "inline-grid": isWeb ? { display: "inline-grid" } : null,
694
+ hidden: { display: "none" },
695
+ contents: isWeb ? { display: "contents" } : null,
696
+ "flow-root": isWeb ? { display: "flow-root" } : null,
697
+ // Flex direction (both web and native)
698
+ "flex-row": { flexDirection: "row" },
699
+ "flex-col": { flexDirection: "column" },
700
+ "flex-row-reverse": { flexDirection: "row-reverse" },
701
+ "flex-col-reverse": { flexDirection: "column-reverse" },
702
+ // Flex wrap (both)
703
+ "flex-wrap": { flexWrap: "wrap" },
704
+ "flex-wrap-reverse": { flexWrap: "wrap-reverse" },
705
+ "flex-nowrap": { flexWrap: "nowrap" },
706
+ // Flex grow / shrink (both)
707
+ "flex-grow": { flexGrow: 1 },
708
+ "flex-grow-0": { flexGrow: 0 },
709
+ "flex-shrink": { flexShrink: 1 },
710
+ "flex-shrink-0": { flexShrink: 0 },
711
+ // Align items (both)
712
+ "items-start": { alignItems: "flex-start" },
713
+ "items-end": { alignItems: "flex-end" },
714
+ "items-center": { alignItems: "center" },
715
+ "items-baseline": { alignItems: "baseline" },
716
+ "items-stretch": { alignItems: "stretch" },
717
+ // Justify content (both)
718
+ "justify-start": { justifyContent: "flex-start" },
719
+ "justify-end": { justifyContent: "flex-end" },
720
+ "justify-center": { justifyContent: "center" },
721
+ "justify-between": { justifyContent: "space-between" },
722
+ "justify-around": { justifyContent: "space-around" },
723
+ "justify-evenly": { justifyContent: "space-evenly" },
724
+ // Align content (both)
725
+ "content-start": { alignContent: "flex-start" },
726
+ "content-end": { alignContent: "flex-end" },
727
+ "content-center": { alignContent: "center" },
728
+ "content-between": { alignContent: "space-between" },
729
+ "content-around": { alignContent: "space-around" },
730
+ "content-evenly": { alignContent: "space-evenly" },
731
+ "content-stretch": { alignContent: "stretch" },
732
+ // Align self (both)
733
+ "self-auto": { alignSelf: "auto" },
734
+ "self-start": { alignSelf: "flex-start" },
735
+ "self-end": { alignSelf: "flex-end" },
736
+ "self-center": { alignSelf: "center" },
737
+ "self-stretch": { alignSelf: "stretch" },
738
+ "self-baseline": { alignSelf: "baseline" },
739
+ // Text align (both)
740
+ "text-left": { textAlign: "left" },
741
+ "text-right": { textAlign: "right" },
742
+ "text-center": { textAlign: "center" },
743
+ "text-justify": { textAlign: "justify" },
744
+ // Font weight shortcuts (both)
745
+ "font-thin": { fontWeight: "100" },
746
+ "font-extralight": { fontWeight: "200" },
747
+ "font-light": { fontWeight: "300" },
748
+ "font-normal": { fontWeight: "400" },
749
+ "font-medium": { fontWeight: "500" },
750
+ "font-semibold": { fontWeight: "600" },
751
+ "font-bold": { fontWeight: "700" },
752
+ "font-extrabold": { fontWeight: "800" },
753
+ "font-black": { fontWeight: "900" },
754
+ // Text decoration (overline is web-only)
755
+ underline: { textDecorationLine: "underline" },
756
+ overline: isWeb ? { textDecorationLine: "overline" } : null,
757
+ "line-through": { textDecorationLine: "line-through" },
758
+ "no-underline": { textDecorationLine: "none" },
759
+ // Text transform (both)
760
+ uppercase: { textTransform: "uppercase" },
761
+ lowercase: { textTransform: "lowercase" },
762
+ capitalize: { textTransform: "capitalize" },
763
+ "normal-case": { textTransform: "none" },
764
+ // Font style (both)
765
+ italic: { fontStyle: "italic" },
766
+ "non-italic": { fontStyle: "normal" },
767
+ // Position (fixed/sticky/static are web-only; RN only supports relative/absolute)
768
+ relative: { position: "relative" },
769
+ absolute: { position: "absolute" },
770
+ fixed: isWeb ? { position: "fixed" } : null,
771
+ sticky: isWeb ? { position: "sticky" } : null,
772
+ static: isWeb ? { position: "static" } : null,
773
+ // Visibility (no `visibility` prop on native; use opacity instead)
774
+ visible: isWeb ? { visibility: "visible" } : null,
775
+ invisible: isWeb ? { visibility: "hidden" } : { opacity: 0 },
776
+ // Overflow (RN supports 'hidden' | 'visible' | 'scroll'; not 'auto')
777
+ "overflow-hidden": { overflow: "hidden" },
778
+ "overflow-visible": { overflow: "visible" },
779
+ "overflow-scroll": { overflow: "scroll" },
780
+ "overflow-auto": isWeb ? { overflow: "auto" } : { overflow: "scroll" },
781
+ // overflowX / overflowY are web-only
782
+ "overflow-x-hidden": isWeb ? { overflowX: "hidden" } : null,
783
+ "overflow-x-scroll": isWeb ? { overflowX: "scroll" } : null,
784
+ "overflow-x-auto": isWeb ? { overflowX: "auto" } : null,
785
+ "overflow-y-hidden": isWeb ? { overflowY: "hidden" } : null,
786
+ "overflow-y-scroll": isWeb ? { overflowY: "scroll" } : null,
787
+ "overflow-y-auto": isWeb ? { overflowY: "auto" } : null,
788
+ // Object fit (web-only; use resizeMode prop on RN Image)
789
+ "object-contain": isWeb ? { objectFit: "contain" } : null,
790
+ "object-cover": isWeb ? { objectFit: "cover" } : null,
791
+ "object-fill": isWeb ? { objectFit: "fill" } : null,
792
+ "object-none": isWeb ? { objectFit: "none" } : null,
793
+ "object-scale-down": isWeb ? { objectFit: "scale-down" } : null,
794
+ // Border style (both)
795
+ "border-solid": { borderStyle: "solid" },
796
+ "border-dashed": { borderStyle: "dashed" },
797
+ "border-dotted": { borderStyle: "dotted" },
798
+ "border-none": { borderWidth: 0 },
799
+ // Border sides default width (both)
800
+ "border-t": { borderTopWidth: 1 },
801
+ "border-r": { borderRightWidth: 1 },
802
+ "border-b": { borderBottomWidth: 1 },
803
+ "border-l": { borderLeftWidth: 1 },
804
+ // Cursor (web-only)
805
+ "cursor-auto": isWeb ? { cursor: "auto" } : null,
806
+ "cursor-default": isWeb ? { cursor: "default" } : null,
807
+ "cursor-pointer": isWeb ? { cursor: "pointer" } : null,
808
+ "cursor-wait": isWeb ? { cursor: "wait" } : null,
809
+ "cursor-text": isWeb ? { cursor: "text" } : null,
810
+ "cursor-move": isWeb ? { cursor: "move" } : null,
811
+ "cursor-not-allowed": isWeb ? { cursor: "not-allowed" } : null,
812
+ // User select (web-only)
813
+ "select-none": isWeb ? { userSelect: "none" } : null,
814
+ "select-text": isWeb ? { userSelect: "text" } : null,
815
+ "select-all": isWeb ? { userSelect: "all" } : null,
816
+ "select-auto": isWeb ? { userSelect: "auto" } : null,
817
+ // Pointer events (both)
818
+ "pointer-events-none": { pointerEvents: "none" },
819
+ "pointer-events-auto": { pointerEvents: "auto" },
820
+ // Whitespace (web-only; RN Text uses numberOfLines prop instead)
821
+ "whitespace-normal": isWeb ? { whiteSpace: "normal" } : null,
822
+ "whitespace-nowrap": isWeb ? { whiteSpace: "nowrap" } : null,
823
+ "whitespace-pre": isWeb ? { whiteSpace: "pre" } : null,
824
+ "whitespace-pre-wrap": isWeb ? { whiteSpace: "pre-wrap" } : null,
825
+ "whitespace-pre-line": isWeb ? { whiteSpace: "pre-line" } : null,
826
+ // Word break (web-only)
827
+ "break-normal": isWeb ? { overflowWrap: "normal", wordBreak: "normal" } : null,
828
+ "break-words": isWeb ? { overflowWrap: "break-word" } : null,
829
+ "break-all": isWeb ? { wordBreak: "break-all" } : null,
830
+ // Misc web-only
831
+ truncate: isWeb ? { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" } : null,
832
+ "box-border": isWeb ? { boxSizing: "border-box" } : null,
833
+ "box-content": isWeb ? { boxSizing: "content-box" } : null,
834
+ "appearance-none": isWeb ? { appearance: "none" } : null,
835
+ "outline-none": isWeb ? { outline: "none", outlineOffset: "0" } : null,
836
+ outline: isWeb ? { outline: "2px solid transparent", outlineOffset: "2px" } : null,
837
+ resize: isWeb ? { resize: "both" } : null,
838
+ "resize-none": isWeb ? { resize: "none" } : null,
839
+ "resize-y": isWeb ? { resize: "vertical" } : null,
840
+ "resize-x": isWeb ? { resize: "horizontal" } : null,
841
+ antialiased: isWeb ? { WebkitFontSmoothing: "antialiased", MozOsxFontSmoothing: "grayscale" } : null,
842
+ "subpixel-antialiased": isWeb ? { WebkitFontSmoothing: "subpixel-antialiased", MozOsxFontSmoothing: "auto" } : null,
843
+ "overflow-ellipsis": isWeb ? { textOverflow: "ellipsis" } : null,
844
+ "sr-only": isWeb ? {
845
+ position: "absolute",
846
+ width: 1,
847
+ height: 1,
848
+ padding: 0,
849
+ margin: -1,
850
+ overflow: "hidden",
851
+ clip: "rect(0,0,0,0)",
852
+ whiteSpace: "nowrap",
853
+ border: 0
854
+ } : null,
855
+ "not-sr-only": isWeb ? {
856
+ position: "static",
857
+ width: "auto",
858
+ height: "auto",
859
+ padding: 0,
860
+ margin: 0,
861
+ overflow: "visible",
862
+ clip: "auto",
863
+ whiteSpace: "normal"
864
+ } : null,
865
+ // Lists (web-only)
866
+ "list-none": isWeb ? { listStyleType: "none" } : null,
867
+ "list-disc": isWeb ? { listStyleType: "disc" } : null,
868
+ "list-decimal": isWeb ? { listStyleType: "decimal" } : null,
869
+ // Background clip (web-only)
870
+ "bg-clip-border": isWeb ? { backgroundClip: "border-box" } : null,
871
+ "bg-clip-padding": isWeb ? { backgroundClip: "padding-box" } : null,
872
+ "bg-clip-content": isWeb ? { backgroundClip: "content-box" } : null,
873
+ "bg-clip-text": isWeb ? { backgroundClip: "text", WebkitBackgroundClip: "text" } : null,
874
+ // Background image
875
+ "bg-none": isWeb ? { backgroundImage: "none" } : null,
876
+ // Background size (web-only)
877
+ "bg-auto": isWeb ? { backgroundSize: "auto" } : null,
878
+ "bg-cover": isWeb ? { backgroundSize: "cover" } : null,
879
+ "bg-contain": isWeb ? { backgroundSize: "contain" } : null,
880
+ // Background position (web-only)
881
+ "bg-center": isWeb ? { backgroundPosition: "center" } : null,
882
+ "bg-top": isWeb ? { backgroundPosition: "top" } : null,
883
+ "bg-bottom": isWeb ? { backgroundPosition: "bottom" } : null,
884
+ "bg-left": isWeb ? { backgroundPosition: "left" } : null,
885
+ "bg-right": isWeb ? { backgroundPosition: "right" } : null,
886
+ "bg-left-top": isWeb ? { backgroundPosition: "left top" } : null,
887
+ "bg-left-bottom": isWeb ? { backgroundPosition: "left bottom" } : null,
888
+ "bg-right-top": isWeb ? { backgroundPosition: "right top" } : null,
889
+ "bg-right-bottom": isWeb ? { backgroundPosition: "right bottom" } : null,
890
+ // Background repeat (web-only)
891
+ "bg-repeat": isWeb ? { backgroundRepeat: "repeat" } : null,
892
+ "bg-no-repeat": isWeb ? { backgroundRepeat: "no-repeat" } : null,
893
+ "bg-repeat-x": isWeb ? { backgroundRepeat: "repeat-x" } : null,
894
+ "bg-repeat-y": isWeb ? { backgroundRepeat: "repeat-y" } : null,
895
+ "bg-repeat-round": isWeb ? { backgroundRepeat: "round" } : null,
896
+ "bg-repeat-space": isWeb ? { backgroundRepeat: "space" } : null,
897
+ // Background attachment (web-only)
898
+ "bg-fixed": isWeb ? { backgroundAttachment: "fixed" } : null,
899
+ "bg-local": isWeb ? { backgroundAttachment: "local" } : null,
900
+ "bg-scroll": isWeb ? { backgroundAttachment: "scroll" } : null,
901
+ // Object position (web-only)
902
+ "object-center": isWeb ? { objectPosition: "center" } : null,
903
+ "object-top": isWeb ? { objectPosition: "top" } : null,
904
+ "object-bottom": isWeb ? { objectPosition: "bottom" } : null,
905
+ "object-left": isWeb ? { objectPosition: "left" } : null,
906
+ "object-right": isWeb ? { objectPosition: "right" } : null,
907
+ "object-left-top": isWeb ? { objectPosition: "left top" } : null,
908
+ "object-left-bottom": isWeb ? { objectPosition: "left bottom" } : null,
909
+ "object-right-top": isWeb ? { objectPosition: "right top" } : null,
910
+ "object-right-bottom": isWeb ? { objectPosition: "right bottom" } : null,
911
+ // Table (web-only)
912
+ table: isWeb ? { display: "table" } : null,
913
+ "table-auto": isWeb ? { tableLayout: "auto" } : null,
914
+ "table-fixed": isWeb ? { tableLayout: "fixed" } : null,
915
+ "caption-top": isWeb ? { captionSide: "top" } : null,
916
+ "caption-bottom": isWeb ? { captionSide: "bottom" } : null,
917
+ "border-collapse": isWeb ? { borderCollapse: "collapse" } : null,
918
+ "border-separate": isWeb ? { borderCollapse: "separate" } : null,
919
+ // List style position (web-only)
920
+ "list-inside": isWeb ? { listStylePosition: "inside" } : null,
921
+ "list-outside": isWeb ? { listStylePosition: "outside" } : null,
922
+ // Font variant numeric (web-only)
923
+ "normal-nums": isWeb ? { fontVariantNumeric: "normal" } : null,
924
+ ordinal: isWeb ? { fontVariantNumeric: "ordinal" } : null,
925
+ "slashed-zero": isWeb ? { fontVariantNumeric: "slashed-zero" } : null,
926
+ "lining-nums": isWeb ? { fontVariantNumeric: "lining-nums" } : null,
927
+ "oldstyle-nums": isWeb ? { fontVariantNumeric: "oldstyle-nums" } : null,
928
+ "proportional-nums": isWeb ? { fontVariantNumeric: "proportional-nums" } : null,
929
+ "tabular-nums": isWeb ? { fontVariantNumeric: "tabular-nums" } : null,
930
+ "diagonal-fractions": isWeb ? { fontVariantNumeric: "diagonal-fractions" } : null,
931
+ "stacked-fractions": isWeb ? { fontVariantNumeric: "stacked-fractions" } : null,
932
+ // Isolation (web-only)
933
+ isolate: isWeb ? { isolation: "isolate" } : null,
934
+ "isolation-auto": isWeb ? { isolation: "auto" } : null,
935
+ // Backface visibility (both iOS and Android)
936
+ "backface-visible": { backfaceVisibility: "visible" },
937
+ "backface-hidden": { backfaceVisibility: "hidden" },
938
+ // CSS filters — standalone = default/full effect (web-only)
939
+ grayscale: isWeb ? { "--tw-grayscale": "grayscale(100%)", filter: FILTER_COMPOSE } : null,
940
+ invert: isWeb ? { "--tw-invert": "invert(100%)", filter: FILTER_COMPOSE } : null,
941
+ sepia: isWeb ? { "--tw-sepia": "sepia(100%)", filter: FILTER_COMPOSE } : null,
942
+ // Divide none
943
+ "divide-none": isWeb ? { __divideX: 0, __divideY: 0 } : null,
944
+ // Group / peer markers (no-op: no style emitted; just ensures isKnownUtility returns true)
945
+ group: isWeb ? {} : null,
946
+ peer: isWeb ? {} : null,
947
+ // Text-wrap (web-only)
948
+ "text-wrap": isWeb ? { textWrap: "wrap" } : null,
949
+ "text-nowrap": isWeb ? { textWrap: "nowrap" } : null,
950
+ "text-balance": isWeb ? { textWrap: "balance" } : null,
951
+ "text-pretty": isWeb ? { textWrap: "pretty" } : null,
952
+ // Screen sizing (vw values are web-only; vh values work cross-platform via spacing scale for h-*)
953
+ "w-screen": isWeb ? { width: "100vw" } : null,
954
+ "min-h-screen": { minHeight: "100vh" },
955
+ "max-h-screen": { maxHeight: "100vh" },
956
+ "min-w-screen": isWeb ? { minWidth: "100vw" } : null,
957
+ "max-w-screen": isWeb ? { maxWidth: "100vw" } : null,
958
+ // max-w named container sizes (mirrors Tailwind's container scale)
959
+ "max-w-none": { maxWidth: "none" },
960
+ "max-w-xs": { maxWidth: 320 },
961
+ "max-w-sm": { maxWidth: 384 },
962
+ "max-w-md": { maxWidth: 448 },
963
+ "max-w-lg": { maxWidth: 512 },
964
+ "max-w-xl": { maxWidth: 576 },
965
+ "max-w-2xl": { maxWidth: 672 },
966
+ "max-w-3xl": { maxWidth: 768 },
967
+ "max-w-4xl": { maxWidth: 896 },
968
+ "max-w-5xl": { maxWidth: 1024 },
969
+ "max-w-6xl": { maxWidth: 1152 },
970
+ "max-w-7xl": { maxWidth: 1280 },
971
+ "max-w-prose": isWeb ? { maxWidth: "65ch" } : null,
972
+ // Extended cursors (web-only)
973
+ "cursor-grab": isWeb ? { cursor: "grab" } : null,
974
+ "cursor-grabbing": isWeb ? { cursor: "grabbing" } : null,
975
+ "cursor-zoom-in": isWeb ? { cursor: "zoom-in" } : null,
976
+ "cursor-zoom-out": isWeb ? { cursor: "zoom-out" } : null,
977
+ "cursor-crosshair": isWeb ? { cursor: "crosshair" } : null,
978
+ "cursor-help": isWeb ? { cursor: "help" } : null,
979
+ "cursor-none": isWeb ? { cursor: "none" } : null,
980
+ // Overflow clip (web-only)
981
+ "overflow-clip": isWeb ? { overflow: "clip" } : null,
982
+ "overflow-x-clip": isWeb ? { overflowX: "clip" } : null,
983
+ "overflow-y-clip": isWeb ? { overflowY: "clip" } : null,
984
+ // Scroll behavior (web-only)
985
+ "scroll-smooth": isWeb ? { scrollBehavior: "smooth" } : null,
986
+ "scroll-auto": isWeb ? { scrollBehavior: "auto" } : null,
987
+ // Float (web-only)
988
+ "float-left": isWeb ? { float: "left" } : null,
989
+ "float-right": isWeb ? { float: "right" } : null,
990
+ "float-start": isWeb ? { float: "inline-start" } : null,
991
+ "float-end": isWeb ? { float: "inline-end" } : null,
992
+ "float-none": isWeb ? { float: "none" } : null,
993
+ // Clear (web-only)
994
+ "clear-left": isWeb ? { clear: "left" } : null,
995
+ "clear-right": isWeb ? { clear: "right" } : null,
996
+ "clear-both": isWeb ? { clear: "both" } : null,
997
+ "clear-start": isWeb ? { clear: "inline-start" } : null,
998
+ "clear-end": isWeb ? { clear: "inline-end" } : null,
999
+ "clear-none": isWeb ? { clear: "none" } : null,
1000
+ // Vertical align (web-only)
1001
+ "align-baseline": isWeb ? { verticalAlign: "baseline" } : null,
1002
+ "align-top": isWeb ? { verticalAlign: "top" } : null,
1003
+ "align-middle": isWeb ? { verticalAlign: "middle" } : null,
1004
+ "align-bottom": isWeb ? { verticalAlign: "bottom" } : null,
1005
+ "align-text-top": isWeb ? { verticalAlign: "text-top" } : null,
1006
+ "align-text-bottom": isWeb ? { verticalAlign: "text-bottom" } : null,
1007
+ "align-sub": isWeb ? { verticalAlign: "sub" } : null,
1008
+ "align-super": isWeb ? { verticalAlign: "super" } : null,
1009
+ // Touch action (web-only)
1010
+ "touch-auto": isWeb ? { touchAction: "auto" } : null,
1011
+ "touch-none": isWeb ? { touchAction: "none" } : null,
1012
+ "touch-pan-x": isWeb ? { touchAction: "pan-x" } : null,
1013
+ "touch-pan-y": isWeb ? { touchAction: "pan-y" } : null,
1014
+ "touch-pan-left": isWeb ? { touchAction: "pan-left" } : null,
1015
+ "touch-pan-right": isWeb ? { touchAction: "pan-right" } : null,
1016
+ "touch-pan-up": isWeb ? { touchAction: "pan-up" } : null,
1017
+ "touch-pan-down": isWeb ? { touchAction: "pan-down" } : null,
1018
+ "touch-pinch-zoom": isWeb ? { touchAction: "pinch-zoom" } : null,
1019
+ "touch-manipulation": isWeb ? { touchAction: "manipulation" } : null
1020
+ };
1021
+ var RESOLVERS = {
1022
+ // ── Background ─────────────────────────────────────────────────────────────
1023
+ bg: ({ value, isArbitrary }, { colors }) => {
1024
+ const color = resolveColor(value, colors, isArbitrary);
1025
+ return color ? { backgroundColor: color } : null;
1026
+ },
1027
+ "bg-opacity": ({ value }, _) => {
1028
+ if (!isWeb) return null;
1029
+ const v = parseFloat(value) / 100;
1030
+ return isNaN(v) ? null : { "--bg-opacity": v };
1031
+ },
1032
+ // ── Text ───────────────────────────────────────────────────────────────────
1033
+ text: ({ value, isArbitrary }, { colors, fontSize }) => {
1034
+ const size = resolveFontSize(value, fontSize, false);
1035
+ if (!isArbitrary && size !== null) return { fontSize: size };
1036
+ if (isArbitrary) {
1037
+ if (/^\d/.test(value) || /^(calc|min|max|clamp)/.test(value)) {
1038
+ return { fontSize: isWeb ? value : toNativeValue(value) };
1039
+ }
1040
+ return { color: value };
1041
+ }
1042
+ const color = resolveColor(value, colors, false);
1043
+ return color ? { color } : null;
1044
+ },
1045
+ "text-opacity": ({ value }, _) => {
1046
+ if (!isWeb) return null;
1047
+ const v = parseFloat(value) / 100;
1048
+ return isNaN(v) ? null : { "--text-opacity": v };
1049
+ },
1050
+ // ── Padding ────────────────────────────────────────────────────────────────
1051
+ p: ({ value, negative, isArbitrary }, { spacing }) => {
1052
+ const v = resolveSpacing(value, negative, spacing, isArbitrary);
1053
+ return v !== null ? { padding: v } : null;
1054
+ },
1055
+ px: ({ value, negative, isArbitrary }, { spacing }) => {
1056
+ const v = resolveSpacing(value, negative, spacing, isArbitrary);
1057
+ return v !== null ? { paddingHorizontal: v } : null;
1058
+ },
1059
+ py: ({ value, negative, isArbitrary }, { spacing }) => {
1060
+ const v = resolveSpacing(value, negative, spacing, isArbitrary);
1061
+ return v !== null ? { paddingVertical: v } : null;
1062
+ },
1063
+ pt: ({ value, negative, isArbitrary }, { spacing }) => {
1064
+ const v = resolveSpacing(value, negative, spacing, isArbitrary);
1065
+ return v !== null ? { paddingTop: v } : null;
1066
+ },
1067
+ pr: ({ value, negative, isArbitrary }, { spacing }) => {
1068
+ const v = resolveSpacing(value, negative, spacing, isArbitrary);
1069
+ return v !== null ? { paddingRight: v } : null;
1070
+ },
1071
+ pb: ({ value, negative, isArbitrary }, { spacing }) => {
1072
+ const v = resolveSpacing(value, negative, spacing, isArbitrary);
1073
+ return v !== null ? { paddingBottom: v } : null;
1074
+ },
1075
+ pl: ({ value, negative, isArbitrary }, { spacing }) => {
1076
+ const v = resolveSpacing(value, negative, spacing, isArbitrary);
1077
+ return v !== null ? { paddingLeft: v } : null;
1078
+ },
1079
+ // ── Margin ─────────────────────────────────────────────────────────────────
1080
+ m: ({ value, negative, isArbitrary }, { spacing }) => {
1081
+ const v = resolveSpacing(value, negative, spacing, isArbitrary);
1082
+ return v !== null ? { margin: v } : null;
1083
+ },
1084
+ mx: ({ value, negative, isArbitrary }, { spacing }) => {
1085
+ const v = resolveSpacing(value, negative, spacing, isArbitrary);
1086
+ return v !== null ? { marginHorizontal: v } : null;
1087
+ },
1088
+ my: ({ value, negative, isArbitrary }, { spacing }) => {
1089
+ const v = resolveSpacing(value, negative, spacing, isArbitrary);
1090
+ return v !== null ? { marginVertical: v } : null;
1091
+ },
1092
+ mt: ({ value, negative, isArbitrary }, { spacing }) => {
1093
+ const v = resolveSpacing(value, negative, spacing, isArbitrary);
1094
+ return v !== null ? { marginTop: v } : null;
1095
+ },
1096
+ mr: ({ value, negative, isArbitrary }, { spacing }) => {
1097
+ const v = resolveSpacing(value, negative, spacing, isArbitrary);
1098
+ return v !== null ? { marginRight: v } : null;
1099
+ },
1100
+ mb: ({ value, negative, isArbitrary }, { spacing }) => {
1101
+ const v = resolveSpacing(value, negative, spacing, isArbitrary);
1102
+ return v !== null ? { marginBottom: v } : null;
1103
+ },
1104
+ ml: ({ value, negative, isArbitrary }, { spacing }) => {
1105
+ const v = resolveSpacing(value, negative, spacing, isArbitrary);
1106
+ return v !== null ? { marginLeft: v } : null;
1107
+ },
1108
+ // ── Sizing ─────────────────────────────────────────────────────────────────
1109
+ w: ({ value, isArbitrary }, { spacing }) => {
1110
+ const v = resolveSizing(value, spacing, isArbitrary);
1111
+ return v !== null ? { width: v } : null;
1112
+ },
1113
+ h: ({ value, isArbitrary }, { spacing }) => {
1114
+ const v = resolveSizing(value, spacing, isArbitrary);
1115
+ return v !== null ? { height: v } : null;
1116
+ },
1117
+ "min-w": ({ value, isArbitrary }, { spacing }) => {
1118
+ const v = resolveSizing(value, spacing, isArbitrary);
1119
+ return v !== null ? { minWidth: v } : null;
1120
+ },
1121
+ "min-h": ({ value, isArbitrary }, { spacing }) => {
1122
+ const v = resolveSizing(value, spacing, isArbitrary);
1123
+ return v !== null ? { minHeight: v } : null;
1124
+ },
1125
+ "max-w": ({ value, isArbitrary }, { spacing }) => {
1126
+ const v = resolveSizing(value, spacing, isArbitrary);
1127
+ return v !== null ? { maxWidth: v } : null;
1128
+ },
1129
+ "max-h": ({ value, isArbitrary }, { spacing }) => {
1130
+ const v = resolveSizing(value, spacing, isArbitrary);
1131
+ return v !== null ? { maxHeight: v } : null;
1132
+ },
1133
+ // ── Border width ───────────────────────────────────────────────────────────
1134
+ border: ({ value, isArbitrary }, { colors, borderWidth, spacing }) => {
1135
+ if (!value) return { borderWidth: borderWidth["DEFAULT"] ?? 1 };
1136
+ if (isArbitrary) {
1137
+ const w2 = toNativeValue(value);
1138
+ if (typeof w2 === "number") return { borderWidth: w2 };
1139
+ return { borderColor: value };
1140
+ }
1141
+ const color = resolveColor(value, colors, false);
1142
+ if (color) return { borderColor: color };
1143
+ const w = borderWidth[value] ?? spacing[value];
1144
+ if (w !== void 0) return { borderWidth: typeof w === "number" ? w : parseFloat(String(w)) };
1145
+ return null;
1146
+ },
1147
+ "border-t": ({ value, isArbitrary }, { colors, borderWidth }) => {
1148
+ if (!value) return { borderTopWidth: 1 };
1149
+ if (isArbitrary) {
1150
+ const w2 = toNativeValue(value);
1151
+ if (typeof w2 === "number") return { borderTopWidth: w2 };
1152
+ return { borderTopColor: value };
1153
+ }
1154
+ const color = resolveColor(value, colors, false);
1155
+ if (color) return { borderTopColor: color };
1156
+ const w = borderWidth[value];
1157
+ return w !== void 0 ? { borderTopWidth: w } : null;
1158
+ },
1159
+ "border-r": ({ value, isArbitrary }, { colors, borderWidth }) => {
1160
+ if (!value) return { borderRightWidth: 1 };
1161
+ if (isArbitrary) {
1162
+ const w2 = toNativeValue(value);
1163
+ if (typeof w2 === "number") return { borderRightWidth: w2 };
1164
+ return { borderRightColor: value };
1165
+ }
1166
+ const color = resolveColor(value, colors, false);
1167
+ if (color) return { borderRightColor: color };
1168
+ const w = borderWidth[value];
1169
+ return w !== void 0 ? { borderRightWidth: w } : null;
1170
+ },
1171
+ "border-b": ({ value, isArbitrary }, { colors, borderWidth }) => {
1172
+ if (!value) return { borderBottomWidth: 1 };
1173
+ if (isArbitrary) {
1174
+ const w2 = toNativeValue(value);
1175
+ if (typeof w2 === "number") return { borderBottomWidth: w2 };
1176
+ return { borderBottomColor: value };
1177
+ }
1178
+ const color = resolveColor(value, colors, false);
1179
+ if (color) return { borderBottomColor: color };
1180
+ const w = borderWidth[value];
1181
+ return w !== void 0 ? { borderBottomWidth: w } : null;
1182
+ },
1183
+ "border-l": ({ value, isArbitrary }, { colors, borderWidth }) => {
1184
+ if (!value) return { borderLeftWidth: 1 };
1185
+ if (isArbitrary) {
1186
+ const w2 = toNativeValue(value);
1187
+ if (typeof w2 === "number") return { borderLeftWidth: w2 };
1188
+ return { borderLeftColor: value };
1189
+ }
1190
+ const color = resolveColor(value, colors, false);
1191
+ if (color) return { borderLeftColor: color };
1192
+ const w = borderWidth[value];
1193
+ return w !== void 0 ? { borderLeftWidth: w } : null;
1194
+ },
1195
+ // ── Border radius ──────────────────────────────────────────────────────────
1196
+ rounded: ({ value, isArbitrary }, { borderRadius }) => {
1197
+ const r = resolveRadius(value, borderRadius, isArbitrary);
1198
+ return r !== null ? { borderRadius: r } : null;
1199
+ },
1200
+ "rounded-t": ({ value, isArbitrary }, { borderRadius }) => {
1201
+ const r = resolveRadius(value, borderRadius, isArbitrary);
1202
+ return r !== null ? { borderTopLeftRadius: r, borderTopRightRadius: r } : null;
1203
+ },
1204
+ "rounded-r": ({ value, isArbitrary }, { borderRadius }) => {
1205
+ const r = resolveRadius(value, borderRadius, isArbitrary);
1206
+ return r !== null ? { borderTopRightRadius: r, borderBottomRightRadius: r } : null;
1207
+ },
1208
+ "rounded-b": ({ value, isArbitrary }, { borderRadius }) => {
1209
+ const r = resolveRadius(value, borderRadius, isArbitrary);
1210
+ return r !== null ? { borderBottomLeftRadius: r, borderBottomRightRadius: r } : null;
1211
+ },
1212
+ "rounded-l": ({ value, isArbitrary }, { borderRadius }) => {
1213
+ const r = resolveRadius(value, borderRadius, isArbitrary);
1214
+ return r !== null ? { borderTopLeftRadius: r, borderBottomLeftRadius: r } : null;
1215
+ },
1216
+ "rounded-tl": ({ value, isArbitrary }, { borderRadius }) => {
1217
+ const r = resolveRadius(value, borderRadius, isArbitrary);
1218
+ return r !== null ? { borderTopLeftRadius: r } : null;
1219
+ },
1220
+ "rounded-tr": ({ value, isArbitrary }, { borderRadius }) => {
1221
+ const r = resolveRadius(value, borderRadius, isArbitrary);
1222
+ return r !== null ? { borderTopRightRadius: r } : null;
1223
+ },
1224
+ "rounded-bl": ({ value, isArbitrary }, { borderRadius }) => {
1225
+ const r = resolveRadius(value, borderRadius, isArbitrary);
1226
+ return r !== null ? { borderBottomLeftRadius: r } : null;
1227
+ },
1228
+ "rounded-br": ({ value, isArbitrary }, { borderRadius }) => {
1229
+ const r = resolveRadius(value, borderRadius, isArbitrary);
1230
+ return r !== null ? { borderBottomRightRadius: r } : null;
1231
+ },
1232
+ // ── Grid (responsive column count: grid-1 … grid-12, or arbitrary) ───────
1233
+ grid: ({ value, isArbitrary }) => {
1234
+ if (!value) return null;
1235
+ if (isArbitrary) return { display: "grid", gridTemplateColumns: value };
1236
+ const n = parseInt(value, 10);
1237
+ if (isNaN(n) || n < 1 || n > 12) return null;
1238
+ return { display: "grid", gridTemplateColumns: `repeat(${n}, minmax(0, 1fr))` };
1239
+ },
1240
+ // ── Grid template columns/rows (Tailwind-style aliases, web-only) ──────────
1241
+ "grid-cols": ({ value, isArbitrary }) => {
1242
+ if (!isWeb) return null;
1243
+ if (!value) return null;
1244
+ if (isArbitrary) return { display: "grid", gridTemplateColumns: value };
1245
+ if (value === "none") return { display: "grid", gridTemplateColumns: "none" };
1246
+ const n = parseInt(value, 10);
1247
+ if (isNaN(n) || n < 1 || n > 12) return null;
1248
+ return { display: "grid", gridTemplateColumns: `repeat(${n}, minmax(0, 1fr))` };
1249
+ },
1250
+ "grid-rows": ({ value, isArbitrary }) => {
1251
+ if (!isWeb) return null;
1252
+ if (!value) return null;
1253
+ if (isArbitrary) return { gridTemplateRows: value };
1254
+ if (value === "none") return { gridTemplateRows: "none" };
1255
+ const n = parseInt(value, 10);
1256
+ if (isNaN(n) || n < 1) return null;
1257
+ return { gridTemplateRows: `repeat(${n}, minmax(0, 1fr))` };
1258
+ },
1259
+ // ── Grid auto flow (web-only) ─────────────────────────────────────────────
1260
+ "grid-flow": ({ value }) => {
1261
+ if (!isWeb) return null;
1262
+ const flows = {
1263
+ row: "row",
1264
+ col: "column",
1265
+ dense: "dense",
1266
+ "row-dense": "row dense",
1267
+ "col-dense": "column dense"
1268
+ };
1269
+ const flow = flows[value];
1270
+ return flow ? { gridAutoFlow: flow } : null;
1271
+ },
1272
+ // ── Grid auto sizing (web-only) ───────────────────────────────────────────
1273
+ "auto-cols": ({ value, isArbitrary }) => {
1274
+ if (!isWeb) return null;
1275
+ if (isArbitrary) return { gridAutoColumns: value };
1276
+ const presets = {
1277
+ auto: "auto",
1278
+ min: "min-content",
1279
+ max: "max-content",
1280
+ fr: "minmax(0, 1fr)"
1281
+ };
1282
+ const v = presets[value];
1283
+ return v ? { gridAutoColumns: v } : null;
1284
+ },
1285
+ "auto-rows": ({ value, isArbitrary }) => {
1286
+ if (!isWeb) return null;
1287
+ if (isArbitrary) return { gridAutoRows: value };
1288
+ const presets = {
1289
+ auto: "auto",
1290
+ min: "min-content",
1291
+ max: "max-content",
1292
+ fr: "minmax(0, 1fr)"
1293
+ };
1294
+ const v = presets[value];
1295
+ return v ? { gridAutoRows: v } : null;
1296
+ },
1297
+ // ── Grid column placement (web-only) ──────────────────────────────────────
1298
+ "col-span": ({ value }) => {
1299
+ if (!isWeb) return null;
1300
+ if (value === "full") return { gridColumn: "1 / -1" };
1301
+ const n = parseInt(value, 10);
1302
+ return isNaN(n) ? null : { gridColumn: `span ${n} / span ${n}` };
1303
+ },
1304
+ "col-start": ({ value, isArbitrary }) => {
1305
+ if (!isWeb) return null;
1306
+ if (value === "auto") return { gridColumnStart: "auto" };
1307
+ if (isArbitrary) return { gridColumnStart: value };
1308
+ const n = parseInt(value, 10);
1309
+ return isNaN(n) ? null : { gridColumnStart: n };
1310
+ },
1311
+ "col-end": ({ value, isArbitrary }) => {
1312
+ if (!isWeb) return null;
1313
+ if (value === "auto") return { gridColumnEnd: "auto" };
1314
+ if (isArbitrary) return { gridColumnEnd: value };
1315
+ const n = parseInt(value, 10);
1316
+ return isNaN(n) ? null : { gridColumnEnd: n };
1317
+ },
1318
+ col: ({ value, isArbitrary }) => {
1319
+ if (!isWeb) return null;
1320
+ if (!value || value === "auto") return { gridColumn: "auto" };
1321
+ if (isArbitrary) return { gridColumn: value };
1322
+ return null;
1323
+ },
1324
+ // ── Grid row placement (web-only) ─────────────────────────────────────────
1325
+ "row-span": ({ value }) => {
1326
+ if (!isWeb) return null;
1327
+ if (value === "full") return { gridRow: "1 / -1" };
1328
+ const n = parseInt(value, 10);
1329
+ return isNaN(n) ? null : { gridRow: `span ${n} / span ${n}` };
1330
+ },
1331
+ "row-start": ({ value, isArbitrary }) => {
1332
+ if (!isWeb) return null;
1333
+ if (value === "auto") return { gridRowStart: "auto" };
1334
+ if (isArbitrary) return { gridRowStart: value };
1335
+ const n = parseInt(value, 10);
1336
+ return isNaN(n) ? null : { gridRowStart: n };
1337
+ },
1338
+ "row-end": ({ value, isArbitrary }) => {
1339
+ if (!isWeb) return null;
1340
+ if (value === "auto") return { gridRowEnd: "auto" };
1341
+ if (isArbitrary) return { gridRowEnd: value };
1342
+ const n = parseInt(value, 10);
1343
+ return isNaN(n) ? null : { gridRowEnd: n };
1344
+ },
1345
+ row: ({ value, isArbitrary }) => {
1346
+ if (!isWeb) return null;
1347
+ if (!value || value === "auto") return { gridRow: "auto" };
1348
+ if (isArbitrary) return { gridRow: value };
1349
+ return null;
1350
+ },
1351
+ // ── Grid alignment (web-only) ──────────────────────────────────────────────
1352
+ // place-items is shorthand for align-items + justify-items on a grid container
1353
+ "place-items": ({ value }) => {
1354
+ if (!isWeb) return null;
1355
+ const map = {
1356
+ start: "start",
1357
+ end: "end",
1358
+ center: "center",
1359
+ stretch: "stretch",
1360
+ baseline: "baseline"
1361
+ };
1362
+ return map[value] ? { placeItems: map[value] } : null;
1363
+ },
1364
+ // place-content is shorthand for align-content + justify-content on a grid container
1365
+ "place-content": ({ value }) => {
1366
+ if (!isWeb) return null;
1367
+ const map = {
1368
+ start: "start",
1369
+ end: "end",
1370
+ center: "center",
1371
+ stretch: "stretch",
1372
+ between: "space-between",
1373
+ around: "space-around",
1374
+ evenly: "space-evenly",
1375
+ baseline: "baseline"
1376
+ };
1377
+ return map[value] ? { placeContent: map[value] } : null;
1378
+ },
1379
+ // justify-items controls inline-axis alignment of grid items within their cells
1380
+ "justify-items": ({ value }) => {
1381
+ if (!isWeb) return null;
1382
+ const map = {
1383
+ start: "start",
1384
+ end: "end",
1385
+ center: "center",
1386
+ stretch: "stretch"
1387
+ };
1388
+ return map[value] ? { justifyItems: map[value] } : null;
1389
+ },
1390
+ // place-self is shorthand for align-self + justify-self on a grid item
1391
+ "place-self": ({ value }) => {
1392
+ if (!isWeb) return null;
1393
+ const map = {
1394
+ auto: "auto",
1395
+ start: "start",
1396
+ end: "end",
1397
+ center: "center",
1398
+ stretch: "stretch"
1399
+ };
1400
+ return map[value] ? { placeSelf: map[value] } : null;
1401
+ },
1402
+ // justify-self controls inline-axis self-alignment of a grid item
1403
+ "justify-self": ({ value }) => {
1404
+ if (!isWeb) return null;
1405
+ const map = {
1406
+ auto: "auto",
1407
+ start: "start",
1408
+ end: "end",
1409
+ center: "center",
1410
+ stretch: "stretch"
1411
+ };
1412
+ return map[value] ? { justifySelf: map[value] } : null;
1413
+ },
1414
+ // ── CSS Filters (composable via CSS variables, web-only) ─────────────────
1415
+ blur: ({ value, isArbitrary }) => {
1416
+ if (!isWeb) return null;
1417
+ const sizes = {
1418
+ "": "blur(8px)",
1419
+ sm: "blur(4px)",
1420
+ md: "blur(12px)",
1421
+ lg: "blur(16px)",
1422
+ xl: "blur(24px)",
1423
+ "2xl": "blur(40px)",
1424
+ "3xl": "blur(64px)"
1425
+ };
1426
+ if (value === "none") return { "--tw-blur": "", filter: FILTER_COMPOSE };
1427
+ const v = isArbitrary ? `blur(${value})` : sizes[value];
1428
+ return v !== void 0 ? { "--tw-blur": v, filter: FILTER_COMPOSE } : null;
1429
+ },
1430
+ brightness: ({ value, isArbitrary }) => {
1431
+ if (!isWeb) return null;
1432
+ const v = isArbitrary ? `brightness(${value})` : `brightness(${parseFloat(value) / 100})`;
1433
+ return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--tw-brightness": v, filter: FILTER_COMPOSE };
1434
+ },
1435
+ contrast: ({ value, isArbitrary }) => {
1436
+ if (!isWeb) return null;
1437
+ const v = isArbitrary ? `contrast(${value})` : `contrast(${parseFloat(value) / 100})`;
1438
+ return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--tw-contrast": v, filter: FILTER_COMPOSE };
1439
+ },
1440
+ grayscale: ({ value }) => {
1441
+ if (!isWeb) return null;
1442
+ const v = value === "0" ? "grayscale(0)" : "grayscale(100%)";
1443
+ return { "--tw-grayscale": v, filter: FILTER_COMPOSE };
1444
+ },
1445
+ "hue-rotate": ({ value, negative, isArbitrary }) => {
1446
+ if (!isWeb) return null;
1447
+ const deg = isArbitrary ? value : `${(negative ? -1 : 1) * parseFloat(value)}deg`;
1448
+ if (isNaN(parseFloat(deg)) && !isArbitrary) return null;
1449
+ return { "--tw-hue-rotate": `hue-rotate(${deg})`, filter: FILTER_COMPOSE };
1450
+ },
1451
+ invert: ({ value }) => {
1452
+ if (!isWeb) return null;
1453
+ const v = value === "0" ? "invert(0)" : "invert(100%)";
1454
+ return { "--tw-invert": v, filter: FILTER_COMPOSE };
1455
+ },
1456
+ saturate: ({ value, isArbitrary }) => {
1457
+ if (!isWeb) return null;
1458
+ const v = isArbitrary ? `saturate(${value})` : `saturate(${parseFloat(value) / 100})`;
1459
+ return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--tw-saturate": v, filter: FILTER_COMPOSE };
1460
+ },
1461
+ sepia: ({ value }) => {
1462
+ if (!isWeb) return null;
1463
+ const v = value === "0" ? "sepia(0)" : "sepia(100%)";
1464
+ return { "--tw-sepia": v, filter: FILTER_COMPOSE };
1465
+ },
1466
+ "drop-shadow": ({ value, isArbitrary }) => {
1467
+ if (!isWeb) return null;
1468
+ if (isArbitrary) return { "--tw-drop-shadow": `drop-shadow(${value.replace(/_/g, " ")})`, filter: FILTER_COMPOSE };
1469
+ const presets = {
1470
+ "": "drop-shadow(0 1px 2px rgb(0 0 0/0.1)) drop-shadow(0 1px 1px rgb(0 0 0/0.06))",
1471
+ sm: "drop-shadow(0 1px 1px rgb(0 0 0/0.05))",
1472
+ md: "drop-shadow(0 4px 3px rgb(0 0 0/0.07)) drop-shadow(0 2px 2px rgb(0 0 0/0.06))",
1473
+ lg: "drop-shadow(0 10px 8px rgb(0 0 0/0.04)) drop-shadow(0 4px 3px rgb(0 0 0/0.1))",
1474
+ xl: "drop-shadow(0 20px 13px rgb(0 0 0/0.03)) drop-shadow(0 8px 5px rgb(0 0 0/0.08))",
1475
+ "2xl": "drop-shadow(0 25px 25px rgb(0 0 0/0.15))",
1476
+ none: "drop-shadow(0 0 #0000)"
1477
+ };
1478
+ const v = presets[value];
1479
+ return v !== void 0 ? { "--tw-drop-shadow": v, filter: FILTER_COMPOSE } : null;
1480
+ },
1481
+ // Arbitrary full filter string: filter-[blur(4px)_grayscale(1)]
1482
+ filter: ({ value, isArbitrary }) => {
1483
+ if (!isWeb) return null;
1484
+ if (isArbitrary) return { filter: value.replace(/_/g, " ") };
1485
+ if (value === "none") return { filter: "none" };
1486
+ return null;
1487
+ },
1488
+ // ── Backdrop Filters (composable via CSS variables, web-only) ────────────
1489
+ "backdrop-blur": ({ value, isArbitrary }) => {
1490
+ if (!isWeb) return null;
1491
+ const sizes = {
1492
+ "": "blur(8px)",
1493
+ sm: "blur(4px)",
1494
+ md: "blur(12px)",
1495
+ lg: "blur(16px)",
1496
+ xl: "blur(24px)",
1497
+ "2xl": "blur(40px)",
1498
+ "3xl": "blur(64px)"
1499
+ };
1500
+ if (value === "none") return { "--tw-backdrop-blur": "", backdropFilter: BACKDROP_FILTER_COMPOSE };
1501
+ const v = isArbitrary ? `blur(${value})` : sizes[value];
1502
+ return v !== void 0 ? { "--tw-backdrop-blur": v, backdropFilter: BACKDROP_FILTER_COMPOSE } : null;
1503
+ },
1504
+ "backdrop-brightness": ({ value, isArbitrary }) => {
1505
+ if (!isWeb) return null;
1506
+ const v = isArbitrary ? `brightness(${value})` : `brightness(${parseFloat(value) / 100})`;
1507
+ return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--tw-backdrop-brightness": v, backdropFilter: BACKDROP_FILTER_COMPOSE };
1508
+ },
1509
+ "backdrop-contrast": ({ value, isArbitrary }) => {
1510
+ if (!isWeb) return null;
1511
+ const v = isArbitrary ? `contrast(${value})` : `contrast(${parseFloat(value) / 100})`;
1512
+ return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--tw-backdrop-contrast": v, backdropFilter: BACKDROP_FILTER_COMPOSE };
1513
+ },
1514
+ "backdrop-grayscale": ({ value }) => {
1515
+ if (!isWeb) return null;
1516
+ return { "--tw-backdrop-grayscale": value === "0" ? "grayscale(0)" : "grayscale(100%)", backdropFilter: BACKDROP_FILTER_COMPOSE };
1517
+ },
1518
+ "backdrop-hue-rotate": ({ value, negative, isArbitrary }) => {
1519
+ if (!isWeb) return null;
1520
+ const deg = isArbitrary ? value : `${(negative ? -1 : 1) * parseFloat(value)}deg`;
1521
+ if (isNaN(parseFloat(deg)) && !isArbitrary) return null;
1522
+ return { "--tw-backdrop-hue-rotate": `hue-rotate(${deg})`, backdropFilter: BACKDROP_FILTER_COMPOSE };
1523
+ },
1524
+ "backdrop-invert": ({ value }) => {
1525
+ if (!isWeb) return null;
1526
+ return { "--tw-backdrop-invert": value === "0" ? "invert(0)" : "invert(100%)", backdropFilter: BACKDROP_FILTER_COMPOSE };
1527
+ },
1528
+ "backdrop-opacity": ({ value, isArbitrary }) => {
1529
+ if (!isWeb) return null;
1530
+ const v = isArbitrary ? `opacity(${value})` : `opacity(${parseFloat(value) / 100})`;
1531
+ return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--tw-backdrop-opacity": v, backdropFilter: BACKDROP_FILTER_COMPOSE };
1532
+ },
1533
+ "backdrop-saturate": ({ value, isArbitrary }) => {
1534
+ if (!isWeb) return null;
1535
+ const v = isArbitrary ? `saturate(${value})` : `saturate(${parseFloat(value) / 100})`;
1536
+ return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--tw-backdrop-saturate": v, backdropFilter: BACKDROP_FILTER_COMPOSE };
1537
+ },
1538
+ "backdrop-sepia": ({ value }) => {
1539
+ if (!isWeb) return null;
1540
+ return { "--tw-backdrop-sepia": value === "0" ? "sepia(0)" : "sepia(100%)", backdropFilter: BACKDROP_FILTER_COMPOSE };
1541
+ },
1542
+ "backdrop-filter": ({ value, isArbitrary }) => {
1543
+ if (!isWeb) return null;
1544
+ if (isArbitrary) return { backdropFilter: value.replace(/_/g, " ") };
1545
+ if (value === "none") return { backdropFilter: "none" };
1546
+ return null;
1547
+ },
1548
+ // ── Background gradient (CSS variable gradient stops, web-only) ──────────
1549
+ "bg-gradient-to": ({ value }) => {
1550
+ if (!isWeb) return null;
1551
+ const directions = {
1552
+ t: "to top",
1553
+ tr: "to top right",
1554
+ r: "to right",
1555
+ br: "to bottom right",
1556
+ b: "to bottom",
1557
+ bl: "to bottom left",
1558
+ l: "to left",
1559
+ tl: "to top left"
1560
+ };
1561
+ const dir = directions[value];
1562
+ if (!dir) return null;
1563
+ return {
1564
+ backgroundImage: `linear-gradient(${dir}, var(--tw-gradient-from, transparent), var(--tw-gradient-stops, transparent))`
1565
+ };
1566
+ },
1567
+ from: ({ value, isArbitrary }, { colors }) => {
1568
+ if (!isWeb) return null;
1569
+ const color = resolveColor(value, colors, isArbitrary);
1570
+ if (!color) return null;
1571
+ return {
1572
+ "--tw-gradient-from": color,
1573
+ "--tw-gradient-stops": `var(--tw-gradient-from), var(--tw-gradient-to, transparent)`
1574
+ };
1575
+ },
1576
+ via: ({ value, isArbitrary }, { colors }) => {
1577
+ if (!isWeb) return null;
1578
+ const color = resolveColor(value, colors, isArbitrary);
1579
+ if (!color) return null;
1580
+ return {
1581
+ "--tw-gradient-via": color,
1582
+ "--tw-gradient-stops": `var(--tw-gradient-from), var(--tw-gradient-via), var(--tw-gradient-to, transparent)`
1583
+ };
1584
+ },
1585
+ to: ({ value, isArbitrary }, { colors }) => {
1586
+ if (!isWeb) return null;
1587
+ const color = resolveColor(value, colors, isArbitrary);
1588
+ if (!color) return null;
1589
+ return { "--tw-gradient-to": color };
1590
+ },
1591
+ // ── Transform extras (web-only) ───────────────────────────────────────────
1592
+ "skew-x": ({ value, negative, isArbitrary }) => {
1593
+ const deg = isArbitrary ? value : `${(negative ? -1 : 1) * parseFloat(value)}deg`;
1594
+ if (!isArbitrary && isNaN(parseFloat(value))) return null;
1595
+ return isWeb ? { transform: `skewX(${deg})` } : { transform: [{ skewX: deg }] };
1596
+ },
1597
+ "skew-y": ({ value, negative, isArbitrary }) => {
1598
+ const deg = isArbitrary ? value : `${(negative ? -1 : 1) * parseFloat(value)}deg`;
1599
+ if (!isArbitrary && isNaN(parseFloat(value))) return null;
1600
+ return isWeb ? { transform: `skewY(${deg})` } : { transform: [{ skewY: deg }] };
1601
+ },
1602
+ // Arbitrary full transform string: transform-[rotate(45deg)_scale(1.5)]
1603
+ transform: ({ value, isArbitrary }) => {
1604
+ if (!isWeb) return null;
1605
+ if (isArbitrary) return { transform: value.replace(/_/g, " ") };
1606
+ if (value === "none") return { transform: "none" };
1607
+ return null;
1608
+ },
1609
+ // Transform origin
1610
+ origin: ({ value, isArbitrary }) => {
1611
+ if (!isWeb) return null;
1612
+ if (isArbitrary) return { transformOrigin: value.replace(/_/g, " ") };
1613
+ const origins = {
1614
+ center: "center",
1615
+ top: "top",
1616
+ "top-right": "top right",
1617
+ right: "right",
1618
+ "bottom-right": "bottom right",
1619
+ bottom: "bottom",
1620
+ "bottom-left": "bottom left",
1621
+ left: "left",
1622
+ "top-left": "top left"
1623
+ };
1624
+ return origins[value] ? { transformOrigin: origins[value] } : null;
1625
+ },
1626
+ // ── Text decoration advanced (web-only) ───────────────────────────────────
1627
+ decoration: ({ value, isArbitrary }, { colors }) => {
1628
+ if (!isWeb) return null;
1629
+ if (isArbitrary) {
1630
+ if (/^\d/.test(value) || value.startsWith("calc(")) return { textDecorationThickness: value };
1631
+ return { textDecorationColor: value };
1632
+ }
1633
+ const thickTokens = {
1634
+ auto: "auto",
1635
+ "from-font": "from-font",
1636
+ "0": "0px",
1637
+ "1": "1px",
1638
+ "2": "2px",
1639
+ "4": "4px",
1640
+ "8": "8px"
1641
+ };
1642
+ if (value in thickTokens) return { textDecorationThickness: thickTokens[value] };
1643
+ const styleTokens = {
1644
+ solid: "solid",
1645
+ dashed: "dashed",
1646
+ dotted: "dotted",
1647
+ double: "double",
1648
+ wavy: "wavy"
1649
+ };
1650
+ if (value in styleTokens) return { textDecorationStyle: styleTokens[value] };
1651
+ const color = resolveColor(value, colors, false);
1652
+ return color ? { textDecorationColor: color } : null;
1653
+ },
1654
+ "underline-offset": ({ value, isArbitrary }) => {
1655
+ if (!isWeb) return null;
1656
+ if (isArbitrary) return { textUnderlineOffset: value };
1657
+ const offsets = {
1658
+ auto: "auto",
1659
+ "0": "0px",
1660
+ "1": "1px",
1661
+ "2": "2px",
1662
+ "4": "4px",
1663
+ "8": "8px"
1664
+ };
1665
+ return offsets[value] ? { textUnderlineOffset: offsets[value] } : null;
1666
+ },
1667
+ // ── Outline extended (web-only) ───────────────────────────────────────────
1668
+ outline: ({ value, isArbitrary }, { colors }) => {
1669
+ if (!isWeb) return null;
1670
+ if (!value) return { outline: "2px solid transparent", outlineOffset: "2px" };
1671
+ if (value === "none") return { outline: "none", outlineOffset: "0" };
1672
+ if (isArbitrary) {
1673
+ if (/^\d/.test(value) || value.startsWith("calc(")) return { outlineWidth: value };
1674
+ return { outlineColor: value };
1675
+ }
1676
+ const widths = { "0": "0px", "1": "1px", "2": "2px", "4": "4px", "8": "8px" };
1677
+ if (value in widths) return { outlineWidth: widths[value] };
1678
+ const color = resolveColor(value, colors, false);
1679
+ return color ? { outlineColor: color } : null;
1680
+ },
1681
+ "outline-offset": ({ value, isArbitrary }) => {
1682
+ if (!isWeb) return null;
1683
+ if (isArbitrary) return { outlineOffset: value };
1684
+ const offsets = { "0": "0px", "1": "1px", "2": "2px", "4": "4px", "8": "8px" };
1685
+ return offsets[value] ? { outlineOffset: offsets[value] } : null;
1686
+ },
1687
+ // ── Columns (web-only) ─────────────────────────────────────────────────────
1688
+ columns: ({ value, isArbitrary }) => {
1689
+ if (!isWeb) return null;
1690
+ if (isArbitrary) return { columnCount: value };
1691
+ if (value === "auto") return { columnCount: "auto" };
1692
+ const n = parseInt(value, 10);
1693
+ if (!isNaN(n)) return { columnCount: n };
1694
+ const widths = {
1695
+ "3xs": "16rem",
1696
+ "2xs": "18rem",
1697
+ xs: "20rem",
1698
+ sm: "24rem",
1699
+ md: "28rem",
1700
+ lg: "32rem",
1701
+ xl: "36rem",
1702
+ "2xl": "42rem",
1703
+ "3xl": "48rem",
1704
+ "4xl": "56rem",
1705
+ "5xl": "64rem",
1706
+ "6xl": "72rem",
1707
+ "7xl": "80rem"
1708
+ };
1709
+ return widths[value] ? { columnWidth: widths[value] } : null;
1710
+ },
1711
+ // ── Mix / background blend mode (web-only) ───────────────────────────────
1712
+ "mix-blend": ({ value }) => {
1713
+ if (!isWeb) return null;
1714
+ const modes = [
1715
+ "normal",
1716
+ "multiply",
1717
+ "screen",
1718
+ "overlay",
1719
+ "darken",
1720
+ "lighten",
1721
+ "color-dodge",
1722
+ "color-burn",
1723
+ "hard-light",
1724
+ "soft-light",
1725
+ "difference",
1726
+ "exclusion",
1727
+ "hue",
1728
+ "saturation",
1729
+ "color",
1730
+ "luminosity",
1731
+ "plus-lighter"
1732
+ ];
1733
+ return modes.includes(value) ? { mixBlendMode: value } : null;
1734
+ },
1735
+ "bg-blend": ({ value }) => {
1736
+ if (!isWeb) return null;
1737
+ const modes = [
1738
+ "normal",
1739
+ "multiply",
1740
+ "screen",
1741
+ "overlay",
1742
+ "darken",
1743
+ "lighten",
1744
+ "color-dodge",
1745
+ "color-burn",
1746
+ "hard-light",
1747
+ "soft-light",
1748
+ "difference",
1749
+ "exclusion",
1750
+ "hue",
1751
+ "saturation",
1752
+ "color",
1753
+ "luminosity"
1754
+ ];
1755
+ return modes.includes(value) ? { backgroundBlendMode: value } : null;
1756
+ },
1757
+ // ── Will-change (web-only) ─────────────────────────────────────────────────
1758
+ "will-change": ({ value, isArbitrary }) => {
1759
+ if (!isWeb) return null;
1760
+ if (isArbitrary) return { willChange: value.replace(/_/g, ", ") };
1761
+ const presets = {
1762
+ auto: "auto",
1763
+ scroll: "scroll-position",
1764
+ contents: "contents",
1765
+ transform: "transform"
1766
+ };
1767
+ return presets[value] ? { willChange: presets[value] } : null;
1768
+ },
1769
+ // ── Divide (child combinator CSS, web-only) ───────────────────────────────
1770
+ // These return special __divide* markers that resolver.ts converts to
1771
+ // .cls > * + * { border-... } CSS rules. No inline style is applied.
1772
+ "divide-x": ({ value, isArbitrary }) => {
1773
+ if (!isWeb) return null;
1774
+ if (value === "reverse") return null;
1775
+ if (!value) return { __divideX: 1 };
1776
+ const n = parseFloat(value);
1777
+ return isNaN(n) ? null : { __divideX: n };
1778
+ },
1779
+ "divide-y": ({ value, isArbitrary }) => {
1780
+ if (!isWeb) return null;
1781
+ if (value === "reverse") return null;
1782
+ if (!value) return { __divideY: 1 };
1783
+ const n = parseFloat(value);
1784
+ return isNaN(n) ? null : { __divideY: n };
1785
+ },
1786
+ divide: ({ value, isArbitrary }, { colors }) => {
1787
+ if (!isWeb) return null;
1788
+ if (isArbitrary) return { __divideColor: value };
1789
+ const styleTokens = {
1790
+ solid: "solid",
1791
+ dashed: "dashed",
1792
+ dotted: "dotted",
1793
+ double: "double",
1794
+ none: "none"
1795
+ };
1796
+ if (value in styleTokens) return { __divideStyle: styleTokens[value] };
1797
+ const color = resolveColor(value, colors, false);
1798
+ return color ? { __divideColor: color } : null;
1799
+ },
1800
+ // ── Text shadow (cross-platform: iOS, Android, web) ─────────────────────
1801
+ // Named presets give cross-platform shadow; arbitrary is web-only.
1802
+ "text-shadow": ({ value, isArbitrary }, { colors }) => {
1803
+ if (value === "none") {
1804
+ return isWeb ? { textShadow: "none" } : { textShadowColor: "transparent", textShadowOffset: { width: 0, height: 0 }, textShadowRadius: 0 };
1805
+ }
1806
+ const webPresets = {
1807
+ "": "0 2px 4px rgba(0,0,0,0.3)",
1808
+ sm: "0 1px 2px rgba(0,0,0,0.3)",
1809
+ md: "0 4px 6px rgba(0,0,0,0.3)",
1810
+ lg: "0 8px 16px rgba(0,0,0,0.5)",
1811
+ xl: "0 16px 32px rgba(0,0,0,0.5)"
1812
+ };
1813
+ const nativePresets = {
1814
+ "": { textShadowColor: "rgba(0,0,0,0.3)", textShadowOffset: { width: 0, height: 2 }, textShadowRadius: 4 },
1815
+ sm: { textShadowColor: "rgba(0,0,0,0.3)", textShadowOffset: { width: 0, height: 1 }, textShadowRadius: 2 },
1816
+ md: { textShadowColor: "rgba(0,0,0,0.3)", textShadowOffset: { width: 0, height: 4 }, textShadowRadius: 6 },
1817
+ lg: { textShadowColor: "rgba(0,0,0,0.5)", textShadowOffset: { width: 0, height: 8 }, textShadowRadius: 16 },
1818
+ xl: { textShadowColor: "rgba(0,0,0,0.5)", textShadowOffset: { width: 0, height: 16 }, textShadowRadius: 32 }
1819
+ };
1820
+ if (value in webPresets) {
1821
+ if (isWeb) return { textShadow: webPresets[value] };
1822
+ return nativePresets[value] ?? null;
1823
+ }
1824
+ if (isArbitrary) {
1825
+ return isWeb ? { textShadow: value.replace(/_/g, " ") } : null;
1826
+ }
1827
+ const color = resolveColor(value, colors, false);
1828
+ if (color) {
1829
+ return isWeb ? { textShadow: `0 2px 4px ${color}` } : { textShadowColor: color };
1830
+ }
1831
+ return null;
1832
+ },
1833
+ // ── Perspective transform (cross-platform: iOS, Android, web) ────────────
1834
+ perspective: ({ value, isArbitrary }) => {
1835
+ if (isArbitrary) {
1836
+ const numPx = parseFloat(value);
1837
+ if (isWeb) return { transform: `perspective(${value})` };
1838
+ return isNaN(numPx) ? null : { transform: [{ perspective: numPx }] };
1839
+ }
1840
+ if (value === "none") return isWeb ? { transform: "none" } : null;
1841
+ const n = parseFloat(value);
1842
+ if (isNaN(n)) return null;
1843
+ return isWeb ? { transform: `perspective(${n}px)` } : { transform: [{ perspective: n }] };
1844
+ },
1845
+ // ── Tint color (native-only, for Image and icon components) ──────────────
1846
+ tint: ({ value, isArbitrary }, { colors }) => {
1847
+ if (isWeb) return null;
1848
+ const color = resolveColor(value, colors, isArbitrary);
1849
+ return color ? { tintColor: color } : null;
1850
+ },
1851
+ // ── Size shorthand (sets width AND height in one utility) ────────────────
1852
+ size: ({ value, isArbitrary }, { spacing }) => {
1853
+ const v = resolveSizing(value, spacing, isArbitrary);
1854
+ return v !== null ? { width: v, height: v } : null;
1855
+ },
1856
+ // ── Animations (CSS keyframe animations, web-only) ────────────────────────
1857
+ // Each variant injects a @keyframes rule once via the __keyframe marker.
1858
+ // resolver.ts detects __keyframe, injects the rule, then strips the marker
1859
+ // so it never reaches element inline styles.
1860
+ animate: ({ value, isArbitrary }) => {
1861
+ if (!isWeb) return null;
1862
+ if (isArbitrary) return { animation: value.replace(/_/g, " ") };
1863
+ const defs = {
1864
+ none: { animation: "none" },
1865
+ spin: {
1866
+ animation: "kb-spin 1s linear infinite",
1867
+ __keyframe: "@keyframes kb-spin { from { transform: rotate(0deg) } to { transform: rotate(360deg) } }"
1868
+ },
1869
+ ping: {
1870
+ animation: "kb-ping 1s cubic-bezier(0,0,0.2,1) infinite",
1871
+ __keyframe: "@keyframes kb-ping { 75%, 100% { transform: scale(2); opacity: 0 } }"
1872
+ },
1873
+ pulse: {
1874
+ animation: "kb-pulse 2s cubic-bezier(0.4,0,0.6,1) infinite",
1875
+ __keyframe: "@keyframes kb-pulse { 0%, 100% { opacity: 1 } 50% { opacity: .5 } }"
1876
+ },
1877
+ bounce: {
1878
+ animation: "kb-bounce 1s infinite",
1879
+ __keyframe: "@keyframes kb-bounce { 0%, 100% { transform: translateY(-25%); animation-timing-function: cubic-bezier(0.8,0,1,1) } 50% { transform: none; animation-timing-function: cubic-bezier(0,0,0.2,1) } }"
1880
+ }
1881
+ };
1882
+ const def = defs[value];
1883
+ return def ? def : null;
1884
+ },
1885
+ // ── Line-clamp (web-only) ─────────────────────────────────────────────────
1886
+ "line-clamp": ({ value }) => {
1887
+ if (!isWeb) return null;
1888
+ if (value === "none") return { overflow: "visible", display: "block", WebkitLineClamp: "unset" };
1889
+ const n = parseInt(value, 10);
1890
+ if (isNaN(n) || n < 1) return null;
1891
+ return {
1892
+ overflow: "hidden",
1893
+ display: "-webkit-box",
1894
+ WebkitBoxOrient: "vertical",
1895
+ WebkitLineClamp: n
1896
+ };
1897
+ },
1898
+ // ── Caret color (web-only) ────────────────────────────────────────────────
1899
+ caret: ({ value, isArbitrary }, { colors }) => {
1900
+ if (!isWeb) return null;
1901
+ if (value === "auto" || value === "transparent") return { caretColor: value };
1902
+ const color = resolveColor(value, colors, isArbitrary);
1903
+ return color ? { caretColor: color } : null;
1904
+ },
1905
+ // ── Accent color (web-only) ───────────────────────────────────────────────
1906
+ accent: ({ value, isArbitrary }, { colors }) => {
1907
+ if (!isWeb) return null;
1908
+ if (value === "auto") return { accentColor: "auto" };
1909
+ const color = resolveColor(value, colors, isArbitrary);
1910
+ return color ? { accentColor: color } : null;
1911
+ },
1912
+ // ── Flex ───────────────────────────────────────────────────────────────────
1913
+ flex: ({ value, isArbitrary }, { flex }) => {
1914
+ if (!value) return { display: "flex" };
1915
+ if (isArbitrary) {
1916
+ const v = parseFloat(value);
1917
+ return isNaN(v) ? null : { flex: v };
1918
+ }
1919
+ if (value in flex) return { flex: flex[value] };
1920
+ const n = parseFloat(value);
1921
+ return isNaN(n) ? null : { flex: n };
1922
+ },
1923
+ basis: ({ value, isArbitrary }, { spacing }) => {
1924
+ const v = resolveSizing(value, spacing, isArbitrary);
1925
+ return v !== null ? { flexBasis: v } : null;
1926
+ },
1927
+ grow: ({ value }, _) => {
1928
+ if (!value) return { flexGrow: 1 };
1929
+ const n = parseFloat(value);
1930
+ return { flexGrow: isNaN(n) ? 1 : n };
1931
+ },
1932
+ shrink: ({ value }, _) => {
1933
+ if (!value) return { flexShrink: 1 };
1934
+ const n = parseFloat(value);
1935
+ return { flexShrink: isNaN(n) ? 1 : n };
1936
+ },
1937
+ order: ({ value, isArbitrary }, _) => {
1938
+ const n = parseInt(value);
1939
+ return isNaN(n) ? null : { order: n };
1940
+ },
1941
+ // ── Gap ────────────────────────────────────────────────────────────────────
1942
+ gap: ({ value, negative, isArbitrary }, { spacing }) => {
1943
+ const v = resolveSpacing(value, negative, spacing, isArbitrary);
1944
+ return v !== null ? { gap: v } : null;
1945
+ },
1946
+ "gap-x": ({ value, negative, isArbitrary }, { spacing }) => {
1947
+ const v = resolveSpacing(value, negative, spacing, isArbitrary);
1948
+ return v !== null ? { columnGap: v } : null;
1949
+ },
1950
+ "gap-y": ({ value, negative, isArbitrary }, { spacing }) => {
1951
+ const v = resolveSpacing(value, negative, spacing, isArbitrary);
1952
+ return v !== null ? { rowGap: v } : null;
1953
+ },
1954
+ // ── Position ───────────────────────────────────────────────────────────────
1955
+ top: ({ value, negative, isArbitrary }, { spacing }) => {
1956
+ const v = resolveSpacing(value, negative, spacing, isArbitrary);
1957
+ return v !== null ? { top: v } : null;
1958
+ },
1959
+ right: ({ value, negative, isArbitrary }, { spacing }) => {
1960
+ const v = resolveSpacing(value, negative, spacing, isArbitrary);
1961
+ return v !== null ? { right: v } : null;
1962
+ },
1963
+ bottom: ({ value, negative, isArbitrary }, { spacing }) => {
1964
+ const v = resolveSpacing(value, negative, spacing, isArbitrary);
1965
+ return v !== null ? { bottom: v } : null;
1966
+ },
1967
+ left: ({ value, negative, isArbitrary }, { spacing }) => {
1968
+ const v = resolveSpacing(value, negative, spacing, isArbitrary);
1969
+ return v !== null ? { left: v } : null;
1970
+ },
1971
+ inset: ({ value, negative, isArbitrary }, { spacing }) => {
1972
+ const v = resolveSpacing(value, negative, spacing, isArbitrary);
1973
+ return v !== null ? { top: v, right: v, bottom: v, left: v } : null;
1974
+ },
1975
+ "inset-x": ({ value, negative, isArbitrary }, { spacing }) => {
1976
+ const v = resolveSpacing(value, negative, spacing, isArbitrary);
1977
+ return v !== null ? { left: v, right: v } : null;
1978
+ },
1979
+ "inset-y": ({ value, negative, isArbitrary }, { spacing }) => {
1980
+ const v = resolveSpacing(value, negative, spacing, isArbitrary);
1981
+ return v !== null ? { top: v, bottom: v } : null;
1982
+ },
1983
+ // ── Z-index ────────────────────────────────────────────────────────────────
1984
+ z: ({ value, isArbitrary }, { zIndex }) => {
1985
+ if (isArbitrary) {
1986
+ const n2 = parseInt(value);
1987
+ return isNaN(n2) ? null : { zIndex: n2 };
1988
+ }
1989
+ const v = zIndex[value];
1990
+ if (v !== void 0) {
1991
+ if (v === "auto") return isWeb ? { zIndex: "auto" } : null;
1992
+ return { zIndex: v };
1993
+ }
1994
+ const n = parseInt(value);
1995
+ return isNaN(n) ? null : { zIndex: n };
1996
+ },
1997
+ // ── Opacity ────────────────────────────────────────────────────────────────
1998
+ opacity: ({ value, isArbitrary }, { opacity }) => {
1999
+ if (isArbitrary) {
2000
+ const v2 = parseFloat(value);
2001
+ return isNaN(v2) ? null : { opacity: v2 > 1 ? v2 / 100 : v2 };
2002
+ }
2003
+ const v = opacity[value];
2004
+ if (v !== void 0) return { opacity: v };
2005
+ const n = parseFloat(value);
2006
+ return isNaN(n) ? null : { opacity: n > 1 ? n / 100 : n };
2007
+ },
2008
+ // ── Font ───────────────────────────────────────────────────────────────────
2009
+ font: ({ value, isArbitrary }, { fontFamily, fontWeight }) => {
2010
+ if (isArbitrary) return { fontFamily: value };
2011
+ if (value in fontFamily) {
2012
+ const ff = fontFamily[value];
2013
+ return { fontFamily: Array.isArray(ff) ? ff.join(", ") : ff };
2014
+ }
2015
+ if (value in fontWeight) return { fontWeight: String(fontWeight[value]) };
2016
+ return null;
2017
+ },
2018
+ // ── Line height ────────────────────────────────────────────────────────────
2019
+ leading: ({ value, isArbitrary }, { lineHeight }) => {
2020
+ if (isArbitrary) return { lineHeight: isWeb ? value : toNativeValue(value) };
2021
+ const v = lineHeight[value];
2022
+ return v !== void 0 ? { lineHeight: v } : null;
2023
+ },
2024
+ // ── Letter spacing ─────────────────────────────────────────────────────────
2025
+ tracking: ({ value, isArbitrary }, { letterSpacing }) => {
2026
+ if (isArbitrary) return { letterSpacing: isWeb ? value : toNativeValue(value) };
2027
+ const v = letterSpacing[value];
2028
+ return v !== void 0 ? { letterSpacing: v } : null;
2029
+ },
2030
+ // ── Shadow ─────────────────────────────────────────────────────────────────
2031
+ shadow: ({ value }, { shadow }) => {
2032
+ const key = value === "" ? "DEFAULT" : value;
2033
+ return shadow[key] ?? null;
2034
+ },
2035
+ // ── Scale ──────────────────────────────────────────────────────────────────
2036
+ // Non-arbitrary: scale-150 → value='150' → 150/100 = 1.5
2037
+ // Arbitrary: scale-[1.5] → value='1.5' → used as-is (already the factor)
2038
+ scale: ({ value, isArbitrary }) => {
2039
+ const n = isArbitrary ? parseFloat(value) : parseFloat(value) / 100;
2040
+ if (isNaN(n)) return null;
2041
+ return isWeb ? { transform: `scale(${n})` } : { transform: [{ scale: n }] };
2042
+ },
2043
+ "scale-x": ({ value, isArbitrary }) => {
2044
+ const n = isArbitrary ? parseFloat(value) : parseFloat(value) / 100;
2045
+ if (isNaN(n)) return null;
2046
+ return isWeb ? { transform: `scaleX(${n})` } : { transform: [{ scaleX: n }] };
2047
+ },
2048
+ "scale-y": ({ value, isArbitrary }) => {
2049
+ const n = isArbitrary ? parseFloat(value) : parseFloat(value) / 100;
2050
+ if (isNaN(n)) return null;
2051
+ return isWeb ? { transform: `scaleY(${n})` } : { transform: [{ scaleY: n }] };
2052
+ },
2053
+ // ── Rotate ─────────────────────────────────────────────────────────────────
2054
+ rotate: ({ value, negative, isArbitrary }) => {
2055
+ if (isArbitrary) {
2056
+ const finalValue = negative ? `-${value}` : value;
2057
+ return isWeb ? { transform: `rotate(${finalValue})` } : { transform: [{ rotate: finalValue }] };
2058
+ }
2059
+ const deg = parseFloat(value);
2060
+ if (isNaN(deg)) return null;
2061
+ const finalDeg = negative ? -deg : deg;
2062
+ return isWeb ? { transform: `rotate(${finalDeg}deg)` } : { transform: [{ rotate: `${finalDeg}deg` }] };
2063
+ },
2064
+ // ── Translate ──────────────────────────────────────────────────────────────
2065
+ "translate-x": ({ value, negative, isArbitrary }, { spacing }) => {
2066
+ const v = resolveSpacing(value, negative, spacing, isArbitrary);
2067
+ if (v === null) return null;
2068
+ if (isWeb) return { transform: `translateX(${v})` };
2069
+ if (typeof v === "string") {
2070
+ const n = parseFloat(v);
2071
+ return isNaN(n) ? null : { transform: [{ translateX: n }] };
2072
+ }
2073
+ return { transform: [{ translateX: v }] };
2074
+ },
2075
+ "translate-y": ({ value, negative, isArbitrary }, { spacing }) => {
2076
+ const v = resolveSpacing(value, negative, spacing, isArbitrary);
2077
+ if (v === null) return null;
2078
+ if (isWeb) return { transform: `translateY(${v})` };
2079
+ if (typeof v === "string") {
2080
+ const n = parseFloat(v);
2081
+ return isNaN(n) ? null : { transform: [{ translateY: n }] };
2082
+ }
2083
+ return { transform: [{ translateY: v }] };
2084
+ },
2085
+ // ── Aspect ratio ───────────────────────────────────────────────────────────
2086
+ aspect: ({ value, isArbitrary }) => {
2087
+ if (isArbitrary) return { aspectRatio: value };
2088
+ const presets = { auto: "auto", square: 1, video: 16 / 9 };
2089
+ if (!(value in presets)) return null;
2090
+ const v = presets[value];
2091
+ if (v === "auto") return isWeb ? { aspectRatio: "auto" } : null;
2092
+ return { aspectRatio: v };
2093
+ },
2094
+ // ── Transition (web-only; use Animated API on native) ─────────────────────
2095
+ transition: ({ value }) => {
2096
+ if (!isWeb) return null;
2097
+ const presets = {
2098
+ "": "color 150ms, background-color 150ms, border-color 150ms, opacity 150ms, box-shadow 150ms",
2099
+ all: "all 150ms",
2100
+ none: "none",
2101
+ colors: "color 150ms, background-color 150ms, border-color 150ms",
2102
+ opacity: "opacity 150ms",
2103
+ shadow: "box-shadow 150ms",
2104
+ transform: "transform 150ms"
2105
+ };
2106
+ const v = presets[value];
2107
+ return v !== void 0 ? { transition: v } : null;
2108
+ },
2109
+ duration: ({ value, isArbitrary }) => {
2110
+ if (!isWeb) return null;
2111
+ const ms = isArbitrary ? value : `${value}ms`;
2112
+ return { transitionDuration: ms };
2113
+ },
2114
+ delay: ({ value, isArbitrary }) => {
2115
+ if (!isWeb) return null;
2116
+ const ms = isArbitrary ? value : `${value}ms`;
2117
+ return { transitionDelay: ms };
2118
+ },
2119
+ // ── Ring (web-only: box-shadow outline ring) ──────────────────────────────
2120
+ ring: ({ value, isArbitrary }, { colors }) => {
2121
+ if (!isWeb) return null;
2122
+ const DEFAULT_COLOR = "rgba(59, 130, 246, 0.5)";
2123
+ const DEFAULT_WIDTH = 3;
2124
+ if (!value) {
2125
+ return { boxShadow: `0 0 0 ${DEFAULT_WIDTH}px ${DEFAULT_COLOR}` };
2126
+ }
2127
+ if (value === "inset") {
2128
+ return { boxShadow: `inset 0 0 0 ${DEFAULT_WIDTH}px ${DEFAULT_COLOR}` };
2129
+ }
2130
+ const widthTokens = { "0": 0, "1": 1, "2": 2, "4": 4, "8": 8 };
2131
+ if (!isArbitrary && value in widthTokens) {
2132
+ const w = widthTokens[value];
2133
+ return { boxShadow: w === 0 ? "none" : `0 0 0 ${w}px ${DEFAULT_COLOR}` };
2134
+ }
2135
+ if (isArbitrary) {
2136
+ const numMatch = /^(\d+(?:\.\d+)?)(px|rem|em|vw|vh)?$/.exec(value);
2137
+ if (numMatch) {
2138
+ const unit = numMatch[2] ?? "px";
2139
+ return { boxShadow: `0 0 0 ${numMatch[1]}${unit} ${DEFAULT_COLOR}` };
2140
+ }
2141
+ return { boxShadow: value.replace(/_/g, " ") };
2142
+ }
2143
+ const color = resolveColor(value, colors, false);
2144
+ if (color) return { boxShadow: `0 0 0 ${DEFAULT_WIDTH}px ${color}` };
2145
+ return null;
2146
+ },
2147
+ "ring-offset": ({ value, isArbitrary }, _theme) => {
2148
+ if (!isWeb) return null;
2149
+ const DEFAULT_RING_COLOR = "rgba(59, 130, 246, 0.5)";
2150
+ const DEFAULT_RING_WIDTH = 3;
2151
+ const offsetTokens = { "0": 0, "1": 1, "2": 2, "4": 4, "8": 8 };
2152
+ const offsetWidth = !isArbitrary ? value in offsetTokens ? offsetTokens[value] : null : parseFloat(value);
2153
+ if (offsetWidth === null || isNaN(offsetWidth)) return null;
2154
+ return {
2155
+ boxShadow: offsetWidth === 0 ? `0 0 0 ${DEFAULT_RING_WIDTH}px ${DEFAULT_RING_COLOR}` : `0 0 0 ${offsetWidth}px #fff, 0 0 0 ${offsetWidth + DEFAULT_RING_WIDTH}px ${DEFAULT_RING_COLOR}`
2156
+ };
2157
+ },
2158
+ // ── Space between (uses CSS gap or margin fallback) ────────────────────────
2159
+ "space-x": ({ value, negative, isArbitrary }, { spacing }) => {
2160
+ const v = resolveSpacing(value, negative, spacing, isArbitrary);
2161
+ return v !== null ? { columnGap: v } : null;
2162
+ },
2163
+ "space-y": ({ value, negative, isArbitrary }, { spacing }) => {
2164
+ const v = resolveSpacing(value, negative, spacing, isArbitrary);
2165
+ return v !== null ? { rowGap: v } : null;
2166
+ }
2167
+ };
2168
+ function resolveUtility(parsed, theme) {
2169
+ if (!parsed.value) {
2170
+ if (parsed.utility in PLUGIN_STANDALONE) return PLUGIN_STANDALONE[parsed.utility] ?? null;
2171
+ if (parsed.utility === "grd" || parsed.utility === "grid") {
2172
+ return { display: "grid" };
2173
+ }
2174
+ if (parsed.utility === "inline-grid") {
2175
+ return { display: "inline-grid" };
2176
+ }
2177
+ if (parsed.utility in STANDALONE) return STANDALONE[parsed.utility] ?? null;
2178
+ }
2179
+ const resolver = PLUGIN_RESOLVERS[parsed.utility] ?? RESOLVERS[parsed.utility];
2180
+ if (resolver) return resolver(parsed, theme);
2181
+ return null;
2182
+ }
2183
+ var PLUGIN_STANDALONE = {};
2184
+ var PLUGIN_RESOLVERS = {};
2185
+ function clearPluginUtilities() {
2186
+ for (const key of Object.keys(PLUGIN_STANDALONE)) delete PLUGIN_STANDALONE[key];
2187
+ for (const key of Object.keys(PLUGIN_RESOLVERS)) delete PLUGIN_RESOLVERS[key];
2188
+ }
2189
+ function getPluginStandaloneMap() {
2190
+ return PLUGIN_STANDALONE;
2191
+ }
2192
+
2193
+ // src/core/parser.ts
2194
+ var PLUGIN_MODIFIERS = /* @__PURE__ */ new Set();
2195
+ function registerModifier(name) {
2196
+ PLUGIN_MODIFIERS.add(name);
2197
+ }
2198
+ function clearPluginModifiers() {
2199
+ PLUGIN_MODIFIERS.clear();
2200
+ }
2201
+ var MODIFIERS = /* @__PURE__ */ new Set([
2202
+ // Theme
2203
+ "dark",
2204
+ "light",
2205
+ "not-dark",
2206
+ "not-light",
2207
+ // Interaction
2208
+ "hover",
2209
+ "focus",
2210
+ "active",
2211
+ "visited",
2212
+ "disabled",
2213
+ "checked",
2214
+ "pressed",
2215
+ "placeholder",
2216
+ "focus-within",
2217
+ "focus-visible",
2218
+ // Negated interaction
2219
+ "not-hover",
2220
+ "not-focus",
2221
+ "not-active",
2222
+ "not-visited",
2223
+ "not-disabled",
2224
+ "not-checked",
2225
+ "not-pressed",
2226
+ // Structural
2227
+ "first",
2228
+ "last",
2229
+ "odd",
2230
+ "even",
2231
+ "only",
2232
+ // Group / peer
2233
+ "group-hover",
2234
+ "group-focus",
2235
+ "peer-hover",
2236
+ "peer-focus",
2237
+ // Responsive (handled separately but accepted)
2238
+ "sm",
2239
+ "md",
2240
+ "lg",
2241
+ "xl",
2242
+ "2xl",
2243
+ // Pseudo-elements (CSS-injection only; matchesMods returns false for these)
2244
+ "before",
2245
+ "after",
2246
+ "selection",
2247
+ "first-letter",
2248
+ "first-line",
2249
+ "marker",
2250
+ // Print media modifier
2251
+ "print",
2252
+ // Orientation media modifiers (CSS-injection only)
2253
+ "landscape",
2254
+ "portrait",
2255
+ // Accessibility media modifiers (CSS-injection only)
2256
+ "motion-reduce",
2257
+ "motion-safe",
2258
+ "contrast-more",
2259
+ "contrast-less",
2260
+ // Directionality modifiers (CSS-injection only)
2261
+ "rtl",
2262
+ "ltr"
2263
+ ]);
2264
+ var UTILITY_PREFIXES = [
2265
+ // Multi-word flex
2266
+ "flex-row-reverse",
2267
+ "flex-col-reverse",
2268
+ "flex-row",
2269
+ "flex-col",
2270
+ "flex-wrap-reverse",
2271
+ "flex-wrap",
2272
+ "flex-nowrap",
2273
+ "flex-shrink-0",
2274
+ "flex-shrink",
2275
+ "flex-grow-0",
2276
+ "flex-grow",
2277
+ "items-start",
2278
+ "items-end",
2279
+ "items-center",
2280
+ "items-baseline",
2281
+ "items-stretch",
2282
+ "justify-start",
2283
+ "justify-end",
2284
+ "justify-center",
2285
+ "justify-between",
2286
+ "justify-around",
2287
+ "justify-evenly",
2288
+ "content-start",
2289
+ "content-end",
2290
+ "content-center",
2291
+ "content-between",
2292
+ "content-around",
2293
+ "content-evenly",
2294
+ "self-start",
2295
+ "self-end",
2296
+ "self-center",
2297
+ "self-auto",
2298
+ "self-stretch",
2299
+ "text-left",
2300
+ "text-right",
2301
+ "text-center",
2302
+ "text-justify",
2303
+ "font-thin",
2304
+ "font-extralight",
2305
+ "font-light",
2306
+ "font-normal",
2307
+ "font-medium",
2308
+ "font-semibold",
2309
+ "font-bold",
2310
+ "font-extrabold",
2311
+ "font-black",
2312
+ "overflow-hidden",
2313
+ "overflow-visible",
2314
+ "overflow-scroll",
2315
+ "overflow-auto",
2316
+ "overflow-x-hidden",
2317
+ "overflow-x-scroll",
2318
+ "overflow-x-auto",
2319
+ "overflow-y-hidden",
2320
+ "overflow-y-scroll",
2321
+ "overflow-y-auto",
2322
+ "object-contain",
2323
+ "object-cover",
2324
+ "object-fill",
2325
+ "object-none",
2326
+ "object-scale-down",
2327
+ "border-solid",
2328
+ "border-dashed",
2329
+ "border-dotted",
2330
+ "border-none",
2331
+ "border-t",
2332
+ "border-r",
2333
+ "border-b",
2334
+ "border-l",
2335
+ "rounded-tl",
2336
+ "rounded-tr",
2337
+ "rounded-bl",
2338
+ "rounded-br",
2339
+ "rounded-t",
2340
+ "rounded-r",
2341
+ "rounded-b",
2342
+ "rounded-l",
2343
+ "list-none",
2344
+ "list-disc",
2345
+ "list-decimal",
2346
+ "cursor-auto",
2347
+ "cursor-default",
2348
+ "cursor-pointer",
2349
+ "cursor-wait",
2350
+ "cursor-text",
2351
+ "cursor-move",
2352
+ "cursor-not-allowed",
2353
+ "select-none",
2354
+ "select-text",
2355
+ "select-all",
2356
+ "select-auto",
2357
+ "pointer-events-none",
2358
+ "pointer-events-auto",
2359
+ "whitespace-normal",
2360
+ "whitespace-nowrap",
2361
+ "whitespace-pre-wrap",
2362
+ "whitespace-pre-line",
2363
+ "whitespace-pre",
2364
+ "break-normal",
2365
+ "break-words",
2366
+ "break-all",
2367
+ "break-keep",
2368
+ "bg-clip-border",
2369
+ "bg-clip-padding",
2370
+ "bg-clip-content",
2371
+ "bg-clip-text",
2372
+ "bg-gradient-to",
2373
+ "resize-none",
2374
+ "resize-y",
2375
+ "resize-x",
2376
+ "box-border",
2377
+ "box-content",
2378
+ "gap-x",
2379
+ "gap-y",
2380
+ "inset-x",
2381
+ "inset-y",
2382
+ "divide-x",
2383
+ "divide-y",
2384
+ "space-x",
2385
+ "space-y",
2386
+ "translate-x",
2387
+ "translate-y",
2388
+ "scale-x",
2389
+ "scale-y",
2390
+ "skew-x",
2391
+ "skew-y",
2392
+ // Transform origin (single prefix, value carries direction)
2393
+ "origin",
2394
+ "min-w",
2395
+ "min-h",
2396
+ "max-w",
2397
+ "max-h",
2398
+ "ring-offset",
2399
+ "bg-opacity",
2400
+ "text-opacity",
2401
+ "border-opacity",
2402
+ // Grid placement
2403
+ "col-span",
2404
+ "col-start",
2405
+ "col-end",
2406
+ "row-span",
2407
+ "row-start",
2408
+ "row-end",
2409
+ "grid-cols",
2410
+ "grid-rows",
2411
+ "grid-flow",
2412
+ "auto-cols",
2413
+ "auto-rows",
2414
+ // Grid alignment
2415
+ "place-items",
2416
+ "place-content",
2417
+ "place-self",
2418
+ "justify-items",
2419
+ "justify-self",
2420
+ // Backdrop filters (longer than 'backdrop' alone)
2421
+ "backdrop-blur",
2422
+ "backdrop-brightness",
2423
+ "backdrop-contrast",
2424
+ "backdrop-grayscale",
2425
+ "backdrop-hue-rotate",
2426
+ "backdrop-invert",
2427
+ "backdrop-opacity",
2428
+ "backdrop-saturate",
2429
+ "backdrop-sepia",
2430
+ "backdrop-filter",
2431
+ // Filters
2432
+ "drop-shadow",
2433
+ "hue-rotate",
2434
+ "text-shadow",
2435
+ "underline-offset",
2436
+ "outline-offset",
2437
+ "will-change",
2438
+ "mix-blend",
2439
+ "bg-blend",
2440
+ "decoration",
2441
+ "perspective",
2442
+ "tint",
2443
+ "animate",
2444
+ // Single-word prefixes last
2445
+ "appearance-none",
2446
+ "outline-none",
2447
+ "outline",
2448
+ "inline-flex",
2449
+ "inline-block",
2450
+ "inline-grid",
2451
+ "italic",
2452
+ "non-italic",
2453
+ "underline",
2454
+ "overline",
2455
+ "line-through",
2456
+ "no-underline",
2457
+ "uppercase",
2458
+ "lowercase",
2459
+ "capitalize",
2460
+ "normal-case",
2461
+ "antialiased",
2462
+ "subpixel-antialiased",
2463
+ "overflow-ellipsis",
2464
+ "truncate",
2465
+ "sr-only",
2466
+ "not-sr-only",
2467
+ "relative",
2468
+ "absolute",
2469
+ "fixed",
2470
+ "sticky",
2471
+ "static",
2472
+ "visible",
2473
+ "invisible",
2474
+ "hidden",
2475
+ "contents",
2476
+ "flow-root",
2477
+ "block",
2478
+ "inline",
2479
+ "flex",
2480
+ "grid",
2481
+ "resize",
2482
+ "appearance",
2483
+ "border",
2484
+ "rounded",
2485
+ "shadow",
2486
+ "size",
2487
+ "opacity",
2488
+ "leading",
2489
+ "tracking",
2490
+ "line-clamp",
2491
+ "basis",
2492
+ "grow",
2493
+ "shrink",
2494
+ "order",
2495
+ "delay",
2496
+ "duration",
2497
+ "scale",
2498
+ "rotate",
2499
+ "aspect",
2500
+ "columns",
2501
+ "ring",
2502
+ "gap",
2503
+ "inset",
2504
+ "filter",
2505
+ "transform",
2506
+ "blur",
2507
+ "brightness",
2508
+ "contrast",
2509
+ "grayscale",
2510
+ "invert",
2511
+ "saturate",
2512
+ "sepia",
2513
+ "bg",
2514
+ "text",
2515
+ "font",
2516
+ "caret",
2517
+ "accent",
2518
+ "from",
2519
+ "via",
2520
+ "to",
2521
+ "divide",
2522
+ "space",
2523
+ "transition",
2524
+ "px",
2525
+ "py",
2526
+ "pt",
2527
+ "pr",
2528
+ "pb",
2529
+ "pl",
2530
+ "p",
2531
+ "mx",
2532
+ "my",
2533
+ "mt",
2534
+ "mr",
2535
+ "mb",
2536
+ "ml",
2537
+ "m",
2538
+ "w",
2539
+ "h",
2540
+ "top",
2541
+ "right",
2542
+ "bottom",
2543
+ "left",
2544
+ "z",
2545
+ "col",
2546
+ "row"
2547
+ ];
2548
+ var SORTED_PREFIXES = [...new Set(UTILITY_PREFIXES)].sort((a, b) => b.length - a.length);
2549
+ var STANDALONE_UTILITIES = /* @__PURE__ */ new Set([
2550
+ // Display
2551
+ "flex",
2552
+ "block",
2553
+ "inline-block",
2554
+ "inline",
2555
+ "grid",
2556
+ "inline-flex",
2557
+ "inline-grid",
2558
+ "grd",
2559
+ "hidden",
2560
+ "contents",
2561
+ "flow-root",
2562
+ // Position
2563
+ "relative",
2564
+ "absolute",
2565
+ "fixed",
2566
+ "sticky",
2567
+ "static",
2568
+ // Visibility
2569
+ "visible",
2570
+ "invisible",
2571
+ // Typography
2572
+ "uppercase",
2573
+ "lowercase",
2574
+ "capitalize",
2575
+ "normal-case",
2576
+ "italic",
2577
+ "non-italic",
2578
+ "underline",
2579
+ "overline",
2580
+ "line-through",
2581
+ "no-underline",
2582
+ "truncate",
2583
+ "antialiased",
2584
+ "sr-only",
2585
+ "not-sr-only",
2586
+ // Font variant numeric
2587
+ "normal-nums",
2588
+ "ordinal",
2589
+ "slashed-zero",
2590
+ "lining-nums",
2591
+ "oldstyle-nums",
2592
+ "proportional-nums",
2593
+ "tabular-nums",
2594
+ "diagonal-fractions",
2595
+ "stacked-fractions",
2596
+ // Flexbox
2597
+ "flex-row",
2598
+ "flex-col",
2599
+ "flex-row-reverse",
2600
+ "flex-col-reverse",
2601
+ "flex-wrap",
2602
+ "flex-wrap-reverse",
2603
+ "flex-nowrap",
2604
+ "flex-shrink",
2605
+ "flex-shrink-0",
2606
+ "flex-grow",
2607
+ "flex-grow-0",
2608
+ "items-start",
2609
+ "items-end",
2610
+ "items-center",
2611
+ "items-baseline",
2612
+ "items-stretch",
2613
+ "justify-start",
2614
+ "justify-end",
2615
+ "justify-center",
2616
+ "justify-between",
2617
+ "justify-around",
2618
+ "justify-evenly",
2619
+ "content-start",
2620
+ "content-end",
2621
+ "content-center",
2622
+ "content-between",
2623
+ "content-around",
2624
+ "content-evenly",
2625
+ "content-stretch",
2626
+ "self-start",
2627
+ "self-end",
2628
+ "self-center",
2629
+ "self-auto",
2630
+ "self-stretch",
2631
+ "self-baseline",
2632
+ // Text align
2633
+ "text-left",
2634
+ "text-right",
2635
+ "text-center",
2636
+ "text-justify",
2637
+ // Font weight shortcuts
2638
+ "font-thin",
2639
+ "font-extralight",
2640
+ "font-light",
2641
+ "font-normal",
2642
+ "font-medium",
2643
+ "font-semibold",
2644
+ "font-bold",
2645
+ "font-extrabold",
2646
+ "font-black",
2647
+ // Overflow
2648
+ "overflow-hidden",
2649
+ "overflow-visible",
2650
+ "overflow-scroll",
2651
+ "overflow-auto",
2652
+ "overflow-x-hidden",
2653
+ "overflow-x-scroll",
2654
+ "overflow-x-auto",
2655
+ "overflow-y-hidden",
2656
+ "overflow-y-scroll",
2657
+ "overflow-y-auto",
2658
+ // Object fit
2659
+ "object-contain",
2660
+ "object-cover",
2661
+ "object-fill",
2662
+ "object-none",
2663
+ "object-scale-down",
2664
+ // Object position
2665
+ "object-center",
2666
+ "object-top",
2667
+ "object-bottom",
2668
+ "object-left",
2669
+ "object-right",
2670
+ "object-left-top",
2671
+ "object-left-bottom",
2672
+ "object-right-top",
2673
+ "object-right-bottom",
2674
+ // Border
2675
+ "border-solid",
2676
+ "border-dashed",
2677
+ "border-dotted",
2678
+ "border-none",
2679
+ "border-t",
2680
+ "border-r",
2681
+ "border-b",
2682
+ "border-l",
2683
+ "border-collapse",
2684
+ "border-separate",
2685
+ // Lists
2686
+ "list-none",
2687
+ "list-disc",
2688
+ "list-decimal",
2689
+ "list-inside",
2690
+ "list-outside",
2691
+ // Cursor / select
2692
+ "cursor-auto",
2693
+ "cursor-default",
2694
+ "cursor-pointer",
2695
+ "cursor-wait",
2696
+ "cursor-text",
2697
+ "cursor-move",
2698
+ "cursor-not-allowed",
2699
+ "select-none",
2700
+ "select-text",
2701
+ "select-all",
2702
+ "select-auto",
2703
+ "pointer-events-none",
2704
+ "pointer-events-auto",
2705
+ // Whitespace / word break
2706
+ "whitespace-normal",
2707
+ "whitespace-nowrap",
2708
+ "whitespace-pre",
2709
+ "whitespace-pre-wrap",
2710
+ "whitespace-pre-line",
2711
+ "break-normal",
2712
+ "break-words",
2713
+ "break-all",
2714
+ // Background clip
2715
+ "bg-clip-border",
2716
+ "bg-clip-padding",
2717
+ "bg-clip-content",
2718
+ "bg-clip-text",
2719
+ // Background size
2720
+ "bg-auto",
2721
+ "bg-cover",
2722
+ "bg-contain",
2723
+ // Background position
2724
+ "bg-center",
2725
+ "bg-top",
2726
+ "bg-bottom",
2727
+ "bg-left",
2728
+ "bg-right",
2729
+ "bg-left-top",
2730
+ "bg-left-bottom",
2731
+ "bg-right-top",
2732
+ "bg-right-bottom",
2733
+ // Background repeat
2734
+ "bg-repeat",
2735
+ "bg-no-repeat",
2736
+ "bg-repeat-x",
2737
+ "bg-repeat-y",
2738
+ "bg-repeat-round",
2739
+ "bg-repeat-space",
2740
+ // Background attachment
2741
+ "bg-fixed",
2742
+ "bg-local",
2743
+ "bg-scroll",
2744
+ // Background image
2745
+ "bg-none",
2746
+ // Box sizing
2747
+ "box-border",
2748
+ "box-content",
2749
+ // Resize
2750
+ "resize",
2751
+ "resize-none",
2752
+ "resize-y",
2753
+ "resize-x",
2754
+ // Outline
2755
+ "appearance-none",
2756
+ "outline-none",
2757
+ "outline",
2758
+ // Table
2759
+ "table",
2760
+ "table-auto",
2761
+ "table-fixed",
2762
+ "caption-top",
2763
+ "caption-bottom",
2764
+ // CSS filters (standalone = default/full effect)
2765
+ "grayscale",
2766
+ "invert",
2767
+ "sepia",
2768
+ // Isolation
2769
+ "isolate",
2770
+ "isolation-auto",
2771
+ // Backface visibility (both platforms)
2772
+ "backface-visible",
2773
+ "backface-hidden",
2774
+ // Divide none
2775
+ "divide-none",
2776
+ // Group / peer markers (no-op style; needed so isKnownUtility recognises them)
2777
+ "group",
2778
+ "peer",
2779
+ // Text-wrap (web-only)
2780
+ "text-wrap",
2781
+ "text-nowrap",
2782
+ "text-balance",
2783
+ "text-pretty",
2784
+ // Screen sizing
2785
+ "w-screen",
2786
+ "min-h-screen",
2787
+ "max-h-screen",
2788
+ "min-w-screen",
2789
+ "max-w-screen",
2790
+ // max-w named container sizes (Tailwind compat)
2791
+ "max-w-none",
2792
+ "max-w-xs",
2793
+ "max-w-sm",
2794
+ "max-w-md",
2795
+ "max-w-lg",
2796
+ "max-w-xl",
2797
+ "max-w-2xl",
2798
+ "max-w-3xl",
2799
+ "max-w-4xl",
2800
+ "max-w-5xl",
2801
+ "max-w-6xl",
2802
+ "max-w-7xl",
2803
+ "max-w-prose",
2804
+ // Extended cursors (web-only)
2805
+ "cursor-grab",
2806
+ "cursor-grabbing",
2807
+ "cursor-zoom-in",
2808
+ "cursor-zoom-out",
2809
+ "cursor-crosshair",
2810
+ "cursor-help",
2811
+ "cursor-none",
2812
+ // Overflow clip (web-only)
2813
+ "overflow-clip",
2814
+ "overflow-x-clip",
2815
+ "overflow-y-clip",
2816
+ // Scroll behavior (web-only)
2817
+ "scroll-smooth",
2818
+ "scroll-auto",
2819
+ // Float & clear (web-only)
2820
+ "float-left",
2821
+ "float-right",
2822
+ "float-start",
2823
+ "float-end",
2824
+ "float-none",
2825
+ "clear-left",
2826
+ "clear-right",
2827
+ "clear-both",
2828
+ "clear-start",
2829
+ "clear-end",
2830
+ "clear-none",
2831
+ // Vertical align (web-only)
2832
+ "align-baseline",
2833
+ "align-top",
2834
+ "align-middle",
2835
+ "align-bottom",
2836
+ "align-text-top",
2837
+ "align-text-bottom",
2838
+ "align-sub",
2839
+ "align-super",
2840
+ // Touch action (web-only)
2841
+ "touch-auto",
2842
+ "touch-none",
2843
+ "touch-pan-x",
2844
+ "touch-pan-y",
2845
+ "touch-pan-left",
2846
+ "touch-pan-right",
2847
+ "touch-pan-up",
2848
+ "touch-pan-down",
2849
+ "touch-pinch-zoom",
2850
+ "touch-manipulation"
2851
+ ]);
2852
+ function parseClass(className) {
2853
+ const trimmed = className.trim();
2854
+ if (!trimmed) return null;
2855
+ const modifiers = [];
2856
+ let remaining = trimmed;
2857
+ for (let i = 0; i < 3; i++) {
2858
+ const colonIdx = findOuterColon(remaining);
2859
+ if (colonIdx === -1) break;
2860
+ const candidate = remaining.slice(0, colonIdx);
2861
+ if (MODIFIERS.has(candidate) || PLUGIN_MODIFIERS.has(candidate)) {
2862
+ modifiers.push(candidate);
2863
+ remaining = remaining.slice(colonIdx + 1);
2864
+ } else {
2865
+ break;
2866
+ }
2867
+ }
2868
+ let important = false;
2869
+ if (remaining.startsWith("!") && remaining.length > 1) {
2870
+ important = true;
2871
+ remaining = remaining.slice(1);
2872
+ }
2873
+ let negative = false;
2874
+ if (remaining.startsWith("-") && remaining.length > 1 && remaining[1] !== "-") {
2875
+ negative = true;
2876
+ remaining = remaining.slice(1);
2877
+ }
2878
+ const bracketStart = remaining.lastIndexOf("-[");
2879
+ if (bracketStart > 0 && remaining.endsWith("]")) {
2880
+ const utility = remaining.slice(0, bracketStart);
2881
+ const value = remaining.slice(bracketStart + 2, -1);
2882
+ return { original: trimmed, modifiers, negative, important, utility, value, isArbitrary: true };
2883
+ }
2884
+ if (STANDALONE_UTILITIES.has(remaining)) {
2885
+ return { original: trimmed, modifiers, negative, important, utility: remaining, value: "", isArbitrary: false };
2886
+ }
2887
+ for (const prefix of SORTED_PREFIXES) {
2888
+ if (remaining === prefix) {
2889
+ return { original: trimmed, modifiers, negative, important, utility: prefix, value: "", isArbitrary: false };
2890
+ }
2891
+ if (remaining.startsWith(prefix + "-")) {
2892
+ const value = remaining.slice(prefix.length + 1);
2893
+ return { original: trimmed, modifiers, negative, important, utility: prefix, value, isArbitrary: false };
2894
+ }
2895
+ }
2896
+ const firstDash = remaining.indexOf("-");
2897
+ if (firstDash > 0) {
2898
+ return {
2899
+ original: trimmed,
2900
+ modifiers,
2901
+ negative,
2902
+ important,
2903
+ utility: remaining.slice(0, firstDash),
2904
+ value: remaining.slice(firstDash + 1),
2905
+ isArbitrary: false
2906
+ };
2907
+ }
2908
+ return { original: trimmed, modifiers, negative, important, utility: remaining, value: "", isArbitrary: false };
2909
+ }
2910
+ function parseClasses(classString) {
2911
+ const results = [];
2912
+ for (const token of classString.split(/\s+/)) {
2913
+ if (!token) continue;
2914
+ const parsed = parseClass(token);
2915
+ if (parsed) results.push(parsed);
2916
+ }
2917
+ return results;
2918
+ }
2919
+ function findOuterColon(s) {
2920
+ let depth = 0;
2921
+ for (let i = 0; i < s.length; i++) {
2922
+ const ch = s[i];
2923
+ if (ch === "[") depth++;
2924
+ else if (ch === "]") depth--;
2925
+ else if (ch === ":" && depth === 0) return i;
2926
+ }
2927
+ return -1;
2928
+ }
2929
+
2930
+ // src/core/cache.ts
2931
+ var LRUCache = class {
2932
+ constructor(capacity = 1e4) {
2933
+ this.capacity = capacity;
2934
+ this.cache = /* @__PURE__ */ new Map();
2935
+ }
2936
+ get(key) {
2937
+ if (!this.cache.has(key)) return void 0;
2938
+ const value = this.cache.get(key);
2939
+ this.cache.delete(key);
2940
+ this.cache.set(key, value);
2941
+ return value;
2942
+ }
2943
+ set(key, value) {
2944
+ if (this.cache.has(key)) {
2945
+ this.cache.delete(key);
2946
+ } else if (this.cache.size >= this.capacity) {
2947
+ this.cache.delete(this.cache.keys().next().value);
2948
+ }
2949
+ this.cache.set(key, value);
2950
+ return this;
2951
+ }
2952
+ has(key) {
2953
+ return this.cache.has(key);
2954
+ }
2955
+ delete(key) {
2956
+ return this.cache.delete(key);
2957
+ }
2958
+ clear() {
2959
+ this.cache.clear();
2960
+ }
2961
+ get size() {
2962
+ return this.cache.size;
2963
+ }
2964
+ };
2965
+
2966
+ // src/core/resolver.ts
2967
+ var styleCache = new LRUCache(1e4);
2968
+ var FONT_KEY = "__kbach_default_font__";
2969
+ function setDefaultFontFamily(font) {
2970
+ globalThis[FONT_KEY] = font;
2971
+ }
2972
+ var _styleEl = null;
2973
+ function getStyleEl() {
2974
+ if (_styleEl) return _styleEl;
2975
+ _styleEl = document.createElement("style");
2976
+ _styleEl.setAttribute("data-kbach", "");
2977
+ document.head.appendChild(_styleEl);
2978
+ return _styleEl;
2979
+ }
2980
+ var _globalStyleEl = null;
2981
+ function getGlobalStyleEl() {
2982
+ if (_globalStyleEl) return _globalStyleEl;
2983
+ _globalStyleEl = document.createElement("style");
2984
+ _globalStyleEl.setAttribute("data-kbach-global", "");
2985
+ document.head.insertBefore(_globalStyleEl, getStyleEl());
2986
+ return _globalStyleEl;
2987
+ }
2988
+ function injectGlobalStyles(theme) {
2989
+ if (typeof document === "undefined") return;
2990
+ const rules = [];
2991
+ const ff = theme.fontFamily;
2992
+ if (ff.sans && ff.sans !== "System") {
2993
+ const family = Array.isArray(ff.sans) ? ff.sans.join(", ") : ff.sans;
2994
+ rules.push(`body { font-family: ${family}; }`);
2995
+ }
2996
+ getGlobalStyleEl().textContent = rules.join("\n");
2997
+ }
2998
+ var MODIFIER_TO_PSEUDO = {
2999
+ hover: ":hover",
3000
+ focus: ":focus",
3001
+ "focus-within": ":focus-within",
3002
+ "focus-visible": ":focus-visible",
3003
+ active: ":active",
3004
+ pressed: ":active",
3005
+ disabled: ":disabled",
3006
+ checked: ":checked",
3007
+ visited: ":visited",
3008
+ placeholder: "::placeholder",
3009
+ first: ":first-child",
3010
+ last: ":last-child",
3011
+ odd: ":nth-child(odd)",
3012
+ even: ":nth-child(even)",
3013
+ only: ":only-child",
3014
+ "not-hover": ":not(:hover)",
3015
+ "not-focus": ":not(:focus)",
3016
+ "not-active": ":not(:active)",
3017
+ "not-pressed": ":not(:active)",
3018
+ "not-disabled": ":not(:disabled)",
3019
+ "not-checked": ":not(:checked)",
3020
+ "not-visited": ":not(:visited)",
3021
+ // Pseudo-elements (CSS-injection only; never applied as inline styles)
3022
+ before: "::before",
3023
+ after: "::after",
3024
+ selection: "::selection",
3025
+ "first-letter": "::first-letter",
3026
+ "first-line": "::first-line",
3027
+ marker: "::marker"
3028
+ };
3029
+ var GROUP_PEER_PREFIX = {
3030
+ "group-hover": ".group:hover",
3031
+ "group-focus": ".group:focus",
3032
+ "peer-hover": ".peer:hover ~",
3033
+ "peer-focus": ".peer:focus ~"
3034
+ };
3035
+ var MODE_MODS = /* @__PURE__ */ new Set(["dark", "light", "not-dark", "not-light"]);
3036
+ var RESPONSIVE_MODS = /* @__PURE__ */ new Set(["sm", "md", "lg", "xl", "2xl"]);
3037
+ var PRINT_MODS = /* @__PURE__ */ new Set(["print"]);
3038
+ var MEDIA_MODS = {
3039
+ landscape: "(orientation: landscape)",
3040
+ portrait: "(orientation: portrait)",
3041
+ "motion-reduce": "(prefers-reduced-motion: reduce)",
3042
+ "motion-safe": "(prefers-reduced-motion: no-preference)",
3043
+ "contrast-more": "(prefers-contrast: more)",
3044
+ "contrast-less": "(prefers-contrast: less)"
3045
+ };
3046
+ var DIR_MODS = {
3047
+ rtl: '[dir="rtl"]',
3048
+ ltr: '[dir="ltr"]'
3049
+ };
3050
+ function buildDivideDecls(styles) {
3051
+ const parts = [];
3052
+ if ("__divideX" in styles) {
3053
+ const w = Number(styles.__divideX);
3054
+ parts.push(`border-left-width: ${w}px`);
3055
+ parts.push("border-right-width: 0px");
3056
+ }
3057
+ if ("__divideY" in styles) {
3058
+ const w = Number(styles.__divideY);
3059
+ parts.push(`border-top-width: ${w}px`);
3060
+ parts.push("border-bottom-width: 0px");
3061
+ }
3062
+ if ("__divideColor" in styles) parts.push(`border-color: ${String(styles.__divideColor)}`);
3063
+ if ("__divideStyle" in styles) parts.push(`border-style: ${String(styles.__divideStyle)}`);
3064
+ return parts.join("; ");
3065
+ }
3066
+ function buildClassCSSRules(cls, bucketKey, styles, darkMode, important, screens) {
3067
+ const rules = [];
3068
+ if ("__keyframe" in styles && typeof styles.__keyframe === "string") {
3069
+ rules.push(styles.__keyframe);
3070
+ }
3071
+ const isDivide = "__divideX" in styles || "__divideY" in styles || "__divideColor" in styles || "__divideStyle" in styles;
3072
+ const escaped = escapeCSSSelector(cls);
3073
+ const childSuffix = isDivide ? " > * + *" : "";
3074
+ if (bucketKey === "base") {
3075
+ const baseCssDecls = isDivide ? buildDivideDecls(styles) : styleValueToCSS(styles, important);
3076
+ if (!baseCssDecls) return rules;
3077
+ rules.push(`.${escaped}${childSuffix} { ${baseCssDecls} }`);
3078
+ return rules;
3079
+ }
3080
+ const mods = bucketKey.split(":");
3081
+ const responsiveMods = mods.filter((m) => RESPONSIVE_MODS.has(m));
3082
+ const nonResponsiveMods = mods.filter((m) => !RESPONSIVE_MODS.has(m));
3083
+ const hasDark = nonResponsiveMods.includes("dark") || nonResponsiveMods.includes("not-light");
3084
+ const hasLight = nonResponsiveMods.includes("light") || nonResponsiveMods.includes("not-dark");
3085
+ const hasPrint = nonResponsiveMods.includes("print");
3086
+ const mediaMods = nonResponsiveMods.filter((m) => m in MEDIA_MODS);
3087
+ const dirMods = nonResponsiveMods.filter((m) => m in DIR_MODS);
3088
+ const ancestorMods = nonResponsiveMods.filter((m) => m in GROUP_PEER_PREFIX);
3089
+ const pseudoMods = nonResponsiveMods.filter(
3090
+ (m) => !MODE_MODS.has(m) && !(m in GROUP_PEER_PREFIX) && !PRINT_MODS.has(m) && !(m in MEDIA_MODS) && !(m in DIR_MODS)
3091
+ );
3092
+ const pseudoSuffix = pseudoMods.map((p) => MODIFIER_TO_PSEUDO[p] ?? `:${p}`).join("");
3093
+ const elementSelector = `.${escaped}${pseudoSuffix}${childSuffix}`;
3094
+ const ancestorPrefix = ancestorMods.length ? ancestorMods.map((m) => GROUP_PEER_PREFIX[m]).join(" ") + " " : "";
3095
+ const dirPrefix = dirMods.length ? dirMods.map((m) => DIR_MODS[m]).join(" ") + " " : "";
3096
+ const selector = `${dirPrefix}${ancestorPrefix}${elementSelector}`;
3097
+ const CSS_ONLY_PSEUDOS = /* @__PURE__ */ new Set([
3098
+ "first",
3099
+ "last",
3100
+ "odd",
3101
+ "even",
3102
+ "only",
3103
+ "focus-within",
3104
+ "focus-visible"
3105
+ ]);
3106
+ const needsImportant = important || hasPrint || mediaMods.length > 0 || dirMods.length > 0 || ancestorMods.length > 0 || pseudoMods.some((m) => CSS_ONLY_PSEUDOS.has(m));
3107
+ const cssDecls = isDivide ? buildDivideDecls(styles) : styleValueToCSS(styles, needsImportant);
3108
+ if (!cssDecls) return rules;
3109
+ let rule;
3110
+ if (hasDark) {
3111
+ if (darkMode === "media") {
3112
+ rule = `@media (prefers-color-scheme: dark) { ${selector} { ${cssDecls} } }`;
3113
+ } else if (darkMode === "class") {
3114
+ rule = `.dark ${selector} { ${cssDecls} }`;
3115
+ } else {
3116
+ rule = `[data-theme="dark"] ${selector} { ${cssDecls} }`;
3117
+ }
3118
+ } else if (hasLight) {
3119
+ if (darkMode === "media") {
3120
+ rule = `@media (prefers-color-scheme: light) { ${selector} { ${cssDecls} } }`;
3121
+ } else if (darkMode === "class") {
3122
+ rule = `:not(.dark) ${selector} { ${cssDecls} }`;
3123
+ } else {
3124
+ rule = `[data-theme="light"] ${selector} { ${cssDecls} }`;
3125
+ }
3126
+ } else {
3127
+ rule = `${selector} { ${cssDecls} }`;
3128
+ }
3129
+ if (hasPrint) rule = `@media print { ${rule} }`;
3130
+ for (const m of mediaMods) rule = `@media ${MEDIA_MODS[m]} { ${rule} }`;
3131
+ if (responsiveMods.length > 0) {
3132
+ const minWidth = Math.max(...responsiveMods.map((m) => screens[m] ?? 0));
3133
+ if (minWidth > 0) rule = `@media (min-width: ${minWidth}px) { ${rule} }`;
3134
+ }
3135
+ rules.push(rule);
3136
+ return rules;
3137
+ }
3138
+ function generateClassCSS(classString, theme, darkMode = "attribute", screens = {}) {
3139
+ const rules = [];
3140
+ for (const parsed of parseClasses(classString)) {
3141
+ const styles = resolveUtility(parsed, theme);
3142
+ if (!styles) continue;
3143
+ const bucketKey = parsed.modifiers.length === 0 ? "base" : parsed.modifiers.join(":");
3144
+ rules.push(...buildClassCSSRules(parsed.original, bucketKey, styles, darkMode, parsed.important, screens));
3145
+ }
3146
+ return rules.join("\n");
3147
+ }
3148
+ var RN_ONLY_PROPS = /* @__PURE__ */ new Set([
3149
+ "shadowColor",
3150
+ "shadowOffset",
3151
+ "shadowOpacity",
3152
+ "shadowRadius",
3153
+ "elevation",
3154
+ "includeFontPadding",
3155
+ "textAlignVertical",
3156
+ "writingDirection",
3157
+ // Text shadow native props — web uses the textShadow CSS shorthand instead
3158
+ "textShadowColor",
3159
+ "textShadowOffset",
3160
+ "textShadowRadius",
3161
+ // tintColor is native-only (Image/icon tinting)
3162
+ "tintColor",
3163
+ // Internal markers — handled specially, never serialized as CSS props
3164
+ "__divideX",
3165
+ "__divideY",
3166
+ "__divideColor",
3167
+ "__divideStyle",
3168
+ "__keyframe"
3169
+ ]);
3170
+ var CSS_UNITLESS = /* @__PURE__ */ new Set([
3171
+ "opacity",
3172
+ "fontWeight",
3173
+ "flex",
3174
+ "flexGrow",
3175
+ "flexShrink",
3176
+ "order",
3177
+ "zIndex",
3178
+ "aspectRatio",
3179
+ "columnCount",
3180
+ "lineHeight",
3181
+ "gridColumnStart",
3182
+ "gridColumnEnd",
3183
+ "gridRowStart",
3184
+ "gridRowEnd"
3185
+ ]);
3186
+ function styleValueToCSS(styles, forceImportant = false) {
3187
+ return Object.entries(styles).filter(
3188
+ ([prop, v]) => v !== void 0 && v !== null && typeof v !== "object" && !RN_ONLY_PROPS.has(prop)
3189
+ ).map(([prop, val]) => {
3190
+ const cssProp = camelToKebab(prop);
3191
+ let cssVal;
3192
+ if (typeof val === "number") {
3193
+ cssVal = val === 0 || CSS_UNITLESS.has(prop) ? String(val) : `${val}px`;
3194
+ } else {
3195
+ cssVal = String(val);
3196
+ }
3197
+ const imp = forceImportant || prop === "display" && (cssVal === "grid" || cssVal === "inline-grid") || prop === "position" && (cssVal === "sticky" || cssVal === "fixed" || cssVal === "static") ? " !important" : "";
3198
+ return `${cssProp}: ${cssVal}${imp}`;
3199
+ }).join("; ");
3200
+ }
3201
+ function camelToKebab(str) {
3202
+ return str.replace(/([A-Z])/g, "-$1").toLowerCase();
3203
+ }
3204
+
3205
+ // src/core/config.ts
3206
+ function deepMerge(base, override) {
3207
+ const result = { ...base };
3208
+ for (const key of Object.keys(override)) {
3209
+ const baseVal = base[key];
3210
+ const overVal = override[key];
3211
+ if (baseVal !== null && typeof baseVal === "object" && !Array.isArray(baseVal) && overVal !== null && typeof overVal === "object" && !Array.isArray(overVal)) {
3212
+ result[key] = deepMerge(
3213
+ baseVal,
3214
+ overVal
3215
+ );
3216
+ } else if (overVal !== void 0) {
3217
+ result[key] = overVal;
3218
+ }
3219
+ }
3220
+ return result;
3221
+ }
3222
+ var CONFIG_KEY = "__kbach_config_store__";
3223
+ function getConfigStore() {
3224
+ const g = globalThis;
3225
+ if (!g[CONFIG_KEY]) {
3226
+ g[CONFIG_KEY] = { resolved: null, listeners: /* @__PURE__ */ new Set(), customVariants: {} };
3227
+ }
3228
+ return g[CONFIG_KEY];
3229
+ }
3230
+ function resolveOneRef(ref, colors) {
3231
+ const m = /^([a-z][a-z0-9]*)-(\d+)$/.exec(ref);
3232
+ if (!m) return null;
3233
+ const entry = colors[m[1]];
3234
+ if (!entry || typeof entry !== "object") return null;
3235
+ return entry[m[2]] ?? null;
3236
+ }
3237
+ function resolveColorRefs(colors) {
3238
+ const out = {};
3239
+ for (const [key, val] of Object.entries(colors)) {
3240
+ if (typeof val === "string") {
3241
+ out[key] = resolveOneRef(val, colors) ?? val;
3242
+ } else {
3243
+ const shades = {};
3244
+ for (const [shade, hex] of Object.entries(val)) {
3245
+ shades[shade] = resolveOneRef(hex, colors) ?? hex;
3246
+ }
3247
+ out[key] = shades;
3248
+ }
3249
+ }
3250
+ return out;
3251
+ }
3252
+ function buildConfig(userConfig) {
3253
+ let theme = { ...defaultTheme };
3254
+ if (userConfig.theme) {
3255
+ theme = deepMerge(theme, userConfig.theme);
3256
+ }
3257
+ if (userConfig.extend) {
3258
+ const { theme: nestedTheme, ...directKeys } = userConfig.extend;
3259
+ const extSources = [];
3260
+ if (nestedTheme) extSources.push(nestedTheme);
3261
+ if (Object.keys(directKeys).length) extSources.push(directKeys);
3262
+ for (const ext of extSources) {
3263
+ for (const [key, value] of Object.entries(ext)) {
3264
+ if (value !== null && typeof value === "object" && !Array.isArray(value)) {
3265
+ theme[key] = deepMerge(
3266
+ theme[key] ?? {},
3267
+ value
3268
+ );
3269
+ } else if (value !== void 0) {
3270
+ theme[key] = value;
3271
+ }
3272
+ }
3273
+ }
3274
+ }
3275
+ theme = { ...theme, colors: resolveColorRefs(theme.colors) };
3276
+ const resolved = {
3277
+ darkMode: userConfig.darkMode ?? "attribute",
3278
+ theme,
3279
+ plugins: userConfig.plugins ?? []
3280
+ };
3281
+ clearPluginUtilities();
3282
+ clearPluginModifiers();
3283
+ const pluginAPI = makePluginAPI(resolved.theme);
3284
+ for (const plugin of resolved.plugins) {
3285
+ plugin(pluginAPI);
3286
+ }
3287
+ const rawSans = theme.fontFamily.sans;
3288
+ const sansFontValue = Array.isArray(rawSans) ? rawSans[0] : rawSans;
3289
+ setDefaultFontFamily(sansFontValue && sansFontValue !== "System" ? sansFontValue : void 0);
3290
+ injectGlobalStyles(resolved.theme);
3291
+ return resolved;
3292
+ }
3293
+ function makePluginAPI(theme) {
3294
+ const standalone = getPluginStandaloneMap();
3295
+ return {
3296
+ addUtility(name, styles) {
3297
+ standalone[name] = styles;
3298
+ },
3299
+ addVariant(name, selector) {
3300
+ customVariants[name] = selector;
3301
+ registerModifier(name);
3302
+ },
3303
+ theme(path, defaultValue) {
3304
+ const parts = path.replace(/\[([^\]]+)\]/g, ".$1").split(".");
3305
+ let current = theme;
3306
+ for (const part of parts) {
3307
+ if (current === null || typeof current !== "object") return defaultValue;
3308
+ current = current[part];
3309
+ }
3310
+ return current ?? defaultValue;
3311
+ },
3312
+ e(className) {
3313
+ return className.replace(/[!"#$%&'()*+,./:;<=>?@[\\\]^`{|}~]/g, "\\$&");
3314
+ }
3315
+ };
3316
+ }
3317
+ var customVariants = new Proxy(
3318
+ {},
3319
+ {
3320
+ get(_t, p) {
3321
+ return typeof p === "string" ? getConfigStore().customVariants[p] : void 0;
3322
+ },
3323
+ set(_t, p, v) {
3324
+ if (typeof p === "string") getConfigStore().customVariants[p] = v;
3325
+ return true;
3326
+ },
3327
+ ownKeys() {
3328
+ return Object.keys(getConfigStore().customVariants);
3329
+ },
3330
+ getOwnPropertyDescriptor(_t, p) {
3331
+ if (typeof p !== "string") return void 0;
3332
+ const v = getConfigStore().customVariants[p];
3333
+ return v !== void 0 ? { value: v, writable: true, enumerable: true, configurable: true } : void 0;
3334
+ }
3335
+ }
3336
+ );
3337
+
3338
+ // src/vite-plugin.ts
3339
+ var VIRTUAL_ID = "virtual:kbach/styles.css";
3340
+ var RESOLVED_ID = "\0" + VIRTUAL_ID;
3341
+ function toNumericScreens(screens) {
3342
+ const out = {};
3343
+ for (const [k, v] of Object.entries(screens)) {
3344
+ out[k] = typeof v === "number" ? v : parseInt(String(v), 10);
3345
+ }
3346
+ return out;
3347
+ }
3348
+ function scanDir(dir, onFile) {
3349
+ try {
3350
+ for (const entry of (0, import_fs.readdirSync)(dir)) {
3351
+ if (entry.startsWith(".") || entry === "node_modules") continue;
3352
+ const full = (0, import_path.join)(dir, entry);
3353
+ try {
3354
+ const st = (0, import_fs.statSync)(full);
3355
+ if (st.isDirectory()) {
3356
+ scanDir(full, onFile);
3357
+ } else if (/\.(tsx?|jsx?)$/.test(entry)) {
3358
+ onFile((0, import_fs.readFileSync)(full, "utf-8"));
3359
+ }
3360
+ } catch {
3361
+ }
3362
+ }
3363
+ } catch {
3364
+ }
3365
+ }
3366
+ function extractClassStrings(code) {
3367
+ const found = [];
3368
+ const re = /(?:className|kb)=(?:["']([^"']+)["']|\{["']([^"']+)["']\})/g;
3369
+ let m;
3370
+ while ((m = re.exec(code)) !== null) {
3371
+ const val = m[1] ?? m[2];
3372
+ if (val) found.push(val);
3373
+ }
3374
+ return found;
3375
+ }
3376
+ function buildGlobalCSS(theme) {
3377
+ const ff = theme.fontFamily;
3378
+ if (!ff?.sans || ff.sans === "System") return "";
3379
+ const family = Array.isArray(ff.sans) ? ff.sans.join(", ") : ff.sans;
3380
+ return `body { font-family: ${family}; }`;
3381
+ }
3382
+ function kbach(userConfig) {
3383
+ const cfg = buildConfig(userConfig ?? {});
3384
+ const screens = toNumericScreens(cfg.theme.screens ?? {});
3385
+ const cssMap = /* @__PURE__ */ new Map();
3386
+ let root = process.cwd();
3387
+ let isDev = false;
3388
+ function processClassString(classStr) {
3389
+ if (cssMap.has(classStr)) return;
3390
+ cssMap.set(classStr, generateClassCSS(classStr, cfg.theme, cfg.darkMode, screens));
3391
+ }
3392
+ function extractFromCode(code) {
3393
+ let added = false;
3394
+ for (const cls of extractClassStrings(code)) {
3395
+ if (!cssMap.has(cls)) {
3396
+ processClassString(cls);
3397
+ added = true;
3398
+ }
3399
+ }
3400
+ return added;
3401
+ }
3402
+ function getAllCSS() {
3403
+ const parts = [];
3404
+ const global = buildGlobalCSS(cfg.theme);
3405
+ if (global) parts.push(global);
3406
+ for (const css of cssMap.values()) {
3407
+ if (css) parts.push(css);
3408
+ }
3409
+ return parts.join("\n");
3410
+ }
3411
+ return {
3412
+ name: "kbach",
3413
+ enforce: "pre",
3414
+ config(_c, env) {
3415
+ isDev = env.command === "serve";
3416
+ },
3417
+ configResolved(resolved) {
3418
+ root = resolved.root;
3419
+ },
3420
+ buildStart() {
3421
+ for (const dir of ["src", "app", "pages", "components"]) {
3422
+ scanDir((0, import_path.join)(root, dir), (code) => extractFromCode(code));
3423
+ }
3424
+ },
3425
+ resolveId(id) {
3426
+ if (id === VIRTUAL_ID) return RESOLVED_ID;
3427
+ },
3428
+ load(id) {
3429
+ if (id === RESOLVED_ID) return getAllCSS();
3430
+ },
3431
+ transform(code, id) {
3432
+ if (id.includes("node_modules") || !/\.(tsx?|jsx?)$/.test(id)) return;
3433
+ const added = extractFromCode(code);
3434
+ if (isDev && added) {
3435
+ }
3436
+ },
3437
+ handleHotUpdate({ file, server }) {
3438
+ if (file.includes("node_modules") || !/\.(tsx?|jsx?)$/.test(file)) return;
3439
+ try {
3440
+ const code = (0, import_fs.readFileSync)(file, "utf-8");
3441
+ const added = extractFromCode(code);
3442
+ if (added) {
3443
+ const mod = server.moduleGraph.getModuleById(RESOLVED_ID);
3444
+ if (mod) {
3445
+ server.moduleGraph.invalidateModule(mod);
3446
+ return [mod];
3447
+ }
3448
+ }
3449
+ } catch {
3450
+ }
3451
+ }
3452
+ };
3453
+ }
3454
+ // Annotate the CommonJS export names for ESM import in node:
3455
+ 0 && (module.exports = {
3456
+ VIRTUAL_ID,
3457
+ kbach
3458
+ });