@barocss/browser 0.4.0 → 0.6.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.
@@ -11,9 +11,6 @@ function atRoot(nodes, source) {
11
11
  function atRule(name, params, nodes, source) {
12
12
  return { type: "at-rule", name, params, nodes, source };
13
13
  }
14
- function styleRule(selector, nodes, source) {
15
- return { type: "style-rule", selector, nodes, source };
16
- }
17
14
  function rule(selector, nodes, source) {
18
15
  return { type: "rule", selector, nodes, source };
19
16
  }
@@ -27,6 +24,16 @@ function property(name, initialValue, syntax, source) {
27
24
  }
28
25
  return atRule("property", name, nodes, source);
29
26
  }
27
+ let debugEnabled = false;
28
+ function setDebug(enabled) {
29
+ debugEnabled = enabled;
30
+ }
31
+ function debugLog(...args) {
32
+ if (debugEnabled) console.log(...args);
33
+ }
34
+ function debugWarn(...args) {
35
+ if (debugEnabled) console.warn(...args);
36
+ }
30
37
  class AstCache {
31
38
  constructor() {
32
39
  this.cache = /* @__PURE__ */ new Map();
@@ -135,7 +142,7 @@ function clearAllCaches() {
135
142
  parseResultCache.clear();
136
143
  utilityCache.clear();
137
144
  resetContextCaches?.();
138
- console.log("[clearAllCaches] All caches cleared");
145
+ debugLog("[clearAllCaches] All caches cleared");
139
146
  }
140
147
  const states = /* @__PURE__ */ new WeakMap();
141
148
  let cacheGeneration = 0;
@@ -172,6 +179,10 @@ function clearContextCaches(ctx) {
172
179
  const utilityRegistry = [];
173
180
  function registerUtility(util, ctx) {
174
181
  utilityRegistry.push(util);
182
+ {
183
+ parseResultCache.clear();
184
+ utilityCache.clear();
185
+ }
175
186
  }
176
187
  function getUtility(ctx) {
177
188
  return ctx && getContextState(ctx)?.utilities || utilityRegistry;
@@ -264,6 +275,11 @@ function staticUtility(name, decls, opts, ctx) {
264
275
  priority: opts?.priority
265
276
  });
266
277
  }
278
+ function spacingKeyValue(ctx, key, negative) {
279
+ if (key === "px" || !/^[a-zA-Z][\w-]*$/.test(key) || ctx.theme("spacing", key) == null) return null;
280
+ const ref = `var(--spacing-${key})`;
281
+ return negative ? `calc(${ref} * -1)` : ref;
282
+ }
267
283
  function functionalUtility(opts, ctx) {
268
284
  registerUtility({
269
285
  name: opts.name,
@@ -282,7 +298,7 @@ function functionalUtility(opts, ctx) {
282
298
  }
283
299
  }
284
300
  if (opts.supportsArbitrary && parsedUtility.arbitrary) {
285
- const processedValue = finalValue.replace(/_/g, " ");
301
+ const processedValue = normalizeMathSpacing(expandThemeFunctions(finalValue.replace(/_/g, " ")));
286
302
  if (opts.handle) {
287
303
  const result = opts.handle(processedValue, ctx2, token, extra);
288
304
  if (result) return result;
@@ -332,14 +348,19 @@ function functionalUtility(opts, ctx) {
332
348
  if (opts.supportsFraction && /^-?\d+\/\d+$/.test(value)) {
333
349
  finalValue = value;
334
350
  }
351
+ const spacingKey = opts.spacingKeys ? spacingKeyValue(ctx2, String(finalValue).replace(/^-/, ""), !!parsedUtility.negative) : null;
335
352
  if (parsedUtility.negative && opts.supportsNegative && opts.handleNegativeBareValue) {
336
- const bare = opts.handleNegativeBareValue({ value: String(finalValue).replace(/^-/, ""), ctx: ctx2, token, extra });
353
+ const bare = opts.handleNegativeBareValue({ value: String(finalValue).replace(/^-/, ""), ctx: ctx2, token, extra }) ?? spacingKey;
337
354
  if (bare == null) return [];
338
355
  finalValue = bare;
339
356
  } else if (opts.handleBareValue) {
340
- const bare = opts.handleBareValue({ value: finalValue, ctx: ctx2, token, extra });
357
+ const bare = opts.handleBareValue({ value: finalValue, ctx: ctx2, token, extra }) ?? spacingKey;
341
358
  if (bare == null) return [];
342
359
  finalValue = bare;
360
+ } else if (spacingKey) {
361
+ finalValue = spacingKey;
362
+ } else if (!/^-?(\d|\.\d)/.test(String(finalValue))) {
363
+ return [];
343
364
  }
344
365
  if (opts.handle) {
345
366
  const result = opts.handle(finalValue, ctx2, token, extra);
@@ -355,6 +376,62 @@ function functionalUtility(opts, ctx) {
355
376
  priority: opts.priority
356
377
  });
357
378
  }
379
+ const MATH_FNS = /* @__PURE__ */ new Set(["calc", "min", "max", "clamp"]);
380
+ function expandThemeFunctions(value) {
381
+ return value.replace(/--spacing\(\s*([^()]+?)\s*\)/g, "calc(var(--spacing) * $1)");
382
+ }
383
+ const arbitraryPropertyRegistration = {
384
+ name: "[arbitrary-property]",
385
+ match: () => false,
386
+ handler: (value, _ctx, token) => {
387
+ const prop = token.property;
388
+ if (!prop || !value) return [];
389
+ return [decl(prop, normalizeMathSpacing(expandThemeFunctions(value.replace(/_/g, " "))))];
390
+ }
391
+ };
392
+ function normalizeMathSpacing(value) {
393
+ if (!/(calc|min|max|clamp)\(/.test(value)) return value;
394
+ const stack = [];
395
+ let out = "";
396
+ for (let i = 0; i < value.length; i++) {
397
+ const ch = value[i];
398
+ if (ch === "(") {
399
+ const name = (/([a-z-]*)$/i.exec(out)?.[1] ?? "").toLowerCase();
400
+ const inMath2 = stack.length > 0 && stack[stack.length - 1];
401
+ stack.push(MATH_FNS.has(name) || name === "" && inMath2);
402
+ out += ch;
403
+ continue;
404
+ }
405
+ if (ch === ")") {
406
+ stack.pop();
407
+ out += ch;
408
+ continue;
409
+ }
410
+ const inMath = stack.length > 0 && stack[stack.length - 1];
411
+ if (!inMath) {
412
+ out += ch;
413
+ continue;
414
+ }
415
+ if (ch === ",") {
416
+ out = out.trimEnd() + ", ";
417
+ while (value[i + 1] === " ") i++;
418
+ continue;
419
+ }
420
+ if ("+-*/".includes(ch)) {
421
+ const prev = out.trimEnd();
422
+ const p = prev[prev.length - 1] ?? "";
423
+ const binary = /[\w%)]/.test(p);
424
+ const exponent = (ch === "+" || ch === "-") && /\de$/i.test(prev) && prev.length === out.length && /\d/.test(value[i + 1] ?? "");
425
+ if (binary && !exponent) {
426
+ out = prev + " " + ch + " ";
427
+ while (value[i + 1] === " ") i++;
428
+ continue;
429
+ }
430
+ }
431
+ out += ch;
432
+ }
433
+ return out;
434
+ }
358
435
  function tokenize(className) {
359
436
  const tokens = [];
360
437
  let current = "";
@@ -421,6 +498,9 @@ function parseClassName(className, ctx) {
421
498
  if (className.startsWith("!")) {
422
499
  important = true;
423
500
  realClassName = className.slice(1);
501
+ } else if (className.length > 1 && className.endsWith("!")) {
502
+ important = true;
503
+ realClassName = className.slice(0, -1);
424
504
  }
425
505
  const tokens = tokenize(realClassName);
426
506
  const result = parseTokens(tokens, ctx);
@@ -436,6 +516,16 @@ function parseTokens(tokens, ctx) {
436
516
  if (tokens.length === 0) {
437
517
  return { modifiers, utility: null };
438
518
  }
519
+ if (tokens.length > 1) {
520
+ const utilityIndex = isUtilityPrefix(tokens[0].value, ctx) ? 0 : tokens.length - 1;
521
+ if (tokens.some((t, i) => i !== utilityIndex && !isSafeVariantToken(t.value))) {
522
+ return { modifiers, utility: null };
523
+ }
524
+ }
525
+ const utilityToken = tokens.length > 1 && !isUtilityPrefix(tokens[0].value, ctx) ? tokens[tokens.length - 1] : tokens[0];
526
+ if (!isStructureSafeValue(utilityToken.value)) {
527
+ return { modifiers, utility: null };
528
+ }
439
529
  if (tokens.length === 1) {
440
530
  utility = parseUtility(tokens[0].value, ctx);
441
531
  } else if (tokens.length === 2) {
@@ -469,6 +559,91 @@ function parseTokens(tokens, ctx) {
469
559
  }
470
560
  return { modifiers, utility };
471
561
  }
562
+ const FUNCTIONAL_VALUE_VARIANT = /^-?(?:(?:group|peer)-)?(?:has|not)-\[(.*)\](?:\/[\w-]+)?$/;
563
+ function isSafeVariantToken(value) {
564
+ if (hasCommentToken(value)) return false;
565
+ const m = FUNCTIONAL_VALUE_VARIANT.exec(value);
566
+ if (m) return isSafeVariantValue(m[1], true);
567
+ return isSafeVariantValue(value);
568
+ }
569
+ function hasCommentToken(value) {
570
+ return value.includes("/*") || value.includes("*/");
571
+ }
572
+ function hasCommentDelimiter(text) {
573
+ for (let i = 0; i < text.length - 1; i++) {
574
+ const c = text[i];
575
+ if (c === "\\") {
576
+ i++;
577
+ continue;
578
+ }
579
+ const n = text[i + 1];
580
+ if (c === "/" && n === "*" || c === "*" && n === "/") return true;
581
+ }
582
+ return false;
583
+ }
584
+ function isStructureSafeValue(value) {
585
+ if (hasCommentToken(value)) return false;
586
+ return isSafeVariantValue(value, true);
587
+ }
588
+ function hasUnquotedAt(value) {
589
+ let quote = "";
590
+ for (let i = 0; i < value.length; i++) {
591
+ const c = value[i];
592
+ if (c === "\\") {
593
+ i++;
594
+ continue;
595
+ }
596
+ if (quote) {
597
+ if (c === quote) quote = "";
598
+ continue;
599
+ }
600
+ if (c === '"' || c === "'") quote = c;
601
+ else if (c === "@") return true;
602
+ }
603
+ return false;
604
+ }
605
+ function isSafeVariantValue(value, allowTopLevelComma = false) {
606
+ const stack = [];
607
+ let quote = "";
608
+ let parenDepth = 0;
609
+ for (let i = 0; i < value.length; i++) {
610
+ const c = value[i];
611
+ if (c === "\\") {
612
+ i++;
613
+ continue;
614
+ }
615
+ if (quote) {
616
+ if (c === quote) quote = "";
617
+ continue;
618
+ }
619
+ switch (c) {
620
+ case '"':
621
+ case "'":
622
+ quote = c;
623
+ break;
624
+ case "(":
625
+ stack.push(")");
626
+ parenDepth++;
627
+ break;
628
+ case "[":
629
+ stack.push("]");
630
+ break;
631
+ case ")":
632
+ case "]":
633
+ if (stack.pop() !== c) return false;
634
+ if (c === ")") parenDepth--;
635
+ break;
636
+ case "{":
637
+ case "}":
638
+ case ";":
639
+ return false;
640
+ case ",":
641
+ if (parenDepth === 0 && !allowTopLevelComma) return false;
642
+ break;
643
+ }
644
+ }
645
+ return stack.length === 0 && !quote;
646
+ }
472
647
  function parseModifier(value) {
473
648
  let negative = false;
474
649
  let modStr = value;
@@ -493,6 +668,11 @@ function parseUtility(value, ctx) {
493
668
  let opacity2 = "";
494
669
  let category = "";
495
670
  let priority = 0;
671
+ const prop = /^\[(--[a-zA-Z_][a-zA-Z0-9_-]*|-?[a-z][a-z-]*):(.+)\]$/.exec(value);
672
+ if (prop) {
673
+ if (!isStructureSafeValue(prop[2]) || hasUnquotedAt(prop[2])) return { prefix: "", value: "" };
674
+ return { prefix: "", value: prop[2], arbitrary: true, property: prop[1] };
675
+ }
496
676
  if (value.startsWith("-")) {
497
677
  negative = true;
498
678
  }
@@ -548,6 +728,8 @@ function parseUtility(value, ctx) {
548
728
  priority
549
729
  };
550
730
  }
731
+ const isSafePrelude = (text) => !hasCommentDelimiter(String(text ?? ""));
732
+ const isSafeDecl = (prop, value) => isStructureSafeValue(String(prop)) && isStructureSafeValue(String(value ?? ""));
551
733
  const importantPrefix = "!important";
552
734
  function astToCss(ast, baseSelector, opts, _indent = "") {
553
735
  const minify = opts?.minify;
@@ -556,7 +738,7 @@ function astToCss(ast, baseSelector, opts, _indent = "") {
556
738
  const important = opts?.important ?? false;
557
739
  const importantString = important ? ` ${importantPrefix}` : "";
558
740
  if (!ast || ast.length === 0) {
559
- console.warn("[astToCss] Empty AST received:", { ast, baseSelector, minify });
741
+ debugWarn("[astToCss] Empty AST received:", { ast, baseSelector, minify });
560
742
  return "";
561
743
  }
562
744
  const dedupedAst = [];
@@ -578,6 +760,7 @@ function astToCss(ast, baseSelector, opts, _indent = "") {
578
760
  switch (node.type) {
579
761
  case "decl": {
580
762
  const value = node.value;
763
+ if (!isSafeDecl(node.prop, value)) return "";
581
764
  if (node.prop.startsWith("--")) {
582
765
  if (minify) {
583
766
  const css = `${node.prop}: ${value}${importantString};`;
@@ -609,6 +792,7 @@ function astToCss(ast, baseSelector, opts, _indent = "") {
609
792
  }).join(", ");
610
793
  }
611
794
  }
795
+ if (!isSafePrelude(selector)) return "";
612
796
  if (minify) {
613
797
  const css = `${indent}${selector}{${astToCss(
614
798
  node.nodes,
@@ -633,6 +817,7 @@ ${astToCss(
633
817
  }
634
818
  }
635
819
  case "style-rule": {
820
+ if (!isSafePrelude(node.selector)) return "";
636
821
  if (minify) {
637
822
  const css = `${indent}${node.selector} {${astToCss(
638
823
  node.nodes,
@@ -657,6 +842,7 @@ ${astToCss(
657
842
  }
658
843
  }
659
844
  case "at-rule": {
845
+ if (!isSafePrelude(node.name) || !isSafePrelude(node.params)) return "";
660
846
  if (minify) {
661
847
  const css = `${indent}@${node.name} ${node.params}{${astToCss(
662
848
  node.nodes,
@@ -685,13 +871,13 @@ ${astToCss(
685
871
  case "raw":
686
872
  return `${indent}${node.value}`;
687
873
  default:
688
- console.warn("[astToCss] Unknown node type:", node);
874
+ debugWarn("[astToCss] Unknown node type:", node);
689
875
  return "";
690
876
  }
691
877
  }).filter(Boolean).join(minify ? "" : "\n");
692
878
  const finalResult = result + (minify ? "" : "\n");
693
879
  if (!finalResult || finalResult.trim() === "") {
694
- console.warn("[astToCss] Empty result generated:", {
880
+ debugWarn("[astToCss] Empty result generated:", {
695
881
  ast,
696
882
  baseSelector,
697
883
  minify,
@@ -702,26 +888,266 @@ ${astToCss(
702
888
  }
703
889
  return finalResult;
704
890
  }
705
- function rootToCss(nodes) {
891
+ function rootToCss(nodes, opts) {
706
892
  const result = nodes.map((node) => {
707
893
  const list = [];
708
894
  if (node.type === "decl") {
709
- list.push(`${node.prop}: ${node.value};`);
710
- } else if (node.type === "at-rule") {
711
- list.push(
712
- `@${node.name} ${node.params} {
895
+ if (isSafeDecl(node.prop, node.value)) {
896
+ list.push(`${node.prop}: ${node.value};`);
897
+ }
898
+ } else if (node.type === "at-rule" && isSafePrelude(node.name) && isSafePrelude(node.params)) {
899
+ {
900
+ list.push(
901
+ `@${node.name} ${node.params} {
713
902
  ${node.nodes.map((node2) => {
714
- if (node2.type === "decl") {
715
- return ` ${node2.prop}: ${node2.value};`;
716
- }
717
- }).join("\n")}
903
+ if (node2.type === "decl" && isSafeDecl(node2.prop, node2.value)) {
904
+ return ` ${node2.prop}: ${node2.value};`;
905
+ }
906
+ }).join("\n")}
718
907
  }`
719
- );
908
+ );
909
+ }
720
910
  }
721
911
  return list.join("\n");
722
912
  }).join("\n");
723
913
  return result;
724
914
  }
915
+ function normalizePrefix(prefix) {
916
+ let p = prefix.trim();
917
+ if (!p.startsWith("--")) p = `--${p}`;
918
+ if (!p.endsWith("-")) p = `${p}-`;
919
+ return p;
920
+ }
921
+ function escapeKey(key) {
922
+ return key.replace(".", "\\.");
923
+ }
924
+ function colorsToCssVars(colors2) {
925
+ if (!colors2) return {};
926
+ const result = {};
927
+ function walk(obj, prefix = []) {
928
+ for (const key in obj) {
929
+ const value = obj[key];
930
+ if (typeof value === "object" && value !== null) {
931
+ walk(value, [...prefix, key]);
932
+ } else {
933
+ const varName2 = "--color-" + [...prefix, key].join("-");
934
+ result[varName2] = value;
935
+ }
936
+ }
937
+ }
938
+ walk(colors2);
939
+ return result;
940
+ }
941
+ function boxShadowToCssVars(boxShadow2) {
942
+ if (!boxShadow2) return {};
943
+ const result = {};
944
+ for (const key in boxShadow2) {
945
+ result[`--shadow-${key}`] = boxShadow2[key];
946
+ }
947
+ return result;
948
+ }
949
+ function fontSizeToCssVars(fontSize2) {
950
+ if (!fontSize2) return {};
951
+ const result = {};
952
+ for (const key in fontSize2) {
953
+ const value = fontSize2[key];
954
+ if (Array.isArray(value)) {
955
+ result[`--text-${key}`] = value[0];
956
+ if (value[1]) result[`--text-${key}--line-height`] = value[1];
957
+ } else {
958
+ result[`--text-${key}`] = value;
959
+ }
960
+ }
961
+ return result;
962
+ }
963
+ function fontWeightToCssVars(fontWeight2) {
964
+ if (!fontWeight2) return {};
965
+ const result = {};
966
+ for (const key in fontWeight2) {
967
+ result[`--font-weight-${key}`] = fontWeight2[key];
968
+ }
969
+ return result;
970
+ }
971
+ function fontFamilyToCssVars(fontFamily2) {
972
+ if (!fontFamily2) return {};
973
+ const result = {};
974
+ for (const key in fontFamily2) {
975
+ const value = fontFamily2[key];
976
+ if (Array.isArray(value)) {
977
+ result[`--font-${key}`] = value.join(", ");
978
+ } else {
979
+ result[`--font-${key}`] = value;
980
+ }
981
+ }
982
+ return result;
983
+ }
984
+ function letterSpacingToCssVars(letterSpacing2) {
985
+ if (!letterSpacing2) return {};
986
+ const result = {};
987
+ for (const key in letterSpacing2) {
988
+ result[`--letter-spacing-${key}`] = letterSpacing2[key];
989
+ }
990
+ return result;
991
+ }
992
+ function spacingToCssVars(spacing2) {
993
+ if (!spacing2) return {};
994
+ const result = {};
995
+ for (const key in spacing2) {
996
+ result[`--spacing-${escapeKey(key)}`] = spacing2[key];
997
+ }
998
+ return result;
999
+ }
1000
+ function borderRadiusToCssVars(borderRadius2) {
1001
+ if (!borderRadius2) return {};
1002
+ const result = {};
1003
+ for (const key in borderRadius2) {
1004
+ result[`--radius-${escapeKey(key)}`] = borderRadius2[key];
1005
+ }
1006
+ return result;
1007
+ }
1008
+ function zIndexToCssVars(zIndex2) {
1009
+ if (!zIndex2) return {};
1010
+ const result = {};
1011
+ for (const key in zIndex2) {
1012
+ result[`--z-${escapeKey(key)}`] = String(zIndex2[key]);
1013
+ }
1014
+ return result;
1015
+ }
1016
+ function opacityToCssVars(opacity2) {
1017
+ if (!opacity2) return {};
1018
+ const result = {};
1019
+ for (const key in opacity2) {
1020
+ result[`--opacity-${escapeKey(key)}`] = String(opacity2[key]);
1021
+ }
1022
+ return result;
1023
+ }
1024
+ function animationToCssVars(animations2) {
1025
+ if (!animations2) return {};
1026
+ const result = {};
1027
+ for (const key in animations2) {
1028
+ result[`--animate-${escapeKey(key)}`] = animations2[key];
1029
+ }
1030
+ return result;
1031
+ }
1032
+ function keyframesToCss(keyframes2) {
1033
+ if (!keyframes2) return "";
1034
+ let css = "";
1035
+ for (const name in keyframes2) {
1036
+ const frames = keyframes2[name];
1037
+ css += `@keyframes ${name} {
1038
+ `;
1039
+ for (const step in frames) {
1040
+ css += ` ${step} {`;
1041
+ const props = frames[step];
1042
+ for (const prop in props) {
1043
+ css += ` ${prop}: ${props[prop]};`;
1044
+ }
1045
+ css += " }\n";
1046
+ }
1047
+ css += "}\n";
1048
+ }
1049
+ return css;
1050
+ }
1051
+ function transitionTimingFunctionToCssVars(transition) {
1052
+ const result = {};
1053
+ for (const key in transition) {
1054
+ if (key === "DEFAULT") {
1055
+ result[`--default-transition-timing-function`] = transition[key];
1056
+ } else {
1057
+ result[`--transition-timing-function-${escapeKey(key)}`] = transition[key];
1058
+ if (key !== "linear") result[`--ease-${escapeKey(key)}`] = transition[key];
1059
+ }
1060
+ }
1061
+ return result;
1062
+ }
1063
+ function transitionDurationToCssVars(transitionDuration2) {
1064
+ const result = {};
1065
+ for (const key in transitionDuration2) {
1066
+ if (key === "DEFAULT") {
1067
+ result[`--default-transition-duration`] = transitionDuration2[key];
1068
+ } else {
1069
+ result[`--transition-duration-${escapeKey(key)}`] = transitionDuration2[key];
1070
+ }
1071
+ }
1072
+ return result;
1073
+ }
1074
+ function transitionDelayToCssVars(transitionDelay2) {
1075
+ const result = {};
1076
+ for (const key in transitionDelay2) {
1077
+ if (key === "DEFAULT") {
1078
+ result[`--default-transition-delay`] = transitionDelay2[key];
1079
+ } else {
1080
+ result[`--transition-delay-${escapeKey(key)}`] = transitionDelay2[key];
1081
+ }
1082
+ }
1083
+ return result;
1084
+ }
1085
+ function blurToCssVars(blur2) {
1086
+ const result = {};
1087
+ for (const key in blur2) {
1088
+ if (key === "DEFAULT") {
1089
+ result[`--default-blur`] = blur2[key];
1090
+ } else {
1091
+ result[`--blur-${escapeKey(key)}`] = blur2[key];
1092
+ }
1093
+ }
1094
+ return result;
1095
+ }
1096
+ function containerToCssVars(container2) {
1097
+ const result = {};
1098
+ for (const key in container2) {
1099
+ result[`--container-${escapeKey(key)}`] = container2[key];
1100
+ }
1101
+ return result;
1102
+ }
1103
+ function themeToCssVarsAll(theme) {
1104
+ return {
1105
+ ...colorsToCssVars(theme.colors),
1106
+ ...boxShadowToCssVars(theme.boxShadow),
1107
+ ...fontSizeToCssVars(theme.fontSize),
1108
+ ...fontWeightToCssVars(theme.fontWeight),
1109
+ ...fontFamilyToCssVars(theme.fontFamily),
1110
+ ...letterSpacingToCssVars(theme.letterSpacing),
1111
+ "--spacing": theme.spacing["1"],
1112
+ ...spacingToCssVars(theme.spacing),
1113
+ ...containerToCssVars(theme.container),
1114
+ ...borderRadiusToCssVars(theme.borderRadius),
1115
+ ...zIndexToCssVars(theme.zIndex),
1116
+ ...opacityToCssVars(theme.opacity),
1117
+ ...animationToCssVars(theme.animations),
1118
+ ...transitionTimingFunctionToCssVars(theme.transitionTimingFunction),
1119
+ ...transitionDurationToCssVars(theme.transitionDuration),
1120
+ ...transitionDelayToCssVars(theme.transitionDelay),
1121
+ ...blurToCssVars(theme.blur),
1122
+ ...Object.fromEntries(Object.entries(theme.aspect ?? {}).map(([k, v2]) => [`--aspect-${escapeKey(k)}`, v2]))
1123
+ // keyframes handled separately
1124
+ };
1125
+ }
1126
+ function isSelfReferencingVar(name, value) {
1127
+ if (typeof value !== "string") return false;
1128
+ const m = /^var\(\s*(--[\w-]+)\s*(?:,[\s\S]*)?\)$/.exec(value.trim());
1129
+ return !!m && m[1] === name.trim();
1130
+ }
1131
+ function toCssVarsBlock(vars, extra = "") {
1132
+ return ":root,:host {\n" + Object.entries(vars).filter(([k, v2]) => !isSelfReferencingVar(k, v2)).map(([k, v2]) => ` ${k}: ${v2};`).join("\n") + "\n}\n" + extra + "\n";
1133
+ }
1134
+ const BARO_VAR = /--baro-/g;
1135
+ const PREFIXED_KEYS = /* @__PURE__ */ new Set(["prop", "value", "params", "selector", "nodes", "items"]);
1136
+ function applyVarPrefix(ast, ctx) {
1137
+ const configured = ctx?.config("cssVarPrefix");
1138
+ if (typeof configured !== "string" || !configured.trim()) return ast;
1139
+ const prefix = normalizePrefix(configured);
1140
+ if (prefix === "--baro-") return ast;
1141
+ const walk = (node) => {
1142
+ if (typeof node === "string") return node.includes("--baro-") ? node.replace(BARO_VAR, prefix) : node;
1143
+ if (Array.isArray(node)) return node.map(walk);
1144
+ if (!node || typeof node !== "object") return node;
1145
+ const out = {};
1146
+ for (const [k, val] of Object.entries(node)) out[k] = PREFIXED_KEYS.has(k) ? walk(val) : val;
1147
+ return out;
1148
+ };
1149
+ return walk(ast);
1150
+ }
725
1151
  const failureCache = /* @__PURE__ */ new Set();
726
1152
  function collectDeclPaths(nodes = [], path = []) {
727
1153
  let result = [];
@@ -877,8 +1303,8 @@ function extractAtRootNodes(nodes, parent, atRootNodes = []) {
877
1303
  if (node.type === "at-root") {
878
1304
  atRootNodes.push(node);
879
1305
  delete nodes[i];
880
- } else if (node.type === "rule" || node.type === "style-rule") {
881
- extractAtRootNodes(node.nodes, node, atRootNodes);
1306
+ } else if (node.type === "rule" || node.type === "style-rule" || node.type === "at-rule") {
1307
+ extractAtRootNodes(node.nodes ?? [], node, atRootNodes);
882
1308
  }
883
1309
  }
884
1310
  if (parent) {
@@ -897,33 +1323,40 @@ function parseClassToAst(fullClassName, ctx) {
897
1323
  }
898
1324
  const { modifiers, utility } = parseClassName(fullClassName, ctx);
899
1325
  if (!utility) {
900
- console.warn(`[BAROCSS] Invalid class name format: "${fullClassName}"`);
1326
+ debugWarn(`[BAROCSS] Invalid class name format: "${fullClassName}"`);
901
1327
  failures.add(fullClassName);
902
1328
  return [];
903
1329
  }
904
- const utilReg = getUtility(ctx).find((u) => {
1330
+ const utilRegs = utility.property ? [arbitraryPropertyRegistration] : getUtility(ctx).filter((u) => {
905
1331
  const fullClassName2 = utility.value ? `${utility.prefix}-${utility.value}` : utility.prefix;
906
1332
  return u.match(fullClassName2);
907
1333
  });
908
- if (!utilReg) {
1334
+ if (utilRegs.length === 0) {
909
1335
  const utilityName = utility.value ? `${utility.prefix}-${utility.value}` : utility.prefix;
910
- console.warn(`[BAROCSS] Unknown utility class: "${utilityName}" in "${fullClassName}"`);
1336
+ debugWarn(`[BAROCSS] Unknown utility class: "${utilityName}" in "${fullClassName}"`);
911
1337
  failures.add(fullClassName);
912
1338
  return [];
913
1339
  }
914
1340
  let value = utility.value;
915
1341
  if (utility.negative && value) value = "-" + value;
916
- let ast = utilReg.handler(value, ctx, utility, utilReg) || [];
1342
+ let ast = [];
1343
+ for (const utilReg of utilRegs) {
1344
+ ast = utilReg.handler(value, ctx, utility, utilReg) || [];
1345
+ if (ast.length > 0) break;
1346
+ }
917
1347
  const wrappers = [];
918
1348
  const selector = "&";
919
1349
  for (let i = 0; i < modifiers.length; i++) {
920
1350
  const variant = modifiers[i];
921
1351
  const plugin = getModifier(ctx).find((p) => p.match(variant.type, ctx));
922
1352
  if (!plugin) {
923
- console.warn(`[BAROCSS] Unknown variant: "${variant.type}" in "${fullClassName}"`);
1353
+ debugWarn(`[BAROCSS] Unknown variant: "${variant.type}" in "${fullClassName}"`);
924
1354
  failures.add(fullClassName);
925
1355
  return [];
926
1356
  }
1357
+ if (plugin.astHandler) {
1358
+ ast = plugin.astHandler(ast, variant, ctx, modifiers, i);
1359
+ }
927
1360
  if (plugin.wrap) {
928
1361
  const items = plugin.wrap(variant, ctx);
929
1362
  wrappers.push({
@@ -1000,7 +1433,7 @@ function parseClassToAst(fullClassName, ctx) {
1000
1433
  }
1001
1434
  const atRootNodes = [];
1002
1435
  extractAtRootNodes(ast, void 0, atRootNodes);
1003
- ast = [...atRootNodes, ...ast].filter(Boolean);
1436
+ ast = applyVarPrefix([...atRootNodes, ...ast].filter(Boolean), ctx);
1004
1437
  cache.set(fullClassName, ast);
1005
1438
  return ast;
1006
1439
  }
@@ -1142,7 +1575,7 @@ class IncrementalParser {
1142
1575
  }
1143
1576
  const ast = parseClassToAst(className, this.ctx);
1144
1577
  if (ast.length === 0) {
1145
- console.warn("[IncrementalParser] ast is empty", className);
1578
+ debugWarn("[IncrementalParser] ast is empty", className);
1146
1579
  return null;
1147
1580
  }
1148
1581
  const rules = generateCssRules(className, this.ctx, { dedup: false });
@@ -1163,7 +1596,7 @@ class IncrementalParser {
1163
1596
  rootCssList: rule2.rootCssList
1164
1597
  };
1165
1598
  } catch (error) {
1166
- console.warn("[IncrementalParser] Failed to process class:", className, error);
1599
+ debugWarn("[IncrementalParser] Failed to process class:", className, error);
1167
1600
  return null;
1168
1601
  }
1169
1602
  }
@@ -1309,6 +1742,15 @@ class IncrementalParser {
1309
1742
  markProcessed(cls) {
1310
1743
  this.processedClasses.add(cls);
1311
1744
  }
1745
+ /**
1746
+ * Forgets that a class was processed, so a later request generates it again
1747
+ * (used when the browser runtime reclaims an unused class's rules, #269).
1748
+ *
1749
+ * @param cls - The CSS class name to forget
1750
+ */
1751
+ unmarkProcessed(cls) {
1752
+ this.processedClasses.delete(cls);
1753
+ }
1312
1754
  /**
1313
1755
  * Process classes synchronously and update BrowserRuntime cache
1314
1756
  * This method is used by ChangeDetector for scan operations
@@ -1662,13 +2104,15 @@ const spacing = {
1662
2104
  };
1663
2105
  const borderRadius = {
1664
2106
  none: "0px",
1665
- sm: "0.125rem",
2107
+ xs: "0.125rem",
2108
+ sm: "0.25rem",
1666
2109
  DEFAULT: "0.25rem",
1667
2110
  md: "0.375rem",
1668
2111
  lg: "0.5rem",
1669
2112
  xl: "0.75rem",
1670
2113
  "2xl": "1rem",
1671
2114
  "3xl": "1.5rem",
2115
+ "4xl": "2rem",
1672
2116
  full: "9999px"
1673
2117
  };
1674
2118
  const fontSize = {
@@ -1745,11 +2189,13 @@ const lineHeight = {
1745
2189
  12: "3rem"
1746
2190
  };
1747
2191
  const boxShadow = {
1748
- sm: "0 1px 2px 0 rgb(0 0 0 / 0.05)",
2192
+ "2xs": "0 1px rgb(0 0 0 / 0.05)",
2193
+ xs: "0 1px 2px 0 rgb(0 0 0 / 0.05)",
2194
+ sm: "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)",
1749
2195
  DEFAULT: "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px 0 rgb(0 0 0 / 0.06)",
1750
- md: "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -1px rgb(0 0 0 / 0.06)",
1751
- lg: "0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -2px rgb(0 0 0 / 0.05)",
1752
- xl: "0 20px 25px -5px rgb(0 0 0 / 0.1), 0 10px 10px -5px rgb(0 0 0 / 0.04)",
2196
+ md: "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)",
2197
+ lg: "0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)",
2198
+ xl: "0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)",
1753
2199
  "2xl": "0 25px 50px -12px rgb(0 0 0 / 0.25)",
1754
2200
  inner: "inset 0 2px 4px 0 rgb(0 0 0 / 0.05)",
1755
2201
  none: "none"
@@ -1892,15 +2338,14 @@ const letterSpacing = {
1892
2338
  widest: "0.1em"
1893
2339
  };
1894
2340
  const blur = {
1895
- DEFAULT: "0px",
1896
- sm: "4px",
1897
- md: "8px",
1898
- lg: "12px",
1899
- xl: "16px",
1900
- "2xl": "24px",
1901
- "3xl": "32px",
1902
- "4xl": "40px",
1903
- "5xl": "48px"
2341
+ DEFAULT: "8px",
2342
+ xs: "4px",
2343
+ sm: "8px",
2344
+ md: "12px",
2345
+ lg: "16px",
2346
+ xl: "24px",
2347
+ "2xl": "40px",
2348
+ "3xl": "64px"
1904
2349
  };
1905
2350
  const defaultTheme = {
1906
2351
  colors,
@@ -1923,214 +2368,10 @@ const defaultTheme = {
1923
2368
  animations,
1924
2369
  keyframes,
1925
2370
  animationVars,
1926
- blur
2371
+ blur,
2372
+ // Tailwind 4.1.13 --aspect-* (aspect-video → var(--aspect-video))
2373
+ aspect: { video: "16 / 9" }
1927
2374
  };
1928
- function escapeKey(key) {
1929
- return key.replace(".", "\\.");
1930
- }
1931
- function colorsToCssVars(colors2) {
1932
- if (!colors2) return {};
1933
- const result = {};
1934
- function walk(obj, prefix = []) {
1935
- for (const key in obj) {
1936
- const value = obj[key];
1937
- if (typeof value === "object" && value !== null) {
1938
- walk(value, [...prefix, key]);
1939
- } else {
1940
- const varName2 = "--color-" + [...prefix, key].join("-");
1941
- result[varName2] = value;
1942
- }
1943
- }
1944
- }
1945
- walk(colors2);
1946
- return result;
1947
- }
1948
- function boxShadowToCssVars(boxShadow2) {
1949
- if (!boxShadow2) return {};
1950
- const result = {};
1951
- for (const key in boxShadow2) {
1952
- result[`--shadow-${key}`] = boxShadow2[key];
1953
- }
1954
- return result;
1955
- }
1956
- function fontSizeToCssVars(fontSize2) {
1957
- if (!fontSize2) return {};
1958
- const result = {};
1959
- for (const key in fontSize2) {
1960
- const value = fontSize2[key];
1961
- if (Array.isArray(value)) {
1962
- result[`--text-${key}`] = value[0];
1963
- if (value[1]) result[`--text-${key}--line-height`] = value[1];
1964
- } else {
1965
- result[`--text-${key}`] = value;
1966
- }
1967
- }
1968
- return result;
1969
- }
1970
- function fontWeightToCssVars(fontWeight2) {
1971
- if (!fontWeight2) return {};
1972
- const result = {};
1973
- for (const key in fontWeight2) {
1974
- result[`--font-weight-${key}`] = fontWeight2[key];
1975
- }
1976
- return result;
1977
- }
1978
- function fontFamilyToCssVars(fontFamily2) {
1979
- if (!fontFamily2) return {};
1980
- const result = {};
1981
- for (const key in fontFamily2) {
1982
- const value = fontFamily2[key];
1983
- if (Array.isArray(value)) {
1984
- result[`--font-${key}`] = value.join(", ");
1985
- } else {
1986
- result[`--font-${key}`] = value;
1987
- }
1988
- }
1989
- return result;
1990
- }
1991
- function letterSpacingToCssVars(letterSpacing2) {
1992
- if (!letterSpacing2) return {};
1993
- const result = {};
1994
- for (const key in letterSpacing2) {
1995
- result[`--letter-spacing-${key}`] = letterSpacing2[key];
1996
- }
1997
- return result;
1998
- }
1999
- function spacingToCssVars(spacing2) {
2000
- if (!spacing2) return {};
2001
- const result = {};
2002
- for (const key in spacing2) {
2003
- result[`--spacing-${escapeKey(key)}`] = spacing2[key];
2004
- }
2005
- return result;
2006
- }
2007
- function borderRadiusToCssVars(borderRadius2) {
2008
- if (!borderRadius2) return {};
2009
- const result = {};
2010
- for (const key in borderRadius2) {
2011
- result[`--radius-${escapeKey(key)}`] = borderRadius2[key];
2012
- }
2013
- return result;
2014
- }
2015
- function zIndexToCssVars(zIndex2) {
2016
- if (!zIndex2) return {};
2017
- const result = {};
2018
- for (const key in zIndex2) {
2019
- result[`--z-${escapeKey(key)}`] = String(zIndex2[key]);
2020
- }
2021
- return result;
2022
- }
2023
- function opacityToCssVars(opacity2) {
2024
- if (!opacity2) return {};
2025
- const result = {};
2026
- for (const key in opacity2) {
2027
- result[`--opacity-${escapeKey(key)}`] = String(opacity2[key]);
2028
- }
2029
- return result;
2030
- }
2031
- function animationToCssVars(animations2) {
2032
- if (!animations2) return {};
2033
- const result = {};
2034
- for (const key in animations2) {
2035
- result[`--animate-${escapeKey(key)}`] = animations2[key];
2036
- }
2037
- return result;
2038
- }
2039
- function keyframesToCss(keyframes2) {
2040
- if (!keyframes2) return "";
2041
- let css = "";
2042
- for (const name in keyframes2) {
2043
- const frames = keyframes2[name];
2044
- css += `@keyframes ${name} {
2045
- `;
2046
- for (const step in frames) {
2047
- css += ` ${step} {`;
2048
- const props = frames[step];
2049
- for (const prop in props) {
2050
- css += ` ${prop}: ${props[prop]};`;
2051
- }
2052
- css += " }\n";
2053
- }
2054
- css += "}\n";
2055
- }
2056
- return css;
2057
- }
2058
- function transitionTimingFunctionToCssVars(transition) {
2059
- const result = {};
2060
- for (const key in transition) {
2061
- if (key === "DEFAULT") {
2062
- result[`--default-transition-timing-function`] = transition[key];
2063
- } else {
2064
- result[`--transition-timing-function-${escapeKey(key)}`] = transition[key];
2065
- }
2066
- }
2067
- return result;
2068
- }
2069
- function transitionDurationToCssVars(transitionDuration2) {
2070
- const result = {};
2071
- for (const key in transitionDuration2) {
2072
- if (key === "DEFAULT") {
2073
- result[`--default-transition-duration`] = transitionDuration2[key];
2074
- } else {
2075
- result[`--transition-duration-${escapeKey(key)}`] = transitionDuration2[key];
2076
- }
2077
- }
2078
- return result;
2079
- }
2080
- function transitionDelayToCssVars(transitionDelay2) {
2081
- const result = {};
2082
- for (const key in transitionDelay2) {
2083
- if (key === "DEFAULT") {
2084
- result[`--default-transition-delay`] = transitionDelay2[key];
2085
- } else {
2086
- result[`--transition-delay-${escapeKey(key)}`] = transitionDelay2[key];
2087
- }
2088
- }
2089
- return result;
2090
- }
2091
- function blurToCssVars(blur2) {
2092
- const result = {};
2093
- for (const key in blur2) {
2094
- if (key === "DEFAULT") {
2095
- result[`--default-blur`] = blur2[key];
2096
- } else {
2097
- result[`--blur-${escapeKey(key)}`] = blur2[key];
2098
- }
2099
- }
2100
- return result;
2101
- }
2102
- function containerToCssVars(container2) {
2103
- const result = {};
2104
- for (const key in container2) {
2105
- result[`--container-${escapeKey(key)}`] = container2[key];
2106
- }
2107
- return result;
2108
- }
2109
- function themeToCssVarsAll(theme) {
2110
- return {
2111
- ...colorsToCssVars(theme.colors),
2112
- ...boxShadowToCssVars(theme.boxShadow),
2113
- ...fontSizeToCssVars(theme.fontSize),
2114
- ...fontWeightToCssVars(theme.fontWeight),
2115
- ...fontFamilyToCssVars(theme.fontFamily),
2116
- ...letterSpacingToCssVars(theme.letterSpacing),
2117
- "--spacing": theme.spacing["1"],
2118
- ...spacingToCssVars(theme.spacing),
2119
- ...containerToCssVars(theme.container),
2120
- ...borderRadiusToCssVars(theme.borderRadius),
2121
- ...zIndexToCssVars(theme.zIndex),
2122
- ...opacityToCssVars(theme.opacity),
2123
- ...animationToCssVars(theme.animations),
2124
- ...transitionTimingFunctionToCssVars(theme.transitionTimingFunction),
2125
- ...transitionDurationToCssVars(theme.transitionDuration),
2126
- ...transitionDelayToCssVars(theme.transitionDelay),
2127
- ...blurToCssVars(theme.blur)
2128
- // keyframes handled separately
2129
- };
2130
- }
2131
- function toCssVarsBlock(vars, extra = "") {
2132
- return ":root,:host {\n" + Object.entries(vars).map(([k, v2]) => ` ${k}: ${v2};`).join("\n") + "\n}\n" + extra + "\n";
2133
- }
2134
2375
  const preflightMinimalCSS = `
2135
2376
  /* BaroCSS Preflight - Minimal Reset */
2136
2377
  /* ================================= */
@@ -2261,6 +2502,10 @@ select {
2261
2502
  html {
2262
2503
  line-height: 1.15;
2263
2504
  -webkit-text-size-adjust: 100%;
2505
+ /* Tailwind 4.1.13 root font (app --default-font-family / --font-sans win) */
2506
+ font-family: var(--default-font-family, var(--font-sans, ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'));
2507
+ font-feature-settings: var(--default-font-feature-settings, normal);
2508
+ font-variation-settings: var(--default-font-variation-settings, normal);
2264
2509
  }
2265
2510
 
2266
2511
  /* Remove the gray background on active links in IE 10 */
@@ -2422,9 +2667,63 @@ textarea {
2422
2667
  outline-offset: -2px;
2423
2668
  }
2424
2669
 
2425
- /* Remove the inner padding in Chrome and Safari on macOS */
2426
- [type="search"]::-webkit-search-decoration {
2427
- -webkit-appearance: none;
2670
+ /* Remove the inner padding in Chrome and Safari on macOS */
2671
+ [type="search"]::-webkit-search-decoration {
2672
+ -webkit-appearance: none;
2673
+ }
2674
+
2675
+ /* Tailwind 4.1.13 monospace stack for code-like elements */
2676
+ code,
2677
+ kbd,
2678
+ samp,
2679
+ pre {
2680
+ font-family: var(--default-mono-font-family, var(--font-mono, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace));
2681
+ font-feature-settings: var(--default-mono-font-feature-settings, normal);
2682
+ font-variation-settings: var(--default-mono-font-variation-settings, normal);
2683
+ font-size: 1em;
2684
+ }
2685
+
2686
+ /* Tailwind 4.1.13 form-control reset: inherit typography and colour, drop native radius/background (#228) */
2687
+ button,
2688
+ input,
2689
+ select,
2690
+ optgroup,
2691
+ textarea,
2692
+ ::file-selector-button {
2693
+ font: inherit;
2694
+ font-feature-settings: inherit;
2695
+ font-variation-settings: inherit;
2696
+ letter-spacing: inherit;
2697
+ color: inherit;
2698
+ border-radius: 0;
2699
+ background-color: transparent;
2700
+ opacity: 1;
2701
+ }
2702
+
2703
+ :where(select:is([multiple], [size])) optgroup {
2704
+ font-weight: bolder;
2705
+ }
2706
+
2707
+ :where(select:is([multiple], [size])) optgroup option {
2708
+ padding-inline-start: 20px;
2709
+ }
2710
+
2711
+ ::file-selector-button {
2712
+ margin-inline-end: 4px;
2713
+ }
2714
+
2715
+ ::placeholder {
2716
+ opacity: 1;
2717
+ }
2718
+
2719
+ @supports (not (-webkit-appearance: -apple-pay-button)) or (contain-intrinsic-size: 1px) {
2720
+ ::placeholder {
2721
+ color: color-mix(in oklab, currentcolor 50%, transparent);
2722
+ }
2723
+ }
2724
+
2725
+ textarea {
2726
+ resize: vertical;
2428
2727
  }
2429
2728
  `;
2430
2729
  const preflightFullCSS = `
@@ -2438,10 +2737,14 @@ const preflightFullCSS = `
2438
2737
  box-sizing: border-box;
2439
2738
  }
2440
2739
 
2441
- /* Remove default margin and padding */
2740
+ /* Remove default margin and padding; reset border to Tailwind v4's universal
2741
+ \`border: 0 solid\` so a bare border/border-t (width set by the utility, style
2742
+ otherwise \`none\`) renders. Width 0 keeps borders invisible until a utility
2743
+ sets one. */
2442
2744
  * {
2443
2745
  margin: 0;
2444
2746
  padding: 0;
2747
+ border: 0 solid;
2445
2748
  }
2446
2749
 
2447
2750
  /* Set core body defaults */
@@ -2502,6 +2805,10 @@ html {
2502
2805
  line-height: 1.15;
2503
2806
  -webkit-text-size-adjust: 100%;
2504
2807
  -ms-text-size-adjust: 100%;
2808
+ /* Tailwind 4.1.13 root font (app --default-font-family / --font-sans win) */
2809
+ font-family: var(--default-font-family, var(--font-sans, ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'));
2810
+ font-feature-settings: var(--default-font-feature-settings, normal);
2811
+ font-variation-settings: var(--default-font-variation-settings, normal);
2505
2812
  }
2506
2813
 
2507
2814
  /* Remove the gray background on active links in IE 10 */
@@ -2687,7 +2994,9 @@ code,
2687
2994
  kbd,
2688
2995
  pre,
2689
2996
  samp {
2690
- font-family: monospace, monospace;
2997
+ font-family: var(--default-mono-font-family, var(--font-mono, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace));
2998
+ font-feature-settings: var(--default-mono-font-feature-settings, normal);
2999
+ font-variation-settings: var(--default-mono-font-variation-settings, normal);
2691
3000
  font-size: 1em;
2692
3001
  }
2693
3002
 
@@ -2789,6 +3098,49 @@ template {
2789
3098
  page-break-after: avoid;
2790
3099
  }
2791
3100
  }
3101
+
3102
+ /* Tailwind 4.1.13 form-control reset: inherit typography and colour, drop native radius/background (#228) */
3103
+ button,
3104
+ input,
3105
+ select,
3106
+ optgroup,
3107
+ textarea,
3108
+ ::file-selector-button {
3109
+ font: inherit;
3110
+ font-feature-settings: inherit;
3111
+ font-variation-settings: inherit;
3112
+ letter-spacing: inherit;
3113
+ color: inherit;
3114
+ border-radius: 0;
3115
+ background-color: transparent;
3116
+ opacity: 1;
3117
+ }
3118
+
3119
+ :where(select:is([multiple], [size])) optgroup {
3120
+ font-weight: bolder;
3121
+ }
3122
+
3123
+ :where(select:is([multiple], [size])) optgroup option {
3124
+ padding-inline-start: 20px;
3125
+ }
3126
+
3127
+ ::file-selector-button {
3128
+ margin-inline-end: 4px;
3129
+ }
3130
+
3131
+ ::placeholder {
3132
+ opacity: 1;
3133
+ }
3134
+
3135
+ @supports (not (-webkit-appearance: -apple-pay-button)) or (contain-intrinsic-size: 1px) {
3136
+ ::placeholder {
3137
+ color: color-mix(in oklab, currentcolor 50%, transparent);
3138
+ }
3139
+ }
3140
+
3141
+ textarea {
3142
+ resize: vertical;
3143
+ }
2792
3144
  `;
2793
3145
  function getPreflightCSS(level = true) {
2794
3146
  if (level === "minimal") {
@@ -2908,6 +3260,7 @@ ${keyframesToCss(theme.keyframes || {})}
2908
3260
  return result;
2909
3261
  }
2910
3262
  function createContext(configObj) {
3263
+ if (configObj.debug !== void 0) setDebug(!!configObj.debug);
2911
3264
  const configWithDefaults = {
2912
3265
  presets: [
2913
3266
  { theme: defaultTheme },
@@ -3192,6 +3545,30 @@ function parseColor(input) {
3192
3545
  }
3193
3546
  return null;
3194
3547
  }
3548
+ const COLOR_KEYWORDS = /* @__PURE__ */ new Set(["inherit", "currentcolor", "transparent"]);
3549
+ function themeColorDecls(prop, value, extra) {
3550
+ const key = String(extra.realThemeValue);
3551
+ const ref = COLOR_KEYWORDS.has(value.toLowerCase()) || value.startsWith("var(") || !/^[\w-]+$/.test(key) ? value : `var(--color-${key})`;
3552
+ if (!extra.opacity) return [decl(prop, ref)];
3553
+ const alpha = normalizeAlpha(String(extra.opacity));
3554
+ const supports = (amount) => atRule("supports", "(color:color-mix(in lab, red, red))", [decl(prop, `color-mix(in oklab, ${ref} ${amount}, transparent)`)]);
3555
+ if (alpha.isVar) return [decl(prop, value), supports(alpha.amount)];
3556
+ return [decl(prop, `color-mix(in srgb, ${value} ${alpha.amount}, transparent)`), supports(alpha.amount)];
3557
+ }
3558
+ function normalizeAlpha(raw) {
3559
+ let v = raw.trim();
3560
+ const bracketed = v.startsWith("[") && v.endsWith("]");
3561
+ if (bracketed) v = v.slice(1, -1).trim();
3562
+ if (v.startsWith("(") && v.endsWith(")")) v = `var(${v.slice(1, -1).trim()})`;
3563
+ if (v.startsWith("var(")) return { amount: v, isVar: true };
3564
+ if (v.endsWith("%")) return { amount: v, isVar: false };
3565
+ const n = Number(v);
3566
+ if (v !== "" && Number.isFinite(n)) {
3567
+ const pct = bracketed && n <= 1 ? n * 100 : n;
3568
+ return { amount: `${+pct.toFixed(4)}%`, isVar: false };
3569
+ }
3570
+ return { amount: v, isVar: false };
3571
+ }
3195
3572
  staticUtility("accent-inherit", [["accent-color", "inherit"]], { category: "interactivity" });
3196
3573
  staticUtility("accent-current", [["accent-color", "currentColor"]], { category: "interactivity" });
3197
3574
  staticUtility("accent-transparent", [["accent-color", "transparent"]], { category: "interactivity" });
@@ -3343,6 +3720,7 @@ staticUtility("snap-proximity", [["--baro-scroll-snap-strictness", "proximity"]]
3343
3720
  ].forEach(([name, prop]) => {
3344
3721
  functionalUtility({
3345
3722
  name: `scroll-${name}`,
3723
+ spacingKeys: true,
3346
3724
  prop,
3347
3725
  supportsArbitrary: true,
3348
3726
  supportsCustomProperty: true,
@@ -3370,6 +3748,7 @@ staticUtility("snap-proximity", [["--baro-scroll-snap-strictness", "proximity"]]
3370
3748
  ].forEach(([name, prop]) => {
3371
3749
  functionalUtility({
3372
3750
  name: `scroll-${name}`,
3751
+ spacingKeys: true,
3373
3752
  prop,
3374
3753
  supportsArbitrary: true,
3375
3754
  supportsCustomProperty: true,
@@ -3394,10 +3773,10 @@ staticUtility("touch-pan-up", [["touch-action", "pan-up"]], { category: "interac
3394
3773
  staticUtility("touch-pan-down", [["touch-action", "pan-down"]], { category: "interactivity" });
3395
3774
  staticUtility("touch-pinch-zoom", [["touch-action", "pinch-zoom"]], { category: "interactivity" });
3396
3775
  staticUtility("touch-manipulation", [["touch-action", "manipulation"]], { category: "interactivity" });
3397
- staticUtility("select-none", [["user-select", "none"]], { category: "interactivity" });
3398
- staticUtility("select-text", [["user-select", "text"]], { category: "interactivity" });
3399
- staticUtility("select-all", [["user-select", "all"]], { category: "interactivity" });
3400
- staticUtility("select-auto", [["user-select", "auto"]], { category: "interactivity" });
3776
+ staticUtility("select-none", [["-webkit-user-select", "none"], ["user-select", "none"]], { category: "interactivity" });
3777
+ staticUtility("select-text", [["-webkit-user-select", "text"], ["user-select", "text"]], { category: "interactivity" });
3778
+ staticUtility("select-all", [["-webkit-user-select", "all"], ["user-select", "all"]], { category: "interactivity" });
3779
+ staticUtility("select-auto", [["-webkit-user-select", "auto"], ["user-select", "auto"]], { category: "interactivity" });
3401
3780
  staticUtility("will-change-auto", [["will-change", "auto"]], { category: "interactivity" });
3402
3781
  staticUtility("will-change-scroll", [["will-change", "scroll-position"]], { category: "interactivity" });
3403
3782
  staticUtility("will-change-contents", [["will-change", "contents"]], { category: "interactivity" });
@@ -3415,7 +3794,7 @@ const defaultDuration = "var(--default-transition-duration)";
3415
3794
  staticUtility("transition", [
3416
3795
  [
3417
3796
  "transition-property",
3418
- "color, background-color, border-color, text-decoration-color, fill, stroke, --baro-gradient-from, --baro-gradient-via, --baro-gradient-to, opacity, box-shadow, transform, translate, scale, rotate, filter, -webkit-backdrop-filter, backdrop-filter"
3797
+ "color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --baro-gradient-from, --baro-gradient-via, --baro-gradient-to, opacity, box-shadow, transform, translate, scale, rotate, filter, -webkit-backdrop-filter, backdrop-filter, display, content-visibility, overlay, pointer-events"
3419
3798
  ],
3420
3799
  ["transition-timing-function", defaultTiming],
3421
3800
  ["transition-duration", defaultDuration]
@@ -3428,7 +3807,7 @@ staticUtility("transition-all", [
3428
3807
  staticUtility("transition-colors", [
3429
3808
  [
3430
3809
  "transition-property",
3431
- "color, background-color, border-color, text-decoration-color, fill, stroke, --baro-gradient-from, --baro-gradient-via, --baro-gradient-to"
3810
+ "color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --baro-gradient-from, --baro-gradient-via, --baro-gradient-to"
3432
3811
  ],
3433
3812
  ["transition-timing-function", defaultTiming],
3434
3813
  ["transition-duration", defaultDuration]
@@ -3618,6 +3997,7 @@ const filters$1 = () => {
3618
3997
  filters$1()
3619
3998
  ], { category: "effects" });
3620
3999
  });
4000
+ staticUtility("blur", [decl("--baro-blur", "blur(8px)"), filters$1()], { category: "effects" });
3621
4001
  staticUtility("blur-none", [decl("--baro-blur", ""), filters$1()], { category: "effects" });
3622
4002
  functionalUtility({
3623
4003
  name: "blur",
@@ -3856,6 +4236,7 @@ functionalUtility({
3856
4236
  { category: "effects" }
3857
4237
  );
3858
4238
  });
4239
+ staticUtility("backdrop-blur", [decl("--baro-backdrop-blur", "blur(8px)"), ...filters()], { category: "effects" });
3859
4240
  staticUtility(
3860
4241
  "backdrop-blur-none",
3861
4242
  [decl("--baro-backdrop-blur", ""), ...filters()],
@@ -4084,56 +4465,52 @@ functionalUtility({
4084
4465
  description: "sepia filter utility (static, number, arbitrary, custom property supported)",
4085
4466
  category: "effects"
4086
4467
  });
4468
+ const SHADOW_COMPOSITE = "var(--baro-inset-shadow), var(--baro-inset-ring-shadow), var(--baro-ring-offset-shadow), var(--baro-ring-shadow), var(--baro-shadow)";
4469
+ const ringShadowProperties = () => atRoot([
4470
+ property("--baro-shadow", "0 0 #0000"),
4471
+ property("--baro-inset-shadow", "0 0 #0000"),
4472
+ property("--baro-inset-ring-shadow", "0 0 #0000"),
4473
+ property("--baro-ring-offset-shadow", "0 0 #0000"),
4474
+ property("--baro-ring-shadow", "0 0 #0000"),
4475
+ property("--baro-ring-offset-width", "0px", "<length>"),
4476
+ property("--baro-ring-offset-color", "#fff")
4477
+ ]);
4478
+ const shadowLayer = (value) => [
4479
+ ringShadowProperties(),
4480
+ decl("--baro-shadow", value),
4481
+ decl("box-shadow", SHADOW_COMPOSITE)
4482
+ ];
4087
4483
  [
4088
4484
  ["shadow-2xs", "var(--shadow-2xs)"],
4089
4485
  ["shadow-xs", "var(--shadow-xs)"],
4090
4486
  ["shadow-sm", "var(--shadow-sm)"],
4091
- ["shadow", "var(--shadow-default)"],
4487
+ ["shadow", "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)"],
4092
4488
  ["shadow-md", "var(--shadow-md)"],
4093
4489
  ["shadow-lg", "var(--shadow-lg)"],
4094
4490
  ["shadow-xl", "var(--shadow-xl)"],
4095
4491
  ["shadow-2xl", "var(--shadow-2xl)"],
4096
4492
  ["shadow-none", "0 0 #0000"]
4097
4493
  ].forEach(([name, value]) => {
4098
- staticUtility(name, [["box-shadow", value]], { category: "effects" });
4494
+ staticUtility(name, [
4495
+ ringShadowProperties,
4496
+ ["--baro-shadow", value],
4497
+ ["box-shadow", SHADOW_COMPOSITE]
4498
+ ], { category: "effects" });
4099
4499
  });
4100
4500
  [
4101
- [
4102
- "inset-shadow-2xs",
4103
- "inset 0 1px 2px var(--baro-inset-shadow-color, #0000000d)"
4104
- ],
4105
- [
4106
- "inset-shadow-xs",
4107
- "inset 0 2px 4px var(--baro-inset-shadow-color, #0000000d)"
4108
- ],
4109
- [
4110
- "inset-shadow-sm",
4111
- "inset 0 2px 4px var(--baro-inset-shadow-color, #0000000d)"
4112
- ],
4113
- [
4114
- "inset-shadow-md",
4115
- "inset 0 4px 6px -1px var(--baro-inset-shadow-color, #0000000d)"
4116
- ],
4117
- [
4118
- "inset-shadow-lg",
4119
- "inset 0 10px 15px -3px var(--baro-inset-shadow-color, #0000000d)"
4120
- ],
4121
- [
4122
- "inset-shadow-xl",
4123
- "inset 0 20px 25px -5px var(--baro-inset-shadow-color, #0000000d)"
4124
- ],
4125
- [
4126
- "inset-shadow-2xl",
4127
- "inset 0 25px 50px -12px var(--baro-inset-shadow-color, #0000000d)"
4128
- ],
4501
+ ["inset-shadow-2xs", "inset 0 1px var(--baro-inset-shadow-color, rgb(0 0 0 / 0.05))"],
4502
+ ["inset-shadow-xs", "inset 0 1px 1px var(--baro-inset-shadow-color, rgb(0 0 0 / 0.05))"],
4503
+ ["inset-shadow-sm", "inset 0 2px 4px var(--baro-inset-shadow-color, rgb(0 0 0 / 0.05))"],
4504
+ ["inset-shadow-md", "inset 0 4px 6px -1px var(--baro-inset-shadow-color, rgb(0 0 0 / 0.05))"],
4505
+ ["inset-shadow-lg", "inset 0 10px 15px -3px var(--baro-inset-shadow-color, rgb(0 0 0 / 0.05))"],
4506
+ ["inset-shadow-xl", "inset 0 20px 25px -5px var(--baro-inset-shadow-color, rgb(0 0 0 / 0.05))"],
4507
+ ["inset-shadow-2xl", "inset 0 25px 50px -12px var(--baro-inset-shadow-color, rgb(0 0 0 / 0.05))"],
4129
4508
  ["inset-shadow-none", "0 0 #0000"]
4130
4509
  ].forEach(([name, value]) => {
4131
4510
  staticUtility(name, [
4511
+ ringShadowProperties,
4132
4512
  ["--baro-inset-shadow", value],
4133
- [
4134
- "box-shadow",
4135
- "var(--baro-inset-shadow), var(--baro-inset-ring-shadow), var(--baro-ring-offset-shadow), var(--baro-ring-shadow), var(--baro-shadow)"
4136
- ]
4513
+ ["box-shadow", SHADOW_COMPOSITE]
4137
4514
  ], { category: "effects" });
4138
4515
  });
4139
4516
  function createShadowThemeColor(key, main, opacity2, realThemeValue) {
@@ -4198,9 +4575,9 @@ functionalUtility({
4198
4575
  )
4199
4576
  ];
4200
4577
  }
4201
- return [decl("box-shadow", main)];
4578
+ return [decl("--baro-shadow-color", main)];
4202
4579
  }
4203
- return [decl("box-shadow", main)];
4580
+ return shadowLayer(main);
4204
4581
  }
4205
4582
  if (main === "inherit" || main === "current" || main === "transparent") {
4206
4583
  return [
@@ -4209,7 +4586,7 @@ functionalUtility({
4209
4586
  }
4210
4587
  return null;
4211
4588
  },
4212
- handleCustomProperty: (value) => [decl("box-shadow", `var(${value})`)]
4589
+ handleCustomProperty: (value) => shadowLayer(`var(${value})`)
4213
4590
  });
4214
4591
  functionalUtility({
4215
4592
  name: "inset-shadow",
@@ -4268,22 +4645,39 @@ functionalUtility({
4268
4645
  ["ring-8", "8px"]
4269
4646
  ].forEach(([name, px]) => {
4270
4647
  staticUtility(name, [
4271
- ["--baro-ring-inset", ""],
4272
- ["--baro-ring-offset-width", "0px"],
4273
- ["--baro-ring-offset-color", "#fff"],
4274
- ["--baro-ring-color", "rgb(59 130 246 / 0.5)"],
4275
- // default blue-500/50
4648
+ ringShadowProperties,
4649
+ // Like Tailwind, ring-N does not set the offset vars (they come from @property defaults and ring-offset-*),
4650
+ // so `ring-N ring-offset-M` composes the same in either rule order.
4651
+ // No hardcoded ring color: Tailwind v4's default ring color is currentColor (via the var() fallback below).
4276
4652
  [
4277
4653
  "--baro-ring-shadow",
4278
- `var(--baro-ring-inset) 0 0 0 calc(${px} + var(--baro-ring-offset-width)) var(--baro-ring-color, currentcolor)`
4654
+ ringShadowValue(px)
4279
4655
  ],
4280
- ["--baro-ring-offset-shadow", `0 0 #0000`],
4281
4656
  [
4282
4657
  "box-shadow",
4283
4658
  "var(--baro-inset-shadow), var(--baro-inset-ring-shadow), var(--baro-ring-offset-shadow), var(--baro-ring-shadow), var(--baro-shadow)"
4284
4659
  ]
4285
4660
  ]);
4286
4661
  });
4662
+ function ringShadowValue(width) {
4663
+ return `var(--baro-ring-inset,) 0 0 0 calc(${width} + var(--baro-ring-offset-width)) var(--baro-ring-color, currentcolor)`;
4664
+ }
4665
+ [
4666
+ ["ring-offset-0", "0px"],
4667
+ ["ring-offset-1", "1px"],
4668
+ ["ring-offset-2", "2px"],
4669
+ ["ring-offset-4", "4px"],
4670
+ ["ring-offset-8", "8px"]
4671
+ ].forEach(([name, px]) => {
4672
+ staticUtility(name, [
4673
+ ["--baro-ring-offset-width", px],
4674
+ ["--baro-ring-offset-color", "#fff"],
4675
+ [
4676
+ "--baro-ring-offset-shadow",
4677
+ `var(--baro-ring-inset,) 0 0 0 var(--baro-ring-offset-width) var(--baro-ring-offset-color)`
4678
+ ]
4679
+ ], { category: "effects" });
4680
+ });
4287
4681
  [
4288
4682
  ["inset-ring", "1px"],
4289
4683
  ["inset-ring-0", "0px"],
@@ -4293,20 +4687,11 @@ functionalUtility({
4293
4687
  ["inset-ring-8", "8px"]
4294
4688
  ].forEach(([name, px]) => {
4295
4689
  staticUtility(name, [
4296
- ["--baro-ring-inset", "inset"],
4297
- ["--baro-ring-offset-width", "0px"],
4298
- ["--baro-ring-offset-color", "#fff"],
4299
- ["--baro-inset-ring-color", "currentcolor"],
4300
- [
4301
- "--baro-inset-ring-shadow",
4302
- `var(--baro-ring-inset) 0 0 0 calc(${px} + var(--baro-ring-offset-width)) var(--baro-inset-ring-color, currentcolor)`
4303
- ],
4304
- ["--baro-ring-offset-shadow", `0 0 #0000`],
4305
- [
4306
- "box-shadow",
4307
- "var(--baro-inset-shadow, 0 0 #0000), var(--baro-inset-ring-shadow), var(--baro-ring-offset-shadow, 0 0 #0000), var(--baro-ring-shadow, 0 0 #0000), var(--baro-shadow, 0 0 #0000)"
4308
- ]
4309
- ]);
4690
+ // Tailwind 4.1.13: only the inset-ring layer; the colour defaults to currentcolor via the var() fallback.
4691
+ ringShadowProperties,
4692
+ ["--baro-inset-ring-shadow", `inset 0 0 0 ${px} var(--baro-inset-ring-color, currentcolor)`],
4693
+ ["box-shadow", SHADOW_COMPOSITE]
4694
+ ], { category: "effects" });
4310
4695
  });
4311
4696
  staticUtility("ring-inset", [["--baro-ring-inset", "inset"]], { category: "effects" });
4312
4697
  function createRingColorDecls(key, main, opacity2, realThemeValue) {
@@ -4380,7 +4765,15 @@ functionalUtility({
4380
4765
  decl("--baro-ring-color", fallback)
4381
4766
  ];
4382
4767
  }
4383
- return [decl("box-shadow", main)];
4768
+ if (!parseColor(main) && /^(-?(\d+\.?\d*|\.\d+)(px|rem|em|%|vw|vh|vmin|vmax|ch|ex|pt|cm|mm|in|pc)|0|(length:.+)|calc\(.+\))$/i.test(main)) {
4769
+ const width = main.startsWith("length:") ? main.slice(7) : main;
4770
+ return [
4771
+ ringShadowProperties(),
4772
+ decl("--baro-ring-shadow", ringShadowValue(width)),
4773
+ decl("box-shadow", SHADOW_COMPOSITE)
4774
+ ];
4775
+ }
4776
+ return [parseColor(main) ? decl("--baro-ring-color", main) : decl("box-shadow", main)];
4384
4777
  }
4385
4778
  if (main === "inherit" || main === "current" || main === "transparent") {
4386
4779
  return [
@@ -4622,18 +5015,30 @@ functionalUtility({
4622
5015
  description: "mask-size utility (static, arbitrary, custom property supported)",
4623
5016
  category: "effects"
4624
5017
  });
5018
+ const maskProperties = () => atRoot([
5019
+ property("--baro-mask-linear", "linear-gradient(#fff, #fff)"),
5020
+ property("--baro-mask-radial", "linear-gradient(#fff, #fff)"),
5021
+ property("--baro-mask-conic", "linear-gradient(#fff, #fff)"),
5022
+ property("--baro-mask-linear-position", "0deg"),
5023
+ property("--baro-mask-linear-from-position", "0%"),
5024
+ property("--baro-mask-linear-to-position", "100%"),
5025
+ property("--baro-mask-linear-from-color", "black"),
5026
+ property("--baro-mask-linear-to-color", "transparent")
5027
+ ]);
4625
5028
  functionalUtility({
4626
5029
  name: "mask-linear-from",
4627
5030
  handleBareValue: ({ value }) => /^(?:100|[1-9]?\d)%$/.test(value) ? value : null,
4628
5031
  handle: (value) => [
4629
- decl("mask-image", "var(--tw-mask-linear), var(--tw-mask-radial, linear-gradient(#fff, #fff)), var(--tw-mask-conic, linear-gradient(#fff, #fff))"),
5032
+ decl("mask-image", "var(--baro-mask-linear), var(--baro-mask-radial), var(--baro-mask-conic)"),
4630
5033
  decl("mask-composite", "intersect"),
4631
- decl("--tw-mask-linear-stops", "var(--tw-mask-linear-position, 0deg), var(--tw-mask-linear-from-color, black) var(--tw-mask-linear-from-position, 0%), var(--tw-mask-linear-to-color, transparent) var(--tw-mask-linear-to-position, 100%)"),
4632
- decl("--tw-mask-linear", "linear-gradient(var(--tw-mask-linear-stops))"),
4633
- decl("--tw-mask-linear-from-position", value)
5034
+ decl("--baro-mask-linear-stops", "var(--baro-mask-linear-position), var(--baro-mask-linear-from-color) var(--baro-mask-linear-from-position), var(--baro-mask-linear-to-color) var(--baro-mask-linear-to-position)"),
5035
+ decl("--baro-mask-linear", "linear-gradient(var(--baro-mask-linear-stops))"),
5036
+ decl("--baro-mask-linear-from-position", value),
5037
+ maskProperties()
4634
5038
  ],
4635
5039
  category: "effects"
4636
5040
  });
5041
+ staticUtility("mask-none", [["mask-image", "none"]], { category: "effects" });
4637
5042
  functionalUtility({
4638
5043
  name: "mask",
4639
5044
  supportsArbitrary: true,
@@ -4669,7 +5074,7 @@ functionalUtility({
4669
5074
  category: "layout"
4670
5075
  });
4671
5076
  staticUtility("aspect-square", [["aspect-ratio", "1 / 1"]], { category: "layout" });
4672
- staticUtility("aspect-video", [["aspect-ratio", "var(--aspect-ratio-video)"]], { category: "layout" });
5077
+ staticUtility("aspect-video", [["aspect-ratio", "var(--aspect-video)"]], { category: "layout" });
4673
5078
  staticUtility("aspect-auto", [["aspect-ratio", "auto"]], { category: "layout" });
4674
5079
  functionalUtility({
4675
5080
  name: "aspect",
@@ -4753,10 +5158,10 @@ staticUtility("sr-only", [
4753
5158
  ["position", "absolute"],
4754
5159
  ["width", "1px"],
4755
5160
  ["height", "1px"],
4756
- ["margin", "-1px"],
4757
5161
  ["padding", "0"],
5162
+ ["margin", "-1px"],
4758
5163
  ["overflow", "hidden"],
4759
- ["clip", "rect(0, 0, 0, 0)"],
5164
+ ["clip-path", "inset(50%)"],
4760
5165
  ["white-space", "nowrap"],
4761
5166
  ["border-width", "0"]
4762
5167
  ], { category: "layout" });
@@ -4764,12 +5169,39 @@ staticUtility("not-sr-only", [
4764
5169
  ["position", "static"],
4765
5170
  ["width", "auto"],
4766
5171
  ["height", "auto"],
4767
- ["margin", "0"],
4768
5172
  ["padding", "0"],
5173
+ ["margin", "0"],
4769
5174
  ["overflow", "visible"],
4770
- ["clip", "auto"],
5175
+ ["clip-path", "none"],
4771
5176
  ["white-space", "normal"]
4772
5177
  ], { category: "layout" });
5178
+ staticUtility("@container", [["container-type", "inline-size"]], { category: "layout" });
5179
+ staticUtility("@container-normal", [["container-type", "normal"]], { category: "layout" });
5180
+ registerUtility({
5181
+ name: "@container",
5182
+ match: (className) => /^@container\/[a-zA-Z0-9_-]+$/.test(className),
5183
+ handler: (_value, _ctx, token) => {
5184
+ const name = /^@container\/([a-zA-Z0-9_-]+)$/.exec(`${token.prefix}${token.value ? `-${token.value}` : ""}`)?.[1];
5185
+ return name ? [decl("container-type", "inline-size"), decl("container-name", name)] : null;
5186
+ },
5187
+ category: "layout"
5188
+ });
5189
+ const toRem = (v) => {
5190
+ const m = /^(-?\d*\.?\d+)(rem|px|em)$/.exec(v.trim());
5191
+ if (!m) return Number.NaN;
5192
+ return m[2] === "px" ? Number(m[1]) / 16 : Number(m[1]);
5193
+ };
5194
+ registerUtility({
5195
+ name: "container",
5196
+ match: (className) => className === "container",
5197
+ handler: (_value, ctx) => {
5198
+ const bps = ctx.theme("breakpoints") || ctx.config("theme.breakpoints") || {};
5199
+ const values = Object.values(bps).filter((v) => typeof v === "string" && !Number.isNaN(toRem(v)));
5200
+ values.sort((a, b) => toRem(a) - toRem(b));
5201
+ return [decl("width", "100%"), ...values.map((v) => atRule("media", `(width >= ${v})`, [decl("max-width", v)]))];
5202
+ },
5203
+ category: "layout"
5204
+ });
4773
5205
  staticUtility("float-right", [["float", "right"]], { category: "layout" });
4774
5206
  staticUtility("float-left", [["float", "left"]], { category: "layout" });
4775
5207
  staticUtility("float-start", [["float", "inline-start"]], { category: "layout" });
@@ -4850,6 +5282,7 @@ staticUtility("sticky", [["position", "sticky"]], { category: "layout" });
4850
5282
  staticUtility(`-${name}-px`, [[prop, "-1px"]], { category: "layout" });
4851
5283
  functionalUtility({
4852
5284
  name,
5285
+ spacingKeys: true,
4853
5286
  prop,
4854
5287
  supportsNegative: true,
4855
5288
  supportsFraction: true,
@@ -4880,12 +5313,13 @@ staticUtility("invisible", [["visibility", "hidden"]], { category: "layout" });
4880
5313
  staticUtility("collapse", [["visibility", "collapse"]], { category: "layout" });
4881
5314
  functionalUtility({
4882
5315
  name: "gap-x",
5316
+ spacingKeys: true,
4883
5317
  prop: "column-gap",
4884
5318
  supportsArbitrary: true,
4885
5319
  // gap-x-[10vw]
4886
5320
  supportsCustomProperty: true,
4887
5321
  // gap-x-(--my-gap-x)
4888
- handleBareValue: ({ value }) => `calc(var(--spacing) * ${value})`,
5322
+ handleBareValue: ({ value }) => parseNumber(value) ? `calc(var(--spacing) * ${value})` : null,
4889
5323
  handle: (value) => {
4890
5324
  if (typeof value === "string") return [decl("column-gap", value)];
4891
5325
  return null;
@@ -4896,12 +5330,13 @@ functionalUtility({
4896
5330
  });
4897
5331
  functionalUtility({
4898
5332
  name: "gap-y",
5333
+ spacingKeys: true,
4899
5334
  prop: "row-gap",
4900
5335
  supportsArbitrary: true,
4901
5336
  // gap-y-[10vw]
4902
5337
  supportsCustomProperty: true,
4903
5338
  // gap-y-(--my-gap-y)
4904
- handleBareValue: ({ value }) => `calc(var(--spacing) * ${value})`,
5339
+ handleBareValue: ({ value }) => parseNumber(value) ? `calc(var(--spacing) * ${value})` : null,
4905
5340
  handle: (value) => {
4906
5341
  if (typeof value === "string") return [decl("row-gap", value)];
4907
5342
  return null;
@@ -4912,12 +5347,13 @@ functionalUtility({
4912
5347
  });
4913
5348
  functionalUtility({
4914
5349
  name: "gap",
5350
+ spacingKeys: true,
4915
5351
  prop: "gap",
4916
5352
  supportsArbitrary: true,
4917
5353
  // gap-[10vw]
4918
5354
  supportsCustomProperty: true,
4919
5355
  // gap-(--my-gap)
4920
- handleBareValue: ({ value }) => `calc(var(--spacing) * ${value})`,
5356
+ handleBareValue: ({ value }) => parseNumber(value) ? `calc(var(--spacing) * ${value})` : null,
4921
5357
  handle: (value) => {
4922
5358
  if (typeof value === "string") return [decl("gap", value)];
4923
5359
  return null;
@@ -4976,6 +5412,31 @@ staticUtility("flex-nowrap", [["flex-wrap", "nowrap"]], { category: "flex-grid"
4976
5412
  staticUtility("flex-auto", [["flex", "1 1 auto"]], { category: "flex-grid" });
4977
5413
  staticUtility("flex-initial", [["flex", "0 1 auto"]], { category: "flex-grid" });
4978
5414
  staticUtility("flex-none", [["flex", "none"]], { category: "flex-grid" });
5415
+ staticUtility("flex-grow", [["flex-grow", "1"]], { category: "flex-grid" });
5416
+ functionalUtility({
5417
+ name: "flex-grow",
5418
+ prop: "flex-grow",
5419
+ supportsArbitrary: true,
5420
+ // grow-[25vw], grow-[2], grow-[var(--factor)], etc.
5421
+ supportsCustomProperty: true,
5422
+ // grow-(--my-grow)
5423
+ handleBareValue: ({ value }) => parseNumber(value),
5424
+ handle: (value) => [decl("flex-grow", value)],
5425
+ description: "flex-grow utility (number, arbitrary, custom property supported)",
5426
+ category: "flex-grid"
5427
+ });
5428
+ staticUtility("flex-shrink", [["flex-shrink", "1"]], { category: "flex-grid" });
5429
+ functionalUtility({
5430
+ name: "flex-shrink",
5431
+ prop: "flex-shrink",
5432
+ supportsArbitrary: true,
5433
+ // shrink-[2], shrink-[calc(100vw-var(--sidebar))], etc.
5434
+ supportsCustomProperty: true,
5435
+ // shrink-(--my-shrink)
5436
+ handleBareValue: ({ value }) => parseNumber(value),
5437
+ description: "flex-shrink utility (number, arbitrary, custom property supported)",
5438
+ category: "flex-grid"
5439
+ });
4979
5440
  functionalUtility({
4980
5441
  name: "flex",
4981
5442
  supportsArbitrary: true,
@@ -5209,7 +5670,7 @@ functionalUtility({
5209
5670
  // gap-x-[10vw]
5210
5671
  supportsCustomProperty: true,
5211
5672
  // gap-x-(--my-gap-x)
5212
- handleBareValue: ({ value }) => `calc(var(--spacing) * ${value})`,
5673
+ handleBareValue: ({ value }) => value === "px" ? "1px" : parseNumber(value) ? `calc(var(--spacing) * ${value})` : null,
5213
5674
  handle: (value) => {
5214
5675
  if (typeof value === "string") return [decl("column-gap", value)];
5215
5676
  return null;
@@ -5225,7 +5686,7 @@ functionalUtility({
5225
5686
  // gap-y-[10vw]
5226
5687
  supportsCustomProperty: true,
5227
5688
  // gap-y-(--my-gap-y)
5228
- handleBareValue: ({ value }) => `calc(var(--spacing) * ${value})`,
5689
+ handleBareValue: ({ value }) => value === "px" ? "1px" : parseNumber(value) ? `calc(var(--spacing) * ${value})` : null,
5229
5690
  handle: (value) => {
5230
5691
  if (typeof value === "string") return [decl("row-gap", value)];
5231
5692
  return null;
@@ -5241,7 +5702,7 @@ functionalUtility({
5241
5702
  // gap-[10vw]
5242
5703
  supportsCustomProperty: true,
5243
5704
  // gap-(--my-gap)
5244
- handleBareValue: ({ value }) => `calc(var(--spacing) * ${value})`,
5705
+ handleBareValue: ({ value }) => value === "px" ? "1px" : parseNumber(value) ? `calc(var(--spacing) * ${value})` : null,
5245
5706
  handle: (value) => {
5246
5707
  if (typeof value === "string") return [decl("gap", value)];
5247
5708
  return null;
@@ -5269,11 +5730,11 @@ staticUtility("justify-items-center-safe", [["justify-items", "safe center"]], {
5269
5730
  staticUtility("justify-items-stretch", [["justify-items", "stretch"]], { category: "flex-grid" });
5270
5731
  staticUtility("justify-items-normal", [["justify-items", "normal"]], { category: "flex-grid" });
5271
5732
  staticUtility("justify-self-auto", [["justify-self", "auto"]], { category: "flex-grid" });
5272
- staticUtility("justify-self-start", [["justify-self", "start"]], { category: "flex-grid" });
5733
+ staticUtility("justify-self-start", [["justify-self", "flex-start"]], { category: "flex-grid" });
5273
5734
  staticUtility("justify-self-center", [["justify-self", "center"]], { category: "flex-grid" });
5274
5735
  staticUtility("justify-self-center-safe", [["justify-self", "safe center"]], { category: "flex-grid" });
5275
- staticUtility("justify-self-end", [["justify-self", "end"]], { category: "flex-grid" });
5276
- staticUtility("justify-self-end-safe", [["justify-self", "safe end"]], { category: "flex-grid" });
5736
+ staticUtility("justify-self-end", [["justify-self", "flex-end"]], { category: "flex-grid" });
5737
+ staticUtility("justify-self-end-safe", [["justify-self", "safe flex-end"]], { category: "flex-grid" });
5277
5738
  staticUtility("justify-self-stretch", [["justify-self", "stretch"]], { category: "flex-grid" });
5278
5739
  staticUtility("content-normal", [["align-content", "normal"]], { category: "flex-grid" });
5279
5740
  staticUtility("content-center", [["align-content", "center"]], { category: "flex-grid" });
@@ -5404,11 +5865,12 @@ functionalUtility({
5404
5865
  ].forEach(([name, prop]) => {
5405
5866
  staticUtility(`${name}-px`, [[prop, "1px"]], { category: "spacing" });
5406
5867
  functionalUtility({
5868
+ spacingKeys: true,
5407
5869
  name,
5408
5870
  prop,
5409
5871
  supportsArbitrary: true,
5410
5872
  supportsCustomProperty: true,
5411
- handleBareValue: ({ value }) => `calc(var(--spacing) * ${value})`,
5873
+ handleBareValue: ({ value }) => parseNumber(value) ? `calc(var(--spacing) * ${value})` : null,
5412
5874
  description: `${name} utility (number, arbitrary, custom property supported)`,
5413
5875
  category: "spacing"
5414
5876
  });
@@ -5428,149 +5890,55 @@ functionalUtility({
5428
5890
  staticUtility(`${name}-px`, [[prop, "1px"]], { category: "spacing" });
5429
5891
  staticUtility(`-${name}-px`, [[prop, "-1px"]], { category: "spacing" });
5430
5892
  functionalUtility({
5893
+ spacingKeys: true,
5431
5894
  name,
5432
5895
  prop,
5433
5896
  supportsNegative: true,
5434
5897
  supportsArbitrary: true,
5435
5898
  supportsCustomProperty: true,
5436
- handleBareValue: ({ value }) => `calc(var(--spacing) * ${value})`,
5437
- handleNegativeBareValue: ({ value }) => `calc(var(--spacing) * -${value})`,
5899
+ handleBareValue: ({ value }) => parseNumber(value) ? `calc(var(--spacing) * ${value})` : null,
5900
+ handleNegativeBareValue: ({ value }) => parseNumber(value) ? `calc(var(--spacing) * -${value})` : null,
5438
5901
  description: `${name} margin utility (number, negative, arbitrary, custom property, auto, px supported)`,
5439
5902
  category: "spacing"
5440
5903
  });
5441
5904
  });
5442
- staticUtility("space-x-px", [
5443
- [
5444
- "& > :not([hidden]) ~ :not([hidden])",
5445
- [
5446
- ["--baro-space-x-reverse", "0"],
5447
- [
5448
- "margin-inline-start",
5449
- "calc(1px * calc(1 - var(--baro-space-x-reverse)))"
5450
- ],
5451
- ["margin-inline-end", "calc(1px * var(--baro-space-x-reverse))"]
5452
- ]
5453
- ]
5454
- ], { category: "spacing" });
5455
- staticUtility("-space-x-px", [
5456
- [
5457
- "& > :not([hidden]) ~ :not([hidden])",
5458
- [
5459
- ["--baro-space-x-reverse", "0"],
5460
- [
5461
- "margin-inline-start",
5462
- "calc(-1px * calc(1 - var(--baro-space-x-reverse)))"
5463
- ],
5464
- ["margin-inline-end", "calc(-1px * var(--baro-space-x-reverse))"]
5465
- ]
5466
- ]
5467
- ], { category: "spacing" });
5468
- staticUtility("space-x-reverse", [
5469
- ["& > :not([hidden]) ~ :not([hidden])", [["--baro-space-x-reverse", "1"]]]
5470
- ], { category: "spacing" });
5471
- functionalUtility({
5472
- name: "space-x",
5473
- supportsNegative: true,
5474
- supportsArbitrary: true,
5475
- supportsCustomProperty: true,
5476
- handleBareValue: ({ value }) => `calc(var(--spacing) * ${value})`,
5477
- handleNegativeBareValue: ({ value }) => `calc(var(--spacing) * -${value})`,
5478
- handle: (value, ctx, token) => {
5479
- let v = value;
5480
- if (typeof v === "number" || /^-?\d+(\.\d+)?$/.test(v)) {
5481
- v = `calc(var(--spacing) * ${token.negative ? "-" : ""}${v})`;
5482
- }
5483
- return [
5484
- rule("& > :not([hidden]) ~ :not([hidden])", [
5485
- decl("--baro-space-x-reverse", "0"),
5486
- decl(
5487
- "margin-inline-start",
5488
- `calc(${v} * calc(1 - var(--baro-space-x-reverse)))`
5489
- ),
5490
- decl("margin-inline-end", `calc(${v} * var(--baro-space-x-reverse))`)
5491
- ])
5492
- ];
5493
- },
5494
- handleCustomProperty: (value) => [
5495
- rule("& > :not([hidden]) ~ :not([hidden])", [
5496
- decl("--baro-space-x-reverse", "0"),
5497
- decl(
5498
- "margin-inline-start",
5499
- `calc(var(${value}) * calc(1 - var(--baro-space-x-reverse)))`
5500
- ),
5501
- decl(
5502
- "margin-inline-end",
5503
- `calc(var(${value}) * var(--baro-space-x-reverse))`
5504
- )
5505
- ])
5506
- ],
5507
- description: "space-x utility (number, negative, px, arbitrary, custom property, reverse supported)",
5508
- category: "spacing"
5509
- });
5510
- staticUtility("space-y-px", [
5511
- [
5512
- "& > :not([hidden]) ~ :not([hidden])",
5513
- [
5514
- ["--baro-space-y-reverse", "0"],
5515
- ["margin-block-start", "calc(1px * calc(1 - var(--baro-space-y-reverse)))"],
5516
- ["margin-block-end", "calc(1px * var(--baro-space-y-reverse))"]
5517
- ]
5518
- ]
5519
- ], { category: "spacing" });
5520
- staticUtility("-space-y-px", [
5521
- [
5522
- "& > :not([hidden]) ~ :not([hidden])",
5523
- [
5524
- ["--baro-space-y-reverse", "0"],
5525
- [
5526
- "margin-block-start",
5527
- "calc(-1px * calc(1 - var(--baro-space-y-reverse)))"
5528
- ],
5529
- ["margin-block-end", "calc(-1px * var(--baro-space-y-reverse))"]
5530
- ]
5531
- ]
5532
- ], { category: "spacing" });
5533
- staticUtility("space-y-reverse", [
5534
- ["& > :not([hidden]) ~ :not([hidden])", [["--baro-space-y-reverse", "1"]]]
5535
- ], { category: "spacing" });
5536
- functionalUtility({
5537
- name: "space-y",
5538
- supportsNegative: true,
5539
- supportsArbitrary: true,
5540
- supportsCustomProperty: true,
5541
- handleBareValue: ({ value }) => `calc(var(--spacing) * ${value})`,
5542
- handleNegativeBareValue: ({ value }) => `calc(var(--spacing) * -${value})`,
5543
- handle: (value, ctx, token) => {
5544
- let v = value;
5545
- if (typeof v === "number" || /^-?\d+(\.\d+)?$/.test(v)) {
5546
- v = `calc(var(--spacing) * ${token.negative ? "-" : ""}${v})`;
5547
- }
5548
- return [
5549
- rule("& > :not([hidden]) ~ :not([hidden])", [
5550
- decl("--baro-space-y-reverse", "0"),
5551
- decl(
5552
- "margin-block-start",
5553
- `calc(${v} * calc(1 - var(--baro-space-y-reverse)))`
5554
- ),
5555
- decl("margin-block-end", `calc(${v} * var(--baro-space-y-reverse))`)
5556
- ])
5557
- ];
5558
- },
5559
- handleCustomProperty: (value) => [
5560
- rule("& > :not([hidden]) ~ :not([hidden])", [
5561
- decl("--baro-space-y-reverse", "0"),
5562
- decl(
5563
- "margin-block-start",
5564
- `calc(var(${value}) * calc(1 - var(--baro-space-y-reverse)))`
5565
- ),
5566
- decl(
5567
- "margin-block-end",
5568
- `calc(var(${value}) * var(--baro-space-y-reverse))`
5569
- )
5570
- ])
5571
- ],
5572
- description: "space-y utility (number, negative, px, arbitrary, custom property, reverse supported)",
5573
- category: "spacing"
5905
+ const SPACE_SELECTOR = ":where(& > :not(:last-child))";
5906
+ ["x", "y"].forEach((axis) => {
5907
+ const name = `space-${axis}`;
5908
+ const rev = `--baro-space-${axis}-reverse`;
5909
+ const [start, end] = axis === "x" ? ["margin-inline-start", "margin-inline-end"] : ["margin-block-start", "margin-block-end"];
5910
+ const reverseProperty = () => atRoot([property(rev, "0")]);
5911
+ const spaceRule = (v) => rule(SPACE_SELECTOR, [
5912
+ decl(rev, "0"),
5913
+ decl(start, `calc(${v} * var(${rev}))`),
5914
+ decl(end, `calc(${v} * calc(1 - var(${rev})))`)
5915
+ ]);
5916
+ const body = (v) => [reverseProperty(), spaceRule(v)];
5917
+ staticUtility(`${name}-px`, [reverseProperty, () => spaceRule("1px")], { category: "spacing" });
5918
+ staticUtility(`-${name}-px`, [reverseProperty, () => spaceRule("-1px")], { category: "spacing" });
5919
+ staticUtility(`${name}-reverse`, [
5920
+ reverseProperty,
5921
+ () => rule(SPACE_SELECTOR, [decl(rev, "1")])
5922
+ ], { category: "spacing" });
5923
+ functionalUtility({
5924
+ spacingKeys: true,
5925
+ name,
5926
+ supportsNegative: true,
5927
+ supportsArbitrary: true,
5928
+ supportsCustomProperty: true,
5929
+ handleBareValue: ({ value }) => parseNumber(value) ? `calc(var(--spacing) * ${value})` : null,
5930
+ handleNegativeBareValue: ({ value }) => parseNumber(value) ? `calc(var(--spacing) * -${value})` : null,
5931
+ handle: (value, _ctx, token) => {
5932
+ let v = String(value);
5933
+ if (/^-?\d+(\.\d+)?$/.test(v)) {
5934
+ v = `calc(var(--spacing) * ${token.negative ? "-" : ""}${v})`;
5935
+ }
5936
+ return body(v);
5937
+ },
5938
+ handleCustomProperty: (value) => body(`var(${value})`),
5939
+ description: `${name} utility (number, negative, px, arbitrary, custom property, reverse supported)`,
5940
+ category: "spacing"
5941
+ });
5574
5942
  });
5575
5943
  [
5576
5944
  ["w-auto", "auto"],
@@ -5603,6 +5971,7 @@ functionalUtility({
5603
5971
  staticUtility(name, [["width", value]]);
5604
5972
  });
5605
5973
  functionalUtility({
5974
+ spacingKeys: true,
5606
5975
  name: "w",
5607
5976
  prop: "width",
5608
5977
  supportsArbitrary: true,
@@ -5635,6 +6004,7 @@ functionalUtility({
5635
6004
  staticUtility(name, [["width", w], ["height", h]]);
5636
6005
  });
5637
6006
  functionalUtility({
6007
+ spacingKeys: true,
5638
6008
  name: "size",
5639
6009
  supportsArbitrary: true,
5640
6010
  supportsCustomProperty: true,
@@ -5674,6 +6044,7 @@ functionalUtility({
5674
6044
  staticUtility(name, [["height", value]]);
5675
6045
  });
5676
6046
  functionalUtility({
6047
+ spacingKeys: true,
5677
6048
  name: "h",
5678
6049
  prop: "height",
5679
6050
  supportsArbitrary: true,
@@ -5704,6 +6075,7 @@ functionalUtility({
5704
6075
  staticUtility(name, [["min-height", value]], { category: "sizing" });
5705
6076
  });
5706
6077
  functionalUtility({
6078
+ spacingKeys: true,
5707
6079
  name: "min-h",
5708
6080
  prop: "min-height",
5709
6081
  supportsArbitrary: true,
@@ -5734,6 +6106,7 @@ functionalUtility({
5734
6106
  staticUtility(name, [["max-height", value]], { category: "sizing" });
5735
6107
  });
5736
6108
  functionalUtility({
6109
+ spacingKeys: true,
5737
6110
  name: "max-h",
5738
6111
  prop: "max-height",
5739
6112
  supportsArbitrary: true,
@@ -5780,6 +6153,7 @@ functionalUtility({
5780
6153
  staticUtility(name, [["min-width", value]], { category: "sizing" });
5781
6154
  });
5782
6155
  functionalUtility({
6156
+ spacingKeys: true,
5783
6157
  name: "min-w",
5784
6158
  prop: "min-width",
5785
6159
  supportsArbitrary: true,
@@ -5797,6 +6171,9 @@ functionalUtility({
5797
6171
  });
5798
6172
  [
5799
6173
  ["max-w-none", "none"],
6174
+ ["max-w-min", "min-content"],
6175
+ ["max-w-max", "max-content"],
6176
+ ["max-w-fit", "fit-content"],
5800
6177
  ["max-w-xs", "var(--container-xs)"],
5801
6178
  ["max-w-sm", "var(--container-sm)"],
5802
6179
  ["max-w-md", "var(--container-md)"],
@@ -5812,6 +6189,7 @@ functionalUtility({
5812
6189
  staticUtility(name, [["max-width", value]], { category: "sizing" });
5813
6190
  });
5814
6191
  functionalUtility({
6192
+ spacingKeys: true,
5815
6193
  name: "max-w",
5816
6194
  prop: "max-width",
5817
6195
  supportsArbitrary: true,
@@ -5827,22 +6205,23 @@ functionalUtility({
5827
6205
  description: "max-width utility (spacing, fraction, arbitrary, custom property, static supported)",
5828
6206
  category: "sizing"
5829
6207
  });
5830
- staticUtility("font-sans", [["font-family", "var(--font-family-sans)"]], { category: "typography" });
5831
- staticUtility("font-serif", [["font-family", "var(--font-family-serif)"]], { category: "typography" });
5832
- staticUtility("font-mono", [["font-family", "var(--font-family-mono)"]], { category: "typography" });
5833
- staticUtility("text-xs", [["font-size", "var(--text-xs)"], ["line-height", "var(--text-xs--line-height)"]], { category: "typography" });
5834
- staticUtility("text-sm", [["font-size", "var(--text-sm)"], ["line-height", "var(--text-sm--line-height)"]], { category: "typography" });
5835
- staticUtility("text-base", [["font-size", "var(--text-base)"], ["line-height", "var(--text-base--line-height)"]], { category: "typography" });
5836
- staticUtility("text-lg", [["font-size", "var(--text-lg)"], ["line-height", "var(--text-lg--line-height)"]], { category: "typography" });
5837
- staticUtility("text-xl", [["font-size", "var(--text-xl)"], ["line-height", "var(--text-xl--line-height)"]], { category: "typography" });
5838
- staticUtility("text-2xl", [["font-size", "var(--text-2xl)"], ["line-height", "var(--text-2xl--line-height)"]], { category: "typography" });
5839
- staticUtility("text-3xl", [["font-size", "var(--text-3xl)"], ["line-height", "var(--text-3xl--line-height)"]], { category: "typography" });
5840
- staticUtility("text-4xl", [["font-size", "var(--text-4xl)"], ["line-height", "var(--text-4xl--line-height)"]], { category: "typography" });
5841
- staticUtility("text-5xl", [["font-size", "var(--text-5xl)"], ["line-height", "var(--text-5xl--line-height)"]], { category: "typography" });
5842
- staticUtility("text-6xl", [["font-size", "var(--text-6xl)"], ["line-height", "var(--text-6xl--line-height)"]], { category: "typography" });
5843
- staticUtility("text-7xl", [["font-size", "var(--text-7xl)"], ["line-height", "var(--text-7xl--line-height)"]], { category: "typography" });
5844
- staticUtility("text-8xl", [["font-size", "var(--text-8xl)"], ["line-height", "var(--text-8xl--line-height)"]], { category: "typography" });
5845
- staticUtility("text-9xl", [["font-size", "var(--text-9xl)"], ["line-height", "var(--text-9xl--line-height)"]], { category: "typography" });
6208
+ const leadingProperty = () => atRoot([property("--baro-leading")]);
6209
+ staticUtility("font-sans", [["font-family", "var(--font-sans)"]], { category: "typography" });
6210
+ staticUtility("font-serif", [["font-family", "var(--font-serif)"]], { category: "typography" });
6211
+ staticUtility("font-mono", [["font-family", "var(--font-mono)"]], { category: "typography" });
6212
+ staticUtility("text-xs", [["font-size", "var(--text-xs)"], ["line-height", "var(--baro-leading, var(--text-xs--line-height))"]], { category: "typography" });
6213
+ staticUtility("text-sm", [["font-size", "var(--text-sm)"], ["line-height", "var(--baro-leading, var(--text-sm--line-height))"]], { category: "typography" });
6214
+ staticUtility("text-base", [["font-size", "var(--text-base)"], ["line-height", "var(--baro-leading, var(--text-base--line-height))"]], { category: "typography" });
6215
+ staticUtility("text-lg", [["font-size", "var(--text-lg)"], ["line-height", "var(--baro-leading, var(--text-lg--line-height))"]], { category: "typography" });
6216
+ staticUtility("text-xl", [["font-size", "var(--text-xl)"], ["line-height", "var(--baro-leading, var(--text-xl--line-height))"]], { category: "typography" });
6217
+ staticUtility("text-2xl", [["font-size", "var(--text-2xl)"], ["line-height", "var(--baro-leading, var(--text-2xl--line-height))"]], { category: "typography" });
6218
+ staticUtility("text-3xl", [["font-size", "var(--text-3xl)"], ["line-height", "var(--baro-leading, var(--text-3xl--line-height))"]], { category: "typography" });
6219
+ staticUtility("text-4xl", [["font-size", "var(--text-4xl)"], ["line-height", "var(--baro-leading, var(--text-4xl--line-height))"]], { category: "typography" });
6220
+ staticUtility("text-5xl", [["font-size", "var(--text-5xl)"], ["line-height", "var(--baro-leading, var(--text-5xl--line-height))"]], { category: "typography" });
6221
+ staticUtility("text-6xl", [["font-size", "var(--text-6xl)"], ["line-height", "var(--baro-leading, var(--text-6xl--line-height))"]], { category: "typography" });
6222
+ staticUtility("text-7xl", [["font-size", "var(--text-7xl)"], ["line-height", "var(--baro-leading, var(--text-7xl--line-height))"]], { category: "typography" });
6223
+ staticUtility("text-8xl", [["font-size", "var(--text-8xl)"], ["line-height", "var(--baro-leading, var(--text-8xl--line-height))"]], { category: "typography" });
6224
+ staticUtility("text-9xl", [["font-size", "var(--text-9xl)"], ["line-height", "var(--baro-leading, var(--text-9xl--line-height))"]], { category: "typography" });
5846
6225
  staticUtility("font-thin", [["font-weight", "var(--font-weight-thin)"]], { category: "typography" });
5847
6226
  staticUtility("font-extralight", [["font-weight", "var(--font-weight-extralight)"]], { category: "typography" });
5848
6227
  staticUtility("font-light", [["font-weight", "var(--font-weight-light)"]], { category: "typography" });
@@ -5888,12 +6267,12 @@ functionalUtility({
5888
6267
  description: "letter-spacing utility (theme, arbitrary, custom property supported)",
5889
6268
  category: "typography"
5890
6269
  });
5891
- staticUtility("leading-none", [["line-height", "var(--line-height-none)"]], { category: "typography" });
5892
- staticUtility("leading-tight", [["line-height", "var(--line-height-tight)"]], { category: "typography" });
5893
- staticUtility("leading-snug", [["line-height", "var(--line-height-snug)"]], { category: "typography" });
5894
- staticUtility("leading-normal", [["line-height", "var(--line-height-normal)"]], { category: "typography" });
5895
- staticUtility("leading-relaxed", [["line-height", "var(--line-height-relaxed)"]], { category: "typography" });
5896
- staticUtility("leading-loose", [["line-height", "var(--line-height-loose)"]], { category: "typography" });
6270
+ staticUtility("leading-none", [["--baro-leading", "var(--leading-none, 1)"], ["line-height", "var(--leading-none, 1)"], leadingProperty()], { category: "typography" });
6271
+ staticUtility("leading-tight", [["--baro-leading", "var(--leading-tight, 1.25)"], ["line-height", "var(--leading-tight, 1.25)"], leadingProperty()], { category: "typography" });
6272
+ staticUtility("leading-snug", [["--baro-leading", "var(--leading-snug, 1.375)"], ["line-height", "var(--leading-snug, 1.375)"], leadingProperty()], { category: "typography" });
6273
+ staticUtility("leading-normal", [["--baro-leading", "var(--leading-normal, 1.5)"], ["line-height", "var(--leading-normal, 1.5)"], leadingProperty()], { category: "typography" });
6274
+ staticUtility("leading-relaxed", [["--baro-leading", "var(--leading-relaxed, 1.625)"], ["line-height", "var(--leading-relaxed, 1.625)"], leadingProperty()], { category: "typography" });
6275
+ staticUtility("leading-loose", [["--baro-leading", "var(--leading-loose, 2)"], ["line-height", "var(--leading-loose, 2)"], leadingProperty()], { category: "typography" });
5897
6276
  functionalUtility({
5898
6277
  name: "leading",
5899
6278
  prop: "line-height",
@@ -5901,6 +6280,8 @@ functionalUtility({
5901
6280
  supportsArbitrary: true,
5902
6281
  supportsCustomProperty: true,
5903
6282
  handleBareValue: ({ value }) => parseNumber(value),
6283
+ handle: (value) => [decl("--baro-leading", value), decl("line-height", value), leadingProperty()],
6284
+ handleCustomProperty: (value) => [decl("--baro-leading", `var(${value})`), decl("line-height", `var(${value})`), leadingProperty()],
5904
6285
  description: "line-height utility (theme, number, arbitrary, custom property supported)",
5905
6286
  category: "typography"
5906
6287
  });
@@ -5910,6 +6291,17 @@ staticUtility("text-right", [["text-align", "right"]], { category: "typography"
5910
6291
  staticUtility("text-justify", [["text-align", "justify"]], { category: "typography" });
5911
6292
  staticUtility("text-start", [["text-align", "start"]], { category: "typography" });
5912
6293
  staticUtility("text-end", [["text-align", "end"]], { category: "typography" });
6294
+ const FONT_SIZE_HINTS = /* @__PURE__ */ new Set(["length", "size", "percentage", "absolute-size", "relative-size"]);
6295
+ const FONT_SIZE_KEYWORDS = /^(xx-small|x-small|small|medium|large|x-large|xx-large|xxx-large|larger|smaller)$/;
6296
+ const LENGTH_RE = /^-?(\d+\.?\d*|\.\d+)(px|r?em|r?lh|r?cap|r?ch|r?ex|r?ic|%|vh|vw|vmin|vmax|[sdl]v[hwib]|v[ib]|cq[whib]|cqmin|cqmax|pt|pc|in|cm|mm|q)$/i;
6297
+ function textArbitraryKind(raw) {
6298
+ const hint = /^([a-z-]+):(.+)$/.exec(raw);
6299
+ if (hint && (hint[1] === "color" || FONT_SIZE_HINTS.has(hint[1]))) {
6300
+ return { fontSize: hint[1] !== "color", value: hint[2] };
6301
+ }
6302
+ const fontSize2 = raw === "0" || LENGTH_RE.test(raw) || FONT_SIZE_KEYWORDS.test(raw) || /^(calc|min|max|clamp)\(/.test(raw);
6303
+ return { fontSize: fontSize2, value: raw };
6304
+ }
5913
6305
  staticUtility("text-inherit", [["color", "inherit"]], { category: "typography" });
5914
6306
  staticUtility("text-current", [["color", "currentColor"]], { category: "typography" });
5915
6307
  staticUtility("text-transparent", [["color", "transparent"]], { category: "typography" });
@@ -5923,27 +6315,14 @@ functionalUtility({
5923
6315
  supportsCustomProperty: true,
5924
6316
  supportsOpacity: true,
5925
6317
  handle: (value, ctx, token, extra) => {
5926
- if (extra?.realThemeValue) {
5927
- if (extra.opacity) {
5928
- return [
5929
- atRule("supports", `(color:color-mix(in lab, red, red))`, [
5930
- decl("color", `color-mix(in lab, ${value} ${extra.opacity}%, transparent)`)
5931
- ]),
5932
- decl("color", `color-mix(in lab, ${value} ${extra.opacity}%, transparent)`)
5933
- ];
5934
- }
5935
- return [decl("color", value)];
5936
- }
5937
- if (parseLength(value)) {
5938
- return [decl("font-size", value)];
5939
- }
5940
- return [decl("color", value)];
6318
+ if (extra?.realThemeValue) return themeColorDecls("color", value, extra);
6319
+ const kind = textArbitraryKind(value);
6320
+ return [decl(kind.fontSize ? "font-size" : "color", kind.value)];
5941
6321
  },
6322
+ // Tailwind 4: text-(--x) is a colour; text-(length:--x) is a font-size.
5942
6323
  handleCustomProperty: (value) => {
5943
- if (value.startsWith("color:")) {
5944
- return [decl("color", `var(${value.replace("color:", "")})`)];
5945
- }
5946
- return [decl("font-size", `var(${value})`)];
6324
+ const kind = textArbitraryKind(value);
6325
+ return [decl(kind.fontSize ? "font-size" : "color", `var(${kind.value})`)];
5947
6326
  },
5948
6327
  description: "text color utility (theme, arbitrary, custom property supported)",
5949
6328
  category: "typography"
@@ -5959,7 +6338,7 @@ functionalUtility({
5959
6338
  if (Array.isArray(themeValue)) {
5960
6339
  return [
5961
6340
  decl("font-size", themeValue[0]),
5962
- decl("line-height", themeValue[1])
6341
+ decl("line-height", `var(--baro-leading, ${themeValue[1]})`)
5963
6342
  ];
5964
6343
  } else {
5965
6344
  return [decl("font-size", themeValue)];
@@ -6073,17 +6452,7 @@ functionalUtility({
6073
6452
  supportsCustomProperty: true,
6074
6453
  supportsOpacity: true,
6075
6454
  handle: (value, ctx, token, extra) => {
6076
- if (extra?.realThemeValue) {
6077
- if (extra.opacity) {
6078
- return [
6079
- atRule("supports", `(color:color-mix(in lab, red, red))`, [
6080
- decl("text-decoration-color", `color-mix(in lab, ${value} ${extra.opacity}%, transparent)`)
6081
- ]),
6082
- decl("text-decoration-color", value)
6083
- ];
6084
- }
6085
- return [decl("text-decoration-color", value)];
6086
- }
6455
+ if (extra?.realThemeValue) return themeColorDecls("text-decoration-color", value, extra);
6087
6456
  return [decl("text-decoration-color", value)];
6088
6457
  },
6089
6458
  handleCustomProperty: (value) => [decl("text-decoration-color", `var(${value})`)],
@@ -6107,7 +6476,7 @@ functionalUtility({
6107
6476
  prop: "text-decoration-thickness",
6108
6477
  supportsArbitrary: true,
6109
6478
  supportsCustomProperty: true,
6110
- handleBareValue: ({ value }) => `${value}px`,
6479
+ handleBareValue: ({ value }) => parseNumber(value) ? `${value}px` : null,
6111
6480
  description: "text-decoration-thickness utility (arbitrary, custom property supported)",
6112
6481
  category: "typography"
6113
6482
  });
@@ -6122,7 +6491,7 @@ functionalUtility({
6122
6491
  prop: "text-underline-offset",
6123
6492
  supportsArbitrary: true,
6124
6493
  supportsCustomProperty: true,
6125
- handleBareValue: ({ value }) => `${value}px`,
6494
+ handleBareValue: ({ value }) => parseNumber(value) ? `${value}px` : null,
6126
6495
  description: "text-underline-offset utility (arbitrary, custom property supported)",
6127
6496
  category: "typography"
6128
6497
  });
@@ -6136,8 +6505,8 @@ functionalUtility({
6136
6505
  supportsNegative: true,
6137
6506
  supportsArbitrary: true,
6138
6507
  supportsCustomProperty: true,
6139
- handleBareValue: ({ value }) => `calc(var(--spacing) * ${value})`,
6140
- handleNegativeBareValue: ({ value }) => `calc(var(--spacing) * -${value})`,
6508
+ handleBareValue: ({ value }) => parseNumber(value) ? `calc(var(--spacing) * ${value})` : null,
6509
+ handleNegativeBareValue: ({ value }) => parseNumber(value) ? `calc(var(--spacing) * -${value})` : null,
6141
6510
  description: "text-indent utility (spacing, negative, arbitrary, custom property supported)",
6142
6511
  category: "typography"
6143
6512
  });
@@ -6160,14 +6529,14 @@ functionalUtility({
6160
6529
  staticUtility("hyphens-none", [["hyphens", "none"]], { category: "typography" });
6161
6530
  staticUtility("hyphens-manual", [["hyphens", "manual"]], { category: "typography" });
6162
6531
  staticUtility("hyphens-auto", [["hyphens", "auto"]], { category: "typography" });
6163
- staticUtility("content-none", [["content", "none"]], { category: "typography" });
6532
+ staticUtility("content-none", [["--baro-content", "none"], ["content", "none"]], { category: "typography" });
6164
6533
  functionalUtility({
6165
6534
  name: "content",
6166
6535
  prop: "content",
6167
6536
  supportsArbitrary: true,
6168
6537
  supportsCustomProperty: true,
6169
- handle: (value) => [decl("content", `"${value}"`)],
6170
- handleCustomProperty: (value) => [decl("content", `var(${value})`)],
6538
+ handle: (value) => [decl("--baro-content", `"${value}"`), decl("content", "var(--baro-content)")],
6539
+ handleCustomProperty: (value) => [decl("--baro-content", `var(${value})`), decl("content", "var(--baro-content)")],
6171
6540
  description: "content utility (arbitrary, custom property supported)",
6172
6541
  category: "typography"
6173
6542
  });
@@ -6177,7 +6546,8 @@ const gradientStopProperties = () => {
6177
6546
  property("--baro-gradient-from", "#0000", "<color>"),
6178
6547
  property("--baro-gradient-via", "#0000", "<color>"),
6179
6548
  property("--baro-gradient-to", "#0000", "<color>"),
6180
- property("--baro-gradient-stops", "transparent"),
6549
+ property("--baro-gradient-stops"),
6550
+ property("--baro-gradient-via-stops"),
6181
6551
  property("--baro-gradient-from-position", "0%", "<length-percentage>"),
6182
6552
  property("--baro-gradient-via-position", "50%", "<length-percentage>"),
6183
6553
  property("--baro-gradient-to-position", "100%", "<length-percentage>")
@@ -6235,18 +6605,17 @@ functionalUtility({
6235
6605
  description: "background-size utility (arbitrary, custom property supported)",
6236
6606
  category: "background"
6237
6607
  });
6238
- const positionValue = (position) => {
6239
- return [
6240
- decl("--baro-gradient-position", position),
6241
- styleRule("@supports (background-image: linear-gradient(in lab, red, red))", [
6242
- decl("--baro-gradient-position", `${position} in oklab`)
6243
- ]),
6244
- decl(
6245
- "background-image",
6246
- `linear-gradient(${position}, var(--baro-gradient-stops))`
6247
- )
6248
- ];
6249
- };
6608
+ const positionValue = (position) => [
6609
+ decl("--baro-gradient-position", position),
6610
+ atRule("supports", "(background-image: linear-gradient(in lab, red, red))", [
6611
+ decl("--baro-gradient-position", `${position} in oklab`)
6612
+ ]),
6613
+ decl("background-image", "linear-gradient(var(--baro-gradient-stops))")
6614
+ ];
6615
+ const legacyPositionValue = (position) => [
6616
+ decl("--baro-gradient-position", `${position} in oklab`),
6617
+ decl("background-image", "linear-gradient(var(--baro-gradient-stops))")
6618
+ ];
6250
6619
  [
6251
6620
  ["bg-linear-to-t", positionValue("to top")],
6252
6621
  ["bg-linear-to-tr", positionValue("to top right")],
@@ -6257,14 +6626,14 @@ const positionValue = (position) => {
6257
6626
  ["bg-linear-to-l", positionValue("to left")],
6258
6627
  ["bg-linear-to-tl", positionValue("to top left")],
6259
6628
  // fallback , legacy CSS compatibility
6260
- ["bg-gradient-to-t", positionValue("to top")],
6261
- ["bg-gradient-to-tr", positionValue("to top right")],
6262
- ["bg-gradient-to-r", positionValue("to right")],
6263
- ["bg-gradient-to-br", positionValue("to bottom right")],
6264
- ["bg-gradient-to-b", positionValue("to bottom")],
6265
- ["bg-gradient-to-bl", positionValue("to bottom left")],
6266
- ["bg-gradient-to-l", positionValue("to left")],
6267
- ["bg-gradient-to-tl", positionValue("to top left")]
6629
+ ["bg-gradient-to-t", legacyPositionValue("to top")],
6630
+ ["bg-gradient-to-tr", legacyPositionValue("to top right")],
6631
+ ["bg-gradient-to-r", legacyPositionValue("to right")],
6632
+ ["bg-gradient-to-br", legacyPositionValue("to bottom right")],
6633
+ ["bg-gradient-to-b", legacyPositionValue("to bottom")],
6634
+ ["bg-gradient-to-bl", legacyPositionValue("to bottom left")],
6635
+ ["bg-gradient-to-l", legacyPositionValue("to left")],
6636
+ ["bg-gradient-to-tl", legacyPositionValue("to top left")]
6268
6637
  ].forEach(([name, value]) => {
6269
6638
  staticUtility(name, value, { category: "background", priority: 1e3 });
6270
6639
  });
@@ -6275,12 +6644,7 @@ functionalUtility({
6275
6644
  supportsCustomProperty: true,
6276
6645
  handle: (value, context, token) => {
6277
6646
  if (parseNumber(value)) {
6278
- return [
6279
- decl(
6280
- "background-image",
6281
- `linear-gradient(${value}deg in oklab, var(--baro-gradient-stops))`
6282
- )
6283
- ];
6647
+ return positionValue(`${value}deg`);
6284
6648
  }
6285
6649
  if (token.arbitrary) {
6286
6650
  return [
@@ -6309,152 +6673,79 @@ functionalUtility({
6309
6673
  description: "linear-gradient background-image utility (angle, arbitrary, custom property supported)",
6310
6674
  category: "background"
6311
6675
  });
6312
- staticUtility("bg-radial", [
6313
- ["background-image", "radial-gradient(in oklab, var(--baro-gradient-stops))"]
6314
- ], { category: "background" });
6676
+ const gradientImage = (fn, position, fallback) => [
6677
+ decl("--baro-gradient-position", position),
6678
+ decl("background-image", `${fn}(var(--baro-gradient-stops${fallback ? `,${fallback}` : ""}))`)
6679
+ ];
6680
+ staticUtility("bg-radial", gradientImage("radial-gradient", "in oklab"), { category: "background" });
6315
6681
  functionalUtility({
6316
6682
  name: "bg-radial",
6317
6683
  prop: "background-image",
6318
6684
  supportsArbitrary: true,
6319
6685
  supportsCustomProperty: true,
6320
- handle: (value, context, token) => {
6321
- if (token.arbitrary) {
6322
- return [
6323
- decl(
6324
- "background-image",
6325
- `radial-gradient(var(--baro-gradient-stops, ${value}))`
6326
- )
6327
- ];
6328
- }
6329
- if (token.customProperty) {
6330
- return [
6331
- decl(
6332
- "background-image",
6333
- `radial-gradient(var(--baro-gradient-stops, var(${value})))`
6334
- )
6335
- ];
6336
- }
6686
+ handle: (value, _context, token) => {
6687
+ if (token.arbitrary) return gradientImage("radial-gradient", value, value);
6688
+ if (token.customProperty) return gradientImage("radial-gradient", `var(${value})`, `var(${value})`);
6337
6689
  return null;
6338
6690
  },
6339
- handleCustomProperty: (value) => [
6340
- decl(
6341
- "background-image",
6342
- `radial-gradient(var(--baro-gradient-stops, var(${value})))`
6343
- )
6344
- ],
6691
+ handleCustomProperty: (value) => gradientImage("radial-gradient", `var(${value})`, `var(${value})`),
6345
6692
  description: "radial-gradient background-image utility (arbitrary, custom property supported)",
6346
6693
  category: "background"
6347
6694
  });
6348
- staticUtility("bg-conic", [
6349
- [
6350
- "background-image",
6351
- "conic-gradient(from 0deg in oklab, var(--baro-gradient-stops))"
6352
- ]
6353
- ], { category: "background" });
6695
+ staticUtility("bg-conic", gradientImage("conic-gradient", "in oklab"), { category: "background" });
6354
6696
  functionalUtility({
6355
6697
  name: "bg-conic",
6356
6698
  prop: "background-image",
6357
6699
  supportsArbitrary: true,
6358
6700
  supportsCustomProperty: true,
6359
- handle: (value, context, token) => {
6360
- if (parseNumber(value)) {
6361
- return [
6362
- decl(
6363
- "background-image",
6364
- `conic-gradient(from ${value}deg in oklab, var(--baro-gradient-stops))`
6365
- )
6366
- ];
6367
- }
6368
- if (token.arbitrary) {
6369
- return [decl("background-image", `${value}`)];
6370
- }
6371
- if (token.customProperty) {
6372
- return [
6373
- decl(
6374
- "background-image",
6375
- `conic-gradient(var(--baro-gradient-stops, var(${value})))`
6376
- )
6377
- ];
6701
+ handle: (value, _context, token) => {
6702
+ if (!token.arbitrary && !token.customProperty && parseNumber(value)) {
6703
+ return gradientImage("conic-gradient", `from ${value}deg in oklab`);
6378
6704
  }
6705
+ if (token.arbitrary) return gradientImage("conic-gradient", value, value);
6706
+ if (token.customProperty) return gradientImage("conic-gradient", `var(${value})`, `var(${value})`);
6379
6707
  return null;
6380
6708
  },
6381
- handleCustomProperty: (value) => [decl("background-image", `var(${value})`)],
6709
+ handleCustomProperty: (value) => gradientImage("conic-gradient", `var(${value})`, `var(${value})`),
6382
6710
  description: "conic-gradient background-image utility (angle, arbitrary, custom property supported)",
6383
6711
  category: "background"
6384
6712
  });
6713
+ const G = "--baro-gradient";
6714
+ const stopsDecls = (stop, color) => {
6715
+ const colorDecls = typeof color === "string" ? [decl(`${G}-${stop}`, color)] : color;
6716
+ if (stop === "via") {
6717
+ return [
6718
+ gradientStopProperties(),
6719
+ ...colorDecls,
6720
+ decl(`${G}-via-stops`, `var(${G}-position), var(${G}-from) var(${G}-from-position), var(${G}-via) var(${G}-via-position), var(${G}-to) var(${G}-to-position)`),
6721
+ decl(`${G}-stops`, `var(${G}-via-stops)`)
6722
+ ];
6723
+ }
6724
+ return [
6725
+ gradientStopProperties(),
6726
+ ...colorDecls,
6727
+ decl(`${G}-stops`, `var(${G}-via-stops, var(${G}-position), var(${G}-from) var(${G}-from-position), var(${G}-to) var(${G}-to-position))`)
6728
+ ];
6729
+ };
6385
6730
  ["from", "via", "to"].forEach((stop) => {
6386
6731
  functionalUtility({
6387
6732
  name: stop,
6388
6733
  themeKeys: ["colors"],
6389
6734
  supportsArbitrary: true,
6390
- supportsCustomProperty: true,
6391
- supportsOpacity: true,
6392
- handle: (value, context, token, extra) => {
6393
- if (extra?.realThemeValue) {
6394
- if (stop === "from") {
6395
- let color = value;
6396
- if (extra?.opacity) {
6397
- color = `color-mix(in lab, ${value} ${extra.opacity}%, transparent)`;
6398
- }
6399
- return [
6400
- gradientStopProperties(),
6401
- decl(`--baro-gradient-from`, color),
6402
- // decl(`--baro-gradient-to`, "var(--baro-gradient-to, transparent)"),
6403
- decl(`--baro-gradient-stops`, "var(--baro-gradient-from),var(--baro-gradient-to)")
6404
- ];
6405
- }
6406
- if (stop === "via") {
6407
- let color = value;
6408
- if (extra?.opacity) {
6409
- color = `color-mix(in lab, ${value} ${extra.opacity}%, transparent)`;
6410
- }
6411
- return [
6412
- gradientStopProperties(),
6413
- decl(`--baro-gradient-to`, color),
6414
- decl(`--baro-gradient-stops`, `var(--baro-gradient-from), ${value} var(--baro-gradient-via-position), var(--baro-gradient-to)`)
6415
- // via 포함 stops
6416
- ];
6417
- }
6418
- if (stop === "to") {
6419
- let color = value;
6420
- if (extra?.opacity) {
6421
- color = `color-mix(in lab, ${value} ${extra.opacity}%, transparent)`;
6422
- }
6423
- return [
6424
- gradientStopProperties(),
6425
- decl(`--baro-gradient-to`, color)
6426
- ];
6427
- }
6735
+ supportsCustomProperty: true,
6736
+ supportsOpacity: true,
6737
+ handle: (value, _context, _token, extra) => {
6738
+ if (extra?.realThemeValue) {
6739
+ return stopsDecls(stop, themeColorDecls(`${G}-${stop}`, value, extra));
6428
6740
  }
6429
6741
  if (parseLength(value)) {
6430
- return [decl(`--baro-gradient-${stop}-position`, value)];
6742
+ return [gradientStopProperties(), decl(`${G}-${stop}-position`, value)];
6431
6743
  }
6432
6744
  if (parseNumber(value)) {
6433
- return [decl(`--baro-gradient-${stop}-position`, `${value}%`)];
6745
+ return [gradientStopProperties(), decl(`${G}-${stop}-position`, `${value}%`)];
6434
6746
  }
6435
6747
  if (parseColor(value)) {
6436
- if (stop === "from") {
6437
- return [
6438
- gradientStopProperties(),
6439
- decl(`--baro-gradient-from`, value),
6440
- decl(`--baro-gradient-to`, "transparent"),
6441
- decl(`--baro-gradient-stops`, "var(--baro-gradient-from),var(--baro-gradient-to)")
6442
- ];
6443
- }
6444
- if (stop === "via") {
6445
- return [
6446
- gradientStopProperties(),
6447
- decl(`--baro-gradient-to`, value),
6448
- decl(`--baro-gradient-stops`, `var(--baro-gradient-from), ${value} var(--baro-gradient-via-position), var(--baro-gradient-to)`)
6449
- // via 포함 stops
6450
- ];
6451
- }
6452
- if (stop === "to") {
6453
- return [
6454
- gradientStopProperties(),
6455
- decl(`--baro-gradient-to`, value)
6456
- ];
6457
- }
6748
+ return stopsDecls(stop, value);
6458
6749
  }
6459
6750
  return null;
6460
6751
  },
@@ -6489,20 +6780,7 @@ functionalUtility({
6489
6780
  if (value.startsWith("length:")) {
6490
6781
  return [decl("background-size", value.replace("length:", ""))];
6491
6782
  }
6492
- if (extra?.realThemeValue) {
6493
- if (extra.opacity) {
6494
- return [
6495
- atRule("supports", `(color:color-mix(in lab, red, red))`, [
6496
- decl(
6497
- "background-color",
6498
- `color-mix(in lab, ${value} ${extra.opacity}%, transparent)`
6499
- )
6500
- ]),
6501
- decl("background-color", `color-mix(in lab, ${value} ${extra.opacity}%, transparent)`)
6502
- ];
6503
- }
6504
- return [decl("background-color", value)];
6505
- }
6783
+ if (extra?.realThemeValue) return themeColorDecls("background-color", value, extra);
6506
6784
  if (parseColor(value)) {
6507
6785
  const parsedColor = parseColor(value);
6508
6786
  if (value.startsWith("color:")) {
@@ -6515,18 +6793,20 @@ functionalUtility({
6515
6793
  }
6516
6794
  return null;
6517
6795
  },
6518
- handleCustomProperty: (value) => [decl("background-size", `var(${value})`)],
6796
+ handleCustomProperty: (value) => value.startsWith("length:") ? [decl("background-size", `var(${value.slice(7)})`)] : [decl("background-color", `var(${value})`)],
6519
6797
  description: "background-size utility (arbitrary, custom property supported)",
6520
6798
  category: "background"
6521
6799
  });
6522
6800
  staticUtility("rounded-none", [["border-radius", "0px"]], { category: "borders" });
6523
6801
  staticUtility("rounded-sm", [["border-radius", "var(--radius-sm)"]], { category: "borders" });
6524
- staticUtility("rounded", [["border-radius", "var(--radius)"]], { category: "borders" });
6802
+ staticUtility("rounded", [["border-radius", "0.25rem"]], { category: "borders" });
6525
6803
  staticUtility("rounded-md", [["border-radius", "var(--radius-md)"]], { category: "borders" });
6526
6804
  staticUtility("rounded-lg", [["border-radius", "var(--radius-lg)"]], { category: "borders" });
6527
6805
  staticUtility("rounded-xl", [["border-radius", "var(--radius-xl)"]], { category: "borders" });
6528
6806
  staticUtility("rounded-2xl", [["border-radius", "var(--radius-2xl)"]], { category: "borders" });
6529
6807
  staticUtility("rounded-3xl", [["border-radius", "var(--radius-3xl)"]], { category: "borders" });
6808
+ staticUtility("rounded-4xl", [["border-radius", "var(--radius-4xl)"]], { category: "borders" });
6809
+ staticUtility("rounded-xs", [["border-radius", "var(--radius-xs)"]], { category: "borders" });
6530
6810
  staticUtility("rounded-full", [["border-radius", "9999px"]], { category: "borders" });
6531
6811
  [
6532
6812
  ["rounded-t", ["border-top-left-radius", "border-top-right-radius"]],
@@ -6541,12 +6821,14 @@ staticUtility("rounded-full", [["border-radius", "9999px"]], { category: "border
6541
6821
  const propList = props;
6542
6822
  staticUtility(`${name}-none`, propList.map((prop) => [prop, "0px"]), { category: "borders" });
6543
6823
  staticUtility(`${name}-sm`, propList.map((prop) => [prop, "var(--radius-sm)"]), { category: "borders" });
6544
- staticUtility(`${name}`, propList.map((prop) => [prop, "var(--radius)"]), { category: "borders" });
6824
+ staticUtility(`${name}`, propList.map((prop) => [prop, "0.25rem"]), { category: "borders" });
6545
6825
  staticUtility(`${name}-md`, propList.map((prop) => [prop, "var(--radius-md)"]), { category: "borders" });
6546
6826
  staticUtility(`${name}-lg`, propList.map((prop) => [prop, "var(--radius-lg)"]), { category: "borders" });
6547
6827
  staticUtility(`${name}-xl`, propList.map((prop) => [prop, "var(--radius-xl)"]), { category: "borders" });
6548
6828
  staticUtility(`${name}-2xl`, propList.map((prop) => [prop, "var(--radius-2xl)"]), { category: "borders" });
6549
6829
  staticUtility(`${name}-3xl`, propList.map((prop) => [prop, "var(--radius-3xl)"]), { category: "borders" });
6830
+ staticUtility(`${name}-4xl`, propList.map((prop) => [prop, "var(--radius-4xl)"]), { category: "borders" });
6831
+ staticUtility(`${name}-xs`, propList.map((prop) => [prop, "var(--radius-xs)"]), { category: "borders" });
6550
6832
  staticUtility(`${name}-full`, propList.map((prop) => [prop, "9999px"]), { category: "borders" });
6551
6833
  functionalUtility({
6552
6834
  name,
@@ -6577,11 +6859,15 @@ functionalUtility({
6577
6859
  description: "border-radius utility (spacing, arbitrary, custom property support)",
6578
6860
  category: "borders"
6579
6861
  });
6580
- staticUtility("border-0", [["border-width", "0px"]], { category: "borders" });
6581
- staticUtility("border-2", [["border-width", "2px"]], { category: "borders" });
6582
- staticUtility("border-4", [["border-width", "4px"]], { category: "borders" });
6583
- staticUtility("border-8", [["border-width", "8px"]], { category: "borders" });
6584
- staticUtility("border", [["border-width", "1px"]], { category: "borders" });
6862
+ const borderStyleProperty = () => atRoot([property("--baro-border-style", "solid")]);
6863
+ const withBorderStyle = (props, width) => [
6864
+ borderStyleProperty(),
6865
+ ...props.map((prop) => decl(prop.replace("width", "style"), "var(--baro-border-style)")),
6866
+ ...props.map((prop) => decl(prop, width))
6867
+ ];
6868
+ [["border-0", "0px"], ["border-2", "2px"], ["border-4", "4px"], ["border-8", "8px"], ["border", "1px"]].forEach(([name, width]) => {
6869
+ staticUtility(name, [borderStyleProperty, ["border-style", "var(--baro-border-style)"], ["border-width", width]], { category: "borders" });
6870
+ });
6585
6871
  [
6586
6872
  ["border-x", ["border-left-width", "border-right-width"]],
6587
6873
  ["border-y", ["border-top-width", "border-bottom-width"]],
@@ -6591,11 +6877,16 @@ staticUtility("border", [["border-width", "1px"]], { category: "borders" });
6591
6877
  ["border-l", ["border-left-width"]]
6592
6878
  ].forEach(([name, props]) => {
6593
6879
  const propList = props;
6594
- staticUtility(`${name}-0`, propList.map((prop) => [prop, "0px"]));
6595
- staticUtility(`${name}-2`, propList.map((prop) => [prop, "2px"]));
6596
- staticUtility(`${name}-4`, propList.map((prop) => [prop, "4px"]));
6597
- staticUtility(`${name}-8`, propList.map((prop) => [prop, "8px"]));
6598
- staticUtility(`${name}`, propList.map((prop) => [prop, "1px"]));
6880
+ const styled = (width) => [
6881
+ borderStyleProperty,
6882
+ ...propList.map((prop) => [prop.replace("width", "style"), "var(--baro-border-style)"]),
6883
+ ...propList.map((prop) => [prop, width])
6884
+ ];
6885
+ staticUtility(`${name}-0`, styled("0px"));
6886
+ staticUtility(`${name}-2`, styled("2px"));
6887
+ staticUtility(`${name}-4`, styled("4px"));
6888
+ staticUtility(`${name}-8`, styled("8px"));
6889
+ staticUtility(`${name}`, styled("1px"));
6599
6890
  functionalUtility({
6600
6891
  name,
6601
6892
  themeKeys: ["borderWidth", "colors"],
@@ -6607,18 +6898,19 @@ staticUtility("border", [["border-width", "1px"]], { category: "borders" });
6607
6898
  }
6608
6899
  return null;
6609
6900
  },
6610
- handle: (value, ctx, token) => {
6901
+ handle: (value, ctx, token, extra) => {
6902
+ if (extra?.realThemeValue) return propList.flatMap((prop) => themeColorDecls(prop.replace("width", "color"), value, extra));
6611
6903
  if (parseColor(value)) {
6612
6904
  return propList.map((prop) => decl(prop.replace("width", "color"), value));
6613
6905
  }
6614
6906
  if (token.arbitrary) {
6615
- return propList.map((prop) => decl(prop, value));
6907
+ return withBorderStyle(propList, value);
6616
6908
  }
6617
6909
  return null;
6618
6910
  },
6619
6911
  handleCustomProperty: (value) => {
6620
6912
  if (value.startsWith("length:")) {
6621
- return propList.map((prop) => decl(prop, `var(${value.replace("length:", "")})`));
6913
+ return withBorderStyle(propList, `var(${value.replace("length:", "")})`);
6622
6914
  }
6623
6915
  return propList.map((prop) => decl(prop.replace("width", "color"), `var(${value})`));
6624
6916
  },
@@ -6629,12 +6921,35 @@ staticUtility("border", [["border-width", "1px"]], { category: "borders" });
6629
6921
  staticUtility("border-inherit", [["border-color", "inherit"]], { category: "borders" });
6630
6922
  staticUtility("border-current", [["border-color", "currentColor"]], { category: "borders" });
6631
6923
  staticUtility("border-transparent", [["border-color", "transparent"]], { category: "borders" });
6632
- staticUtility("border-solid", [["border-style", "solid"]], { category: "borders" });
6633
- staticUtility("border-dashed", [["border-style", "dashed"]], { category: "borders" });
6634
- staticUtility("border-dotted", [["border-style", "dotted"]], { category: "borders" });
6635
- staticUtility("border-double", [["border-style", "double"]], { category: "borders" });
6636
- staticUtility("border-hidden", [["border-style", "hidden"]], { category: "borders" });
6637
- staticUtility("border-none", [["border-style", "none"]], { category: "borders" });
6924
+ staticUtility("border-solid", [["--baro-border-style", "solid"], ["border-style", "solid"]], { category: "borders" });
6925
+ staticUtility("border-dashed", [["--baro-border-style", "dashed"], ["border-style", "dashed"]], { category: "borders" });
6926
+ staticUtility("border-dotted", [["--baro-border-style", "dotted"], ["border-style", "dotted"]], { category: "borders" });
6927
+ staticUtility("border-double", [["--baro-border-style", "double"], ["border-style", "double"]], { category: "borders" });
6928
+ staticUtility("border-hidden", [["--baro-border-style", "hidden"], ["border-style", "hidden"]], { category: "borders" });
6929
+ staticUtility("border-none", [["--baro-border-style", "none"], ["border-style", "none"]], { category: "borders" });
6930
+ const divideSides = { x: ["border-inline-start", "border-inline-end", "border-inline-style"], y: ["border-top", "border-bottom", "border-bottom-style", "border-top-style"] };
6931
+ Object.entries(divideSides).forEach(([axis, [start, end, ...styles]]) => {
6932
+ const rev = `--baro-divide-${axis}-reverse`;
6933
+ const divide = (width) => [
6934
+ borderStyleProperty(),
6935
+ rule(":where(& > :not(:last-child))", [
6936
+ decl(rev, "0"),
6937
+ ...styles.map((s) => decl(s, "var(--baro-border-style)")),
6938
+ decl(`${start}-width`, `calc(${width} * var(${rev}))`),
6939
+ decl(`${end}-width`, `calc(${width} * calc(1 - var(${rev})))`)
6940
+ ])
6941
+ ];
6942
+ staticUtility(`divide-${axis}`, divide("1px"), { category: "borders" });
6943
+ staticUtility(`divide-${axis}-reverse`, [rule(":where(& > :not(:last-child))", [decl(rev, "1")])], { category: "borders" });
6944
+ functionalUtility({
6945
+ name: `divide-${axis}`,
6946
+ supportsArbitrary: true,
6947
+ handleBareValue: ({ value }) => /^\d+$/.test(value) ? `${value}px` : null,
6948
+ handle: (value) => divide(value),
6949
+ description: `divide-${axis} width utility`,
6950
+ category: "borders"
6951
+ });
6952
+ });
6638
6953
  functionalUtility({
6639
6954
  name: "border",
6640
6955
  themeKeys: ["colors", "borderWidth"],
@@ -6642,25 +6957,15 @@ functionalUtility({
6642
6957
  supportsCustomProperty: true,
6643
6958
  supportsOpacity: true,
6644
6959
  handle: (value, ctx, token, extra) => {
6645
- if (extra?.realThemeValue) {
6646
- if (extra.opacity) {
6647
- return [
6648
- atRule("supports", `(color:color-mix(in lab, red, red))`, [
6649
- decl("border-color", `color-mix(in lab, ${value} ${extra.opacity}%, transparent)`)
6650
- ]),
6651
- decl("border-color", `color-mix(in lab, ${value} ${extra.opacity}%, transparent)`)
6652
- ];
6653
- }
6654
- return [decl("border-color", value)];
6655
- }
6960
+ if (extra?.realThemeValue) return themeColorDecls("border-color", value, extra);
6656
6961
  if (token.arbitrary) {
6657
6962
  if (parseLength(value)) {
6658
- return [decl("border-width", value)];
6963
+ return withBorderStyle(["border-width"], value);
6659
6964
  }
6660
6965
  return [decl("border-color", value)];
6661
6966
  }
6662
6967
  if (parseNumber(value)) {
6663
- return [decl("border-width", `${value}px`)];
6968
+ return withBorderStyle(["border-width"], `${value}px`);
6664
6969
  }
6665
6970
  if (parseColor(value)) {
6666
6971
  return [decl("border-color", value)];
@@ -6669,26 +6974,35 @@ functionalUtility({
6669
6974
  },
6670
6975
  handleCustomProperty: (value) => {
6671
6976
  if (value.startsWith("length:")) {
6672
- return [decl("border-width", `var(${value.replace("length:", "")})`)];
6977
+ return withBorderStyle(["border-width"], `var(${value.replace("length:", "")})`);
6673
6978
  }
6674
6979
  return [decl("border-color", `var(${value})`)];
6675
6980
  },
6676
6981
  description: "border-width utility (number, arbitrary, custom property support)",
6677
6982
  category: "borders"
6678
6983
  });
6679
- staticUtility("outline-0", [["outline-width", "0px"]], { category: "borders" });
6680
- staticUtility("outline-1", [["outline-width", "1px"]], { category: "borders" });
6681
- staticUtility("outline-2", [["outline-width", "2px"]], { category: "borders" });
6682
- staticUtility("outline-4", [["outline-width", "4px"]], { category: "borders" });
6683
- staticUtility("outline-8", [["outline-width", "8px"]], { category: "borders" });
6984
+ const outlineStyleProperty = () => atRoot([property("--baro-outline-style", "solid")]);
6985
+ const withOutlineStyle = (width) => [
6986
+ outlineStyleProperty(),
6987
+ decl("outline-style", "var(--baro-outline-style)"),
6988
+ decl("outline-width", width)
6989
+ ];
6990
+ [["outline-0", "0px"], ["outline-1", "1px"], ["outline-2", "2px"], ["outline-4", "4px"], ["outline-8", "8px"]].forEach(([name, width]) => {
6991
+ staticUtility(name, [outlineStyleProperty, ["outline-style", "var(--baro-outline-style)"], ["outline-width", width]], { category: "borders" });
6992
+ });
6684
6993
  staticUtility("outline-inherit", [["outline-color", "inherit"]], { category: "borders" });
6685
6994
  staticUtility("outline-current", [["outline-color", "currentColor"]], { category: "borders" });
6686
6995
  staticUtility("outline-transparent", [["outline-color", "transparent"]], { category: "borders" });
6687
- staticUtility("outline-none", [["outline", "2px solid transparent"], ["outline-offset", "2px"]], { category: "borders" });
6688
- staticUtility("outline", [["outline-style", "solid"]], { category: "borders" });
6689
- staticUtility("outline-dashed", [["outline-style", "dashed"]], { category: "borders" });
6690
- staticUtility("outline-dotted", [["outline-style", "dotted"]], { category: "borders" });
6691
- staticUtility("outline-double", [["outline-style", "double"]], { category: "borders" });
6996
+ staticUtility("outline-none", [["--baro-outline-style", "none"], ["outline-style", "none"]], { category: "borders" });
6997
+ staticUtility("outline-hidden", [
6998
+ ["--baro-outline-style", "none"],
6999
+ ["outline-style", "none"],
7000
+ atRule("media", "(forced-colors: active)", [decl("outline", "2px solid transparent"), decl("outline-offset", "2px")])
7001
+ ], { category: "borders" });
7002
+ staticUtility("outline", [outlineStyleProperty, ["outline-style", "var(--baro-outline-style)"], ["outline-width", "1px"]], { category: "borders" });
7003
+ ["solid", "dashed", "dotted", "double"].forEach((style) => {
7004
+ staticUtility(`outline-${style}`, [["--baro-outline-style", style], ["outline-style", style]], { category: "borders" });
7005
+ });
6692
7006
  staticUtility("outline-offset-0", [["outline-offset", "0px"]], { category: "borders" });
6693
7007
  staticUtility("outline-offset-1", [["outline-offset", "1px"]], { category: "borders" });
6694
7008
  staticUtility("outline-offset-2", [["outline-offset", "2px"]], { category: "borders" });
@@ -6713,16 +7027,18 @@ functionalUtility({
6713
7027
  themeKeys: ["colors", "borderWidth"],
6714
7028
  supportsArbitrary: true,
6715
7029
  supportsCustomProperty: true,
6716
- handle: (value, ctx, token) => {
7030
+ supportsOpacity: true,
7031
+ handle: (value, ctx, token, extra) => {
7032
+ if (extra?.realThemeValue) return themeColorDecls("outline-color", value, extra);
6717
7033
  if (parseColor(value)) {
6718
7034
  return [decl("outline-color", value)];
6719
7035
  }
6720
7036
  if (parseNumber(value)) {
6721
- return [decl("outline-width", `${value}px`)];
7037
+ return withOutlineStyle(`${value}px`);
6722
7038
  }
6723
7039
  if (token.arbitrary) {
6724
7040
  if (parseLength(value)) {
6725
- return [decl("outline-width", value)];
7041
+ return withOutlineStyle(value);
6726
7042
  }
6727
7043
  return [decl("outline-color", value)];
6728
7044
  }
@@ -6733,7 +7049,7 @@ functionalUtility({
6733
7049
  return [decl("outline-color", value.replace("color:", ""))];
6734
7050
  }
6735
7051
  if (value.startsWith("length:")) {
6736
- return [decl("outline-width", `var(${value.replace("length:", "")})`)];
7052
+ return withOutlineStyle(`var(${value.replace("length:", "")})`);
6737
7053
  }
6738
7054
  return [decl("outline-color", `var(${value})`)];
6739
7055
  },
@@ -6754,6 +7070,40 @@ functionalUtility({
6754
7070
  description: "outline-width utility (number, arbitrary, custom property support)",
6755
7071
  category: "borders"
6756
7072
  });
7073
+ const divideColor = (value) => [rule(":where(& > :not(:last-child))", [decl("border-color", value)])];
7074
+ staticUtility("divide-inherit", divideColor("inherit"), { category: "borders" });
7075
+ staticUtility("divide-current", divideColor("currentColor"), { category: "borders" });
7076
+ staticUtility("divide-transparent", divideColor("transparent"), { category: "borders" });
7077
+ functionalUtility({
7078
+ name: "divide",
7079
+ themeKeys: ["colors"],
7080
+ supportsArbitrary: true,
7081
+ supportsCustomProperty: true,
7082
+ supportsOpacity: true,
7083
+ handle: (value, _ctx, _token, extra) => {
7084
+ if (extra?.realThemeValue) {
7085
+ return [rule(":where(& > :not(:last-child))", themeColorDecls("border-color", value, extra))];
7086
+ }
7087
+ if (parseColor(value)) return divideColor(value);
7088
+ return null;
7089
+ },
7090
+ handleCustomProperty: (value) => divideColor(`var(${value})`),
7091
+ description: "divide-color utility (theme, alpha, arbitrary, custom property)",
7092
+ category: "borders"
7093
+ });
7094
+ const ROTATE_SKEW = "var(--baro-rotate-x,) var(--baro-rotate-y,) var(--baro-rotate-z,) var(--baro-skew-x,) var(--baro-skew-y,)";
7095
+ const rotateAxis = (axis, fn) => [decl(`--baro-rotate-${axis}`, fn), decl("transform", ROTATE_SKEW)];
7096
+ const skewAxis = (axis, fn) => [decl(`--baro-skew-${axis}`, fn), decl("transform", ROTATE_SKEW)];
7097
+ const scaleProperties = () => atRoot([
7098
+ property("--baro-scale-x", "1"),
7099
+ property("--baro-scale-y", "1"),
7100
+ property("--baro-scale-z", "1")
7101
+ ]);
7102
+ const scaleAxis = (axis, v) => [
7103
+ scaleProperties(),
7104
+ decl(`--baro-scale-${axis}`, v),
7105
+ decl("scale", axis === "z" ? "var(--baro-scale-x) var(--baro-scale-y) var(--baro-scale-z)" : "var(--baro-scale-x) var(--baro-scale-y)")
7106
+ ];
6757
7107
  staticUtility("transform-none", [["transform", "none"]], {
6758
7108
  category: "transform"
6759
7109
  });
@@ -6762,7 +7112,7 @@ staticUtility(
6762
7112
  [
6763
7113
  [
6764
7114
  "transform",
6765
- "translateZ(0) var(--baro-rotate-x) var(--baro-rotate-y) var(--baro-rotate-z) var(--baro-skew-x) var(--baro-skew-y)"
7115
+ `translateZ(0) ${ROTATE_SKEW}`
6766
7116
  ]
6767
7117
  ],
6768
7118
  { category: "transform" }
@@ -6770,7 +7120,7 @@ staticUtility(
6770
7120
  staticUtility("transform-cpu", [
6771
7121
  [
6772
7122
  "transform",
6773
- "var(--baro-rotate-x) var(--baro-rotate-y) var(--baro-rotate-z) var(--baro-skew-x) var(--baro-skew-y)"
7123
+ ROTATE_SKEW
6774
7124
  ]
6775
7125
  ]);
6776
7126
  staticUtility("transform-3d", [["transform-style", "preserve-3d"]], {
@@ -6899,13 +7249,11 @@ functionalUtility({
6899
7249
  if (parseNumber(value) || negative) {
6900
7250
  const deg = `${Math.abs(Number(value))}deg`;
6901
7251
  const sign = negative || String(value).startsWith("-") ? "-" : "";
6902
- return [decl("transform", `rotateX(${sign}${deg}) var(--baro-rotate-y)`)];
7252
+ return rotateAxis("x", `rotateX(${sign}${deg})`);
6903
7253
  }
6904
- return [decl("transform", `rotateX(${value}) var(--baro-rotate-y)`)];
7254
+ return rotateAxis("x", `rotateX(${value})`);
6905
7255
  },
6906
- handleCustomProperty: (value) => [
6907
- decl("transform", `rotateX(var(${value})) var(--baro-rotate-y)`)
6908
- ],
7256
+ handleCustomProperty: (value) => rotateAxis("x", `rotateX(var(${value}))`),
6909
7257
  description: "rotate-x utility (named, arbitrary, custom property supported)",
6910
7258
  category: "transform"
6911
7259
  });
@@ -6919,13 +7267,11 @@ functionalUtility({
6919
7267
  if (parseNumber(value) || negative) {
6920
7268
  const deg = `${Math.abs(Number(value))}deg`;
6921
7269
  const sign = negative || String(value).startsWith("-") ? "-" : "";
6922
- return [decl("transform", `var(--baro-rotate-x) rotateY(${sign}${deg})`)];
7270
+ return rotateAxis("y", `rotateY(${sign}${deg})`);
6923
7271
  }
6924
- return [decl("transform", `var(--baro-rotate-x) rotateY(${value})`)];
7272
+ return rotateAxis("y", `rotateY(${value})`);
6925
7273
  },
6926
- handleCustomProperty: (value) => [
6927
- decl("transform", `var(--baro-rotate-x) rotateY(var(${value}))`)
6928
- ],
7274
+ handleCustomProperty: (value) => rotateAxis("y", `rotateY(var(${value}))`),
6929
7275
  description: "rotate-y utility (named, arbitrary, custom property supported)",
6930
7276
  category: "transform"
6931
7277
  });
@@ -6939,26 +7285,11 @@ functionalUtility({
6939
7285
  if (parseNumber(value) || negative) {
6940
7286
  const deg = `${Math.abs(Number(value))}deg`;
6941
7287
  const sign = negative || String(value).startsWith("-") ? "-" : "";
6942
- return [
6943
- decl(
6944
- "transform",
6945
- `var(--baro-rotate-x) var(--baro-rotate-y) rotateZ(${sign}${deg})`
6946
- )
6947
- ];
7288
+ return rotateAxis("z", `rotateZ(${sign}${deg})`);
6948
7289
  }
6949
- return [
6950
- decl(
6951
- "transform",
6952
- `var(--baro-rotate-x) var(--baro-rotate-y) rotateZ(${value})`
6953
- )
6954
- ];
7290
+ return rotateAxis("z", `rotateZ(${value})`);
6955
7291
  },
6956
- handleCustomProperty: (value) => [
6957
- decl(
6958
- "transform",
6959
- `var(--baro-rotate-x) var(--baro-rotate-y) rotateZ(var(${value}))`
6960
- )
6961
- ],
7292
+ handleCustomProperty: (value) => rotateAxis("z", `rotateZ(var(${value}))`),
6962
7293
  description: "rotate-z utility (named, arbitrary, custom property supported)",
6963
7294
  category: "transform"
6964
7295
  });
@@ -6985,7 +7316,7 @@ functionalUtility({
6985
7316
  staticUtility("scale-none", [["scale", "none"]], { category: "transform" });
6986
7317
  staticUtility(
6987
7318
  "scale-3d",
6988
- [["scale", "var(--baro-scale-x) var(--baro-scale-y) var(--baro-scale-z)"]],
7319
+ [scaleProperties, ["scale", "var(--baro-scale-x) var(--baro-scale-y) var(--baro-scale-z)"]],
6989
7320
  { category: "transform" }
6990
7321
  );
6991
7322
  functionalUtility({
@@ -6996,18 +7327,16 @@ functionalUtility({
6996
7327
  supportsNegative: true,
6997
7328
  handle: (value, ctx, { negative, arbitrary }) => {
6998
7329
  if (arbitrary) {
6999
- return [decl("scale", `${value}`)];
7330
+ return scaleAxis("x", value);
7000
7331
  }
7001
7332
  if (parseNumber(value) || negative) {
7002
7333
  const pct = `${Math.abs(Number(value))}%`;
7003
7334
  const sign = negative || String(value).startsWith("-") ? "-" : "";
7004
- return [decl("scale", `calc(${pct} * ${sign}1) var(--baro-scale-y)`)];
7335
+ return scaleAxis("x", `calc(${pct} * ${sign}1)`);
7005
7336
  }
7006
- return [decl("scale", `${value} var(--baro-scale-y)`)];
7337
+ return scaleAxis("x", value);
7007
7338
  },
7008
- handleCustomProperty: (value) => [
7009
- decl("scale", `var(${value}) var(--baro-scale-y)`)
7010
- ],
7339
+ handleCustomProperty: (value) => scaleAxis("x", `var(${value})`),
7011
7340
  description: "scale-x utility (named, arbitrary, custom property supported)",
7012
7341
  category: "transform"
7013
7342
  });
@@ -7019,18 +7348,16 @@ functionalUtility({
7019
7348
  supportsNegative: true,
7020
7349
  handle: (value, ctx, { negative, arbitrary }) => {
7021
7350
  if (arbitrary) {
7022
- return [decl("scale", `var(--baro-scale-x) ${value}`)];
7351
+ return scaleAxis("y", value);
7023
7352
  }
7024
7353
  if (parseNumber(value) || negative) {
7025
7354
  const pct = `${Math.abs(Number(value))}%`;
7026
7355
  const sign = negative || String(value).startsWith("-") ? "-" : "";
7027
- return [decl("scale", `var(--baro-scale-x) calc(${pct} * ${sign}1)`)];
7356
+ return scaleAxis("y", `calc(${pct} * ${sign}1)`);
7028
7357
  }
7029
- return [decl("scale", `var(--baro-scale-x) ${value}`)];
7358
+ return scaleAxis("y", value);
7030
7359
  },
7031
- handleCustomProperty: (value) => [
7032
- decl("scale", `var(--baro-scale-x) var(${value})`)
7033
- ],
7360
+ handleCustomProperty: (value) => scaleAxis("y", `var(${value})`),
7034
7361
  description: "scale-y utility (named, arbitrary, custom property supported)",
7035
7362
  category: "transform"
7036
7363
  });
@@ -7042,25 +7369,16 @@ functionalUtility({
7042
7369
  supportsNegative: true,
7043
7370
  handle: (value, ctx, { negative, arbitrary }) => {
7044
7371
  if (arbitrary) {
7045
- return [
7046
- decl("scale", `var(--baro-scale-x) var(--baro-scale-y) ${value}`)
7047
- ];
7372
+ return scaleAxis("z", value);
7048
7373
  }
7049
7374
  if (parseNumber(value) || negative) {
7050
7375
  const pct = `${Math.abs(Number(value))}%`;
7051
7376
  const sign = negative || String(value).startsWith("-") ? "-" : "";
7052
- return [
7053
- decl(
7054
- "scale",
7055
- `var(--baro-scale-x) var(--baro-scale-y) calc(${pct} * ${sign}1)`
7056
- )
7057
- ];
7377
+ return scaleAxis("z", `calc(${pct} * ${sign}1)`);
7058
7378
  }
7059
- return [decl("scale", `var(--baro-scale-x) var(--baro-scale-y) ${value}`)];
7379
+ return scaleAxis("z", value);
7060
7380
  },
7061
- handleCustomProperty: (value) => [
7062
- decl("scale", `var(--baro-scale-x) var(--baro-scale-y) var(${value})`)
7063
- ],
7381
+ handleCustomProperty: (value) => scaleAxis("z", `var(${value})`),
7064
7382
  description: "scale-z utility (named, arbitrary, custom property supported)",
7065
7383
  category: "transform"
7066
7384
  });
@@ -7099,11 +7417,11 @@ functionalUtility({
7099
7417
  if (parseNumber(value) || negative) {
7100
7418
  const deg = `${Math.abs(Number(value))}deg`;
7101
7419
  const sign = negative || String(value).startsWith("-") ? "-" : "";
7102
- return [decl("transform", `skewX(${sign}${deg})`)];
7420
+ return skewAxis("x", `skewX(${sign}${deg})`);
7103
7421
  }
7104
- return [decl("transform", `skewX(${value})`)];
7422
+ return skewAxis("x", `skewX(${value})`);
7105
7423
  },
7106
- handleCustomProperty: (value) => [decl("transform", `skewX(var(${value}))`)],
7424
+ handleCustomProperty: (value) => skewAxis("x", `skewX(var(${value}))`),
7107
7425
  description: "skew-x utility (named, arbitrary, custom property supported)",
7108
7426
  category: "transform"
7109
7427
  });
@@ -7117,11 +7435,11 @@ functionalUtility({
7117
7435
  if (parseNumber(value) || negative) {
7118
7436
  const deg = `${Math.abs(Number(value))}deg`;
7119
7437
  const sign = negative || String(value).startsWith("-") ? "-" : "";
7120
- return [decl("transform", `skewY(${sign}${deg})`)];
7438
+ return skewAxis("y", `skewY(${sign}${deg})`);
7121
7439
  }
7122
- return [decl("transform", `skewY(${value})`)];
7440
+ return skewAxis("y", `skewY(${value})`);
7123
7441
  },
7124
- handleCustomProperty: (value) => [decl("transform", `skewY(var(${value}))`)],
7442
+ handleCustomProperty: (value) => skewAxis("y", `skewY(var(${value}))`),
7125
7443
  description: "skew-y utility (named, arbitrary, custom property supported)",
7126
7444
  category: "transform"
7127
7445
  });
@@ -7135,12 +7453,14 @@ functionalUtility({
7135
7453
  if (parseNumber(value) || negative) {
7136
7454
  const deg = `${Math.abs(Number(value))}deg`;
7137
7455
  const sign = negative || String(value).startsWith("-") ? "-" : "";
7138
- return [decl("transform", `skewX(${sign}${deg}) skewY(${sign}${deg})`)];
7456
+ return [decl("--baro-skew-x", `skewX(${sign}${deg})`), decl("--baro-skew-y", `skewY(${sign}${deg})`), decl("transform", ROTATE_SKEW)];
7139
7457
  }
7140
- return [decl("transform", `skewX(${value}) skewY(${value})`)];
7458
+ return [decl("--baro-skew-x", `skewX(${value})`), decl("--baro-skew-y", `skewY(${value})`), decl("transform", ROTATE_SKEW)];
7141
7459
  },
7142
7460
  handleCustomProperty: (value) => [
7143
- decl("transform", `skewX(var(${value})) skewY(var(${value}))`)
7461
+ decl("--baro-skew-x", `skewX(var(${value}))`),
7462
+ decl("--baro-skew-y", `skewY(var(${value}))`),
7463
+ decl("transform", ROTATE_SKEW)
7144
7464
  ],
7145
7465
  description: "skew utility (named, arbitrary, custom property supported)",
7146
7466
  category: "transform"
@@ -7185,6 +7505,22 @@ const translateProperties = () => atRoot([
7185
7505
  property("--baro-translate-y", "0"),
7186
7506
  property("--baro-translate-z", "0")
7187
7507
  ]);
7508
+ const translateAxis = (axis, v) => [
7509
+ translateProperties(),
7510
+ decl(`--baro-translate-${axis}`, v),
7511
+ decl(
7512
+ "translate",
7513
+ axis === "z" ? "var(--baro-translate-x) var(--baro-translate-y) var(--baro-translate-z)" : "var(--baro-translate-x) var(--baro-translate-y)"
7514
+ )
7515
+ ];
7516
+ const staticTranslateAxis = (axis, v) => [
7517
+ translateProperties,
7518
+ [`--baro-translate-${axis}`, v],
7519
+ [
7520
+ "translate",
7521
+ axis === "z" ? "var(--baro-translate-x) var(--baro-translate-y) var(--baro-translate-z)" : "var(--baro-translate-x) var(--baro-translate-y)"
7522
+ ]
7523
+ ];
7188
7524
  staticUtility("translate-none", [["translate", "none"]], {
7189
7525
  category: "transform"
7190
7526
  });
@@ -7216,52 +7552,52 @@ staticUtility(
7216
7552
  );
7217
7553
  staticUtility(
7218
7554
  "translate-x-px",
7219
- [["translate", "1px var(--baro-translate-y)"]],
7555
+ staticTranslateAxis("x", "1px"),
7220
7556
  { category: "transform" }
7221
7557
  );
7222
7558
  staticUtility(
7223
7559
  "-translate-x-px",
7224
- [["translate", "-1px var(--baro-translate-y)"]],
7560
+ staticTranslateAxis("x", "-1px"),
7225
7561
  { category: "transform" }
7226
7562
  );
7227
7563
  staticUtility(
7228
7564
  "translate-x-full",
7229
- [["translate", "100% var(--baro-translate-y)"]],
7565
+ staticTranslateAxis("x", "100%"),
7230
7566
  { category: "transform" }
7231
7567
  );
7232
7568
  staticUtility(
7233
7569
  "-translate-x-full",
7234
- [["translate", "-100% var(--baro-translate-y)"]],
7570
+ staticTranslateAxis("x", "-100%"),
7235
7571
  { category: "transform" }
7236
7572
  );
7237
7573
  staticUtility(
7238
7574
  "translate-y-px",
7239
- [["translate", "var(--baro-translate-x) 1px"]],
7575
+ staticTranslateAxis("y", "1px"),
7240
7576
  { category: "transform" }
7241
7577
  );
7242
7578
  staticUtility(
7243
7579
  "-translate-y-px",
7244
- [["translate", "var(--baro-translate-x) -1px"]],
7580
+ staticTranslateAxis("y", "-1px"),
7245
7581
  { category: "transform" }
7246
7582
  );
7247
7583
  staticUtility(
7248
7584
  "translate-y-full",
7249
- [["translate", "var(--baro-translate-x) 100%"]],
7585
+ staticTranslateAxis("y", "100%"),
7250
7586
  { category: "transform" }
7251
7587
  );
7252
7588
  staticUtility(
7253
7589
  "-translate-y-full",
7254
- [["translate", "var(--baro-translate-x) -100%"]],
7590
+ staticTranslateAxis("y", "-100%"),
7255
7591
  { category: "transform" }
7256
7592
  );
7257
7593
  staticUtility(
7258
7594
  "translate-z-px",
7259
- [["translate", "var(--baro-translate-x) var(--baro-translate-y) 1px"]],
7595
+ staticTranslateAxis("z", "1px"),
7260
7596
  { category: "transform" }
7261
7597
  );
7262
7598
  staticUtility(
7263
7599
  "-translate-z-px",
7264
- [["translate", "var(--baro-translate-x) var(--baro-translate-y) -1px"]],
7600
+ staticTranslateAxis("z", "-1px"),
7265
7601
  { category: "transform" }
7266
7602
  );
7267
7603
  functionalUtility({
@@ -7271,19 +7607,17 @@ functionalUtility({
7271
7607
  supportsArbitrary: true,
7272
7608
  supportsCustomProperty: true,
7273
7609
  handle: (value, ctx, { negative }) => {
7274
- if (parseFractionOrNumber(value)) {
7610
+ if (value.includes("/") && parseFractionOrNumber(value)) {
7275
7611
  const v = `calc(${value} * 100%)`;
7276
- return [decl("translate", `${v} var(--baro-translate-y)`)];
7612
+ return translateAxis("x", v);
7277
7613
  }
7278
7614
  if (parseNumber(value) || negative) {
7279
7615
  const v = `calc(var(--spacing) * ${value})`;
7280
- return [decl("translate", `${v} var(--baro-translate-y)`)];
7616
+ return translateAxis("x", v);
7281
7617
  }
7282
- return [decl("translate", `${value} var(--baro-translate-y)`)];
7618
+ return translateAxis("x", value);
7283
7619
  },
7284
- handleCustomProperty: (value) => [
7285
- decl("translate", `var(${value}) var(--baro-translate-y)`)
7286
- ],
7620
+ handleCustomProperty: (value) => translateAxis("x", `var(${value})`),
7287
7621
  description: "translate-x utility (spacing, fraction, arbitrary, custom property, negative)",
7288
7622
  category: "transform"
7289
7623
  });
@@ -7294,19 +7628,17 @@ functionalUtility({
7294
7628
  supportsArbitrary: true,
7295
7629
  supportsCustomProperty: true,
7296
7630
  handle: (value, ctx, { negative }) => {
7297
- if (parseFractionOrNumber(value)) {
7631
+ if (value.includes("/") && parseFractionOrNumber(value)) {
7298
7632
  const v = `calc(${value} * 100%)`;
7299
- return [decl("translate", `var(--baro-translate-x) ${v}`)];
7633
+ return translateAxis("y", v);
7300
7634
  }
7301
7635
  if (parseNumber(value) || negative) {
7302
7636
  const v = `calc(var(--spacing) * ${value})`;
7303
- return [decl("translate", `var(--baro-translate-x) ${v}`)];
7637
+ return translateAxis("y", v);
7304
7638
  }
7305
- return [decl("translate", `var(--baro-translate-x) ${value}`)];
7639
+ return translateAxis("y", value);
7306
7640
  },
7307
- handleCustomProperty: (value) => [
7308
- decl("translate", `var(--baro-translate-x) var(${value})`)
7309
- ],
7641
+ handleCustomProperty: (value) => translateAxis("y", `var(${value})`),
7310
7642
  description: "translate-y utility (spacing, fraction, arbitrary, custom property, negative)",
7311
7643
  category: "transform"
7312
7644
  });
@@ -7317,37 +7649,17 @@ functionalUtility({
7317
7649
  supportsArbitrary: true,
7318
7650
  supportsCustomProperty: true,
7319
7651
  handle: (value, ctx, { negative }) => {
7320
- if (parseFractionOrNumber(value)) {
7652
+ if (value.includes("/") && parseFractionOrNumber(value)) {
7321
7653
  const v = `calc(${value} * 100%)`;
7322
- return [
7323
- decl(
7324
- "translate",
7325
- `var(--baro-translate-x) var(--baro-translate-y) ${v}`
7326
- )
7327
- ];
7654
+ return translateAxis("z", v);
7328
7655
  }
7329
7656
  if (parseNumber(value) || negative) {
7330
7657
  const v = `calc(var(--spacing) * ${value})`;
7331
- return [
7332
- decl(
7333
- "translate",
7334
- `var(--baro-translate-x) var(--baro-translate-y) ${v}`
7335
- )
7336
- ];
7658
+ return translateAxis("z", v);
7337
7659
  }
7338
- return [
7339
- decl(
7340
- "translate",
7341
- `var(--baro-translate-x) var(--baro-translate-y) ${value}`
7342
- )
7343
- ];
7660
+ return translateAxis("z", value);
7344
7661
  },
7345
- handleCustomProperty: (value) => [
7346
- decl(
7347
- "translate",
7348
- `var(--baro-translate-x) var(--baro-translate-y) var(${value})`
7349
- )
7350
- ],
7662
+ handleCustomProperty: (value) => translateAxis("z", `var(${value})`),
7351
7663
  description: "translate-z utility (spacing, fraction, arbitrary, custom property, negative)",
7352
7664
  category: "transform"
7353
7665
  });
@@ -7358,7 +7670,7 @@ functionalUtility({
7358
7670
  supportsArbitrary: true,
7359
7671
  supportsCustomProperty: true,
7360
7672
  handle: (value, ctx, { negative }) => {
7361
- if (parseFractionOrNumber(value)) {
7673
+ if (value.includes("/") && parseFractionOrNumber(value)) {
7362
7674
  const v = `calc(${value} * 100%)`;
7363
7675
  return [decl("translate", `${v} ${v}`)];
7364
7676
  }
@@ -7523,8 +7835,13 @@ staticModifier("rtl", ["&[dir=rtl]"], { order: 20, source: "attribute" });
7523
7835
  staticModifier("ltr", ["&[dir=ltr]"], { order: 20, source: "attribute" });
7524
7836
  staticModifier("inert", ["&[inert]"], { order: 40, source: "attribute" });
7525
7837
  staticModifier("open", ["&:is([open], :popover-open, :open)"], { order: 40, source: "attribute" });
7526
- staticModifier("before", ["&::before"], { source: "pseudo" });
7527
- staticModifier("after", ["&::after"], { source: "pseudo" });
7838
+ const withPseudoContent = (ast) => [
7839
+ atRoot([property("--baro-content", '""')]),
7840
+ ...ast,
7841
+ decl("content", "var(--baro-content)")
7842
+ ];
7843
+ staticModifier("before", ["&::before"], { source: "pseudo", astHandler: withPseudoContent });
7844
+ staticModifier("after", ["&::after"], { source: "pseudo", astHandler: withPseudoContent });
7528
7845
  staticModifier("placeholder", [
7529
7846
  "&::placeholder",
7530
7847
  "&::-webkit-input-placeholder",
@@ -7557,9 +7874,6 @@ function createContainerParams(type, value, name) {
7557
7874
  const condition = type === "min" ? "width >=" : "width <";
7558
7875
  return name ? `${name} (${condition} ${value})` : `(${condition} ${value})`;
7559
7876
  }
7560
- function getThemeSize(ctx, key) {
7561
- return ctx.theme("container." + key) || ctx.theme("breakpoint." + key);
7562
- }
7563
7877
  function createContainerRule(params, ast) {
7564
7878
  return {
7565
7879
  type: "at-rule",
@@ -7579,6 +7893,35 @@ function getDefaultBreakpoint(breakpoint) {
7579
7893
  };
7580
7894
  return defaults[breakpoint] || `(min-width: ${breakpoint})`;
7581
7895
  }
7896
+ function decodeArbitrarySelector(value) {
7897
+ return value.replace(/\\_|_/g, (m) => m === "_" ? " " : "_");
7898
+ }
7899
+ function attributeVariantSelector(variant) {
7900
+ const bracket = /^(data|aria)-\[([a-zA-Z0-9_-]+)(?:=([^\]]+))?\]$/.exec(variant);
7901
+ if (bracket) {
7902
+ const [, kind, key, raw] = bracket;
7903
+ if (raw === void 0) return `[${kind}-${key}]`;
7904
+ const value = /^(["']).*\1$/.test(raw) ? raw : `"${decodeArbitrarySelector(raw)}"`;
7905
+ return `[${kind}-${key}=${value}]`;
7906
+ }
7907
+ const bare = /^data-([a-zA-Z0-9_-]+)$/.exec(variant);
7908
+ return bare ? `[data-${bare[1]}]` : void 0;
7909
+ }
7910
+ function functionalArgument(value) {
7911
+ const v = decodeArbitrarySelector(value);
7912
+ return /^[>+~]/.test(v.trim()) || !hasTopLevelComma(v) ? v : `*:is(${v})`;
7913
+ }
7914
+ function hasTopLevelComma(value) {
7915
+ let depth = 0;
7916
+ for (let i = 0; i < value.length; i++) {
7917
+ const c = value[i];
7918
+ if (c === "\\") i++;
7919
+ else if (c === "(" || c === "[") depth++;
7920
+ else if (c === ")" || c === "]") depth--;
7921
+ else if (c === "," && depth === 0) return true;
7922
+ }
7923
+ return false;
7924
+ }
7582
7925
  functionalModifier(
7583
7926
  (mod, context) => {
7584
7927
  const breakpoints2 = context.theme("breakpoints") || context.config("theme.breakpoints") || {};
@@ -7609,7 +7952,7 @@ functionalModifier(
7609
7952
  const breakpoints2 = context.theme("breakpoints") || context.config("theme.breakpoints") || {};
7610
7953
  if (Object.keys(breakpoints2).includes(breakpoint)) {
7611
7954
  let mediaQuery = context.theme(`breakpoints.${breakpoint}`) || getDefaultBreakpoint(breakpoint);
7612
- if (/^\d+(px|em|rem)?$/.test(mediaQuery)) {
7955
+ if (/^\d*\.?\d+(px|em|rem)?$/.test(mediaQuery)) {
7613
7956
  mediaQuery = `(min-width: ${mediaQuery})`;
7614
7957
  }
7615
7958
  return [atRule("media", mediaQuery, [], "responsive")];
@@ -7628,6 +7971,8 @@ functionalModifier(
7628
7971
  if (value) {
7629
7972
  mediaQuery = `(width < ${value})`;
7630
7973
  }
7974
+ } else if (/^\d*\.?\d+(px|em|rem)?$/.test(mediaQuery)) {
7975
+ mediaQuery = `(width < ${mediaQuery})`;
7631
7976
  }
7632
7977
  return [atRule("media", mediaQuery, [], "responsive")];
7633
7978
  }
@@ -7696,132 +8041,137 @@ functionalModifier(
7696
8041
  return result;
7697
8042
  }
7698
8043
  );
8044
+ const SIZE_VARIANT = /^@(?:(min|max)-)?(\[[^\]]+\]|[a-zA-Z0-9.]+)(?:\/([a-zA-Z0-9_-]+))?$/;
7699
8045
  functionalModifier(
7700
- (mod) => /^@container\/([a-zA-Z0-9_-]+)$/.test(mod),
7701
- void 0,
7702
- (mod, context) => {
7703
- const containerMatch = /^@container\/([a-zA-Z0-9_-]+)$/.exec(mod.type);
7704
- if (containerMatch) {
7705
- const name = containerMatch[1];
7706
- const params = name;
7707
- return [createContainerRule(params, [])];
7708
- }
7709
- return [];
7710
- }
7711
- );
7712
- functionalModifier(
7713
- (mod) => /^@container\/([a-zA-Z0-9_-]+)\s+\(([^)]+)\)$/.test(mod),
8046
+ (mod) => SIZE_VARIANT.test(mod) && !/^@container(?:\/|$)/.test(mod),
7714
8047
  void 0,
7715
8048
  (mod, context) => {
7716
- const containerSizeMatch = /^@container\/([a-zA-Z0-9_-]+)\s+\(([^)]+)\)$/.exec(mod.type);
7717
- if (containerSizeMatch) {
7718
- const [, name, size] = containerSizeMatch;
7719
- const params = createContainerParams("min", size, name);
7720
- return [createContainerRule(params, [])];
7721
- }
7722
- return [];
8049
+ const m = SIZE_VARIANT.exec(mod.type);
8050
+ if (!m) return [];
8051
+ const [, type, size, name] = m;
8052
+ const value = size.startsWith("[") ? size.slice(1, -1).replace(/_/g, " ") : context.theme("container." + size);
8053
+ if (!value) return [];
8054
+ return [createContainerRule(createContainerParams(type === "max" ? "max" : "min", value, name), [])];
7723
8055
  }
7724
8056
  );
8057
+ const startsAtRule = (bracket) => /^[\s_]*@/.test(bracket);
7725
8058
  functionalModifier(
7726
- (mod) => /^@(sm|md|lg|xl|2xl)\/([a-zA-Z0-9_-]+)$/.test(mod),
7727
- void 0,
7728
- (mod, context) => {
7729
- const namedSizeMatch = /^@(sm|md|lg|xl|2xl)\/([a-zA-Z0-9_-]+)$/.exec(mod.type);
7730
- if (namedSizeMatch) {
7731
- const [, size, name] = namedSizeMatch;
7732
- const sizeValue = getThemeSize(context, size) || size;
7733
- const params = createContainerParams("min", sizeValue, name);
7734
- return [createContainerRule(params, [])];
7735
- }
7736
- return [];
7737
- }
8059
+ (mod) => /^has-\[.*\]$/.test(mod) && !startsAtRule(mod.slice(5)),
8060
+ ({ selector, mod }) => {
8061
+ const m = /^has-\[(.+)\]$/.exec(mod.type);
8062
+ return m ? {
8063
+ selector: `&:has(${functionalArgument(m[1])})`,
8064
+ flatten: false,
8065
+ wrappingType: "rule",
8066
+ source: "attribute"
8067
+ } : {
8068
+ selector,
8069
+ source: "attribute"
8070
+ };
8071
+ },
8072
+ void 0
7738
8073
  );
7739
8074
  functionalModifier(
7740
- (mod) => /^@(sm|md|lg|xl|2xl)$/.test(mod),
7741
- void 0,
7742
- (mod, context) => {
7743
- const themeSizeMatch = /^@(sm|md|lg|xl|2xl)$/.exec(mod.type);
7744
- if (themeSizeMatch) {
7745
- const size = themeSizeMatch[1];
7746
- const sizeValue = getThemeSize(context, size) || size;
7747
- const params = createContainerParams("min", sizeValue);
7748
- return [createContainerRule(params, [])];
7749
- }
7750
- return [];
7751
- }
8075
+ (mod) => /^has-(data|aria)-/.test(mod) && !!attributeVariantSelector(mod.slice(4)),
8076
+ ({ mod }) => ({
8077
+ selector: `&:has(*${attributeVariantSelector(mod.type.slice(4))})`,
8078
+ flatten: false,
8079
+ wrappingType: "rule",
8080
+ source: "attribute"
8081
+ }),
8082
+ void 0
7752
8083
  );
8084
+ function innerCompound(variant, ctx) {
8085
+ const attr = attributeVariantSelector(variant);
8086
+ if (attr) return { compound: attr };
8087
+ if (/^(has|in|not|group|peer)-|[^a-z0-9-]/.test(variant)) return void 0;
8088
+ const inner = getModifier(ctx).find((m) => m.match(variant, ctx));
8089
+ if (!inner?.modifySelector || inner.astHandler) return void 0;
8090
+ const out = inner.modifySelector({ selector: "&", fullClassName: "", mod: { type: variant }, context: ctx });
8091
+ const list = typeof out === "string" ? [{ selector: out }] : Array.isArray(out) ? out : [out];
8092
+ if (list.length !== 1) return void 0;
8093
+ const sel = list[0].selector;
8094
+ if (!/^&[:[]/.test(sel) || sel.slice(1).includes("&") || /[\s,>+~]/.test(sel.replace(/\([^()]*\)/g, ""))) return void 0;
8095
+ return { compound: sel.slice(1), inner };
8096
+ }
8097
+ function resolveHasIn(mod, ctx) {
8098
+ const m = /^(has|in)-(.+)$/.exec(mod);
8099
+ if (!m) return void 0;
8100
+ const [, kind, v] = m;
8101
+ if (kind === "in" && /^\[.+\]$/.test(v)) {
8102
+ if (startsAtRule(v.slice(1))) return void 0;
8103
+ const sel = decodeArbitrarySelector(v.slice(1, -1));
8104
+ return { kind, compound: sel.startsWith("&") ? sel.slice(1) : `:is(${sel})` };
8105
+ }
8106
+ if (kind === "has" && (v.startsWith("[") || /^(data|aria)-/.test(v))) return void 0;
8107
+ const r = innerCompound(v, ctx);
8108
+ return r && { kind, ...r };
8109
+ }
8110
+ const hasInSelector = ({ selector, mod, context }) => {
8111
+ const r = resolveHasIn(mod.type, context);
8112
+ if (!r) return { selector };
8113
+ return {
8114
+ selector: r.kind === "has" ? `&:has(*${r.compound})` : `:where(*${r.compound}) &`,
8115
+ flatten: false,
8116
+ wrappingType: "rule",
8117
+ source: "attribute"
8118
+ };
8119
+ };
7753
8120
  functionalModifier(
7754
- (mod) => /^@max-(sm|md|lg|xl|2xl)$/.test(mod),
7755
- void 0,
7756
- (mod, context) => {
7757
- const themeSizeMatch = /^@max-(sm|md|lg|xl|2xl)$/.exec(mod.type);
7758
- if (themeSizeMatch) {
7759
- const size = themeSizeMatch[1];
7760
- const sizeValue = getThemeSize(context, size) || size;
7761
- const params = createContainerParams("max", sizeValue);
7762
- return [createContainerRule(params, [])];
7763
- }
7764
- return [];
7765
- }
8121
+ (mod, ctx) => !!resolveHasIn(mod, ctx)?.inner?.wrap,
8122
+ hasInSelector,
8123
+ (mod, context) => resolveHasIn(mod.type, context).inner.wrap({ ...mod, type: mod.type.replace(/^(has|in)-/, "") }, context)
7766
8124
  );
7767
8125
  functionalModifier(
7768
- (mod) => /^@(min|max)-\[.*\]$/.test(mod),
7769
- void 0,
7770
- (mod, context) => {
7771
- const arbitraryMatch = /^@(min|max)-\[(.+)\]$/.exec(mod.type);
7772
- if (arbitraryMatch) {
7773
- const [, type, value] = arbitraryMatch;
7774
- const params = createContainerParams(type, value);
7775
- return [createContainerRule(params, [])];
7776
- }
7777
- return [];
7778
- }
8126
+ (mod, ctx) => {
8127
+ const r = resolveHasIn(mod, ctx);
8128
+ return !!r && !r.inner?.wrap;
8129
+ },
8130
+ hasInSelector
7779
8131
  );
8132
+ function resolveGroupHas(mod, ctx) {
8133
+ const m = /^(group|peer)-has-(.+?)(?:\/([a-zA-Z0-9_-]+))?$/.exec(mod);
8134
+ if (!m) return void 0;
8135
+ const kind = m[1];
8136
+ const v = m[2];
8137
+ const base = m[3] ? `.${kind}\\/${m[3]}` : `.${kind}`;
8138
+ if (/^\[.+\]$/.test(v)) {
8139
+ if (startsAtRule(v.slice(1))) return void 0;
8140
+ const sel = decodeArbitrarySelector(v.slice(1, -1));
8141
+ return { kind, base, v, arg: /^[>+~]/.test(sel.trim()) ? sel : `*:is(${sel})` };
8142
+ }
8143
+ const r = innerCompound(v, ctx);
8144
+ return r && { kind, base, v, arg: `*${r.compound}`, inner: r.inner };
8145
+ }
8146
+ const groupHasSelector = ({ selector, mod, context }) => {
8147
+ const r = resolveGroupHas(mod.type, context);
8148
+ if (!r) return { selector };
8149
+ const tail = r.kind === "group" ? " *" : " ~ *";
8150
+ return { selector: `&:is(:where(${r.base}):has(${r.arg})${tail})`, wrappingType: "rule", source: r.kind };
8151
+ };
7780
8152
  functionalModifier(
7781
- (mod) => /^@(min|max)-\[.*\]\/([a-zA-Z0-9_-]+)$/.test(mod),
7782
- void 0,
8153
+ (mod, ctx) => !!resolveGroupHas(mod, ctx)?.inner?.wrap,
8154
+ groupHasSelector,
7783
8155
  (mod, context) => {
7784
- const arbitraryNamedMatch = /^@(min|max)-\[(.+)\]\/([a-zA-Z0-9_-]+)$/.exec(mod.type);
7785
- if (arbitraryNamedMatch) {
7786
- const [, type, value, name] = arbitraryNamedMatch;
7787
- const params = createContainerParams(type, value, name);
7788
- return [createContainerRule(params, [])];
7789
- }
7790
- return [];
8156
+ const r = resolveGroupHas(mod.type, context);
8157
+ return r.inner.wrap({ ...mod, type: r.v }, context);
7791
8158
  }
7792
8159
  );
7793
8160
  functionalModifier(
7794
- (mod) => /^has-\[.*\]$/.test(mod),
7795
- ({ selector, mod }) => {
7796
- const m = /^has-\[(.+)\]$/.exec(mod.type);
7797
- if (m && m[1].startsWith(".")) {
7798
- return {
7799
- selector: `&:has(${m[1]})`,
7800
- flatten: false,
7801
- wrappingType: "rule",
7802
- source: "attribute"
7803
- };
7804
- }
7805
- return m ? {
7806
- selector: `&:has(${m[1]})`,
7807
- flatten: false,
7808
- wrappingType: "rule",
7809
- source: "attribute"
7810
- } : {
7811
- selector,
7812
- source: "attribute"
7813
- };
8161
+ (mod, ctx) => {
8162
+ const r = resolveGroupHas(mod, ctx);
8163
+ return !!r && !r.inner?.wrap;
7814
8164
  },
7815
- void 0
8165
+ groupHasSelector
7816
8166
  );
7817
8167
  functionalModifier(
7818
8168
  (mod) => /^not-\[.*\]$/.test(mod),
7819
8169
  ({ selector, mod }) => {
7820
8170
  const m = /^not-\[(.+)\]$/.exec(mod.type);
7821
8171
  if (m) {
7822
- if (m[1].startsWith(".")) {
8172
+ if (!/^[a-zA-Z0-9_-]+(=.+)?$/.test(m[1])) {
7823
8173
  return {
7824
- selector: `&:not(${m[1]})`,
8174
+ selector: `&:not(${functionalArgument(m[1])})`,
7825
8175
  flatten: false,
7826
8176
  wrappingType: "rule",
7827
8177
  source: "attribute"
@@ -7854,27 +8204,14 @@ functionalModifier(
7854
8204
  );
7855
8205
  functionalModifier(
7856
8206
  (mod) => mod === "*",
7857
- ({ selector, fullClassName, variantChain }) => {
7858
- const isSingle = !variantChain || variantChain.length === 1;
7859
- return {
7860
- selector: `:is(.${escapeClassName(fullClassName)} > *)`,
7861
- flatten: true,
7862
- wrappingType: isSingle ? "rule" : "style-rule",
7863
- source: "universal"
7864
- };
8207
+ () => {
8208
+ return { selector: ":is(& > *)", wrappingType: "rule", source: "universal" };
7865
8209
  },
7866
8210
  void 0
7867
8211
  );
7868
8212
  functionalModifier(
7869
8213
  (mod) => mod === "**",
7870
- ({ selector, fullClassName }) => {
7871
- return {
7872
- selector: `:is(.${escapeClassName(fullClassName)} *)`,
7873
- flatten: false,
7874
- wrappingType: "style-rule",
7875
- source: "universal"
7876
- };
7877
- },
8214
+ () => ({ selector: ":is(& *)", wrappingType: "rule", source: "universal" }),
7878
8215
  void 0
7879
8216
  );
7880
8217
  functionalModifier(
@@ -7882,17 +8219,14 @@ functionalModifier(
7882
8219
  ({ selector, mod }) => {
7883
8220
  const m = /^\[(.+)\]$/.exec(mod.type);
7884
8221
  if (!m) return { selector };
7885
- const inner = m[1].trim();
8222
+ const inner = decodeArbitrarySelector(m[1]).trim();
7886
8223
  if (/^[a-zA-Z0-9_-]+(=.+)?$/.test(inner)) {
7887
8224
  return { selector: `&[${inner}]`, wrappingType: "rule", source: "attribute" };
7888
8225
  }
7889
- if (inner === "&>*") {
7890
- return { selector: `${inner}`, wrappingType: "style-rule", source: "peer" };
7891
- }
7892
8226
  if (inner.startsWith("&")) {
7893
8227
  return { selector: `${inner}`, wrappingType: "rule", source: "pseudo" };
7894
8228
  }
7895
- return { selector: `${inner} &`.trim(), wrappingType: "rule", source: "base" };
8229
+ return { selector: `&:is(${inner})`, wrappingType: "rule", source: "base" };
7896
8230
  },
7897
8231
  void 0
7898
8232
  );
@@ -7936,7 +8270,7 @@ functionalModifier(
7936
8270
  };
7937
8271
  } else {
7938
8272
  return {
7939
- selector: `&:not(${inner})`,
8273
+ selector: `&:not(${functionalArgument(inner)})`,
7940
8274
  source: "attribute"
7941
8275
  };
7942
8276
  }
@@ -8087,29 +8421,56 @@ functionalModifier(
8087
8421
  return m ? [atRule("scope", m[1], [])] : [];
8088
8422
  }
8089
8423
  );
8424
+ const atRuleHas = (mod) => /^(group|peer)-has-\[/.test(mod) && startsAtRule(mod.slice(mod.indexOf("[") + 1));
8425
+ function splitGroupName(kind, variant) {
8426
+ const named = /^(.+)\/([a-zA-Z0-9_-]+)$/.exec(variant);
8427
+ return named ? [named[1], `.${kind}\\/${named[2]}`] : [variant, `.${kind}`];
8428
+ }
8429
+ functionalModifier(
8430
+ (mod) => /^(group|peer)-hover(\/[a-zA-Z0-9_-]+)?$/.test(mod),
8431
+ ({ mod }) => {
8432
+ const kind = mod.type.startsWith("group") ? "group" : "peer";
8433
+ const [, base] = splitGroupName(kind, mod.type.slice(kind.length + 1));
8434
+ const tail = kind === "group" ? " *" : " ~ *";
8435
+ return { selector: `&:is(:where(${base}):hover${tail})`, wrappingType: "rule", source: kind };
8436
+ },
8437
+ () => [atRule("media", "(hover: hover)", [])]
8438
+ );
8439
+ function negated(value) {
8440
+ const v = value.slice(4);
8441
+ return v.startsWith("[") && v.endsWith("]") ? `:not(*:is(${decodeArbitrarySelector(v.slice(1, -1))}))` : `:not(:${v})`;
8442
+ }
8090
8443
  functionalModifier(
8091
- (mod) => /^group-(.+)$/.test(mod),
8444
+ (mod) => /^group-(.+)$/.test(mod) && !atRuleHas(mod),
8092
8445
  ({ selector, mod }) => {
8093
- const m = /^group-(.+)$/.exec(mod.type);
8446
+ const raw = /^group-(.+)$/.exec(mod.type);
8447
+ const [variant, base] = splitGroupName("group", raw?.[1] ?? "");
8448
+ const m = raw ? [raw[0], variant] : null;
8449
+ const g = `:where(${base})`;
8450
+ const attr = m ? attributeVariantSelector(m[1]) : void 0;
8451
+ if (attr) return { selector: `&:is(${g}${attr} *)`, wrappingType: "rule", source: "group" };
8094
8452
  if (m?.[1].startsWith("[") && m?.[1].endsWith("]")) {
8095
8453
  const value = m?.[1].slice(1, -1).replace(/_/g, "");
8096
8454
  return {
8097
- selector: `&:is(:where(.group):is(${value}) *)`,
8455
+ selector: `&:is(${g}:is(${value}) *)`,
8098
8456
  wrappingType: "rule",
8099
8457
  source: "group"
8100
8458
  };
8101
8459
  }
8460
+ if (m?.[1]?.startsWith("not-")) {
8461
+ return { selector: `&:is(${g}${negated(m[1])} *)`, wrappingType: "rule", source: "group" };
8462
+ }
8102
8463
  if (m?.[1]?.startsWith("has-")) {
8103
8464
  const pattern = /^has-\[([a-zA-Z0-9_-]+)\]$/.exec(m?.[1]);
8104
8465
  if (pattern) {
8105
8466
  const value = pattern[1];
8106
8467
  return {
8107
- selector: `&:is(:where(.group):has(:is(${value})) *)`,
8468
+ selector: `&:is(${g}:has(:is(${value})) *)`,
8108
8469
  source: "group"
8109
8470
  };
8110
8471
  }
8111
8472
  return {
8112
- selector: `&:is(:where(.group):has(:is(${m?.[1].slice(4, -1)})) *)`,
8473
+ selector: `&:is(${g}:has(${functionalArgument(m[1].slice(5, -1))}) *)`,
8113
8474
  source: "group"
8114
8475
  };
8115
8476
  }
@@ -8119,19 +8480,19 @@ functionalModifier(
8119
8480
  const value = pattern[1];
8120
8481
  if (pattern[2]) {
8121
8482
  return {
8122
- selector: `&:is(:where(.group)[aria-${value}="${pattern[2]}"] *)`,
8483
+ selector: `&:is(${g}[aria-${value}="${pattern[2]}"] *)`,
8123
8484
  source: "group"
8124
8485
  };
8125
8486
  } else {
8126
8487
  return {
8127
- selector: `&:is(:where(.group)[aria-${value}] *)`,
8488
+ selector: `&:is(${g}[aria-${value}] *)`,
8128
8489
  source: "group"
8129
8490
  };
8130
8491
  }
8131
8492
  }
8132
8493
  }
8133
8494
  return m ? {
8134
- selector: `&:is(:where(.group):${m[1]} *)`,
8495
+ selector: `&:is(${g}:${m[1]} *)`,
8135
8496
  wrappingType: "rule",
8136
8497
  source: "group"
8137
8498
  } : {
@@ -8142,27 +8503,35 @@ functionalModifier(
8142
8503
  void 0
8143
8504
  );
8144
8505
  functionalModifier(
8145
- (mod) => /^peer-(.+)$/.test(mod),
8506
+ (mod) => /^peer-(.+)$/.test(mod) && !atRuleHas(mod),
8146
8507
  ({ selector, mod }) => {
8147
- const m = /^peer-(.+)$/.exec(mod.type);
8508
+ const raw = /^peer-(.+)$/.exec(mod.type);
8509
+ const [variant, base] = splitGroupName("peer", raw?.[1] ?? "");
8510
+ const m = raw ? [raw[0], variant] : null;
8511
+ const g = `:where(${base})`;
8512
+ const attr = m ? attributeVariantSelector(m[1]) : void 0;
8513
+ if (attr) return { selector: `&:is(${g}${attr} ~ *)`, wrappingType: "rule", source: "peer" };
8148
8514
  if (m?.[1].startsWith("[") && m?.[1].endsWith("]")) {
8149
8515
  const value2 = m?.[1].slice(1, -1).replace(/_/g, "");
8150
8516
  return {
8151
- selector: `&:is(:where(.peer):is(${value2})~*)`,
8517
+ selector: `&:is(${g}:is(${value2})~*)`,
8152
8518
  wrappingType: "rule",
8153
8519
  source: "peer"
8154
8520
  };
8155
8521
  }
8156
8522
  const value = m?.[1];
8523
+ if (value?.startsWith("has-[") && value.endsWith("]")) {
8524
+ return { selector: `&:is(${g}:has(${functionalArgument(value.slice(5, -1))}) ~ *)`, source: "peer" };
8525
+ }
8157
8526
  if (value?.startsWith("has-")) {
8158
8527
  return {
8159
- selector: `&:is(:where(.peer):has(:${value.slice(4)})~*)`,
8528
+ selector: `&:is(${g}:has(:${value.slice(4)})~*)`,
8160
8529
  source: "peer"
8161
8530
  };
8162
8531
  }
8163
8532
  if (value?.startsWith("not-")) {
8164
8533
  return {
8165
- selector: `&:is(:where(.peer):not(:${value.slice(4)})~*)`,
8534
+ selector: `&:is(${g}${negated(value)} ~ *)`,
8166
8535
  source: "peer"
8167
8536
  };
8168
8537
  }
@@ -8171,7 +8540,7 @@ functionalModifier(
8171
8540
  if (pattern) {
8172
8541
  const key = pattern[1];
8173
8542
  return {
8174
- selector: `&:is(:where(.peer)[aria-${key}]~*)`,
8543
+ selector: `&:is(${g}[aria-${key}]~*)`,
8175
8544
  source: "peer"
8176
8545
  };
8177
8546
  }
@@ -8181,19 +8550,19 @@ functionalModifier(
8181
8550
  const value2 = pattern[2];
8182
8551
  if (pattern[2]) {
8183
8552
  return {
8184
- selector: `&:is(:where(.peer)[aria-${key}="${value2}"]~*)`,
8553
+ selector: `&:is(${g}[aria-${key}="${value2}"]~*)`,
8185
8554
  source: "peer"
8186
8555
  };
8187
8556
  } else {
8188
8557
  return {
8189
- selector: `&:is(:where(.peer)[aria-${key}]~*)`,
8558
+ selector: `&:is(${g}[aria-${key}]~*)`,
8190
8559
  source: "peer"
8191
8560
  };
8192
8561
  }
8193
8562
  }
8194
8563
  }
8195
8564
  return m ? {
8196
- selector: `&:is(:where(.peer):${value}~*)`,
8565
+ selector: `&:is(${g}:${value}~*)`,
8197
8566
  source: "peer"
8198
8567
  } : {
8199
8568
  selector,
@@ -8244,8 +8613,53 @@ functionalModifier(
8244
8613
  },
8245
8614
  void 0
8246
8615
  );
8616
+ const LEADING_AT = /^\s*@(media|container)\s+([^{]*)\{/;
8617
+ const LATE_MEDIA = /prefers-color-scheme|\bprint\b|forced-colors|orientation/;
8618
+ const MIN_W = /(?:min-width\s*:\s*|width\s*>=?\s*)([\d.]+)(px|rem|em)?/;
8619
+ const MAX_W = /(?:max-width\s*:\s*|width\s*<=?\s*)([\d.]+)(px|rem|em)?/;
8620
+ function toPx(n, unit) {
8621
+ const v = parseFloat(n);
8622
+ return unit === "rem" || unit === "em" ? v * 16 : v;
8623
+ }
8624
+ function preludeKey(kind, prelude) {
8625
+ const container2 = kind === "container";
8626
+ const min = MIN_W.exec(prelude);
8627
+ if (min) return [container2 ? 4 : 2, toPx(min[1], min[2])];
8628
+ const max = MAX_W.exec(prelude);
8629
+ if (max) return [container2 ? 3 : 1, -toPx(max[1], max[2])];
8630
+ if (!container2 && LATE_MEDIA.test(prelude)) return [5, 0];
8631
+ return [0, 0];
8632
+ }
8633
+ function ruleSortKey(rule2) {
8634
+ const key = [];
8635
+ let rest = rule2;
8636
+ let m;
8637
+ while (m = LEADING_AT.exec(rest)) {
8638
+ const [g, v] = preludeKey(m[1], m[2]);
8639
+ key.push(g, v);
8640
+ rest = rest.slice(m[0].length);
8641
+ }
8642
+ return key;
8643
+ }
8644
+ function compareKeys(a, b) {
8645
+ const n = Math.min(a.length, b.length);
8646
+ for (let i = 0; i < n; i++) {
8647
+ if (a[i] !== b[i]) return a[i] - b[i];
8648
+ }
8649
+ return a.length - b.length;
8650
+ }
8651
+ function upperBound(keys, key) {
8652
+ let lo = 0;
8653
+ let hi = keys.length;
8654
+ while (lo < hi) {
8655
+ const mid = lo + hi >> 1;
8656
+ if (compareKeys(keys[mid], key) <= 0) lo = mid + 1;
8657
+ else hi = mid;
8658
+ }
8659
+ return lo;
8660
+ }
8247
8661
  class StylePartitionManager {
8248
- constructor(insertionPoint, maxRulesPerPartition = 50, styleIdPrefix = "barocss-style-partition-") {
8662
+ constructor(insertionPoint, maxRulesPerPartition = 50, styleIdPrefix = "barocss-style-partition-", getCategory = (cls) => parseClassName(cls).utility?.category) {
8249
8663
  this.partitions = [];
8250
8664
  this.categoryPartitions = /* @__PURE__ */ new Map();
8251
8665
  this.partitionCounter = 0;
@@ -8256,12 +8670,30 @@ class StylePartitionManager {
8256
8670
  this.insertionPoint = insertionPoint;
8257
8671
  this.maxRulesPerPartition = maxRulesPerPartition;
8258
8672
  this.styleIdPrefix = styleIdPrefix;
8673
+ this.getCategory = getCategory;
8259
8674
  this.initializeDefaultPartition();
8260
8675
  }
8676
+ /**
8677
+ * Insert `rule` at its Tailwind variant position within `partition` (#254):
8678
+ * one insertRule at a binary-searched index, no sheet rewrite.
8679
+ */
8680
+ insertSorted(partition, rule2, key) {
8681
+ const keys = partition.keys ??= [];
8682
+ const index = upperBound(keys, key);
8683
+ const sheet = partition.styleElement.sheet;
8684
+ if (sheet && sheet.cssRules.length === keys.length) {
8685
+ sheet.insertRule(this.escapeCssRule(rule2), index);
8686
+ partition.styles.splice(index, 0, rule2);
8687
+ } else {
8688
+ partition.styles.splice(index, 0, rule2);
8689
+ partition.styleElement.textContent = partition.styles.join("\n") + "\n";
8690
+ }
8691
+ keys.splice(index, 0, key);
8692
+ }
8261
8693
  initializeDefaultPartition() {
8262
8694
  this.createNewPartition();
8263
8695
  }
8264
- createNewCategoryPartition(category) {
8696
+ createNewCategoryPartition(category, atDocumentStart = false) {
8265
8697
  const newPartition = {
8266
8698
  id: this.styleIdPrefix + `-${category}`,
8267
8699
  styles: [],
@@ -8270,7 +8702,12 @@ class StylePartitionManager {
8270
8702
  newPartition.styleElement.id = newPartition.id;
8271
8703
  newPartition.styleElement.setAttribute("data-barocss", "partition");
8272
8704
  newPartition.styleElement.setAttribute("data-category", category);
8273
- this.insertionPoint.appendChild(newPartition.styleElement);
8705
+ const head = this.insertionPoint.ownerDocument?.head;
8706
+ if (atDocumentStart && head) {
8707
+ head.insertBefore(newPartition.styleElement, head.firstChild);
8708
+ } else {
8709
+ this.insertionPoint.appendChild(newPartition.styleElement);
8710
+ }
8274
8711
  this.categoryPartitions.set(category, newPartition);
8275
8712
  return newPartition;
8276
8713
  }
@@ -8324,20 +8761,21 @@ class StylePartitionManager {
8324
8761
  if (this.hasRule(rule2)) {
8325
8762
  return false;
8326
8763
  }
8327
- if (this.currentPartition.styles.length >= this.maxRulesPerPartition) {
8328
- this.createNewPartition();
8764
+ const key = ruleSortKey(rule2);
8765
+ let partitionIndex = this.partitions.findIndex((p) => {
8766
+ const keys = p.keys;
8767
+ return !!keys && keys.length > 0 && compareKeys(keys[keys.length - 1], key) > 0;
8768
+ });
8769
+ if (partitionIndex === -1) {
8770
+ if (this.currentPartition.styles.length >= this.maxRulesPerPartition) {
8771
+ this.createNewPartition();
8772
+ }
8773
+ partitionIndex = this.partitions.length - 1;
8329
8774
  }
8330
- const currentPartition = this.currentPartition;
8331
- const partitionIndex = this.partitions.length - 1;
8775
+ const partition = this.partitions[partitionIndex];
8332
8776
  try {
8333
- const sheet = currentPartition.styleElement.sheet;
8334
- if (sheet) {
8335
- sheet.insertRule(this.escapeCssRule(rule2), sheet.cssRules.length);
8336
- } else {
8337
- currentPartition.styleElement.textContent += rule2 + "\n";
8338
- }
8777
+ this.insertSorted(partition, rule2, key);
8339
8778
  this.setRuleCache(rule2, partitionIndex);
8340
- currentPartition.styles.push(rule2);
8341
8779
  return true;
8342
8780
  } catch (error) {
8343
8781
  console.warn(
@@ -8356,12 +8794,7 @@ class StylePartitionManager {
8356
8794
  categoryPartition = this.createNewCategoryPartition(category);
8357
8795
  }
8358
8796
  try {
8359
- const sheet = categoryPartition.styleElement.sheet;
8360
- if (sheet) {
8361
- sheet.insertRule(this.escapeCssRule(rule2), sheet.cssRules.length);
8362
- } else {
8363
- categoryPartition.styleElement.textContent += rule2 + "\n";
8364
- }
8797
+ this.insertSorted(categoryPartition, rule2, ruleSortKey(rule2));
8365
8798
  } catch (error) {
8366
8799
  console.warn(
8367
8800
  `[StylePartitionManager] Failed to insert rule in category: ${category} ${rule2}`,
@@ -8370,7 +8803,6 @@ class StylePartitionManager {
8370
8803
  return false;
8371
8804
  }
8372
8805
  this.setCategoryRuleCache(rule2, category);
8373
- categoryPartition.styles.push(rule2);
8374
8806
  return true;
8375
8807
  }
8376
8808
  addRootRules(rules) {
@@ -8400,8 +8832,7 @@ class StylePartitionManager {
8400
8832
  let success = 0;
8401
8833
  let failed = 0;
8402
8834
  for (const rule2 of rules) {
8403
- const parsedResult = parseResultCache.get(rule2.cls);
8404
- const category = parsedResult?.utility?.category;
8835
+ const category = this.getCategory(rule2.cls);
8405
8836
  if (category) {
8406
8837
  for (const css of rule2.cssList) {
8407
8838
  this.addCategoryRule(css, category);
@@ -8418,6 +8849,41 @@ class StylePartitionManager {
8418
8849
  }
8419
8850
  return { success, failed };
8420
8851
  }
8852
+ /**
8853
+ * Remove one generated rule (#269 GC). Keeps `styles`, the #254 `keys` and the
8854
+ * sheet's cssRules parallel: one deleteRule at the rule's index, or a text
8855
+ * rebuild when the sheet isn't solely ours / has no CSSOM. Returns whether
8856
+ * the rule was found.
8857
+ */
8858
+ removeRule(rule2, category) {
8859
+ let partition;
8860
+ if (category) {
8861
+ if (this.classToCategoryPartitionMap.get(rule2) !== category) return false;
8862
+ partition = this.categoryPartitions.get(category);
8863
+ } else {
8864
+ const partitionIndex = this.classToPartitionMap.get(rule2);
8865
+ partition = partitionIndex === void 0 ? void 0 : this.partitions[partitionIndex];
8866
+ }
8867
+ if (!partition) return false;
8868
+ const index = partition.styles.indexOf(rule2);
8869
+ if (index === -1) return false;
8870
+ const sheet = partition.styleElement.sheet;
8871
+ const inSync = !!sheet && sheet.cssRules.length === partition.styles.length;
8872
+ partition.styles.splice(index, 1);
8873
+ partition.keys?.splice(index, 1);
8874
+ if (inSync && sheet) {
8875
+ sheet.deleteRule(index);
8876
+ } else {
8877
+ partition.styleElement.textContent = partition.styles.length ? partition.styles.join("\n") + "\n" : "";
8878
+ }
8879
+ if (category) this.classToCategoryPartitionMap.delete(rule2);
8880
+ else this.classToPartitionMap.delete(rule2);
8881
+ return true;
8882
+ }
8883
+ /** Number of generated (non-root, non-preflight) rules currently held. */
8884
+ get ruleCount() {
8885
+ return this.classToPartitionMap.size + this.classToCategoryPartitionMap.size;
8886
+ }
8421
8887
  /**
8422
8888
  * 특정 규칙이 어느 파티션에 있는지 찾기
8423
8889
  */
@@ -8432,12 +8898,12 @@ class StylePartitionManager {
8432
8898
  }
8433
8899
  return null;
8434
8900
  }
8435
- updateRuleContent(category, ruleContent) {
8901
+ updateRuleContent(category, ruleContent, atDocumentStart = false) {
8436
8902
  const partition = this.getCategoryPartition(category);
8437
8903
  if (partition) {
8438
8904
  partition.styleElement.textContent = ruleContent;
8439
8905
  } else {
8440
- const newPartition = this.createNewCategoryPartition(category);
8906
+ const newPartition = this.createNewCategoryPartition(category, atDocumentStart);
8441
8907
  console.log(`[StylePartitionManager] Created new partition for category: ${category}`);
8442
8908
  newPartition.styleElement.textContent = ruleContent;
8443
8909
  }
@@ -8465,8 +8931,8 @@ class StylePartitionManager {
8465
8931
  }
8466
8932
  function normalizeClassName(className) {
8467
8933
  if (!className) return "";
8468
- if (className instanceof SVGAnimatedString) {
8469
- return className.baseVal.toString();
8934
+ if (typeof className === "object" && typeof className.baseVal === "string") {
8935
+ return className.baseVal;
8470
8936
  }
8471
8937
  return className.toString();
8472
8938
  }
@@ -8481,10 +8947,15 @@ class ChangeDetector {
8481
8947
  * @param incrementalParser - IncrementalParser instance for class processing
8482
8948
  * @param BrowserRuntime - Optional BrowserRuntime instance for CSS injection
8483
8949
  */
8484
- constructor(incrementalParser, BrowserRuntime2) {
8950
+ constructor(incrementalParser, BrowserRuntime2, getCategory = (cls) => parseClassName(cls).utility?.category) {
8485
8951
  this.observer = null;
8952
+ this.gc = null;
8486
8953
  this.incrementalParser = incrementalParser;
8487
8954
  this.BrowserRuntime = BrowserRuntime2;
8955
+ this.getCategory = getCategory;
8956
+ }
8957
+ setGc(gc) {
8958
+ this.gc = gc;
8488
8959
  }
8489
8960
  setParser(parser) {
8490
8961
  this.incrementalParser = parser;
@@ -8512,10 +8983,20 @@ class ChangeDetector {
8512
8983
  if (this.observer) {
8513
8984
  this.observer.disconnect();
8514
8985
  }
8986
+ this.gc?.setRoot(root);
8515
8987
  this.observer = new MutationObserver((mutations) => {
8516
8988
  const newClasses = /* @__PURE__ */ new Set();
8989
+ const gc = this.gc;
8517
8990
  mutations.forEach((mutation) => {
8518
- if (mutation.type === "attributes" && mutation.attributeName === "class") {
8991
+ if (gc) {
8992
+ if (mutation.type === "attributes") {
8993
+ gc.reconcile(mutation.target);
8994
+ } else if (mutation.type === "childList") {
8995
+ mutation.removedNodes.forEach((node) => gc.reconcileTree(node));
8996
+ mutation.addedNodes.forEach((node) => gc.reconcileTree(node));
8997
+ }
8998
+ }
8999
+ if (mutation.type === "attributes" && mutation.attributeName === "class" && root.contains(mutation.target)) {
8519
9000
  const target = mutation.target;
8520
9001
  if (target.className) {
8521
9002
  const classes = normalizeClassNameList(target.className);
@@ -8528,9 +9009,10 @@ class ChangeDetector {
8528
9009
  }
8529
9010
  if (mutation.type === "childList") {
8530
9011
  mutation.addedNodes.forEach((node) => {
8531
- if (node instanceof Element) {
8532
- this.processElement(node, newClasses);
8533
- node.querySelectorAll("[class]").forEach((el) => {
9012
+ if (node.nodeType === Node.ELEMENT_NODE && root.contains(node)) {
9013
+ const element = node;
9014
+ this.processElement(element, newClasses);
9015
+ element.querySelectorAll("[class]").forEach((el) => {
8534
9016
  this.processElement(el, newClasses);
8535
9017
  });
8536
9018
  }
@@ -8541,7 +9023,10 @@ class ChangeDetector {
8541
9023
  const classesArray = Array.from(newClasses);
8542
9024
  const results = this.incrementalParser.processClasses(classesArray);
8543
9025
  this.BrowserRuntime?.applyParseResults(results);
9026
+ } else {
9027
+ this.BrowserRuntime?.applyParseResults([]);
8544
9028
  }
9029
+ gc?.afterBatch();
8545
9030
  });
8546
9031
  this.observer.observe(root, {
8547
9032
  attributes: true,
@@ -8581,11 +9066,13 @@ class ChangeDetector {
8581
9066
  if (existingClasses.size > 0) {
8582
9067
  const classes = Array.from(existingClasses);
8583
9068
  const results = this.incrementalParser.processClasses(classes);
8584
- const layoutResults = results.filter((result) => parseResultCache.get(result.cls)?.utility?.category === "layout");
8585
- const nonLayoutResults = results.filter((result) => parseResultCache.get(result.cls)?.utility?.category !== "layout");
9069
+ const layoutResults = results.filter((result) => this.getCategory(result.cls) === "layout");
9070
+ const nonLayoutResults = results.filter((result) => this.getCategory(result.cls) !== "layout");
8586
9071
  this.BrowserRuntime?.applyParseResults(layoutResults);
8587
9072
  options?.onReady?.();
8588
9073
  this.BrowserRuntime?.applyParseResults(nonLayoutResults);
9074
+ } else {
9075
+ options?.onReady?.();
8589
9076
  }
8590
9077
  }
8591
9078
  /**
@@ -8624,22 +9111,184 @@ class ChangeDetector {
8624
9111
  }
8625
9112
  }
8626
9113
  }
9114
+ function unescapeCssIdent(s) {
9115
+ return s.replace(/\\([0-9a-fA-F]{1,6})\s?|\\(.)/g, (_m, hex, ch) => hex ? String.fromCodePoint(parseInt(hex, 16)) : ch);
9116
+ }
9117
+ const LEADING_CLASS = /^\s*\.((?:\\[0-9a-fA-F]{1,6}\s?|\\.|[\w-]|[^\x00-\x7F])+)/;
9118
+ function splitTopLevel(sel) {
9119
+ const parts = [];
9120
+ let depth = 0, start = 0;
9121
+ for (let i = 0; i < sel.length; i++) {
9122
+ const c = sel[i];
9123
+ if (c === "\\") i++;
9124
+ else if (c === "(" || c === "[") depth++;
9125
+ else if (c === ")" || c === "]") depth--;
9126
+ else if (c === "," && depth === 0) {
9127
+ parts.push(sel.slice(start, i));
9128
+ start = i + 1;
9129
+ }
9130
+ }
9131
+ parts.push(sel.slice(start));
9132
+ return parts;
9133
+ }
9134
+ function collectLeadingClasses(rules, out = /* @__PURE__ */ new Set()) {
9135
+ for (const rule2 of Array.from(rules)) {
9136
+ const selectorText = rule2.selectorText;
9137
+ if (typeof selectorText === "string") {
9138
+ for (const part of splitTopLevel(selectorText)) {
9139
+ const m = LEADING_CLASS.exec(part);
9140
+ if (m) out.add(unescapeCssIdent(m[1]));
9141
+ }
9142
+ }
9143
+ const inner = rule2.cssRules;
9144
+ if (inner && inner.length) collectLeadingClasses(inner, out);
9145
+ }
9146
+ return out;
9147
+ }
9148
+ class ClassGc {
9149
+ constructor(host, graceMs, maxRules, now = () => Date.now()) {
9150
+ this.host = host;
9151
+ this.graceMs = graceMs;
9152
+ this.maxRules = maxRules;
9153
+ this.now = now;
9154
+ this.counts = /* @__PURE__ */ new Map();
9155
+ this.counted = /* @__PURE__ */ new WeakMap();
9156
+ this.candidates = /* @__PURE__ */ new Map();
9157
+ this.timer = null;
9158
+ this.root = null;
9159
+ }
9160
+ /** Start counting for a new root: count every element currently inside it. */
9161
+ setRoot(root) {
9162
+ this.counts.clear();
9163
+ this.counted = /* @__PURE__ */ new WeakMap();
9164
+ this.candidates.clear();
9165
+ this.cancel();
9166
+ this.root = root;
9167
+ this.reconcileTree(root);
9168
+ }
9169
+ count(cls) {
9170
+ return this.counts.get(cls) ?? 0;
9171
+ }
9172
+ /** Re-count `el` and (optionally) all its descendants from their current state. */
9173
+ reconcileTree(node) {
9174
+ if (node.nodeType !== 1) return;
9175
+ const el = node;
9176
+ this.reconcile(el);
9177
+ el.querySelectorAll("[class]").forEach((child) => this.reconcile(child));
9178
+ }
9179
+ reconcile(el) {
9180
+ const root = this.root;
9181
+ const live = !!root && root.contains(el);
9182
+ const next = live ? Array.from(new Set(normalizeClassNameList(el.getAttribute("class")))) : [];
9183
+ const prev = this.counted.get(el);
9184
+ if (!prev && next.length === 0) return;
9185
+ const prevSet = new Set(prev ?? []);
9186
+ const nextSet = new Set(next);
9187
+ for (const cls of nextSet) {
9188
+ if (prevSet.has(cls)) continue;
9189
+ const c = (this.counts.get(cls) ?? 0) + 1;
9190
+ this.counts.set(cls, c);
9191
+ this.candidates.delete(cls);
9192
+ }
9193
+ for (const cls of prevSet) {
9194
+ if (nextSet.has(cls)) continue;
9195
+ const c = (this.counts.get(cls) ?? 0) - 1;
9196
+ if (c > 0) {
9197
+ this.counts.set(cls, c);
9198
+ } else {
9199
+ this.counts.delete(cls);
9200
+ this.candidates.delete(cls);
9201
+ this.candidates.set(cls, this.now());
9202
+ }
9203
+ }
9204
+ if (next.length) this.counted.set(el, next);
9205
+ else this.counted.delete(el);
9206
+ }
9207
+ /** Call after a mutation batch has been counted and its classes inserted. */
9208
+ afterBatch() {
9209
+ if (this.candidates.size === 0) return;
9210
+ if (this.host.cachedCount() > this.maxRules) {
9211
+ this.schedule(0);
9212
+ } else {
9213
+ this.schedule(this.graceMs);
9214
+ }
9215
+ }
9216
+ schedule(delay) {
9217
+ if (this.timer !== null) {
9218
+ if (delay > 0) return;
9219
+ clearTimeout(this.timer);
9220
+ }
9221
+ this.timer = setTimeout(() => {
9222
+ this.timer = null;
9223
+ this.sweep();
9224
+ }, delay);
9225
+ }
9226
+ /** Reclaim candidates whose grace period elapsed (plus LRU overflow). Public for tests. */
9227
+ sweep() {
9228
+ const now = this.now();
9229
+ const overflow = Math.max(0, this.host.cachedCount() - this.maxRules);
9230
+ const doomed = [];
9231
+ let evicted = 0;
9232
+ for (const [cls, since] of this.candidates) {
9233
+ const expired = now - since >= this.graceMs;
9234
+ if (!expired && evicted >= overflow) continue;
9235
+ this.candidates.delete(cls);
9236
+ if (this.count(cls) > 0 || this.inDom(cls) || this.host.isPermanent(cls)) continue;
9237
+ doomed.push(cls);
9238
+ if (!expired) evicted++;
9239
+ }
9240
+ if (doomed.length) this.host.reclaim(doomed);
9241
+ if (this.candidates.size) this.schedule(this.graceMs);
9242
+ }
9243
+ inDom(cls) {
9244
+ const root = this.root;
9245
+ if (!root) return false;
9246
+ const doc = root.ownerDocument ?? document;
9247
+ return root.classList.contains(cls) || doc.documentElement.classList.contains(cls) || doc.getElementsByClassName(cls).length > 0;
9248
+ }
9249
+ cancel() {
9250
+ if (this.timer !== null) clearTimeout(this.timer);
9251
+ this.timer = null;
9252
+ }
9253
+ stats() {
9254
+ return { trackedClasses: this.counts.size, candidates: this.candidates.size };
9255
+ }
9256
+ }
9257
+ const LAYER_ORDER = "@layer theme, base, components, utilities;";
8627
9258
  class BrowserRuntime {
8628
9259
  constructor(options = {}) {
8629
9260
  this.cache = /* @__PURE__ */ new Map();
8630
9261
  this.rootCache = /* @__PURE__ */ new Set();
8631
9262
  this.isDestroyed = false;
9263
+ this.existing = null;
9264
+ this.existingSheetCount = -1;
9265
+ this.pinned = /* @__PURE__ */ new Set();
9266
+ this.gc = null;
9267
+ this.reclaimedCount = 0;
9268
+ this.getCategory = (cls) => parseClassName(cls, this.context).utility?.category;
8632
9269
  const defaultConfig = {};
8633
9270
  this.options = {
8634
9271
  config: options.config || defaultConfig,
8635
9272
  styleId: options.styleId || "barocss-runtime",
8636
9273
  insertionPoint: options.insertionPoint || "head",
8637
- maxRulesPerPartition: options.maxRulesPerPartition || 50
9274
+ maxRulesPerPartition: options.maxRulesPerPartition || 50,
9275
+ skipExisting: options.skipExisting ?? false,
9276
+ gc: options.gc ?? true,
9277
+ gcGraceMs: options.gcGraceMs ?? 3e3,
9278
+ maxRules: options.maxRules ?? Infinity
8638
9279
  };
8639
9280
  this.context = createContext(this.options.config);
8640
9281
  this.incrementalParser = new IncrementalParser(this.context);
8641
- this.changeDetector = new ChangeDetector(this.incrementalParser, this);
8642
- this.stylePartitionManager = new StylePartitionManager(this.getInsertionPoint(), this.options.maxRulesPerPartition, `${this.options.styleId}-partition`);
9282
+ this.changeDetector = new ChangeDetector(this.incrementalParser, this, this.getCategory);
9283
+ this.stylePartitionManager = new StylePartitionManager(this.getInsertionPoint(), this.options.maxRulesPerPartition, `${this.options.styleId}-partition`, this.getCategory);
9284
+ if (this.options.gc) {
9285
+ this.gc = new ClassGc({
9286
+ reclaim: (classes) => this.reclaim(classes),
9287
+ isPermanent: (cls) => this.isPermanent(cls),
9288
+ cachedCount: () => this.cache.size
9289
+ }, this.options.gcGraceMs, this.options.maxRules);
9290
+ this.changeDetector.setGc(this.gc);
9291
+ }
8643
9292
  this.init();
8644
9293
  }
8645
9294
  // Debugging and logging helpers
@@ -8656,9 +9305,17 @@ class BrowserRuntime {
8656
9305
  this.ensureCssVars();
8657
9306
  }
8658
9307
  injectPreflightCSS() {
8659
- if (this.options.config.preflight) {
8660
- const preflightCSS = this.context.getPreflightCSS(this.options.config.preflight);
8661
- this.stylePartitionManager.updateRuleContent("preflight", preflightCSS);
9308
+ const level = this.options.config.preflight ?? true;
9309
+ if (level) {
9310
+ const preflightCSS = this.context.getPreflightCSS(level);
9311
+ this.stylePartitionManager.updateRuleContent(
9312
+ "preflight",
9313
+ `${LAYER_ORDER}
9314
+ @layer base {
9315
+ ${preflightCSS}
9316
+ }`,
9317
+ true
9318
+ );
8662
9319
  }
8663
9320
  }
8664
9321
  ensureCssVars() {
@@ -8667,7 +9324,7 @@ class BrowserRuntime {
8667
9324
  this.stylePartitionManager.updateRuleContent("css-vars", cssVars);
8668
9325
  }
8669
9326
  getInsertionPoint() {
8670
- if (this.options.insertionPoint instanceof HTMLElement) {
9327
+ if (typeof this.options.insertionPoint !== "string") {
8671
9328
  return this.options.insertionPoint;
8672
9329
  }
8673
9330
  switch (this.options.insertionPoint) {
@@ -8683,7 +9340,8 @@ class BrowserRuntime {
8683
9340
  */
8684
9341
  addClass(classes) {
8685
9342
  if (this.isDestroyed) return;
8686
- const classList = this.normalizeClasses(classes);
9343
+ const classList = this.normalizeClasses(classes).filter(Boolean);
9344
+ classList.forEach((cls) => this.pinned.add(cls));
8687
9345
  this.processClasses(classList);
8688
9346
  }
8689
9347
  /**
@@ -8712,6 +9370,11 @@ class BrowserRuntime {
8712
9370
  results = [...existingResults, ...results];
8713
9371
  results.forEach((result) => this.incrementalParser.markProcessed(result.cls));
8714
9372
  }
9373
+ if (this.options.skipExisting && results.length > 0 && typeof document !== "undefined") {
9374
+ const existing = this.getExistingClasses();
9375
+ results = results.filter((result) => !existing.has(result.cls));
9376
+ }
9377
+ if (results.length === 0) return;
8715
9378
  const cssRules = [];
8716
9379
  const rootCssRules = [];
8717
9380
  for (const result of results) {
@@ -8739,6 +9402,58 @@ class BrowserRuntime {
8739
9402
  rootCssCount: rootCssRules.length
8740
9403
  });
8741
9404
  }
9405
+ /** #269: a class that must never be reclaimed. */
9406
+ isPermanent(cls) {
9407
+ if (this.pinned.has(cls)) return true;
9408
+ if (typeof document === "undefined") return true;
9409
+ return this.getExistingClasses().has(cls);
9410
+ }
9411
+ /**
9412
+ * #269: delete the generated rules of classes no live element uses. Root/@property rules stay
9413
+ * (they are shared and harmless); a rule text another cached class still emits is kept.
9414
+ */
9415
+ reclaim(classes) {
9416
+ if (this.isDestroyed) return;
9417
+ const victims = classes.filter((cls) => this.cache.has(cls));
9418
+ if (victims.length === 0) return;
9419
+ const results = victims.map((cls) => this.cache.get(cls));
9420
+ victims.forEach((cls) => {
9421
+ this.cache.delete(cls);
9422
+ this.incrementalParser.unmarkProcessed(cls);
9423
+ });
9424
+ const stillUsed = /* @__PURE__ */ new Set();
9425
+ for (const result of this.cache.values()) result.cssList.forEach((css) => stillUsed.add(css));
9426
+ for (const result of results) {
9427
+ const category = this.getCategory(result.cls);
9428
+ for (const css of result.cssList) {
9429
+ if (!stillUsed.has(css)) this.stylePartitionManager.removeRule(css, category);
9430
+ }
9431
+ }
9432
+ this.reclaimedCount += victims.length;
9433
+ }
9434
+ /** Class names defined by the page's own stylesheets (BaroCSS's sheets and cross-origin sheets excluded). */
9435
+ getExistingClasses() {
9436
+ const own = new Set(Array.from(document.querySelectorAll("style[data-barocss]"), (s) => s.sheet));
9437
+ const sheets = Array.from(document.styleSheets).filter((sheet) => {
9438
+ if (own.has(sheet)) return false;
9439
+ const owner = sheet.ownerNode;
9440
+ return !(owner && typeof owner.hasAttribute === "function" && (owner.hasAttribute("data-barocss") || (owner.id || "").startsWith(this.options.styleId)));
9441
+ });
9442
+ if (this.existing && sheets.length === this.existingSheetCount) return this.existing;
9443
+ const out = /* @__PURE__ */ new Set();
9444
+ for (const sheet of sheets) {
9445
+ let rules;
9446
+ try {
9447
+ rules = sheet.cssRules;
9448
+ } catch {
9449
+ continue;
9450
+ }
9451
+ collectLeadingClasses(rules, out);
9452
+ }
9453
+ this.existing = out;
9454
+ this.existingSheetCount = sheets.length;
9455
+ return out;
9456
+ }
8742
9457
  /**
8743
9458
  * MutationObserver instance method to automatically call addClass when class attributes change in DOM
8744
9459
  */
@@ -8757,7 +9472,7 @@ class BrowserRuntime {
8757
9472
  return css;
8758
9473
  }
8759
9474
  getAllCss() {
8760
- const all = Array.from(this.cache.values()).flatMap((result) => result.cssList).join("\n");
9475
+ const all = [...this.rootCache, ...Array.from(this.cache.values()).flatMap((result) => result.cssList)].join("\n");
8761
9476
  return all;
8762
9477
  }
8763
9478
  getClasses() {
@@ -8772,7 +9487,10 @@ class BrowserRuntime {
8772
9487
  return {
8773
9488
  runtime: {
8774
9489
  cachedClasses: this.cache.size,
8775
- rootCacheSize: this.rootCache.size
9490
+ rootCacheSize: this.rootCache.size,
9491
+ ruleCount: this.stylePartitionManager.ruleCount,
9492
+ reclaimedClasses: this.reclaimedCount,
9493
+ gc: this.gc?.stats() ?? null
8776
9494
  },
8777
9495
  ast: incremental.cacheStats.ast,
8778
9496
  incremental
@@ -8788,7 +9506,7 @@ class BrowserRuntime {
8788
9506
  clearAstCache(this.context);
8789
9507
  this.incrementalParser.clearProcessed();
8790
9508
  this.stylePartitionManager.cleanup();
8791
- this.stylePartitionManager = new StylePartitionManager(this.getInsertionPoint(), this.options.maxRulesPerPartition, `${this.options.styleId}-partition`);
9509
+ this.stylePartitionManager = new StylePartitionManager(this.getInsertionPoint(), this.options.maxRulesPerPartition, `${this.options.styleId}-partition`, this.getCategory);
8792
9510
  this.injectPreflightCSS();
8793
9511
  this.ensureCssVars();
8794
9512
  }
@@ -8798,7 +9516,7 @@ class BrowserRuntime {
8798
9516
  this.rootCache.clear();
8799
9517
  this.incrementalParser.clearProcessed();
8800
9518
  this.stylePartitionManager.cleanup();
8801
- this.stylePartitionManager = new StylePartitionManager(this.getInsertionPoint(), this.options.maxRulesPerPartition, `${this.options.styleId}-partition`);
9519
+ this.stylePartitionManager = new StylePartitionManager(this.getInsertionPoint(), this.options.maxRulesPerPartition, `${this.options.styleId}-partition`, this.getCategory);
8802
9520
  this.injectPreflightCSS();
8803
9521
  this.ensureCssVars();
8804
9522
  }
@@ -8826,6 +9544,7 @@ class BrowserRuntime {
8826
9544
  destroy() {
8827
9545
  if (this.isDestroyed) return;
8828
9546
  this.changeDetector.disconnect();
9547
+ this.gc?.cancel();
8829
9548
  this.stylePartitionManager.cleanup();
8830
9549
  this.cache.clear();
8831
9550
  this.rootCache.clear();
@@ -8843,13 +9562,22 @@ class BrowserRuntime {
8843
9562
  }
8844
9563
  }
8845
9564
  let runtime = null;
8846
- function getRuntime(options) {
8847
- if (!runtime) {
9565
+ let runtimeConfig;
9566
+ function getRuntime(options = {}) {
9567
+ if (!runtime || runtime.getStats().isDestroyed) {
8848
9568
  runtime = new BrowserRuntime(options);
9569
+ runtimeConfig = options.config;
9570
+ } else if (options.config && options.config !== runtimeConfig) {
9571
+ runtime.updateConfig(options.config);
9572
+ runtimeConfig = options.config;
8849
9573
  }
8850
9574
  return runtime;
8851
9575
  }
8852
9576
  function baroBoot({ loadingClassName = "baro-boot", ...options } = {}) {
9577
+ if (!document.body) {
9578
+ document.addEventListener("DOMContentLoaded", () => baroBoot({ loadingClassName, ...options }), { once: true });
9579
+ return;
9580
+ }
8853
9581
  const startClassName = `${loadingClassName}-doing`;
8854
9582
  const endClassName = `${loadingClassName}-done`;
8855
9583
  try {
@@ -8860,18 +9588,87 @@ function baroBoot({ loadingClassName = "baro-boot", ...options } = {}) {
8860
9588
  document.body.classList.add(endClassName);
8861
9589
  } });
8862
9590
  } catch (error) {
9591
+ document.body?.classList.remove(startClassName);
8863
9592
  console.error("BaroCSS boot failed:", error);
8864
9593
  }
8865
9594
  }
8866
9595
  const baroStart = baroBoot;
9596
+ function collectJsonRenderClassNames(spec) {
9597
+ if (!spec || typeof spec !== "object" || Array.isArray(spec)) return [];
9598
+ const elements = spec.elements;
9599
+ if (!elements || typeof elements !== "object" || Array.isArray(elements)) return [];
9600
+ const classes = /* @__PURE__ */ new Set();
9601
+ for (const key of Object.keys(elements)) {
9602
+ const element = elements[key];
9603
+ if (!element || typeof element !== "object" || Array.isArray(element)) continue;
9604
+ const props = element.props;
9605
+ if (!props || typeof props !== "object" || Array.isArray(props)) continue;
9606
+ const className = props.className;
9607
+ if (typeof className !== "string") continue;
9608
+ for (const cls of className.split(/\s+/)) {
9609
+ if (cls) classes.add(cls);
9610
+ }
9611
+ }
9612
+ return Array.from(classes);
9613
+ }
9614
+ function preloadJsonRenderClasses(spec, runtime2) {
9615
+ const classes = collectJsonRenderClassNames(spec);
9616
+ if (classes.length > 0) runtime2.addClass(classes);
9617
+ }
9618
+ const SHADCN_COLOR_NAMES = [
9619
+ "background",
9620
+ "foreground",
9621
+ "card",
9622
+ "card-foreground",
9623
+ "popover",
9624
+ "popover-foreground",
9625
+ "primary",
9626
+ "primary-foreground",
9627
+ "secondary",
9628
+ "secondary-foreground",
9629
+ "muted",
9630
+ "muted-foreground",
9631
+ "accent",
9632
+ "accent-foreground",
9633
+ "destructive",
9634
+ "border",
9635
+ "input",
9636
+ "ring",
9637
+ "chart-1",
9638
+ "chart-2",
9639
+ "chart-3",
9640
+ "chart-4",
9641
+ "chart-5",
9642
+ "sidebar",
9643
+ "sidebar-foreground",
9644
+ "sidebar-primary",
9645
+ "sidebar-primary-foreground",
9646
+ "sidebar-accent",
9647
+ "sidebar-accent-foreground",
9648
+ "sidebar-border",
9649
+ "sidebar-ring"
9650
+ ];
9651
+ const shadcnTheme = {
9652
+ colors: Object.fromEntries(SHADCN_COLOR_NAMES.map((n) => [n, `var(--${n})`])),
9653
+ borderRadius: {
9654
+ sm: "calc(var(--radius) - 4px)",
9655
+ md: "calc(var(--radius) - 2px)",
9656
+ lg: "var(--radius)",
9657
+ xl: "calc(var(--radius) + 4px)"
9658
+ }
9659
+ };
8867
9660
  export {
8868
9661
  BrowserRuntime,
8869
9662
  ChangeDetector,
9663
+ LAYER_ORDER,
8870
9664
  StylePartitionManager,
8871
9665
  baroBoot,
8872
9666
  baroStart,
9667
+ collectJsonRenderClassNames,
8873
9668
  getRuntime,
8874
9669
  normalizeClassName,
8875
- normalizeClassNameList
9670
+ normalizeClassNameList,
9671
+ preloadJsonRenderClasses,
9672
+ shadcnTheme
8876
9673
  };
8877
9674
  //# sourceMappingURL=barocss.js.map