@kbach/react 0.6.39 → 0.6.40

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.
@@ -30,6 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/vite-plugin.ts
31
31
  var vite_plugin_exports = {};
32
32
  __export(vite_plugin_exports, {
33
+ formatKbachCSS: () => formatKbachCSS,
33
34
  kbach: () => kbach
34
35
  });
35
36
  module.exports = __toCommonJS(vite_plugin_exports);
@@ -653,6 +654,11 @@ var defaultTheme = {
653
654
  function isModeAwareColor(v) {
654
655
  return typeof v === "object" && v !== null && "light" in v && "dark" in v;
655
656
  }
657
+ function splitColorShadeRef(ref) {
658
+ const lastDash = ref.lastIndexOf("-");
659
+ if (lastDash <= 0) return null;
660
+ return { name: ref.slice(0, lastDash), shade: ref.slice(lastDash + 1) };
661
+ }
656
662
 
657
663
  // src/core/resolvers/color.ts
658
664
  function pickModeAwareFallback(v) {
@@ -672,13 +678,11 @@ function resolveColor(value, colors, isArbitrary) {
672
678
  else if (isModeAwareColor(entry)) hex = pickModeAwareFallback(entry);
673
679
  else if (typeof entry === "object" && "6" in entry) hex = pickModeAwareFallback(entry["6"]);
674
680
  } else {
675
- const lastDash = colorPart.lastIndexOf("-");
676
- if (lastDash > 0) {
677
- const colorName = colorPart.slice(0, lastDash);
678
- const shade = colorPart.slice(lastDash + 1);
679
- const scale = colors[colorName];
680
- if (scale && typeof scale === "object" && !isModeAwareColor(scale) && shade in scale) {
681
- const shadeVal = scale[shade];
681
+ const split = splitColorShadeRef(colorPart);
682
+ if (split) {
683
+ const scale = colors[split.name];
684
+ if (scale && typeof scale === "object" && !isModeAwareColor(scale) && split.shade in scale) {
685
+ const shadeVal = scale[split.shade];
682
686
  hex = shadeVal !== void 0 ? pickModeAwareFallback(shadeVal) : null;
683
687
  }
684
688
  }
@@ -819,6 +823,7 @@ function resolveSpacing(value, negative, spacing, isArbitrary) {
819
823
  if (negative) {
820
824
  if (typeof resolved === "number") return -resolved;
821
825
  if (typeof resolved === "string") {
826
+ if (resolved.startsWith("-")) return resolved.slice(1);
822
827
  if (/^\d/.test(resolved)) return `-${resolved}`;
823
828
  if (/^(calc|var|min|max|clamp|env)\s*\(/.test(resolved)) return `calc(-1 * (${resolved}))`;
824
829
  }
@@ -997,7 +1002,7 @@ function makeBorderSideResolver(widthProp, colorProp) {
997
1002
  if (!value) return { [widthProp]: 1 };
998
1003
  if (isArbitrary) {
999
1004
  const w2 = toNativeValue(value);
1000
- if (typeof w2 === "number") return { [widthProp]: w2 };
1005
+ if (typeof w2 === "number") return { [widthProp]: getEffectiveIsWeb() ? value : w2 };
1001
1006
  return { [colorProp]: value };
1002
1007
  }
1003
1008
  const color = resolveColor(value, colors, false);
@@ -1018,7 +1023,7 @@ var borderResolvers = {
1018
1023
  if (!value) return { borderWidth: borderWidth["DEFAULT"] ?? 1 };
1019
1024
  if (isArbitrary) {
1020
1025
  const w2 = toNativeValue(value);
1021
- if (typeof w2 === "number") return { borderWidth: w2 };
1026
+ if (typeof w2 === "number") return { borderWidth: getEffectiveIsWeb() ? value : w2 };
1022
1027
  return { borderColor: value };
1023
1028
  }
1024
1029
  const color = resolveColor(value, colors, false);
@@ -1217,9 +1222,9 @@ var filterResolvers = {
1217
1222
  const v = isArbitrary ? `contrast(${value})` : `contrast(${parseFloat(value) / 100})`;
1218
1223
  return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--kb-contrast": v, filter: FILTER_COMPOSE };
1219
1224
  },
1220
- grayscale: ({ value }) => {
1225
+ grayscale: ({ value, isArbitrary }) => {
1221
1226
  if (!getEffectiveIsWeb()) return null;
1222
- const v = value === "0" ? "grayscale(0)" : "grayscale(100%)";
1227
+ const v = isArbitrary ? `grayscale(${value})` : value === "0" ? "grayscale(0)" : "grayscale(100%)";
1223
1228
  return { "--kb-grayscale": v, filter: FILTER_COMPOSE };
1224
1229
  },
1225
1230
  "hue-rotate": ({ value, negative, isArbitrary }) => {
@@ -1228,9 +1233,9 @@ var filterResolvers = {
1228
1233
  if (isNaN(parseFloat(deg)) && !isArbitrary) return null;
1229
1234
  return { "--kb-hue-rotate": `hue-rotate(${deg})`, filter: FILTER_COMPOSE };
1230
1235
  },
1231
- invert: ({ value }) => {
1236
+ invert: ({ value, isArbitrary }) => {
1232
1237
  if (!getEffectiveIsWeb()) return null;
1233
- const v = value === "0" ? "invert(0)" : "invert(100%)";
1238
+ const v = isArbitrary ? `invert(${value})` : value === "0" ? "invert(0)" : "invert(100%)";
1234
1239
  return { "--kb-invert": v, filter: FILTER_COMPOSE };
1235
1240
  },
1236
1241
  saturate: ({ value, isArbitrary }) => {
@@ -1238,9 +1243,9 @@ var filterResolvers = {
1238
1243
  const v = isArbitrary ? `saturate(${value})` : `saturate(${parseFloat(value) / 100})`;
1239
1244
  return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--kb-saturate": v, filter: FILTER_COMPOSE };
1240
1245
  },
1241
- sepia: ({ value }) => {
1246
+ sepia: ({ value, isArbitrary }) => {
1242
1247
  if (!getEffectiveIsWeb()) return null;
1243
- const v = value === "0" ? "sepia(0)" : "sepia(100%)";
1248
+ const v = isArbitrary ? `sepia(${value})` : value === "0" ? "sepia(0)" : "sepia(100%)";
1244
1249
  return { "--kb-sepia": v, filter: FILTER_COMPOSE };
1245
1250
  },
1246
1251
  "drop-shadow": ({ value, isArbitrary }) => {
@@ -1291,9 +1296,10 @@ var filterResolvers = {
1291
1296
  const v = isArbitrary ? `contrast(${value})` : `contrast(${parseFloat(value) / 100})`;
1292
1297
  return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--kb-backdrop-contrast": v, backdropFilter: BACKDROP_FILTER_COMPOSE };
1293
1298
  },
1294
- "backdrop-grayscale": ({ value }) => {
1299
+ "backdrop-grayscale": ({ value, isArbitrary }) => {
1295
1300
  if (!getEffectiveIsWeb()) return null;
1296
- return { "--kb-backdrop-grayscale": value === "0" ? "grayscale(0)" : "grayscale(100%)", backdropFilter: BACKDROP_FILTER_COMPOSE };
1301
+ const v = isArbitrary ? `grayscale(${value})` : value === "0" ? "grayscale(0)" : "grayscale(100%)";
1302
+ return { "--kb-backdrop-grayscale": v, backdropFilter: BACKDROP_FILTER_COMPOSE };
1297
1303
  },
1298
1304
  "backdrop-hue-rotate": ({ value, negative, isArbitrary }) => {
1299
1305
  if (!getEffectiveIsWeb()) return null;
@@ -1301,9 +1307,10 @@ var filterResolvers = {
1301
1307
  if (isNaN(parseFloat(deg)) && !isArbitrary) return null;
1302
1308
  return { "--kb-backdrop-hue-rotate": `hue-rotate(${deg})`, backdropFilter: BACKDROP_FILTER_COMPOSE };
1303
1309
  },
1304
- "backdrop-invert": ({ value }) => {
1310
+ "backdrop-invert": ({ value, isArbitrary }) => {
1305
1311
  if (!getEffectiveIsWeb()) return null;
1306
- return { "--kb-backdrop-invert": value === "0" ? "invert(0)" : "invert(100%)", backdropFilter: BACKDROP_FILTER_COMPOSE };
1312
+ const v = isArbitrary ? `invert(${value})` : value === "0" ? "invert(0)" : "invert(100%)";
1313
+ return { "--kb-backdrop-invert": v, backdropFilter: BACKDROP_FILTER_COMPOSE };
1307
1314
  },
1308
1315
  "backdrop-opacity": ({ value, isArbitrary }) => {
1309
1316
  if (!getEffectiveIsWeb()) return null;
@@ -1315,9 +1322,10 @@ var filterResolvers = {
1315
1322
  const v = isArbitrary ? `saturate(${value})` : `saturate(${parseFloat(value) / 100})`;
1316
1323
  return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--kb-backdrop-saturate": v, backdropFilter: BACKDROP_FILTER_COMPOSE };
1317
1324
  },
1318
- "backdrop-sepia": ({ value }) => {
1325
+ "backdrop-sepia": ({ value, isArbitrary }) => {
1319
1326
  if (!getEffectiveIsWeb()) return null;
1320
- return { "--kb-backdrop-sepia": value === "0" ? "sepia(0)" : "sepia(100%)", backdropFilter: BACKDROP_FILTER_COMPOSE };
1327
+ const v = isArbitrary ? `sepia(${value})` : value === "0" ? "sepia(0)" : "sepia(100%)";
1328
+ return { "--kb-backdrop-sepia": v, backdropFilter: BACKDROP_FILTER_COMPOSE };
1321
1329
  },
1322
1330
  "backdrop-filter": ({ value, isArbitrary }) => {
1323
1331
  if (!getEffectiveIsWeb()) return null;
@@ -1387,8 +1395,8 @@ var filterResolvers = {
1387
1395
 
1388
1396
  // src/core/resolvers/layout.ts
1389
1397
  var _standalone = null;
1390
- function buildStandalone() {
1391
- const web = getEffectiveIsWeb();
1398
+ var _standaloneWeb = null;
1399
+ function buildStandalone(web) {
1392
1400
  return {
1393
1401
  // Display
1394
1402
  // React Native only supports display:'flex'|'none'. Setting 'flex' explicitly is
@@ -1403,7 +1411,6 @@ function buildStandalone() {
1403
1411
  "inline-block": { display: web ? "inline-block" : "flex" },
1404
1412
  inline: { display: web ? "inline" : "flex" },
1405
1413
  grid: web ? { display: "grid" } : null,
1406
- grd: web ? { display: "grid" } : null,
1407
1414
  "inline-flex": { display: web ? "inline-flex" : "flex" },
1408
1415
  "inline-grid": { display: web ? "inline-grid" : "flex" },
1409
1416
  hidden: { display: "none" },
@@ -1755,7 +1762,11 @@ function buildStandalone() {
1755
1762
  };
1756
1763
  }
1757
1764
  function getStandalone() {
1758
- if (!_standalone) _standalone = buildStandalone();
1765
+ const web = getEffectiveIsWeb();
1766
+ if (!_standalone || _standaloneWeb !== web) {
1767
+ _standalone = buildStandalone(web);
1768
+ _standaloneWeb = web;
1769
+ }
1759
1770
  return _standalone;
1760
1771
  }
1761
1772
  var layoutResolvers = {
@@ -2523,64 +2534,64 @@ var LRUCache = class {
2523
2534
  // src/core/registry.ts
2524
2535
  var BUILTIN_MODIFIERS = {
2525
2536
  // ── Mode ─────────────────────────────────────────────────────────────────
2526
- dark: { darkScheme: "dark", jsBehavior: "mode", jsMatch: (d) => d },
2527
- "not-light": { darkScheme: "dark", jsBehavior: "mode", jsMatch: (d) => d },
2528
- light: { darkScheme: "light", jsBehavior: "mode", jsMatch: (d) => !d },
2529
- "not-dark": { darkScheme: "light", jsBehavior: "mode", jsMatch: (d) => !d },
2537
+ dark: { order: 60, darkScheme: "dark", jsBehavior: "mode", jsMatch: (d) => d },
2538
+ "not-light": { order: 60, darkScheme: "dark", jsBehavior: "mode", jsMatch: (d) => d },
2539
+ light: { order: 60, darkScheme: "light", jsBehavior: "mode", jsMatch: (d) => !d },
2540
+ "not-dark": { order: 60, darkScheme: "light", jsBehavior: "mode", jsMatch: (d) => !d },
2530
2541
  // ── Interactive — JS state + CSS pseudo ───────────────────────────────────
2531
- hover: { pseudo: ":hover", jsBehavior: "interactive", jsMatch: (_, s) => !!s.hover },
2532
- "not-hover": { pseudo: ":not(:hover)", jsBehavior: "interactive", jsMatch: (_, s) => !s.hover },
2533
- focus: { pseudo: ":focus", jsBehavior: "interactive", jsMatch: (_, s) => !!s.focus },
2534
- "not-focus": { pseudo: ":not(:focus)", jsBehavior: "interactive", jsMatch: (_, s) => !s.focus },
2535
- active: { pseudo: ":active", jsBehavior: "interactive", jsMatch: (_, s) => !!s.active || !!s.pressed },
2536
- "not-active": { pseudo: ":not(:active)", jsBehavior: "interactive", jsMatch: (_, s) => !s.active && !s.pressed },
2537
- pressed: { pseudo: ":active", jsBehavior: "interactive", jsMatch: (_, s) => !!s.pressed || !!s.active },
2538
- "not-pressed": { pseudo: ":not(:active)", jsBehavior: "interactive", jsMatch: (_, s) => !s.pressed && !s.active },
2539
- disabled: { pseudo: ":disabled", jsBehavior: "interactive", jsMatch: (_, s) => !!s.disabled },
2540
- "not-disabled": { pseudo: ":not(:disabled)", jsBehavior: "interactive", jsMatch: (_, s) => !s.disabled },
2541
- checked: { pseudo: ":checked", jsBehavior: "interactive", jsMatch: (_, s) => !!s.checked },
2542
- "not-checked": { pseudo: ":not(:checked)", jsBehavior: "interactive", jsMatch: (_, s) => !s.checked },
2543
- visited: { pseudo: ":visited", jsBehavior: "interactive", jsMatch: (_, s) => !!s.visited },
2544
- "not-visited": { pseudo: ":not(:visited)", jsBehavior: "interactive", jsMatch: (_, s) => !s.visited },
2545
- placeholder: { pseudo: "::placeholder", jsBehavior: "interactive", jsMatch: (_, s) => !!s.placeholder },
2542
+ hover: { order: 10, pseudo: ":hover", jsBehavior: "interactive", jsMatch: (_, s) => !!s.hover },
2543
+ "not-hover": { order: 10, pseudo: ":not(:hover)", jsBehavior: "interactive", jsMatch: (_, s) => !s.hover },
2544
+ focus: { order: 20, pseudo: ":focus", jsBehavior: "interactive", jsMatch: (_, s) => !!s.focus },
2545
+ "not-focus": { order: 20, pseudo: ":not(:focus)", jsBehavior: "interactive", jsMatch: (_, s) => !s.focus },
2546
+ active: { order: 30, pseudo: ":active", jsBehavior: "interactive", jsMatch: (_, s) => !!s.active || !!s.pressed },
2547
+ "not-active": { order: 30, pseudo: ":not(:active)", jsBehavior: "interactive", jsMatch: (_, s) => !s.active && !s.pressed },
2548
+ pressed: { order: 30, pseudo: ":active", jsBehavior: "interactive", jsMatch: (_, s) => !!s.pressed || !!s.active },
2549
+ "not-pressed": { order: 30, pseudo: ":not(:active)", jsBehavior: "interactive", jsMatch: (_, s) => !s.pressed && !s.active },
2550
+ disabled: { order: 40, pseudo: ":disabled", jsBehavior: "interactive", jsMatch: (_, s) => !!s.disabled },
2551
+ "not-disabled": { order: 40, pseudo: ":not(:disabled)", jsBehavior: "interactive", jsMatch: (_, s) => !s.disabled },
2552
+ checked: { order: 35, pseudo: ":checked", jsBehavior: "interactive", jsMatch: (_, s) => !!s.checked },
2553
+ "not-checked": { order: 35, pseudo: ":not(:checked)", jsBehavior: "interactive", jsMatch: (_, s) => !s.checked },
2554
+ visited: { order: 5, pseudo: ":visited", jsBehavior: "interactive", jsMatch: (_, s) => !!s.visited },
2555
+ "not-visited": { order: 5, pseudo: ":not(:visited)", jsBehavior: "interactive", jsMatch: (_, s) => !s.visited },
2556
+ placeholder: { order: 0, pseudo: "::placeholder", jsBehavior: "interactive", jsMatch: (_, s) => !!s.placeholder },
2546
2557
  // ── CSS-only pseudo-classes (structural) ──────────────────────────────────
2547
- first: { pseudo: ":first-child", jsBehavior: "css-only", forcesImportant: true },
2548
- last: { pseudo: ":last-child", jsBehavior: "css-only", forcesImportant: true },
2549
- odd: { pseudo: ":nth-child(odd)", jsBehavior: "css-only", forcesImportant: true },
2550
- even: { pseudo: ":nth-child(even)", jsBehavior: "css-only", forcesImportant: true },
2551
- only: { pseudo: ":only-child", jsBehavior: "css-only", forcesImportant: true },
2552
- "focus-within": { pseudo: ":focus-within", jsBehavior: "css-only", forcesImportant: true },
2553
- "focus-visible": { pseudo: ":focus-visible", jsBehavior: "css-only", forcesImportant: true },
2558
+ first: { order: 0, pseudo: ":first-child", jsBehavior: "css-only", forcesImportant: true },
2559
+ last: { order: 0, pseudo: ":last-child", jsBehavior: "css-only", forcesImportant: true },
2560
+ odd: { order: 0, pseudo: ":nth-child(odd)", jsBehavior: "css-only", forcesImportant: true },
2561
+ even: { order: 0, pseudo: ":nth-child(even)", jsBehavior: "css-only", forcesImportant: true },
2562
+ only: { order: 0, pseudo: ":only-child", jsBehavior: "css-only", forcesImportant: true },
2563
+ "focus-within": { order: 15, pseudo: ":focus-within", jsBehavior: "css-only", forcesImportant: true },
2564
+ "focus-visible": { order: 25, pseudo: ":focus-visible", jsBehavior: "css-only", forcesImportant: true },
2554
2565
  // ── CSS-only pseudo-elements ───────────────────────────────────────────────
2555
- before: { pseudo: "::before", jsBehavior: "css-only" },
2556
- after: { pseudo: "::after", jsBehavior: "css-only" },
2557
- selection: { pseudo: "::selection", jsBehavior: "css-only" },
2558
- "first-letter": { pseudo: "::first-letter", jsBehavior: "css-only" },
2559
- "first-line": { pseudo: "::first-line", jsBehavior: "css-only" },
2560
- marker: { pseudo: "::marker", jsBehavior: "css-only" },
2566
+ before: { order: 0, pseudo: "::before", jsBehavior: "css-only" },
2567
+ after: { order: 0, pseudo: "::after", jsBehavior: "css-only" },
2568
+ selection: { order: 0, pseudo: "::selection", jsBehavior: "css-only" },
2569
+ "first-letter": { order: 0, pseudo: "::first-letter", jsBehavior: "css-only" },
2570
+ "first-line": { order: 0, pseudo: "::first-line", jsBehavior: "css-only" },
2571
+ marker: { order: 0, pseudo: "::marker", jsBehavior: "css-only" },
2561
2572
  // ── Group / peer ancestor selectors (CSS-only) ─────────────────────────────
2562
- "group-hover": { ancestorSelector: ".group:hover ", jsBehavior: "css-only", forcesImportant: true },
2563
- "group-focus": { ancestorSelector: ".group:focus ", jsBehavior: "css-only", forcesImportant: true },
2564
- "peer-hover": { ancestorSelector: ".peer:hover ~ ", jsBehavior: "css-only", forcesImportant: true },
2565
- "peer-focus": { ancestorSelector: ".peer:focus ~ ", jsBehavior: "css-only", forcesImportant: true },
2573
+ "group-hover": { order: 10, ancestorSelector: ".group:hover ", jsBehavior: "css-only", forcesImportant: true },
2574
+ "group-focus": { order: 20, ancestorSelector: ".group:focus ", jsBehavior: "css-only", forcesImportant: true },
2575
+ "peer-hover": { order: 10, ancestorSelector: ".peer:hover ~ ", jsBehavior: "css-only", forcesImportant: true },
2576
+ "peer-focus": { order: 20, ancestorSelector: ".peer:focus ~ ", jsBehavior: "css-only", forcesImportant: true },
2566
2577
  // ── Responsive — both CSS (@media min-width) and JS (breakpoints set) ──────
2567
- sm: { isResponsive: true, jsBehavior: "responsive", jsMatch: (_, __, bp) => bp.has("sm") },
2568
- md: { isResponsive: true, jsBehavior: "responsive", jsMatch: (_, __, bp) => bp.has("md") },
2569
- lg: { isResponsive: true, jsBehavior: "responsive", jsMatch: (_, __, bp) => bp.has("lg") },
2570
- xl: { isResponsive: true, jsBehavior: "responsive", jsMatch: (_, __, bp) => bp.has("xl") },
2571
- "2xl": { isResponsive: true, jsBehavior: "responsive", jsMatch: (_, __, bp) => bp.has("2xl") },
2578
+ sm: { order: 50, isResponsive: true, jsBehavior: "responsive", jsMatch: (_, __, bp) => bp.has("sm") },
2579
+ md: { order: 50, isResponsive: true, jsBehavior: "responsive", jsMatch: (_, __, bp) => bp.has("md") },
2580
+ lg: { order: 50, isResponsive: true, jsBehavior: "responsive", jsMatch: (_, __, bp) => bp.has("lg") },
2581
+ xl: { order: 50, isResponsive: true, jsBehavior: "responsive", jsMatch: (_, __, bp) => bp.has("xl") },
2582
+ "2xl": { order: 50, isResponsive: true, jsBehavior: "responsive", jsMatch: (_, __, bp) => bp.has("2xl") },
2572
2583
  // ── Print media (CSS-only) ─────────────────────────────────────────────────
2573
- print: { mediaQuery: "print", jsBehavior: "css-only", forcesImportant: true },
2584
+ print: { order: 70, mediaQuery: "print", jsBehavior: "css-only", forcesImportant: true },
2574
2585
  // ── Orientation / accessibility media (CSS-only) ───────────────────────────
2575
- landscape: { mediaQuery: "(orientation: landscape)", jsBehavior: "css-only", forcesImportant: true },
2576
- portrait: { mediaQuery: "(orientation: portrait)", jsBehavior: "css-only", forcesImportant: true },
2577
- "motion-reduce": { mediaQuery: "(prefers-reduced-motion: reduce)", jsBehavior: "css-only", forcesImportant: true },
2578
- "motion-safe": { mediaQuery: "(prefers-reduced-motion: no-preference)", jsBehavior: "css-only", forcesImportant: true },
2579
- "contrast-more": { mediaQuery: "(prefers-contrast: more)", jsBehavior: "css-only", forcesImportant: true },
2580
- "contrast-less": { mediaQuery: "(prefers-contrast: less)", jsBehavior: "css-only", forcesImportant: true },
2586
+ landscape: { order: 70, mediaQuery: "(orientation: landscape)", jsBehavior: "css-only", forcesImportant: true },
2587
+ portrait: { order: 70, mediaQuery: "(orientation: portrait)", jsBehavior: "css-only", forcesImportant: true },
2588
+ "motion-reduce": { order: 70, mediaQuery: "(prefers-reduced-motion: reduce)", jsBehavior: "css-only", forcesImportant: true },
2589
+ "motion-safe": { order: 70, mediaQuery: "(prefers-reduced-motion: no-preference)", jsBehavior: "css-only", forcesImportant: true },
2590
+ "contrast-more": { order: 70, mediaQuery: "(prefers-contrast: more)", jsBehavior: "css-only", forcesImportant: true },
2591
+ "contrast-less": { order: 70, mediaQuery: "(prefers-contrast: less)", jsBehavior: "css-only", forcesImportant: true },
2581
2592
  // ── Directionality (CSS-only) ──────────────────────────────────────────────
2582
- rtl: { dirSelector: '[dir="rtl"] ', jsBehavior: "css-only", forcesImportant: true },
2583
- ltr: { dirSelector: '[dir="ltr"] ', jsBehavior: "css-only", forcesImportant: true }
2593
+ rtl: { order: 80, dirSelector: '[dir="rtl"] ', jsBehavior: "css-only", forcesImportant: true },
2594
+ ltr: { order: 80, dirSelector: '[dir="ltr"] ', jsBehavior: "css-only", forcesImportant: true }
2584
2595
  };
2585
2596
  var _pluginModifiers = {};
2586
2597
  var _allNames = null;
@@ -2617,6 +2628,8 @@ function getNamedGroupPeerModifier(name) {
2617
2628
  const pseudo = trigger === "hover" ? ":hover" : ":focus";
2618
2629
  const combinator = kind === "group" ? " " : " ~ ";
2619
2630
  const def = {
2631
+ // Matches the plain group-hover/group-focus/peer-hover/peer-focus order below.
2632
+ order: trigger === "hover" ? 10 : 20,
2620
2633
  ancestorSelector: `.${kind}\\/${escapedName}${pseudo}${combinator}`,
2621
2634
  jsBehavior: "css-only",
2622
2635
  forcesImportant: true
@@ -2630,6 +2643,15 @@ function getModifier(name) {
2630
2643
  function isKnownModifier(name) {
2631
2644
  return name in BUILTIN_MODIFIERS || name in _pluginModifiers || NAMED_GROUP_PEER_RE.test(name);
2632
2645
  }
2646
+ function getModifierOrder(bucketKey) {
2647
+ if (bucketKey === "base") return -1;
2648
+ let max = 0;
2649
+ for (const mod of bucketKey.split(":")) {
2650
+ const order = getModifier(mod)?.order ?? 0;
2651
+ if (order > max) max = order;
2652
+ }
2653
+ return max;
2654
+ }
2633
2655
 
2634
2656
  // src/core/parser.ts
2635
2657
  var UNSAFE_ARBITRARY_VALUE = /[{};\\]|\/\*|\*\//;
@@ -2842,9 +2864,12 @@ function setDefaultFontFamily(font) {
2842
2864
  }
2843
2865
  var _styleEl = null;
2844
2866
  var _ruleIndexByKey = /* @__PURE__ */ new Map();
2867
+ var _sheetKeys = [];
2868
+ var _ruleOrderByKey = /* @__PURE__ */ new Map();
2845
2869
  function evictInjectedRule(rule) {
2846
2870
  const idx = _ruleIndexByKey.get(rule);
2847
2871
  _ruleIndexByKey.delete(rule);
2872
+ _ruleOrderByKey.delete(rule);
2848
2873
  if (idx === void 0) return;
2849
2874
  const sheet = _styleEl?.sheet;
2850
2875
  if (!sheet) return;
@@ -2853,6 +2878,7 @@ function evictInjectedRule(rule) {
2853
2878
  } catch {
2854
2879
  return;
2855
2880
  }
2881
+ _sheetKeys.splice(idx, 1);
2856
2882
  for (const [key, i] of _ruleIndexByKey) {
2857
2883
  if (i > idx) _ruleIndexByKey.set(key, i - 1);
2858
2884
  }
@@ -3083,7 +3109,6 @@ function deepMerge(base, override) {
3083
3109
  }
3084
3110
  return result;
3085
3111
  }
3086
- var configStore = { resolved: null, listeners: /* @__PURE__ */ new Set(), customVariants: {} };
3087
3112
  function resolveColorRefs(colors) {
3088
3113
  const MAX_DEPTH = 5;
3089
3114
  function resolveChain(raw, side) {
@@ -3117,10 +3142,9 @@ function resolveColorRefs(colors) {
3117
3142
  const a = opacity > 1 ? opacity / 100 : opacity;
3118
3143
  return hexToRgba(baseHex, a);
3119
3144
  }
3120
- const lastDash = ref.lastIndexOf("-");
3121
- if (lastDash <= 0) return null;
3122
- const name = ref.slice(0, lastDash);
3123
- const shade = ref.slice(lastDash + 1);
3145
+ const split = splitColorShadeRef(ref);
3146
+ if (!split) return null;
3147
+ const { name, shade } = split;
3124
3148
  if (!/^\d+$/.test(shade)) return null;
3125
3149
  const entry = colors[name];
3126
3150
  if (!entry || typeof entry !== "object" || isModeAwareColor(entry)) return null;
@@ -3182,7 +3206,6 @@ function buildConfig(userConfig) {
3182
3206
  clearPluginUtilities();
3183
3207
  clearPluginModifiers();
3184
3208
  }
3185
- for (const k of Object.keys(configStore.customVariants)) delete configStore.customVariants[k];
3186
3209
  const pluginAPI = makePluginAPI(resolved.theme);
3187
3210
  for (const plugin of resolved.plugins) {
3188
3211
  plugin(pluginAPI);
@@ -3211,8 +3234,6 @@ function makePluginAPI(theme) {
3211
3234
  },
3212
3235
  addVariant(name, selectorOrDef) {
3213
3236
  const def = typeof selectorOrDef === "string" ? _selectorToModifierDef(selectorOrDef) : selectorOrDef;
3214
- const selector = typeof selectorOrDef === "string" ? selectorOrDef : selectorOrDef.pseudo ?? selectorOrDef.mediaQuery ?? selectorOrDef.ancestorSelector ?? null;
3215
- if (selector !== null && selector !== name) customVariants[name] = selector;
3216
3237
  registerModifier(name, def);
3217
3238
  },
3218
3239
  theme(path, defaultValue) {
@@ -3229,7 +3250,6 @@ function makePluginAPI(theme) {
3229
3250
  }
3230
3251
  };
3231
3252
  }
3232
- var customVariants = configStore.customVariants;
3233
3253
 
3234
3254
  // src/core/generateTypesDts.ts
3235
3255
  var HEADER = `// AUTO-GENERATED by Kbach from your kbach.config.js \u2014 do not edit by hand.
@@ -3331,7 +3351,8 @@ var GROUP_ORDER = ["Layout", "Sizing", "Spacing", "Typography", "Colors", "Borde
3331
3351
  function classifyToken(token, responsiveRe) {
3332
3352
  if (/^dark:/.test(token)) return "Dark Mode";
3333
3353
  if (responsiveRe.test(token)) return "Responsive";
3334
- const base = token.replace(/^(hover|focus|active|group-hover|peer-hover):/, "");
3354
+ const parsed = parseClass(token);
3355
+ const base = parsed ? parsed.value ? `${parsed.utility}-${parsed.value}` : parsed.utility : token;
3335
3356
  for (const [label, re] of GROUPS) {
3336
3357
  if (re.test(base)) return label;
3337
3358
  }
@@ -3467,7 +3488,9 @@ function formatKbachCSS(tokenCSS, theme, responsiveRe) {
3467
3488
  if (!css) continue;
3468
3489
  const label = classifyToken(token, responsiveRe);
3469
3490
  if (!groups.has(label)) groups.set(label, []);
3470
- groups.get(label).push(prettifyCSS(applyVars(css)));
3491
+ const parsedToken = parseClass(token);
3492
+ const bucketKey = parsedToken && parsedToken.modifiers.length > 0 ? parsedToken.modifiers.join(":") : "base";
3493
+ groups.get(label).push({ order: getModifierOrder(bucketKey), css: prettifyCSS(applyVars(css)) });
3471
3494
  }
3472
3495
  const out = ["/* Generated by Kbach \u2014 do not edit */"];
3473
3496
  if (declarations.size > 0) {
@@ -3482,9 +3505,10 @@ ${prettifyCSS(globalCSS)}`);
3482
3505
  for (const label of GROUP_ORDER) {
3483
3506
  const items = groups.get(label) ?? [];
3484
3507
  if (!items.length) continue;
3508
+ const sorted = [...items].sort((a, b) => a.order - b.order);
3485
3509
  out.push(`
3486
3510
  /* ${label} */`);
3487
- out.push(items.join("\n\n"));
3511
+ out.push(sorted.map((it) => it.css).join("\n\n"));
3488
3512
  }
3489
3513
  return out.join("\n");
3490
3514
  }
@@ -3753,6 +3777,13 @@ function kbach(userConfigOrOptions) {
3753
3777
  function scanProjectCssSelectors() {
3754
3778
  for (const dir of includeDirs) scanCssSelectorsInto((0, import_path.join)(root, dir), projectCssClasses);
3755
3779
  }
3780
+ function isWithinIncludeDirs(file) {
3781
+ const nf = normPath(file);
3782
+ return includeDirs.some((dir) => {
3783
+ const base = normPath((0, import_path.join)(root, dir));
3784
+ return nf === base || nf.startsWith(base.endsWith("/") ? base : `${base}/`);
3785
+ });
3786
+ }
3756
3787
  function buildTokenCSSView() {
3757
3788
  const active = /* @__PURE__ */ new Set();
3758
3789
  for (const tokens of fileTokens.values()) for (const t of tokens) active.add(t);
@@ -3854,6 +3885,7 @@ ${code}`,
3854
3885
  configureServer(server) {
3855
3886
  const onAddOrUnlink = (file, isUnlink) => {
3856
3887
  if (file.includes("node_modules")) return;
3888
+ if (!isWithinIncludeDirs(file)) return;
3857
3889
  if (CSS_FILE_RE.test(file)) {
3858
3890
  if (!isUnlink) scanCssFileInto(file, projectCssClasses);
3859
3891
  return;
@@ -3875,6 +3907,7 @@ ${code}`,
3875
3907
  },
3876
3908
  handleHotUpdate({ file, server }) {
3877
3909
  if (file.includes("node_modules")) return;
3910
+ if (!isWithinIncludeDirs(file)) return;
3878
3911
  if (CSS_FILE_RE.test(file)) {
3879
3912
  scanCssFileInto(file, projectCssClasses);
3880
3913
  return;
@@ -3891,5 +3924,6 @@ ${code}`,
3891
3924
  }
3892
3925
  // Annotate the CommonJS export names for ESM import in node:
3893
3926
  0 && (module.exports = {
3927
+ formatKbachCSS,
3894
3928
  kbach
3895
3929
  });