@kbach/react 0.4.2 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -747,10 +747,19 @@ var MODIFIERS = /* @__PURE__ */ new Set([
747
747
  "md",
748
748
  "lg",
749
749
  "xl",
750
- "2xl"
750
+ "2xl",
751
+ // Pseudo-elements (CSS-injection only; matchesMods returns false for these)
752
+ "before",
753
+ "after",
754
+ "selection",
755
+ "first-letter",
756
+ "first-line",
757
+ "marker",
758
+ // Print media modifier
759
+ "print"
751
760
  ]);
752
761
  var UTILITY_PREFIXES = [
753
- // Multi-word order matters
762
+ // Multi-word flex
754
763
  "flex-row-reverse",
755
764
  "flex-col-reverse",
756
765
  "flex-row",
@@ -828,7 +837,6 @@ var UTILITY_PREFIXES = [
828
837
  "rounded-r",
829
838
  "rounded-b",
830
839
  "rounded-l",
831
- "text-decoration-none",
832
840
  "list-none",
833
841
  "list-disc",
834
842
  "list-decimal",
@@ -858,6 +866,7 @@ var UTILITY_PREFIXES = [
858
866
  "bg-clip-padding",
859
867
  "bg-clip-content",
860
868
  "bg-clip-text",
869
+ "bg-gradient-to",
861
870
  "resize-none",
862
871
  "resize-y",
863
872
  "resize-x",
@@ -877,15 +886,8 @@ var UTILITY_PREFIXES = [
877
886
  "scale-y",
878
887
  "skew-x",
879
888
  "skew-y",
880
- "origin-center",
881
- "origin-top",
882
- "origin-top-right",
883
- "origin-right",
884
- "origin-bottom-right",
885
- "origin-bottom",
886
- "origin-bottom-left",
887
- "origin-left",
888
- "origin-top-left",
889
+ // Transform origin (single prefix, value carries direction)
890
+ "origin",
889
891
  "min-w",
890
892
  "min-h",
891
893
  "max-w",
@@ -894,7 +896,7 @@ var UTILITY_PREFIXES = [
894
896
  "bg-opacity",
895
897
  "text-opacity",
896
898
  "border-opacity",
897
- // Grid placement (longer prefixes before shorter ones)
899
+ // Grid placement
898
900
  "col-span",
899
901
  "col-start",
900
902
  "col-end",
@@ -906,6 +908,35 @@ var UTILITY_PREFIXES = [
906
908
  "grid-flow",
907
909
  "auto-cols",
908
910
  "auto-rows",
911
+ // Grid alignment
912
+ "place-items",
913
+ "place-content",
914
+ "place-self",
915
+ "justify-items",
916
+ "justify-self",
917
+ // Backdrop filters (longer than 'backdrop' alone)
918
+ "backdrop-blur",
919
+ "backdrop-brightness",
920
+ "backdrop-contrast",
921
+ "backdrop-grayscale",
922
+ "backdrop-hue-rotate",
923
+ "backdrop-invert",
924
+ "backdrop-opacity",
925
+ "backdrop-saturate",
926
+ "backdrop-sepia",
927
+ "backdrop-filter",
928
+ // Filters
929
+ "drop-shadow",
930
+ "hue-rotate",
931
+ "text-shadow",
932
+ "underline-offset",
933
+ "outline-offset",
934
+ "will-change",
935
+ "mix-blend",
936
+ "decoration",
937
+ "perspective",
938
+ "tint",
939
+ "animate",
909
940
  // Single-word prefixes last
910
941
  "appearance-none",
911
942
  "outline-none",
@@ -946,9 +977,11 @@ var UTILITY_PREFIXES = [
946
977
  "border",
947
978
  "rounded",
948
979
  "shadow",
980
+ "size",
949
981
  "opacity",
950
982
  "leading",
951
983
  "tracking",
984
+ "line-clamp",
952
985
  "basis",
953
986
  "grow",
954
987
  "shrink",
@@ -959,13 +992,23 @@ var UTILITY_PREFIXES = [
959
992
  "rotate",
960
993
  "aspect",
961
994
  "columns",
962
- "placeholder",
963
995
  "ring",
964
996
  "gap",
965
997
  "inset",
998
+ "filter",
999
+ "transform",
1000
+ "blur",
1001
+ "brightness",
1002
+ "contrast",
1003
+ "grayscale",
1004
+ "invert",
1005
+ "saturate",
1006
+ "sepia",
966
1007
  "bg",
967
1008
  "text",
968
1009
  "font",
1010
+ "caret",
1011
+ "accent",
969
1012
  "from",
970
1013
  "via",
971
1014
  "to",
@@ -994,12 +1037,11 @@ var UTILITY_PREFIXES = [
994
1037
  "left",
995
1038
  "z",
996
1039
  "col",
997
- "row",
998
- "flex"
999
- // also a standalone
1040
+ "row"
1000
1041
  ];
1001
1042
  var SORTED_PREFIXES = [...new Set(UTILITY_PREFIXES)].sort((a, b) => b.length - a.length);
1002
1043
  var STANDALONE_UTILITIES = /* @__PURE__ */ new Set([
1044
+ // Display
1003
1045
  "flex",
1004
1046
  "block",
1005
1047
  "inline-block",
@@ -1011,13 +1053,16 @@ var STANDALONE_UTILITIES = /* @__PURE__ */ new Set([
1011
1053
  "hidden",
1012
1054
  "contents",
1013
1055
  "flow-root",
1056
+ // Position
1014
1057
  "relative",
1015
1058
  "absolute",
1016
1059
  "fixed",
1017
1060
  "sticky",
1018
1061
  "static",
1062
+ // Visibility
1019
1063
  "visible",
1020
1064
  "invisible",
1065
+ // Typography
1021
1066
  "uppercase",
1022
1067
  "lowercase",
1023
1068
  "capitalize",
@@ -1032,6 +1077,17 @@ var STANDALONE_UTILITIES = /* @__PURE__ */ new Set([
1032
1077
  "antialiased",
1033
1078
  "sr-only",
1034
1079
  "not-sr-only",
1080
+ // Font variant numeric
1081
+ "normal-nums",
1082
+ "ordinal",
1083
+ "slashed-zero",
1084
+ "lining-nums",
1085
+ "oldstyle-nums",
1086
+ "proportional-nums",
1087
+ "tabular-nums",
1088
+ "diagonal-fractions",
1089
+ "stacked-fractions",
1090
+ // Flexbox
1035
1091
  "flex-row",
1036
1092
  "flex-col",
1037
1093
  "flex-row-reverse",
@@ -1060,15 +1116,19 @@ var STANDALONE_UTILITIES = /* @__PURE__ */ new Set([
1060
1116
  "content-between",
1061
1117
  "content-around",
1062
1118
  "content-evenly",
1119
+ "content-stretch",
1063
1120
  "self-start",
1064
1121
  "self-end",
1065
1122
  "self-center",
1066
1123
  "self-auto",
1067
1124
  "self-stretch",
1125
+ "self-baseline",
1126
+ // Text align
1068
1127
  "text-left",
1069
1128
  "text-right",
1070
1129
  "text-center",
1071
1130
  "text-justify",
1131
+ // Font weight shortcuts
1072
1132
  "font-thin",
1073
1133
  "font-extralight",
1074
1134
  "font-light",
@@ -1078,6 +1138,7 @@ var STANDALONE_UTILITIES = /* @__PURE__ */ new Set([
1078
1138
  "font-bold",
1079
1139
  "font-extrabold",
1080
1140
  "font-black",
1141
+ // Overflow
1081
1142
  "overflow-hidden",
1082
1143
  "overflow-visible",
1083
1144
  "overflow-scroll",
@@ -1088,11 +1149,23 @@ var STANDALONE_UTILITIES = /* @__PURE__ */ new Set([
1088
1149
  "overflow-y-hidden",
1089
1150
  "overflow-y-scroll",
1090
1151
  "overflow-y-auto",
1152
+ // Object fit
1091
1153
  "object-contain",
1092
1154
  "object-cover",
1093
1155
  "object-fill",
1094
1156
  "object-none",
1095
1157
  "object-scale-down",
1158
+ // Object position
1159
+ "object-center",
1160
+ "object-top",
1161
+ "object-bottom",
1162
+ "object-left",
1163
+ "object-right",
1164
+ "object-left-top",
1165
+ "object-left-bottom",
1166
+ "object-right-top",
1167
+ "object-right-bottom",
1168
+ // Border
1096
1169
  "border-solid",
1097
1170
  "border-dashed",
1098
1171
  "border-dotted",
@@ -1101,9 +1174,15 @@ var STANDALONE_UTILITIES = /* @__PURE__ */ new Set([
1101
1174
  "border-r",
1102
1175
  "border-b",
1103
1176
  "border-l",
1177
+ "border-collapse",
1178
+ "border-separate",
1179
+ // Lists
1104
1180
  "list-none",
1105
1181
  "list-disc",
1106
1182
  "list-decimal",
1183
+ "list-inside",
1184
+ "list-outside",
1185
+ // Cursor / select
1107
1186
  "cursor-auto",
1108
1187
  "cursor-default",
1109
1188
  "cursor-pointer",
@@ -1117,6 +1196,7 @@ var STANDALONE_UTILITIES = /* @__PURE__ */ new Set([
1117
1196
  "select-auto",
1118
1197
  "pointer-events-none",
1119
1198
  "pointer-events-auto",
1199
+ // Whitespace / word break
1120
1200
  "whitespace-normal",
1121
1201
  "whitespace-nowrap",
1122
1202
  "whitespace-pre",
@@ -1125,19 +1205,129 @@ var STANDALONE_UTILITIES = /* @__PURE__ */ new Set([
1125
1205
  "break-normal",
1126
1206
  "break-words",
1127
1207
  "break-all",
1208
+ // Background clip
1128
1209
  "bg-clip-border",
1129
1210
  "bg-clip-padding",
1130
1211
  "bg-clip-content",
1131
1212
  "bg-clip-text",
1213
+ // Background size
1214
+ "bg-auto",
1215
+ "bg-cover",
1216
+ "bg-contain",
1217
+ // Background position
1218
+ "bg-center",
1219
+ "bg-top",
1220
+ "bg-bottom",
1221
+ "bg-left",
1222
+ "bg-right",
1223
+ "bg-left-top",
1224
+ "bg-left-bottom",
1225
+ "bg-right-top",
1226
+ "bg-right-bottom",
1227
+ // Background repeat
1228
+ "bg-repeat",
1229
+ "bg-no-repeat",
1230
+ "bg-repeat-x",
1231
+ "bg-repeat-y",
1232
+ "bg-repeat-round",
1233
+ "bg-repeat-space",
1234
+ // Background attachment
1235
+ "bg-fixed",
1236
+ "bg-local",
1237
+ "bg-scroll",
1238
+ // Background image
1239
+ "bg-none",
1240
+ // Box sizing
1132
1241
  "box-border",
1133
1242
  "box-content",
1243
+ // Resize
1134
1244
  "resize",
1135
1245
  "resize-none",
1136
1246
  "resize-y",
1137
1247
  "resize-x",
1248
+ // Outline
1138
1249
  "appearance-none",
1139
1250
  "outline-none",
1140
- "outline"
1251
+ "outline",
1252
+ // Table
1253
+ "table",
1254
+ "table-auto",
1255
+ "table-fixed",
1256
+ "caption-top",
1257
+ "caption-bottom",
1258
+ // CSS filters (standalone = default/full effect)
1259
+ "grayscale",
1260
+ "invert",
1261
+ "sepia",
1262
+ // Isolation
1263
+ "isolate",
1264
+ "isolation-auto",
1265
+ // Backface visibility (both platforms)
1266
+ "backface-visible",
1267
+ "backface-hidden",
1268
+ // Divide none
1269
+ "divide-none",
1270
+ // Group / peer markers (no-op style; needed so isKnownUtility recognises them)
1271
+ "group",
1272
+ "peer",
1273
+ // Text-wrap (web-only)
1274
+ "text-wrap",
1275
+ "text-nowrap",
1276
+ "text-balance",
1277
+ "text-pretty",
1278
+ // Screen sizing
1279
+ "w-screen",
1280
+ "min-h-screen",
1281
+ "max-h-screen",
1282
+ "min-w-screen",
1283
+ "max-w-screen",
1284
+ // Extended cursors (web-only)
1285
+ "cursor-grab",
1286
+ "cursor-grabbing",
1287
+ "cursor-zoom-in",
1288
+ "cursor-zoom-out",
1289
+ "cursor-crosshair",
1290
+ "cursor-help",
1291
+ "cursor-none",
1292
+ // Overflow clip (web-only)
1293
+ "overflow-clip",
1294
+ "overflow-x-clip",
1295
+ "overflow-y-clip",
1296
+ // Scroll behavior (web-only)
1297
+ "scroll-smooth",
1298
+ "scroll-auto",
1299
+ // Float & clear (web-only)
1300
+ "float-left",
1301
+ "float-right",
1302
+ "float-start",
1303
+ "float-end",
1304
+ "float-none",
1305
+ "clear-left",
1306
+ "clear-right",
1307
+ "clear-both",
1308
+ "clear-start",
1309
+ "clear-end",
1310
+ "clear-none",
1311
+ // Vertical align (web-only)
1312
+ "align-baseline",
1313
+ "align-top",
1314
+ "align-middle",
1315
+ "align-bottom",
1316
+ "align-text-top",
1317
+ "align-text-bottom",
1318
+ "align-sub",
1319
+ "align-super",
1320
+ // Touch action (web-only)
1321
+ "touch-auto",
1322
+ "touch-none",
1323
+ "touch-pan-x",
1324
+ "touch-pan-y",
1325
+ "touch-pan-left",
1326
+ "touch-pan-right",
1327
+ "touch-pan-up",
1328
+ "touch-pan-down",
1329
+ "touch-pinch-zoom",
1330
+ "touch-manipulation"
1141
1331
  ]);
1142
1332
  function parseClass(className) {
1143
1333
  const trimmed = className.trim();
@@ -1155,6 +1345,11 @@ function parseClass(className) {
1155
1345
  break;
1156
1346
  }
1157
1347
  }
1348
+ let important = false;
1349
+ if (remaining.startsWith("!") && remaining.length > 1) {
1350
+ important = true;
1351
+ remaining = remaining.slice(1);
1352
+ }
1158
1353
  let negative = false;
1159
1354
  if (remaining.startsWith("-") && remaining.length > 1 && remaining[1] !== "-") {
1160
1355
  negative = true;
@@ -1164,18 +1359,18 @@ function parseClass(className) {
1164
1359
  if (bracketStart > 0 && remaining.endsWith("]")) {
1165
1360
  const utility = remaining.slice(0, bracketStart);
1166
1361
  const value = remaining.slice(bracketStart + 2, -1);
1167
- return { original: trimmed, modifiers, negative, utility, value, isArbitrary: true };
1362
+ return { original: trimmed, modifiers, negative, important, utility, value, isArbitrary: true };
1168
1363
  }
1169
1364
  if (STANDALONE_UTILITIES.has(remaining)) {
1170
- return { original: trimmed, modifiers, negative, utility: remaining, value: "", isArbitrary: false };
1365
+ return { original: trimmed, modifiers, negative, important, utility: remaining, value: "", isArbitrary: false };
1171
1366
  }
1172
1367
  for (const prefix of SORTED_PREFIXES) {
1173
1368
  if (remaining === prefix) {
1174
- return { original: trimmed, modifiers, negative, utility: prefix, value: "", isArbitrary: false };
1369
+ return { original: trimmed, modifiers, negative, important, utility: prefix, value: "", isArbitrary: false };
1175
1370
  }
1176
1371
  if (remaining.startsWith(prefix + "-")) {
1177
1372
  const value = remaining.slice(prefix.length + 1);
1178
- return { original: trimmed, modifiers, negative, utility: prefix, value, isArbitrary: false };
1373
+ return { original: trimmed, modifiers, negative, important, utility: prefix, value, isArbitrary: false };
1179
1374
  }
1180
1375
  }
1181
1376
  const firstDash = remaining.indexOf("-");
@@ -1184,12 +1379,13 @@ function parseClass(className) {
1184
1379
  original: trimmed,
1185
1380
  modifiers,
1186
1381
  negative,
1382
+ important,
1187
1383
  utility: remaining.slice(0, firstDash),
1188
1384
  value: remaining.slice(firstDash + 1),
1189
1385
  isArbitrary: false
1190
1386
  };
1191
1387
  }
1192
- return { original: trimmed, modifiers, negative, utility: remaining, value: "", isArbitrary: false };
1388
+ return { original: trimmed, modifiers, negative, important, utility: remaining, value: "", isArbitrary: false };
1193
1389
  }
1194
1390
  function parseClasses(classString) {
1195
1391
  const results = [];
@@ -1311,6 +1507,8 @@ function resolveFontSize(value, fontSizes, isArbitrary) {
1311
1507
  if (isArbitrary) return isWeb ? value : toNativeValue(value);
1312
1508
  return fontSizes[value] ?? null;
1313
1509
  }
1510
+ 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,)";
1511
+ 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,)";
1314
1512
  var STANDALONE = {
1315
1513
  // Display
1316
1514
  // React Native only supports display:'flex'|'none'. Setting 'flex' explicitly is
@@ -1361,12 +1559,14 @@ var STANDALONE = {
1361
1559
  "content-between": { alignContent: "space-between" },
1362
1560
  "content-around": { alignContent: "space-around" },
1363
1561
  "content-evenly": { alignContent: "space-evenly" },
1562
+ "content-stretch": { alignContent: "stretch" },
1364
1563
  // Align self (both)
1365
1564
  "self-auto": { alignSelf: "auto" },
1366
1565
  "self-start": { alignSelf: "flex-start" },
1367
1566
  "self-end": { alignSelf: "flex-end" },
1368
1567
  "self-center": { alignSelf: "center" },
1369
1568
  "self-stretch": { alignSelf: "stretch" },
1569
+ "self-baseline": { alignSelf: "baseline" },
1370
1570
  // Text align (both)
1371
1571
  "text-left": { textAlign: "left" },
1372
1572
  "text-right": { textAlign: "right" },
@@ -1499,7 +1699,139 @@ var STANDALONE = {
1499
1699
  "bg-clip-border": isWeb ? { backgroundClip: "border-box" } : null,
1500
1700
  "bg-clip-padding": isWeb ? { backgroundClip: "padding-box" } : null,
1501
1701
  "bg-clip-content": isWeb ? { backgroundClip: "content-box" } : null,
1502
- "bg-clip-text": isWeb ? { backgroundClip: "text", WebkitBackgroundClip: "text" } : null
1702
+ "bg-clip-text": isWeb ? { backgroundClip: "text", WebkitBackgroundClip: "text" } : null,
1703
+ // Background image
1704
+ "bg-none": isWeb ? { backgroundImage: "none" } : null,
1705
+ // Background size (web-only)
1706
+ "bg-auto": isWeb ? { backgroundSize: "auto" } : null,
1707
+ "bg-cover": isWeb ? { backgroundSize: "cover" } : null,
1708
+ "bg-contain": isWeb ? { backgroundSize: "contain" } : null,
1709
+ // Background position (web-only)
1710
+ "bg-center": isWeb ? { backgroundPosition: "center" } : null,
1711
+ "bg-top": isWeb ? { backgroundPosition: "top" } : null,
1712
+ "bg-bottom": isWeb ? { backgroundPosition: "bottom" } : null,
1713
+ "bg-left": isWeb ? { backgroundPosition: "left" } : null,
1714
+ "bg-right": isWeb ? { backgroundPosition: "right" } : null,
1715
+ "bg-left-top": isWeb ? { backgroundPosition: "left top" } : null,
1716
+ "bg-left-bottom": isWeb ? { backgroundPosition: "left bottom" } : null,
1717
+ "bg-right-top": isWeb ? { backgroundPosition: "right top" } : null,
1718
+ "bg-right-bottom": isWeb ? { backgroundPosition: "right bottom" } : null,
1719
+ // Background repeat (web-only)
1720
+ "bg-repeat": isWeb ? { backgroundRepeat: "repeat" } : null,
1721
+ "bg-no-repeat": isWeb ? { backgroundRepeat: "no-repeat" } : null,
1722
+ "bg-repeat-x": isWeb ? { backgroundRepeat: "repeat-x" } : null,
1723
+ "bg-repeat-y": isWeb ? { backgroundRepeat: "repeat-y" } : null,
1724
+ "bg-repeat-round": isWeb ? { backgroundRepeat: "round" } : null,
1725
+ "bg-repeat-space": isWeb ? { backgroundRepeat: "space" } : null,
1726
+ // Background attachment (web-only)
1727
+ "bg-fixed": isWeb ? { backgroundAttachment: "fixed" } : null,
1728
+ "bg-local": isWeb ? { backgroundAttachment: "local" } : null,
1729
+ "bg-scroll": isWeb ? { backgroundAttachment: "scroll" } : null,
1730
+ // Object position (web-only)
1731
+ "object-center": isWeb ? { objectPosition: "center" } : null,
1732
+ "object-top": isWeb ? { objectPosition: "top" } : null,
1733
+ "object-bottom": isWeb ? { objectPosition: "bottom" } : null,
1734
+ "object-left": isWeb ? { objectPosition: "left" } : null,
1735
+ "object-right": isWeb ? { objectPosition: "right" } : null,
1736
+ "object-left-top": isWeb ? { objectPosition: "left top" } : null,
1737
+ "object-left-bottom": isWeb ? { objectPosition: "left bottom" } : null,
1738
+ "object-right-top": isWeb ? { objectPosition: "right top" } : null,
1739
+ "object-right-bottom": isWeb ? { objectPosition: "right bottom" } : null,
1740
+ // Table (web-only)
1741
+ table: isWeb ? { display: "table" } : null,
1742
+ "table-auto": isWeb ? { tableLayout: "auto" } : null,
1743
+ "table-fixed": isWeb ? { tableLayout: "fixed" } : null,
1744
+ "caption-top": isWeb ? { captionSide: "top" } : null,
1745
+ "caption-bottom": isWeb ? { captionSide: "bottom" } : null,
1746
+ "border-collapse": isWeb ? { borderCollapse: "collapse" } : null,
1747
+ "border-separate": isWeb ? { borderCollapse: "separate" } : null,
1748
+ // List style position (web-only)
1749
+ "list-inside": isWeb ? { listStylePosition: "inside" } : null,
1750
+ "list-outside": isWeb ? { listStylePosition: "outside" } : null,
1751
+ // Font variant numeric (web-only)
1752
+ "normal-nums": isWeb ? { fontVariantNumeric: "normal" } : null,
1753
+ ordinal: isWeb ? { fontVariantNumeric: "ordinal" } : null,
1754
+ "slashed-zero": isWeb ? { fontVariantNumeric: "slashed-zero" } : null,
1755
+ "lining-nums": isWeb ? { fontVariantNumeric: "lining-nums" } : null,
1756
+ "oldstyle-nums": isWeb ? { fontVariantNumeric: "oldstyle-nums" } : null,
1757
+ "proportional-nums": isWeb ? { fontVariantNumeric: "proportional-nums" } : null,
1758
+ "tabular-nums": isWeb ? { fontVariantNumeric: "tabular-nums" } : null,
1759
+ "diagonal-fractions": isWeb ? { fontVariantNumeric: "diagonal-fractions" } : null,
1760
+ "stacked-fractions": isWeb ? { fontVariantNumeric: "stacked-fractions" } : null,
1761
+ // Isolation (web-only)
1762
+ isolate: isWeb ? { isolation: "isolate" } : null,
1763
+ "isolation-auto": isWeb ? { isolation: "auto" } : null,
1764
+ // Backface visibility (both iOS and Android)
1765
+ "backface-visible": { backfaceVisibility: "visible" },
1766
+ "backface-hidden": { backfaceVisibility: "hidden" },
1767
+ // CSS filters — standalone = default/full effect (web-only)
1768
+ grayscale: isWeb ? { "--tw-grayscale": "grayscale(100%)", filter: FILTER_COMPOSE } : null,
1769
+ invert: isWeb ? { "--tw-invert": "invert(100%)", filter: FILTER_COMPOSE } : null,
1770
+ sepia: isWeb ? { "--tw-sepia": "sepia(100%)", filter: FILTER_COMPOSE } : null,
1771
+ // Divide none
1772
+ "divide-none": isWeb ? { __divideX: 0, __divideY: 0 } : null,
1773
+ // Group / peer markers (no-op: no style emitted; just ensures isKnownUtility returns true)
1774
+ group: isWeb ? {} : null,
1775
+ peer: isWeb ? {} : null,
1776
+ // Text-wrap (web-only)
1777
+ "text-wrap": isWeb ? { textWrap: "wrap" } : null,
1778
+ "text-nowrap": isWeb ? { textWrap: "nowrap" } : null,
1779
+ "text-balance": isWeb ? { textWrap: "balance" } : null,
1780
+ "text-pretty": isWeb ? { textWrap: "pretty" } : null,
1781
+ // Screen sizing (vw values are web-only; vh values work cross-platform via spacing scale for h-*)
1782
+ "w-screen": isWeb ? { width: "100vw" } : null,
1783
+ "min-h-screen": { minHeight: "100vh" },
1784
+ "max-h-screen": { maxHeight: "100vh" },
1785
+ "min-w-screen": isWeb ? { minWidth: "100vw" } : null,
1786
+ "max-w-screen": isWeb ? { maxWidth: "100vw" } : null,
1787
+ // Extended cursors (web-only)
1788
+ "cursor-grab": isWeb ? { cursor: "grab" } : null,
1789
+ "cursor-grabbing": isWeb ? { cursor: "grabbing" } : null,
1790
+ "cursor-zoom-in": isWeb ? { cursor: "zoom-in" } : null,
1791
+ "cursor-zoom-out": isWeb ? { cursor: "zoom-out" } : null,
1792
+ "cursor-crosshair": isWeb ? { cursor: "crosshair" } : null,
1793
+ "cursor-help": isWeb ? { cursor: "help" } : null,
1794
+ "cursor-none": isWeb ? { cursor: "none" } : null,
1795
+ // Overflow clip (web-only)
1796
+ "overflow-clip": isWeb ? { overflow: "clip" } : null,
1797
+ "overflow-x-clip": isWeb ? { overflowX: "clip" } : null,
1798
+ "overflow-y-clip": isWeb ? { overflowY: "clip" } : null,
1799
+ // Scroll behavior (web-only)
1800
+ "scroll-smooth": isWeb ? { scrollBehavior: "smooth" } : null,
1801
+ "scroll-auto": isWeb ? { scrollBehavior: "auto" } : null,
1802
+ // Float (web-only)
1803
+ "float-left": isWeb ? { float: "left" } : null,
1804
+ "float-right": isWeb ? { float: "right" } : null,
1805
+ "float-start": isWeb ? { float: "inline-start" } : null,
1806
+ "float-end": isWeb ? { float: "inline-end" } : null,
1807
+ "float-none": isWeb ? { float: "none" } : null,
1808
+ // Clear (web-only)
1809
+ "clear-left": isWeb ? { clear: "left" } : null,
1810
+ "clear-right": isWeb ? { clear: "right" } : null,
1811
+ "clear-both": isWeb ? { clear: "both" } : null,
1812
+ "clear-start": isWeb ? { clear: "inline-start" } : null,
1813
+ "clear-end": isWeb ? { clear: "inline-end" } : null,
1814
+ "clear-none": isWeb ? { clear: "none" } : null,
1815
+ // Vertical align (web-only)
1816
+ "align-baseline": isWeb ? { verticalAlign: "baseline" } : null,
1817
+ "align-top": isWeb ? { verticalAlign: "top" } : null,
1818
+ "align-middle": isWeb ? { verticalAlign: "middle" } : null,
1819
+ "align-bottom": isWeb ? { verticalAlign: "bottom" } : null,
1820
+ "align-text-top": isWeb ? { verticalAlign: "text-top" } : null,
1821
+ "align-text-bottom": isWeb ? { verticalAlign: "text-bottom" } : null,
1822
+ "align-sub": isWeb ? { verticalAlign: "sub" } : null,
1823
+ "align-super": isWeb ? { verticalAlign: "super" } : null,
1824
+ // Touch action (web-only)
1825
+ "touch-auto": isWeb ? { touchAction: "auto" } : null,
1826
+ "touch-none": isWeb ? { touchAction: "none" } : null,
1827
+ "touch-pan-x": isWeb ? { touchAction: "pan-x" } : null,
1828
+ "touch-pan-y": isWeb ? { touchAction: "pan-y" } : null,
1829
+ "touch-pan-left": isWeb ? { touchAction: "pan-left" } : null,
1830
+ "touch-pan-right": isWeb ? { touchAction: "pan-right" } : null,
1831
+ "touch-pan-up": isWeb ? { touchAction: "pan-up" } : null,
1832
+ "touch-pan-down": isWeb ? { touchAction: "pan-down" } : null,
1833
+ "touch-pinch-zoom": isWeb ? { touchAction: "pinch-zoom" } : null,
1834
+ "touch-manipulation": isWeb ? { touchAction: "manipulation" } : null
1503
1835
  };
1504
1836
  var RESOLVERS = {
1505
1837
  // ── Background ─────────────────────────────────────────────────────────────
@@ -1831,6 +2163,545 @@ var RESOLVERS = {
1831
2163
  if (isArbitrary) return { gridRow: value };
1832
2164
  return null;
1833
2165
  },
2166
+ // ── Grid alignment (web-only) ──────────────────────────────────────────────
2167
+ // place-items is shorthand for align-items + justify-items on a grid container
2168
+ "place-items": ({ value }) => {
2169
+ if (!isWeb) return null;
2170
+ const map = {
2171
+ start: "start",
2172
+ end: "end",
2173
+ center: "center",
2174
+ stretch: "stretch",
2175
+ baseline: "baseline"
2176
+ };
2177
+ return map[value] ? { placeItems: map[value] } : null;
2178
+ },
2179
+ // place-content is shorthand for align-content + justify-content on a grid container
2180
+ "place-content": ({ value }) => {
2181
+ if (!isWeb) return null;
2182
+ const map = {
2183
+ start: "start",
2184
+ end: "end",
2185
+ center: "center",
2186
+ stretch: "stretch",
2187
+ between: "space-between",
2188
+ around: "space-around",
2189
+ evenly: "space-evenly",
2190
+ baseline: "baseline"
2191
+ };
2192
+ return map[value] ? { placeContent: map[value] } : null;
2193
+ },
2194
+ // justify-items controls inline-axis alignment of grid items within their cells
2195
+ "justify-items": ({ value }) => {
2196
+ if (!isWeb) return null;
2197
+ const map = {
2198
+ start: "start",
2199
+ end: "end",
2200
+ center: "center",
2201
+ stretch: "stretch"
2202
+ };
2203
+ return map[value] ? { justifyItems: map[value] } : null;
2204
+ },
2205
+ // place-self is shorthand for align-self + justify-self on a grid item
2206
+ "place-self": ({ value }) => {
2207
+ if (!isWeb) return null;
2208
+ const map = {
2209
+ auto: "auto",
2210
+ start: "start",
2211
+ end: "end",
2212
+ center: "center",
2213
+ stretch: "stretch"
2214
+ };
2215
+ return map[value] ? { placeSelf: map[value] } : null;
2216
+ },
2217
+ // justify-self controls inline-axis self-alignment of a grid item
2218
+ "justify-self": ({ value }) => {
2219
+ if (!isWeb) return null;
2220
+ const map = {
2221
+ auto: "auto",
2222
+ start: "start",
2223
+ end: "end",
2224
+ center: "center",
2225
+ stretch: "stretch"
2226
+ };
2227
+ return map[value] ? { justifySelf: map[value] } : null;
2228
+ },
2229
+ // ── CSS Filters (composable via CSS variables, web-only) ─────────────────
2230
+ blur: ({ value, isArbitrary }) => {
2231
+ if (!isWeb) return null;
2232
+ const sizes = {
2233
+ "": "blur(8px)",
2234
+ sm: "blur(4px)",
2235
+ md: "blur(12px)",
2236
+ lg: "blur(16px)",
2237
+ xl: "blur(24px)",
2238
+ "2xl": "blur(40px)",
2239
+ "3xl": "blur(64px)"
2240
+ };
2241
+ if (value === "none") return { "--tw-blur": "", filter: FILTER_COMPOSE };
2242
+ const v = isArbitrary ? `blur(${value})` : sizes[value];
2243
+ return v !== void 0 ? { "--tw-blur": v, filter: FILTER_COMPOSE } : null;
2244
+ },
2245
+ brightness: ({ value, isArbitrary }) => {
2246
+ if (!isWeb) return null;
2247
+ const v = isArbitrary ? `brightness(${value})` : `brightness(${parseFloat(value) / 100})`;
2248
+ return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--tw-brightness": v, filter: FILTER_COMPOSE };
2249
+ },
2250
+ contrast: ({ value, isArbitrary }) => {
2251
+ if (!isWeb) return null;
2252
+ const v = isArbitrary ? `contrast(${value})` : `contrast(${parseFloat(value) / 100})`;
2253
+ return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--tw-contrast": v, filter: FILTER_COMPOSE };
2254
+ },
2255
+ grayscale: ({ value }) => {
2256
+ if (!isWeb) return null;
2257
+ const v = value === "0" ? "grayscale(0)" : "grayscale(100%)";
2258
+ return { "--tw-grayscale": v, filter: FILTER_COMPOSE };
2259
+ },
2260
+ "hue-rotate": ({ value, negative, isArbitrary }) => {
2261
+ if (!isWeb) return null;
2262
+ const deg = isArbitrary ? value : `${(negative ? -1 : 1) * parseFloat(value)}deg`;
2263
+ if (isNaN(parseFloat(deg)) && !isArbitrary) return null;
2264
+ return { "--tw-hue-rotate": `hue-rotate(${deg})`, filter: FILTER_COMPOSE };
2265
+ },
2266
+ invert: ({ value }) => {
2267
+ if (!isWeb) return null;
2268
+ const v = value === "0" ? "invert(0)" : "invert(100%)";
2269
+ return { "--tw-invert": v, filter: FILTER_COMPOSE };
2270
+ },
2271
+ saturate: ({ value, isArbitrary }) => {
2272
+ if (!isWeb) return null;
2273
+ const v = isArbitrary ? `saturate(${value})` : `saturate(${parseFloat(value) / 100})`;
2274
+ return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--tw-saturate": v, filter: FILTER_COMPOSE };
2275
+ },
2276
+ sepia: ({ value }) => {
2277
+ if (!isWeb) return null;
2278
+ const v = value === "0" ? "sepia(0)" : "sepia(100%)";
2279
+ return { "--tw-sepia": v, filter: FILTER_COMPOSE };
2280
+ },
2281
+ "drop-shadow": ({ value, isArbitrary }) => {
2282
+ if (!isWeb) return null;
2283
+ if (isArbitrary) return { "--tw-drop-shadow": `drop-shadow(${value.replace(/_/g, " ")})`, filter: FILTER_COMPOSE };
2284
+ const presets = {
2285
+ "": "drop-shadow(0 1px 2px rgb(0 0 0/0.1)) drop-shadow(0 1px 1px rgb(0 0 0/0.06))",
2286
+ sm: "drop-shadow(0 1px 1px rgb(0 0 0/0.05))",
2287
+ md: "drop-shadow(0 4px 3px rgb(0 0 0/0.07)) drop-shadow(0 2px 2px rgb(0 0 0/0.06))",
2288
+ lg: "drop-shadow(0 10px 8px rgb(0 0 0/0.04)) drop-shadow(0 4px 3px rgb(0 0 0/0.1))",
2289
+ xl: "drop-shadow(0 20px 13px rgb(0 0 0/0.03)) drop-shadow(0 8px 5px rgb(0 0 0/0.08))",
2290
+ "2xl": "drop-shadow(0 25px 25px rgb(0 0 0/0.15))",
2291
+ none: "drop-shadow(0 0 #0000)"
2292
+ };
2293
+ const v = presets[value];
2294
+ return v !== void 0 ? { "--tw-drop-shadow": v, filter: FILTER_COMPOSE } : null;
2295
+ },
2296
+ // Arbitrary full filter string: filter-[blur(4px)_grayscale(1)]
2297
+ filter: ({ value, isArbitrary }) => {
2298
+ if (!isWeb) return null;
2299
+ if (isArbitrary) return { filter: value.replace(/_/g, " ") };
2300
+ if (value === "none") return { filter: "none" };
2301
+ return null;
2302
+ },
2303
+ // ── Backdrop Filters (composable via CSS variables, web-only) ────────────
2304
+ "backdrop-blur": ({ value, isArbitrary }) => {
2305
+ if (!isWeb) return null;
2306
+ const sizes = {
2307
+ "": "blur(8px)",
2308
+ sm: "blur(4px)",
2309
+ md: "blur(12px)",
2310
+ lg: "blur(16px)",
2311
+ xl: "blur(24px)",
2312
+ "2xl": "blur(40px)",
2313
+ "3xl": "blur(64px)"
2314
+ };
2315
+ if (value === "none") return { "--tw-backdrop-blur": "", backdropFilter: BACKDROP_FILTER_COMPOSE };
2316
+ const v = isArbitrary ? `blur(${value})` : sizes[value];
2317
+ return v !== void 0 ? { "--tw-backdrop-blur": v, backdropFilter: BACKDROP_FILTER_COMPOSE } : null;
2318
+ },
2319
+ "backdrop-brightness": ({ value, isArbitrary }) => {
2320
+ if (!isWeb) return null;
2321
+ const v = isArbitrary ? `brightness(${value})` : `brightness(${parseFloat(value) / 100})`;
2322
+ return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--tw-backdrop-brightness": v, backdropFilter: BACKDROP_FILTER_COMPOSE };
2323
+ },
2324
+ "backdrop-contrast": ({ value, isArbitrary }) => {
2325
+ if (!isWeb) return null;
2326
+ const v = isArbitrary ? `contrast(${value})` : `contrast(${parseFloat(value) / 100})`;
2327
+ return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--tw-backdrop-contrast": v, backdropFilter: BACKDROP_FILTER_COMPOSE };
2328
+ },
2329
+ "backdrop-grayscale": ({ value }) => {
2330
+ if (!isWeb) return null;
2331
+ return { "--tw-backdrop-grayscale": value === "0" ? "grayscale(0)" : "grayscale(100%)", backdropFilter: BACKDROP_FILTER_COMPOSE };
2332
+ },
2333
+ "backdrop-hue-rotate": ({ value, negative, isArbitrary }) => {
2334
+ if (!isWeb) return null;
2335
+ const deg = isArbitrary ? value : `${(negative ? -1 : 1) * parseFloat(value)}deg`;
2336
+ if (isNaN(parseFloat(deg)) && !isArbitrary) return null;
2337
+ return { "--tw-backdrop-hue-rotate": `hue-rotate(${deg})`, backdropFilter: BACKDROP_FILTER_COMPOSE };
2338
+ },
2339
+ "backdrop-invert": ({ value }) => {
2340
+ if (!isWeb) return null;
2341
+ return { "--tw-backdrop-invert": value === "0" ? "invert(0)" : "invert(100%)", backdropFilter: BACKDROP_FILTER_COMPOSE };
2342
+ },
2343
+ "backdrop-opacity": ({ value, isArbitrary }) => {
2344
+ if (!isWeb) return null;
2345
+ const v = isArbitrary ? `opacity(${value})` : `opacity(${parseFloat(value) / 100})`;
2346
+ return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--tw-backdrop-opacity": v, backdropFilter: BACKDROP_FILTER_COMPOSE };
2347
+ },
2348
+ "backdrop-saturate": ({ value, isArbitrary }) => {
2349
+ if (!isWeb) return null;
2350
+ const v = isArbitrary ? `saturate(${value})` : `saturate(${parseFloat(value) / 100})`;
2351
+ return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--tw-backdrop-saturate": v, backdropFilter: BACKDROP_FILTER_COMPOSE };
2352
+ },
2353
+ "backdrop-sepia": ({ value }) => {
2354
+ if (!isWeb) return null;
2355
+ return { "--tw-backdrop-sepia": value === "0" ? "sepia(0)" : "sepia(100%)", backdropFilter: BACKDROP_FILTER_COMPOSE };
2356
+ },
2357
+ "backdrop-filter": ({ value, isArbitrary }) => {
2358
+ if (!isWeb) return null;
2359
+ if (isArbitrary) return { backdropFilter: value.replace(/_/g, " ") };
2360
+ if (value === "none") return { backdropFilter: "none" };
2361
+ return null;
2362
+ },
2363
+ // ── Background gradient (CSS variable gradient stops, web-only) ──────────
2364
+ "bg-gradient-to": ({ value }) => {
2365
+ if (!isWeb) return null;
2366
+ const directions = {
2367
+ t: "to top",
2368
+ tr: "to top right",
2369
+ r: "to right",
2370
+ br: "to bottom right",
2371
+ b: "to bottom",
2372
+ bl: "to bottom left",
2373
+ l: "to left",
2374
+ tl: "to top left"
2375
+ };
2376
+ const dir = directions[value];
2377
+ if (!dir) return null;
2378
+ return {
2379
+ backgroundImage: `linear-gradient(${dir}, var(--tw-gradient-from, transparent), var(--tw-gradient-stops, transparent))`
2380
+ };
2381
+ },
2382
+ from: ({ value, isArbitrary }, { colors }) => {
2383
+ if (!isWeb) return null;
2384
+ const color = resolveColor(value, colors, isArbitrary);
2385
+ if (!color) return null;
2386
+ return {
2387
+ "--tw-gradient-from": color,
2388
+ "--tw-gradient-stops": `var(--tw-gradient-from), var(--tw-gradient-to, transparent)`
2389
+ };
2390
+ },
2391
+ via: ({ value, isArbitrary }, { colors }) => {
2392
+ if (!isWeb) return null;
2393
+ const color = resolveColor(value, colors, isArbitrary);
2394
+ if (!color) return null;
2395
+ return {
2396
+ "--tw-gradient-via": color,
2397
+ "--tw-gradient-stops": `var(--tw-gradient-from), var(--tw-gradient-via), var(--tw-gradient-to, transparent)`
2398
+ };
2399
+ },
2400
+ to: ({ value, isArbitrary }, { colors }) => {
2401
+ if (!isWeb) return null;
2402
+ const color = resolveColor(value, colors, isArbitrary);
2403
+ if (!color) return null;
2404
+ return { "--tw-gradient-to": color };
2405
+ },
2406
+ // ── Transform extras (web-only) ───────────────────────────────────────────
2407
+ "skew-x": ({ value, negative, isArbitrary }) => {
2408
+ const deg = isArbitrary ? value : `${(negative ? -1 : 1) * parseFloat(value)}deg`;
2409
+ if (!isArbitrary && isNaN(parseFloat(value))) return null;
2410
+ return isWeb ? { transform: `skewX(${deg})` } : { transform: [{ skewX: deg }] };
2411
+ },
2412
+ "skew-y": ({ value, negative, isArbitrary }) => {
2413
+ const deg = isArbitrary ? value : `${(negative ? -1 : 1) * parseFloat(value)}deg`;
2414
+ if (!isArbitrary && isNaN(parseFloat(value))) return null;
2415
+ return isWeb ? { transform: `skewY(${deg})` } : { transform: [{ skewY: deg }] };
2416
+ },
2417
+ // Arbitrary full transform string: transform-[rotate(45deg)_scale(1.5)]
2418
+ transform: ({ value, isArbitrary }) => {
2419
+ if (!isWeb) return null;
2420
+ if (isArbitrary) return { transform: value.replace(/_/g, " ") };
2421
+ if (value === "none") return { transform: "none" };
2422
+ return null;
2423
+ },
2424
+ // Transform origin
2425
+ origin: ({ value, isArbitrary }) => {
2426
+ if (!isWeb) return null;
2427
+ if (isArbitrary) return { transformOrigin: value.replace(/_/g, " ") };
2428
+ const origins = {
2429
+ center: "center",
2430
+ top: "top",
2431
+ "top-right": "top right",
2432
+ right: "right",
2433
+ "bottom-right": "bottom right",
2434
+ bottom: "bottom",
2435
+ "bottom-left": "bottom left",
2436
+ left: "left",
2437
+ "top-left": "top left"
2438
+ };
2439
+ return origins[value] ? { transformOrigin: origins[value] } : null;
2440
+ },
2441
+ // ── Text decoration advanced (web-only) ───────────────────────────────────
2442
+ decoration: ({ value, isArbitrary }, { colors }) => {
2443
+ if (!isWeb) return null;
2444
+ if (isArbitrary) {
2445
+ if (/^\d/.test(value) || value.startsWith("calc(")) return { textDecorationThickness: value };
2446
+ return { textDecorationColor: value };
2447
+ }
2448
+ const thickTokens = {
2449
+ auto: "auto",
2450
+ "from-font": "from-font",
2451
+ "0": "0px",
2452
+ "1": "1px",
2453
+ "2": "2px",
2454
+ "4": "4px",
2455
+ "8": "8px"
2456
+ };
2457
+ if (value in thickTokens) return { textDecorationThickness: thickTokens[value] };
2458
+ const styleTokens = {
2459
+ solid: "solid",
2460
+ dashed: "dashed",
2461
+ dotted: "dotted",
2462
+ double: "double",
2463
+ wavy: "wavy"
2464
+ };
2465
+ if (value in styleTokens) return { textDecorationStyle: styleTokens[value] };
2466
+ const color = resolveColor(value, colors, false);
2467
+ return color ? { textDecorationColor: color } : null;
2468
+ },
2469
+ "underline-offset": ({ value, isArbitrary }) => {
2470
+ if (!isWeb) return null;
2471
+ if (isArbitrary) return { textUnderlineOffset: value };
2472
+ const offsets = {
2473
+ auto: "auto",
2474
+ "0": "0px",
2475
+ "1": "1px",
2476
+ "2": "2px",
2477
+ "4": "4px",
2478
+ "8": "8px"
2479
+ };
2480
+ return offsets[value] ? { textUnderlineOffset: offsets[value] } : null;
2481
+ },
2482
+ // ── Outline extended (web-only) ───────────────────────────────────────────
2483
+ outline: ({ value, isArbitrary }, { colors }) => {
2484
+ if (!isWeb) return null;
2485
+ if (!value) return { outline: "2px solid transparent", outlineOffset: "2px" };
2486
+ if (value === "none") return { outline: "none", outlineOffset: "0" };
2487
+ if (isArbitrary) {
2488
+ if (/^\d/.test(value) || value.startsWith("calc(")) return { outlineWidth: value };
2489
+ return { outlineColor: value };
2490
+ }
2491
+ const widths = { "0": "0px", "1": "1px", "2": "2px", "4": "4px", "8": "8px" };
2492
+ if (value in widths) return { outlineWidth: widths[value] };
2493
+ const color = resolveColor(value, colors, false);
2494
+ return color ? { outlineColor: color } : null;
2495
+ },
2496
+ "outline-offset": ({ value, isArbitrary }) => {
2497
+ if (!isWeb) return null;
2498
+ if (isArbitrary) return { outlineOffset: value };
2499
+ const offsets = { "0": "0px", "1": "1px", "2": "2px", "4": "4px", "8": "8px" };
2500
+ return offsets[value] ? { outlineOffset: offsets[value] } : null;
2501
+ },
2502
+ // ── Columns (web-only) ─────────────────────────────────────────────────────
2503
+ columns: ({ value, isArbitrary }) => {
2504
+ if (!isWeb) return null;
2505
+ if (isArbitrary) return { columnCount: value };
2506
+ if (value === "auto") return { columnCount: "auto" };
2507
+ const n = parseInt(value, 10);
2508
+ if (!isNaN(n)) return { columnCount: n };
2509
+ const widths = {
2510
+ "3xs": "16rem",
2511
+ "2xs": "18rem",
2512
+ xs: "20rem",
2513
+ sm: "24rem",
2514
+ md: "28rem",
2515
+ lg: "32rem",
2516
+ xl: "36rem",
2517
+ "2xl": "42rem",
2518
+ "3xl": "48rem",
2519
+ "4xl": "56rem",
2520
+ "5xl": "64rem",
2521
+ "6xl": "72rem",
2522
+ "7xl": "80rem"
2523
+ };
2524
+ return widths[value] ? { columnWidth: widths[value] } : null;
2525
+ },
2526
+ // ── Mix blend mode (web-only) ─────────────────────────────────────────────
2527
+ "mix-blend": ({ value }) => {
2528
+ if (!isWeb) return null;
2529
+ const modes = [
2530
+ "normal",
2531
+ "multiply",
2532
+ "screen",
2533
+ "overlay",
2534
+ "darken",
2535
+ "lighten",
2536
+ "color-dodge",
2537
+ "color-burn",
2538
+ "hard-light",
2539
+ "soft-light",
2540
+ "difference",
2541
+ "exclusion",
2542
+ "hue",
2543
+ "saturation",
2544
+ "color",
2545
+ "luminosity",
2546
+ "plus-lighter"
2547
+ ];
2548
+ return modes.includes(value) ? { mixBlendMode: value } : null;
2549
+ },
2550
+ // ── Will-change (web-only) ─────────────────────────────────────────────────
2551
+ "will-change": ({ value, isArbitrary }) => {
2552
+ if (!isWeb) return null;
2553
+ if (isArbitrary) return { willChange: value.replace(/_/g, ", ") };
2554
+ const presets = {
2555
+ auto: "auto",
2556
+ scroll: "scroll-position",
2557
+ contents: "contents",
2558
+ transform: "transform"
2559
+ };
2560
+ return presets[value] ? { willChange: presets[value] } : null;
2561
+ },
2562
+ // ── Divide (child combinator CSS, web-only) ───────────────────────────────
2563
+ // These return special __divide* markers that resolver.ts converts to
2564
+ // .cls > * + * { border-... } CSS rules. No inline style is applied.
2565
+ "divide-x": ({ value, isArbitrary }) => {
2566
+ if (!isWeb) return null;
2567
+ if (value === "reverse") return null;
2568
+ if (!value) return { __divideX: 1 };
2569
+ const n = parseFloat(value);
2570
+ return isNaN(n) ? null : { __divideX: n };
2571
+ },
2572
+ "divide-y": ({ value, isArbitrary }) => {
2573
+ if (!isWeb) return null;
2574
+ if (value === "reverse") return null;
2575
+ if (!value) return { __divideY: 1 };
2576
+ const n = parseFloat(value);
2577
+ return isNaN(n) ? null : { __divideY: n };
2578
+ },
2579
+ divide: ({ value, isArbitrary }, { colors }) => {
2580
+ if (!isWeb) return null;
2581
+ if (isArbitrary) return { __divideColor: value };
2582
+ const styleTokens = {
2583
+ solid: "solid",
2584
+ dashed: "dashed",
2585
+ dotted: "dotted",
2586
+ double: "double",
2587
+ none: "none"
2588
+ };
2589
+ if (value in styleTokens) return { __divideStyle: styleTokens[value] };
2590
+ const color = resolveColor(value, colors, false);
2591
+ return color ? { __divideColor: color } : null;
2592
+ },
2593
+ // ── Text shadow (cross-platform: iOS, Android, web) ─────────────────────
2594
+ // Named presets give cross-platform shadow; arbitrary is web-only.
2595
+ "text-shadow": ({ value, isArbitrary }, { colors }) => {
2596
+ if (value === "none") {
2597
+ return isWeb ? { textShadow: "none" } : { textShadowColor: "transparent", textShadowOffset: { width: 0, height: 0 }, textShadowRadius: 0 };
2598
+ }
2599
+ const webPresets = {
2600
+ "": "0 2px 4px rgba(0,0,0,0.3)",
2601
+ sm: "0 1px 2px rgba(0,0,0,0.3)",
2602
+ md: "0 4px 6px rgba(0,0,0,0.3)",
2603
+ lg: "0 8px 16px rgba(0,0,0,0.5)",
2604
+ xl: "0 16px 32px rgba(0,0,0,0.5)"
2605
+ };
2606
+ const nativePresets = {
2607
+ "": { textShadowColor: "rgba(0,0,0,0.3)", textShadowOffset: { width: 0, height: 2 }, textShadowRadius: 4 },
2608
+ sm: { textShadowColor: "rgba(0,0,0,0.3)", textShadowOffset: { width: 0, height: 1 }, textShadowRadius: 2 },
2609
+ md: { textShadowColor: "rgba(0,0,0,0.3)", textShadowOffset: { width: 0, height: 4 }, textShadowRadius: 6 },
2610
+ lg: { textShadowColor: "rgba(0,0,0,0.5)", textShadowOffset: { width: 0, height: 8 }, textShadowRadius: 16 },
2611
+ xl: { textShadowColor: "rgba(0,0,0,0.5)", textShadowOffset: { width: 0, height: 16 }, textShadowRadius: 32 }
2612
+ };
2613
+ if (value in webPresets) {
2614
+ if (isWeb) return { textShadow: webPresets[value] };
2615
+ return nativePresets[value] ?? null;
2616
+ }
2617
+ if (isArbitrary) {
2618
+ return isWeb ? { textShadow: value.replace(/_/g, " ") } : null;
2619
+ }
2620
+ const color = resolveColor(value, colors, false);
2621
+ if (color) {
2622
+ return isWeb ? { textShadow: `0 2px 4px ${color}` } : { textShadowColor: color };
2623
+ }
2624
+ return null;
2625
+ },
2626
+ // ── Perspective transform (cross-platform: iOS, Android, web) ────────────
2627
+ perspective: ({ value, isArbitrary }) => {
2628
+ if (isArbitrary) {
2629
+ const numPx = parseFloat(value);
2630
+ if (isWeb) return { transform: `perspective(${value})` };
2631
+ return isNaN(numPx) ? null : { transform: [{ perspective: numPx }] };
2632
+ }
2633
+ if (value === "none") return isWeb ? { transform: "none" } : null;
2634
+ const n = parseFloat(value);
2635
+ if (isNaN(n)) return null;
2636
+ return isWeb ? { transform: `perspective(${n}px)` } : { transform: [{ perspective: n }] };
2637
+ },
2638
+ // ── Tint color (native-only, for Image and icon components) ──────────────
2639
+ tint: ({ value, isArbitrary }, { colors }) => {
2640
+ if (isWeb) return null;
2641
+ const color = resolveColor(value, colors, isArbitrary);
2642
+ return color ? { tintColor: color } : null;
2643
+ },
2644
+ // ── Size shorthand (sets width AND height in one utility) ────────────────
2645
+ size: ({ value, isArbitrary }, { spacing }) => {
2646
+ const v = resolveSizing(value, spacing, isArbitrary);
2647
+ return v !== null ? { width: v, height: v } : null;
2648
+ },
2649
+ // ── Animations (CSS keyframe animations, web-only) ────────────────────────
2650
+ // Each variant injects a @keyframes rule once via the __keyframe marker.
2651
+ // resolver.ts detects __keyframe, injects the rule, then strips the marker
2652
+ // so it never reaches element inline styles.
2653
+ animate: ({ value, isArbitrary }) => {
2654
+ if (!isWeb) return null;
2655
+ if (isArbitrary) return { animation: value.replace(/_/g, " ") };
2656
+ const defs = {
2657
+ none: { animation: "none" },
2658
+ spin: {
2659
+ animation: "kb-spin 1s linear infinite",
2660
+ __keyframe: "@keyframes kb-spin { from { transform: rotate(0deg) } to { transform: rotate(360deg) } }"
2661
+ },
2662
+ ping: {
2663
+ animation: "kb-ping 1s cubic-bezier(0,0,0.2,1) infinite",
2664
+ __keyframe: "@keyframes kb-ping { 75%, 100% { transform: scale(2); opacity: 0 } }"
2665
+ },
2666
+ pulse: {
2667
+ animation: "kb-pulse 2s cubic-bezier(0.4,0,0.6,1) infinite",
2668
+ __keyframe: "@keyframes kb-pulse { 0%, 100% { opacity: 1 } 50% { opacity: .5 } }"
2669
+ },
2670
+ bounce: {
2671
+ animation: "kb-bounce 1s infinite",
2672
+ __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) } }"
2673
+ }
2674
+ };
2675
+ const def = defs[value];
2676
+ return def ? def : null;
2677
+ },
2678
+ // ── Line-clamp (web-only) ─────────────────────────────────────────────────
2679
+ "line-clamp": ({ value }) => {
2680
+ if (!isWeb) return null;
2681
+ if (value === "none") return { overflow: "visible", display: "block", WebkitLineClamp: "unset" };
2682
+ const n = parseInt(value, 10);
2683
+ if (isNaN(n) || n < 1) return null;
2684
+ return {
2685
+ overflow: "hidden",
2686
+ display: "-webkit-box",
2687
+ WebkitBoxOrient: "vertical",
2688
+ WebkitLineClamp: n
2689
+ };
2690
+ },
2691
+ // ── Caret color (web-only) ────────────────────────────────────────────────
2692
+ caret: ({ value, isArbitrary }, { colors }) => {
2693
+ if (!isWeb) return null;
2694
+ if (value === "auto" || value === "transparent") return { caretColor: value };
2695
+ const color = resolveColor(value, colors, isArbitrary);
2696
+ return color ? { caretColor: color } : null;
2697
+ },
2698
+ // ── Accent color (web-only) ───────────────────────────────────────────────
2699
+ accent: ({ value, isArbitrary }, { colors }) => {
2700
+ if (!isWeb) return null;
2701
+ if (value === "auto") return { accentColor: "auto" };
2702
+ const color = resolveColor(value, colors, isArbitrary);
2703
+ return color ? { accentColor: color } : null;
2704
+ },
1834
2705
  // ── Flex ───────────────────────────────────────────────────────────────────
1835
2706
  flex: ({ value, isArbitrary }, { flex }) => {
1836
2707
  if (!value) return { display: "flex" };
@@ -2111,6 +2982,9 @@ function clearPluginUtilities() {
2111
2982
  function getPluginStandaloneMap() {
2112
2983
  return PLUGIN_STANDALONE;
2113
2984
  }
2985
+ function isKnownUtility(utility) {
2986
+ return utility in STANDALONE || utility in RESOLVERS || utility in PLUGIN_STANDALONE || utility in PLUGIN_RESOLVERS;
2987
+ }
2114
2988
 
2115
2989
  // src/core/responsiveStore.ts
2116
2990
  var RESPONSIVE_KEY = "__kbach_responsive__";
@@ -2195,7 +3069,14 @@ var MODIFIER_TO_PSEUDO = {
2195
3069
  "not-pressed": ":not(:active)",
2196
3070
  "not-disabled": ":not(:disabled)",
2197
3071
  "not-checked": ":not(:checked)",
2198
- "not-visited": ":not(:visited)"
3072
+ "not-visited": ":not(:visited)",
3073
+ // Pseudo-elements (CSS-injection only; never applied as inline styles)
3074
+ before: "::before",
3075
+ after: "::after",
3076
+ selection: "::selection",
3077
+ "first-letter": "::first-letter",
3078
+ "first-line": "::first-line",
3079
+ marker: "::marker"
2199
3080
  };
2200
3081
  var GROUP_PEER_PREFIX = {
2201
3082
  "group-hover": ".group:hover",
@@ -2205,12 +3086,34 @@ var GROUP_PEER_PREFIX = {
2205
3086
  };
2206
3087
  var MODE_MODS = /* @__PURE__ */ new Set(["dark", "light", "not-dark", "not-light"]);
2207
3088
  var RESPONSIVE_MODS = /* @__PURE__ */ new Set(["sm", "md", "lg", "xl", "2xl"]);
2208
- function injectClassRule(cls, bucketKey, styles, darkMode) {
2209
- const cssDecls = styleValueToCSS(styles);
3089
+ var PRINT_MODS = /* @__PURE__ */ new Set(["print"]);
3090
+ function buildDivideDecls(styles) {
3091
+ const parts = [];
3092
+ if ("__divideX" in styles) {
3093
+ const w = Number(styles.__divideX);
3094
+ parts.push(`border-left-width: ${w}px`);
3095
+ parts.push("border-right-width: 0px");
3096
+ }
3097
+ if ("__divideY" in styles) {
3098
+ const w = Number(styles.__divideY);
3099
+ parts.push(`border-top-width: ${w}px`);
3100
+ parts.push("border-bottom-width: 0px");
3101
+ }
3102
+ if ("__divideColor" in styles) parts.push(`border-color: ${String(styles.__divideColor)}`);
3103
+ if ("__divideStyle" in styles) parts.push(`border-style: ${String(styles.__divideStyle)}`);
3104
+ return parts.join("; ");
3105
+ }
3106
+ function injectClassRule(cls, bucketKey, styles, darkMode, important = false) {
3107
+ if ("__keyframe" in styles && typeof styles.__keyframe === "string") {
3108
+ injectRule(styles.__keyframe);
3109
+ }
3110
+ const isDivide = "__divideX" in styles || "__divideY" in styles || "__divideColor" in styles || "__divideStyle" in styles;
3111
+ const cssDecls = isDivide ? buildDivideDecls(styles) : styleValueToCSS(styles, important);
2210
3112
  if (!cssDecls) return;
2211
3113
  const escaped = escapeCSSSelector(cls);
3114
+ const childSuffix = isDivide ? " > * + *" : "";
2212
3115
  if (bucketKey === "base") {
2213
- injectRule(`.${escaped} { ${cssDecls} }`);
3116
+ injectRule(`.${escaped}${childSuffix} { ${cssDecls} }`);
2214
3117
  return;
2215
3118
  }
2216
3119
  const mods = bucketKey.split(":");
@@ -2218,10 +3121,11 @@ function injectClassRule(cls, bucketKey, styles, darkMode) {
2218
3121
  const nonResponsiveMods = mods.filter((m) => !RESPONSIVE_MODS.has(m));
2219
3122
  const hasDark = nonResponsiveMods.includes("dark") || nonResponsiveMods.includes("not-light");
2220
3123
  const hasLight = nonResponsiveMods.includes("light") || nonResponsiveMods.includes("not-dark");
3124
+ const hasPrint = nonResponsiveMods.includes("print");
2221
3125
  const ancestorMods = nonResponsiveMods.filter((m) => m in GROUP_PEER_PREFIX);
2222
- const pseudoMods = nonResponsiveMods.filter((m) => !MODE_MODS.has(m) && !(m in GROUP_PEER_PREFIX));
3126
+ const pseudoMods = nonResponsiveMods.filter((m) => !MODE_MODS.has(m) && !(m in GROUP_PEER_PREFIX) && !PRINT_MODS.has(m));
2223
3127
  const pseudoSuffix = pseudoMods.map((p) => MODIFIER_TO_PSEUDO[p] ?? `:${p}`).join("");
2224
- const elementSelector = `.${escaped}${pseudoSuffix}`;
3128
+ const elementSelector = `.${escaped}${pseudoSuffix}${childSuffix}`;
2225
3129
  const ancestorPrefix = ancestorMods.length ? ancestorMods.map((m) => GROUP_PEER_PREFIX[m]).join(" ") + " " : "";
2226
3130
  const selector = `${ancestorPrefix}${elementSelector}`;
2227
3131
  let rule;
@@ -2244,6 +3148,9 @@ function injectClassRule(cls, bucketKey, styles, darkMode) {
2244
3148
  } else {
2245
3149
  rule = `${selector} { ${cssDecls} }`;
2246
3150
  }
3151
+ if (hasPrint) {
3152
+ rule = `@media print { ${rule} }`;
3153
+ }
2247
3154
  if (responsiveMods.length > 0) {
2248
3155
  const screens = getGlobalScreens();
2249
3156
  const minWidth = Math.max(...responsiveMods.map((m) => screens[m] ?? 0));
@@ -2261,7 +3168,19 @@ var RN_ONLY_PROPS = /* @__PURE__ */ new Set([
2261
3168
  "elevation",
2262
3169
  "includeFontPadding",
2263
3170
  "textAlignVertical",
2264
- "writingDirection"
3171
+ "writingDirection",
3172
+ // Text shadow native props — web uses the textShadow CSS shorthand instead
3173
+ "textShadowColor",
3174
+ "textShadowOffset",
3175
+ "textShadowRadius",
3176
+ // tintColor is native-only (Image/icon tinting)
3177
+ "tintColor",
3178
+ // Internal markers — handled specially, never serialized as CSS props
3179
+ "__divideX",
3180
+ "__divideY",
3181
+ "__divideColor",
3182
+ "__divideStyle",
3183
+ "__keyframe"
2265
3184
  ]);
2266
3185
  var CSS_UNITLESS = /* @__PURE__ */ new Set([
2267
3186
  "opacity",
@@ -2279,7 +3198,7 @@ var CSS_UNITLESS = /* @__PURE__ */ new Set([
2279
3198
  "gridRowStart",
2280
3199
  "gridRowEnd"
2281
3200
  ]);
2282
- function styleValueToCSS(styles) {
3201
+ function styleValueToCSS(styles, forceImportant = false) {
2283
3202
  return Object.entries(styles).filter(
2284
3203
  ([prop, v]) => v !== void 0 && v !== null && typeof v !== "object" && !RN_ONLY_PROPS.has(prop)
2285
3204
  ).map(([prop, val]) => {
@@ -2290,8 +3209,8 @@ function styleValueToCSS(styles) {
2290
3209
  } else {
2291
3210
  cssVal = String(val);
2292
3211
  }
2293
- const important = prop === "display" && (cssVal === "grid" || cssVal === "inline-grid") || prop === "position" && (cssVal === "sticky" || cssVal === "fixed" || cssVal === "static") ? " !important" : "";
2294
- return `${cssProp}: ${cssVal}${important}`;
3212
+ const imp = forceImportant || prop === "display" && (cssVal === "grid" || cssVal === "inline-grid") || prop === "position" && (cssVal === "sticky" || cssVal === "fixed" || cssVal === "static") ? " !important" : "";
3213
+ return `${cssProp}: ${cssVal}${imp}`;
2295
3214
  }).join("; ");
2296
3215
  }
2297
3216
  function camelToKebab(str) {
@@ -2306,18 +3225,23 @@ function resolve(classString, theme, darkMode = "attribute") {
2306
3225
  const injectQueue = [];
2307
3226
  for (const parsed of parsedClasses) {
2308
3227
  const styles = resolveUtility(parsed, theme);
2309
- if (!styles) continue;
3228
+ if (!styles) {
3229
+ if (process.env.NODE_ENV !== "production" && !parsed.isArbitrary && !isKnownUtility(parsed.utility)) {
3230
+ console.warn(`[kbach] Unknown utility "${parsed.utility}" in class "${parsed.original}"`);
3231
+ }
3232
+ continue;
3233
+ }
2310
3234
  const bucketKey = parsed.modifiers.length === 0 ? "base" : parsed.modifiers.join(":");
2311
3235
  if (!result[bucketKey]) result[bucketKey] = {};
2312
3236
  Object.assign(result[bucketKey], styles);
2313
3237
  if (typeof document !== "undefined") {
2314
- injectQueue.push({ cls: parsed.original, bucketKey, styles });
3238
+ injectQueue.push({ cls: parsed.original, bucketKey, styles, important: parsed.important });
2315
3239
  }
2316
3240
  }
2317
3241
  styleCache.set(cacheKey, result);
2318
3242
  if (typeof document !== "undefined") {
2319
- for (const { cls, bucketKey, styles } of injectQueue) {
2320
- injectClassRule(cls, bucketKey, styles, darkMode);
3243
+ for (const { cls, bucketKey, styles, important } of injectQueue) {
3244
+ injectClassRule(cls, bucketKey, styles, darkMode, important);
2321
3245
  }
2322
3246
  }
2323
3247
  return result;
@@ -2384,6 +3308,11 @@ function matchesMods(mods, isDark, state, breakpoints) {
2384
3308
  }
2385
3309
  function clearCache() {
2386
3310
  styleCache.clear();
3311
+ _injectedRules.clear();
3312
+ if (_styleEl) {
3313
+ _styleEl.remove();
3314
+ _styleEl = null;
3315
+ }
2387
3316
  }
2388
3317
 
2389
3318
  // src/core/config.ts
@@ -2823,9 +3752,75 @@ function ThemeToggle({
2823
3752
  }
2824
3753
 
2825
3754
  // src/styled.tsx
3755
+ var import_react6 = __toESM(require("react"));
3756
+
3757
+ // src/useGlobalWidth.ts
2826
3758
  var import_react5 = __toESM(require("react"));
3759
+ var useSyncExternalStore = import_react5.default.useSyncExternalStore ?? function useSyncExternalStoreFallback(subscribe, getSnapshot, _getServerSnapshot) {
3760
+ const [, forceUpdate] = import_react5.default.useReducer((n) => n + 1, 0);
3761
+ import_react5.default.useEffect(() => subscribe(forceUpdate), [subscribe]);
3762
+ return getSnapshot();
3763
+ };
3764
+ var NOOP_SUB = (_) => () => {
3765
+ };
3766
+ var ZERO_SNAP = () => 0;
3767
+ var EMPTY_BREAKPOINTS = /* @__PURE__ */ new Set();
3768
+ var _webListeners = null;
3769
+ var _webRaf = 0;
3770
+ function _webResizeHandler() {
3771
+ cancelAnimationFrame(_webRaf);
3772
+ _webRaf = requestAnimationFrame(() => {
3773
+ if (_webListeners) for (const cb of _webListeners) cb();
3774
+ });
3775
+ }
3776
+ function subscribeWebWidth(cb) {
3777
+ if (typeof window === "undefined") return () => {
3778
+ };
3779
+ if (!_webListeners) {
3780
+ _webListeners = /* @__PURE__ */ new Set();
3781
+ window.addEventListener("resize", _webResizeHandler);
3782
+ }
3783
+ _webListeners.add(cb);
3784
+ return () => {
3785
+ _webListeners.delete(cb);
3786
+ if (_webListeners.size === 0) {
3787
+ window.removeEventListener("resize", _webResizeHandler);
3788
+ cancelAnimationFrame(_webRaf);
3789
+ _webListeners = null;
3790
+ }
3791
+ };
3792
+ }
3793
+ function getWebWidth() {
3794
+ return typeof window !== "undefined" ? window.innerWidth : 0;
3795
+ }
3796
+ function useGlobalWidth() {
3797
+ return useSyncExternalStore(
3798
+ isWeb ? subscribeWebWidth : subscribeGlobalWidth,
3799
+ isWeb ? getWebWidth : getGlobalWidth,
3800
+ ZERO_SNAP
3801
+ );
3802
+ }
3803
+ function useConditionalWidth(active) {
3804
+ return useSyncExternalStore(
3805
+ active ? isWeb ? subscribeWebWidth : subscribeGlobalWidth : NOOP_SUB,
3806
+ active ? isWeb ? getWebWidth : getGlobalWidth : ZERO_SNAP,
3807
+ ZERO_SNAP
3808
+ );
3809
+ }
3810
+
3811
+ // src/styled.tsx
3812
+ var RESPONSIVE_MODS2 = /* @__PURE__ */ new Set(["sm", "md", "lg", "xl", "2xl"]);
3813
+ function hasResponsiveBuckets(resolved) {
3814
+ for (const key of Object.keys(resolved)) {
3815
+ if (key === "base") continue;
3816
+ for (const mod of key.split(":")) {
3817
+ if (RESPONSIVE_MODS2.has(mod)) return true;
3818
+ }
3819
+ }
3820
+ return false;
3821
+ }
2827
3822
  function styled(Component, baseClasses = "") {
2828
- const Styled = (0, import_react5.forwardRef)(
3823
+ const Styled = (0, import_react6.forwardRef)(
2829
3824
  (props, ref) => {
2830
3825
  const {
2831
3826
  kb: extraClasses,
@@ -2839,45 +3834,51 @@ function styled(Component, baseClasses = "") {
2839
3834
  ...rest
2840
3835
  } = props;
2841
3836
  const { isDark, config } = useTheme();
2842
- const [pressed, setPressed] = (0, import_react5.useState)(false);
2843
- const [hovered, setHovered] = (0, import_react5.useState)(false);
2844
- const [focused, setFocused] = (0, import_react5.useState)(false);
2845
- const handlePressIn = (0, import_react5.useCallback)((e) => {
3837
+ const [pressed, setPressed] = (0, import_react6.useState)(false);
3838
+ const [hovered, setHovered] = (0, import_react6.useState)(false);
3839
+ const [focused, setFocused] = (0, import_react6.useState)(false);
3840
+ const handlePressIn = (0, import_react6.useCallback)((e) => {
2846
3841
  setPressed(true);
2847
3842
  onPressIn?.(e);
2848
3843
  }, [onPressIn]);
2849
- const handlePressOut = (0, import_react5.useCallback)((e) => {
3844
+ const handlePressOut = (0, import_react6.useCallback)((e) => {
2850
3845
  setPressed(false);
2851
3846
  onPressOut?.(e);
2852
3847
  }, [onPressOut]);
2853
- const handleMouseEnter = (0, import_react5.useCallback)((e) => {
3848
+ const handleMouseEnter = (0, import_react6.useCallback)((e) => {
2854
3849
  setHovered(true);
2855
3850
  onMouseEnter?.(e);
2856
3851
  }, [onMouseEnter]);
2857
- const handleMouseLeave = (0, import_react5.useCallback)((e) => {
3852
+ const handleMouseLeave = (0, import_react6.useCallback)((e) => {
2858
3853
  setHovered(false);
2859
3854
  onMouseLeave?.(e);
2860
3855
  }, [onMouseLeave]);
2861
- const handleFocus = (0, import_react5.useCallback)((e) => {
3856
+ const handleFocus = (0, import_react6.useCallback)((e) => {
2862
3857
  setFocused(true);
2863
3858
  onFocus?.(e);
2864
3859
  }, [onFocus]);
2865
- const handleBlur = (0, import_react5.useCallback)((e) => {
3860
+ const handleBlur = (0, import_react6.useCallback)((e) => {
2866
3861
  setFocused(false);
2867
3862
  onBlur?.(e);
2868
3863
  }, [onBlur]);
2869
3864
  const combined = extraClasses ? `${baseClasses} ${extraClasses}` : baseClasses;
2870
- const resolved = (0, import_react5.useMemo)(() => resolve(combined, config.theme, config.darkMode), [combined, config.theme, config.darkMode]);
2871
- const computedStyle = (0, import_react5.useMemo)(
2872
- () => flatten(resolved, isDark, { pressed, hover: hovered, focus: focused }),
2873
- [resolved, isDark, pressed, hovered, focused]
3865
+ const resolved = (0, import_react6.useMemo)(() => resolve(combined, config.theme, config.darkMode), [combined, config.theme, config.darkMode]);
3866
+ const needsWidth = hasResponsiveBuckets(resolved);
3867
+ const width = useConditionalWidth(needsWidth);
3868
+ const breakpoints = needsWidth ? getActiveBreakpoints(width) : EMPTY_BREAKPOINTS;
3869
+ const computedStyle = (0, import_react6.useMemo)(
3870
+ () => flatten(resolved, isDark, { pressed, hover: hovered, focus: focused }, breakpoints),
3871
+ [resolved, isDark, pressed, hovered, focused, width]
3872
+ // eslint-disable-line react-hooks/exhaustive-deps
2874
3873
  );
2875
3874
  const extraStyle = Array.isArray(styleProp) ? Object.assign({}, ...styleProp) : styleProp;
2876
3875
  const finalStyle = extraStyle ? { ...computedStyle, ...extraStyle } : computedStyle;
2877
- return import_react5.default.createElement(Component, {
3876
+ return import_react6.default.createElement(Component, {
2878
3877
  ref,
2879
3878
  ...rest,
2880
3879
  style: finalStyle,
3880
+ // className lets injected CSS rules (group-hover:, before:, print:, etc.) match the element.
3881
+ ...isWeb && combined ? { className: combined } : {},
2881
3882
  // onPressIn / onPressOut are React Native-only events; forwarding them to
2882
3883
  // a DOM element on web triggers React's unknown-prop warning.
2883
3884
  ...isWeb ? {} : { onPressIn: handlePressIn, onPressOut: handlePressOut },
@@ -2895,62 +3896,6 @@ function styled(Component, baseClasses = "") {
2895
3896
 
2896
3897
  // src/useStyles.ts
2897
3898
  var import_react7 = require("react");
2898
-
2899
- // src/useGlobalWidth.ts
2900
- var import_react6 = __toESM(require("react"));
2901
- var useSyncExternalStore = import_react6.default.useSyncExternalStore ?? function useSyncExternalStoreFallback(subscribe, getSnapshot, _getServerSnapshot) {
2902
- const [, forceUpdate] = import_react6.default.useReducer((n) => n + 1, 0);
2903
- import_react6.default.useEffect(() => subscribe(forceUpdate), [subscribe]);
2904
- return getSnapshot();
2905
- };
2906
- var NOOP_SUB = (_) => () => {
2907
- };
2908
- var ZERO_SNAP = () => 0;
2909
- var EMPTY_BREAKPOINTS = /* @__PURE__ */ new Set();
2910
- var _webListeners = null;
2911
- var _webRaf = 0;
2912
- function _webResizeHandler() {
2913
- cancelAnimationFrame(_webRaf);
2914
- _webRaf = requestAnimationFrame(() => {
2915
- if (_webListeners) for (const cb of _webListeners) cb();
2916
- });
2917
- }
2918
- function subscribeWebWidth(cb) {
2919
- if (typeof window === "undefined") return () => {
2920
- };
2921
- if (!_webListeners) {
2922
- _webListeners = /* @__PURE__ */ new Set();
2923
- window.addEventListener("resize", _webResizeHandler);
2924
- }
2925
- _webListeners.add(cb);
2926
- return () => {
2927
- _webListeners.delete(cb);
2928
- if (_webListeners.size === 0) {
2929
- window.removeEventListener("resize", _webResizeHandler);
2930
- cancelAnimationFrame(_webRaf);
2931
- _webListeners = null;
2932
- }
2933
- };
2934
- }
2935
- function getWebWidth() {
2936
- return typeof window !== "undefined" ? window.innerWidth : 0;
2937
- }
2938
- function useGlobalWidth() {
2939
- return useSyncExternalStore(
2940
- isWeb ? subscribeWebWidth : subscribeGlobalWidth,
2941
- isWeb ? getWebWidth : getGlobalWidth,
2942
- ZERO_SNAP
2943
- );
2944
- }
2945
- function useConditionalWidth(active) {
2946
- return useSyncExternalStore(
2947
- active ? isWeb ? subscribeWebWidth : subscribeGlobalWidth : NOOP_SUB,
2948
- active ? isWeb ? getWebWidth : getGlobalWidth : ZERO_SNAP,
2949
- ZERO_SNAP
2950
- );
2951
- }
2952
-
2953
- // src/useStyles.ts
2954
3899
  function useStyles(classString, state = {}) {
2955
3900
  const { isDark, config } = useTheme();
2956
3901
  const width = useGlobalWidth();
@@ -3016,12 +3961,12 @@ function chain(original, extra) {
3016
3961
  extra();
3017
3962
  };
3018
3963
  }
3019
- var RESPONSIVE_MODS2 = /* @__PURE__ */ new Set(["sm", "md", "lg", "xl", "2xl"]);
3020
- function hasResponsiveBuckets(resolved) {
3964
+ var RESPONSIVE_MODS3 = /* @__PURE__ */ new Set(["sm", "md", "lg", "xl", "2xl"]);
3965
+ function hasResponsiveBuckets2(resolved) {
3021
3966
  for (const key of Object.keys(resolved)) {
3022
3967
  if (key === "base") continue;
3023
3968
  for (const mod of key.split(":")) {
3024
- if (RESPONSIVE_MODS2.has(mod)) return true;
3969
+ if (RESPONSIVE_MODS3.has(mod)) return true;
3025
3970
  }
3026
3971
  }
3027
3972
  return false;
@@ -3041,7 +3986,7 @@ var InteractiveWrapper = (0, import_react9.forwardRef)(
3041
3986
  ...rest
3042
3987
  }, ref) {
3043
3988
  const isDark = useGlobalDarkMode();
3044
- const needsWidth = hasResponsiveBuckets(resolvedStyle);
3989
+ const needsWidth = hasResponsiveBuckets2(resolvedStyle);
3045
3990
  const width = useConditionalWidth(needsWidth);
3046
3991
  const breakpoints = needsWidth ? getActiveBreakpoints(width) : EMPTY_BREAKPOINTS;
3047
3992
  const [pressed, setPressed] = (0, import_react9.useState)(false);
@@ -3056,6 +4001,11 @@ var InteractiveWrapper = (0, import_react9.forwardRef)(
3056
4001
  const computedStyle = (0, import_react9.useMemo)(
3057
4002
  () => {
3058
4003
  const s = flatten(resolvedStyle, isDark, { pressed, hover: hovered, focus: focused }, breakpoints);
4004
+ delete s.__divideX;
4005
+ delete s.__divideY;
4006
+ delete s.__divideColor;
4007
+ delete s.__divideStyle;
4008
+ delete s.__keyframe;
3059
4009
  if (typeof Component !== "string") {
3060
4010
  if (s.display === "grid" || s.display === "inline-grid") delete s.display;
3061
4011
  delete s.gridTemplateColumns;
@@ -3063,9 +4013,18 @@ var InteractiveWrapper = (0, import_react9.forwardRef)(
3063
4013
  delete s.gridColumn;
3064
4014
  delete s.gridRow;
3065
4015
  delete s.gridArea;
4016
+ delete s.gridColumnStart;
4017
+ delete s.gridColumnEnd;
4018
+ delete s.gridRowStart;
4019
+ delete s.gridRowEnd;
3066
4020
  delete s.gridAutoFlow;
3067
4021
  delete s.gridAutoColumns;
3068
4022
  delete s.gridAutoRows;
4023
+ delete s.placeItems;
4024
+ delete s.placeContent;
4025
+ delete s.justifyItems;
4026
+ delete s.placeSelf;
4027
+ delete s.justifySelf;
3069
4028
  if (s.position === "sticky" || s.position === "fixed" || s.position === "static") {
3070
4029
  delete s.position;
3071
4030
  }