@barocss/kit 0.8.2 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -436,6 +436,26 @@ function staticUtility(name, decls, opts, ctx) {
436
436
  * category: 'layout',
437
437
  * });
438
438
  */
439
+ /**
440
+ * #300: a theme key that no built-in utility names (`theme.extend.borderRadius.card`) still resolves, as in
441
+ * Tailwind 4 where `--radius-card` gives `rounded-card`. Only word keys that start with a letter (numbers stay
442
+ * bare values), never `DEFAULT`; unknown keys return null so the utility emits nothing (#213).
443
+ */
444
+ function themeKeyEntry(ctx, namespace, key) {
445
+ if (key === "DEFAULT" || !/^[a-zA-Z][\w-]*$/.test(key) || typeof ctx?.theme !== "function") return void 0;
446
+ const table = ctx.theme(namespace);
447
+ if (!table || typeof table !== "object" || !Object.prototype.hasOwnProperty.call(table, key)) return void 0;
448
+ return table[key] ?? void 0;
449
+ }
450
+ /** #300: the literal value of `theme.<namespace>.<key>` when it is a string, else null. */
451
+ function themeKeyValue(ctx, namespace, key) {
452
+ const v = themeKeyEntry(ctx, namespace, key);
453
+ return typeof v === "string" ? v : null;
454
+ }
455
+ /** #300: `var(--<varPrefix>-<key>)` when `theme.<namespace>.<key>` exists (the :root var BaroCSS emits for it), else null. */
456
+ function themeKeyVar(ctx, namespace, key, varPrefix) {
457
+ return themeKeyEntry(ctx, namespace, key) === void 0 ? null : `var(--${varPrefix}-${key})`;
458
+ }
439
459
  /** #261: `var(--spacing-<key>)` for a named (non-numeric) `theme.spacing` key, else null. */
440
460
  function spacingKeyValue(ctx, key, negative) {
441
461
  if (key === "px" || !/^[a-zA-Z][\w-]*$/.test(key) || ctx.theme("spacing", key) == null) return null;
@@ -478,12 +498,18 @@ function functionalUtility(opts, ctx) {
478
498
  }
479
499
  let themeValue;
480
500
  if (opts.themeKey && ctx.theme) themeValue = themeScalar(ctx.theme(opts.themeKey, finalValue));
501
+ let namespace = themeValue !== void 0 ? opts.themeKey : void 0;
481
502
  if (!themeValue && opts.themeKeys && ctx.theme) for (const key of opts.themeKeys) {
482
503
  themeValue = themeScalar(ctx.theme(key, finalValue));
483
- if (themeValue !== void 0) break;
504
+ if (themeValue !== void 0) {
505
+ namespace = key;
506
+ break;
507
+ }
484
508
  }
485
509
  if (themeValue !== void 0) {
486
- extra.realThemeValue = finalValue;
510
+ extra.themeNamespace = namespace;
511
+ extra.themeKey = finalValue;
512
+ if (namespace === "colors" || !(opts.themeKeys ?? [opts.themeKey]).includes("colors")) extra.realThemeValue = finalValue;
487
513
  finalValue = themeValue;
488
514
  if (opts.prop) return [decl(opts.prop, finalValue)];
489
515
  if (opts.handle) {
@@ -1057,7 +1083,13 @@ function parseUtility(value, ctx) {
1057
1083
  //#region src/core/astToCss.ts
1058
1084
  var isSafePrelude = (text) => {
1059
1085
  const t = String(text ?? "");
1060
- return !hasCommentDelimiter(t) && !hasHtmlEndTagOpener(t) && isBalancedPrelude(t);
1086
+ return !hasCommentDelimiter(t) && !hasHtmlEndTagOpener(t) && isBalancedPrelude(t) && !/url\s*\(/i.test(t);
1087
+ };
1088
+ var uniqueDescriptors = (node) => {
1089
+ if (node.type !== "at-rule") return [];
1090
+ if (node.name !== "property") return node.nodes;
1091
+ const seen = /* @__PURE__ */ new Set();
1092
+ return node.nodes.filter((c) => c.type !== "decl" || !seen.has(c.prop) && !!seen.add(c.prop));
1061
1093
  };
1062
1094
  var isSafeDecl = (prop, value) => isStructureSafeValue(String(prop)) && isStructureSafeValue(String(value ?? "")) && !hasHtmlEndTagOpener(String(prop)) && !hasHtmlEndTagOpener(String(value ?? ""));
1063
1095
  var importantPrefix = "!important";
@@ -1153,10 +1185,10 @@ function rootToCss(nodes, opts) {
1153
1185
  if (isSafeDecl(node.prop, node.value)) list.push(minify ? `${node.prop}:${node.value};` : `${node.prop}: ${node.value};`);
1154
1186
  } else if (node.type === "at-rule" && isSafePrelude(node.name) && isSafePrelude(node.params)) {
1155
1187
  if (minify) {
1156
- const body = node.nodes.filter((child) => child.type === "decl" && isSafeDecl(child.prop, child.value)).map((child) => child.type === "decl" ? `${child.prop}:${child.value};` : "").join("");
1188
+ const body = uniqueDescriptors(node).filter((child) => child.type === "decl" && isSafeDecl(child.prop, child.value)).map((child) => child.type === "decl" ? `${child.prop}:${child.value};` : "").join("");
1157
1189
  list.push(`@${node.name} ${node.params}{${body}}`);
1158
1190
  } else list.push(`@${node.name} ${node.params} {
1159
- ${node.nodes.map((node) => {
1191
+ ${uniqueDescriptors(node).map((node) => {
1160
1192
  if (node.type === "decl" && isSafeDecl(node.prop, node.value)) return `\t${node.prop}: ${node.value};`;
1161
1193
  }).join("\n")}
1162
1194
  }`);
@@ -1209,6 +1241,14 @@ function boxShadowToCssVars(boxShadow) {
1209
1241
  * fontSize: { xs: ['0.75rem', '1rem'], ... }
1210
1242
  * → { '--text-xs': '0.75rem', '--text-xs--line-height': '1rem' }
1211
1243
  */
1244
+ /** The line height of a fontSize tuple: `['4rem', '1.1']` or Tailwind's `['4rem', { lineHeight: '1.1' }]` (#300). */
1245
+ function fontSizeLineHeight(value) {
1246
+ if (!Array.isArray(value)) return void 0;
1247
+ const second = value[1];
1248
+ if (typeof second === "string" || typeof second === "number") return String(second);
1249
+ const lh = second?.lineHeight;
1250
+ return lh == null ? void 0 : String(lh);
1251
+ }
1212
1252
  function fontSizeToCssVars(fontSize) {
1213
1253
  if (!fontSize) return {};
1214
1254
  const result = {};
@@ -1216,7 +1256,8 @@ function fontSizeToCssVars(fontSize) {
1216
1256
  const value = fontSize[key];
1217
1257
  if (Array.isArray(value)) {
1218
1258
  result[`--text-${key}`] = value[0];
1219
- if (value[1]) result[`--text-${key}--line-height`] = value[1];
1259
+ const lineHeight = fontSizeLineHeight(value);
1260
+ if (lineHeight) result[`--text-${key}--line-height`] = lineHeight;
1220
1261
  } else result[`--text-${key}`] = value;
1221
1262
  }
1222
1263
  return result;
@@ -1702,6 +1743,11 @@ function parseClassToAst(fullClassName, ctx) {
1702
1743
  variantChain: modifiers,
1703
1744
  index: i
1704
1745
  });
1746
+ if (result == null) {
1747
+ debugWarn(`[BAROCSS] Unknown variant: "${variant.type}" in "${fullClassName}"`);
1748
+ failures.add(fullClassName);
1749
+ return [];
1750
+ }
1705
1751
  if (plugin.wrap && (result === "&" || typeof result === "object" && !Array.isArray(result) && result.selector === "&" || Array.isArray(result) && result.length === 1 && result[0].selector === "&")) continue;
1706
1752
  if (typeof result === "string" && result.includes("&")) wrappers.push({
1707
1753
  type: "rule",
@@ -1788,10 +1834,11 @@ function getAstCacheStats(ctx) {
1788
1834
  * @example
1789
1835
  * const css = generateCss('sm:dark:hover:bg-red-500 sm:focus:bg-blue-500', ctx);
1790
1836
  */
1837
+ var CLASS_SEPARATOR = /[ \t\n\f\r]+/;
1791
1838
  function generateCss(classList, ctx, opts) {
1792
1839
  const seen = /* @__PURE__ */ new Set();
1793
1840
  const allAtRootNodes = [];
1794
- const results = classList.split(/\s+/).filter((cls) => {
1841
+ const results = classList.split(CLASS_SEPARATOR).filter((cls) => {
1795
1842
  if (!cls) return false;
1796
1843
  if (opts?.dedup) {
1797
1844
  if (seen.has(cls)) return false;
@@ -1851,7 +1898,7 @@ function generateCss(classList, ctx, opts) {
1851
1898
  */
1852
1899
  function generateCssRules(classList, ctx, opts) {
1853
1900
  const seen = /* @__PURE__ */ new Set();
1854
- return classList.split(/\s+/).filter((cls) => {
1901
+ return classList.split(CLASS_SEPARATOR).filter((cls) => {
1855
1902
  if (!cls) return false;
1856
1903
  if (opts?.dedup) {
1857
1904
  if (seen.has(cls)) return false;
@@ -2627,105 +2674,81 @@ textarea {
2627
2674
  resize: vertical;
2628
2675
  }
2629
2676
  `;
2677
+ /**
2678
+ * Full preflight: a port of Tailwind CSS v4.3.3's preflight.css (MIT), rule for rule (#336).
2679
+ * `--theme(--x, fallback)` becomes `var(--x, fallback)`; the default sans/mono families also fall back to
2680
+ * `--font-sans`/`--font-mono` so a BaroCSS theme applies. Checked by tests/compat/preflight-336.test.ts.
2681
+ */
2630
2682
  var preflightFullCSS = `
2631
- /* BaroCSS Preflight - Full Reset */
2632
- /* =============================== */
2633
-
2634
- /* Box sizing rules */
2683
+ /* BaroCSS Preflight - Full (Tailwind 4.3.3) */
2635
2684
  *,
2636
- *::before,
2637
- *::after {
2685
+ ::after,
2686
+ ::before,
2687
+ ::backdrop,
2688
+ ::file-selector-button {
2638
2689
  box-sizing: border-box;
2639
- }
2640
-
2641
- /* Remove default margin and padding; reset border to Tailwind v4's universal
2642
- \`border: 0 solid\` so a bare border/border-t (width set by the utility, style
2643
- otherwise \`none\`) renders. Width 0 keeps borders invisible until a utility
2644
- sets one. */
2645
- * {
2646
2690
  margin: 0;
2647
2691
  padding: 0;
2648
2692
  border: 0 solid;
2649
2693
  }
2650
2694
 
2651
- /* Set core body defaults */
2652
- body {
2653
- min-height: 100vh;
2654
- scroll-behavior: smooth;
2655
- text-rendering: optimizeSpeed;
2695
+ html,
2696
+ :host {
2656
2697
  line-height: 1.5;
2657
- -webkit-font-smoothing: antialiased;
2658
- -moz-osx-font-smoothing: grayscale;
2659
- }
2660
-
2661
- /* Remove list styles on ul, ol elements */
2662
- ul,
2663
- ol {
2664
- list-style: none;
2665
- }
2666
-
2667
- /* Make images easier to work with */
2668
- img,
2669
- picture {
2670
- max-width: 100%;
2671
- display: block;
2672
- }
2673
-
2674
- /* Inherit fonts for inputs and buttons */
2675
- input,
2676
- button,
2677
- textarea,
2678
- select {
2679
- font: inherit;
2698
+ -webkit-text-size-adjust: 100%;
2699
+ tab-size: 4;
2700
+ font-family: var(--default-font-family, var(--font-sans, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', 'Noto Sans', Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'));
2701
+ font-feature-settings: var(--default-font-feature-settings, normal);
2702
+ font-variation-settings: var(--default-font-variation-settings, normal);
2703
+ -webkit-tap-highlight-color: transparent;
2680
2704
  }
2681
2705
 
2682
- /* Remove all animations, transitions and smooth scroll for people that prefer not to see them */
2683
- @media (prefers-reduced-motion: reduce) {
2684
- html {
2685
- scroll-behavior: auto;
2686
- }
2687
-
2688
- *,
2689
- *::before,
2690
- *::after {
2691
- animation-duration: 0.01ms !important;
2692
- animation-iteration-count: 1 !important;
2693
- transition-duration: 0.01ms !important;
2694
- scroll-behavior: auto !important;
2695
- }
2706
+ hr {
2707
+ height: 0;
2708
+ color: inherit;
2709
+ border-top-width: 1px;
2696
2710
  }
2697
2711
 
2698
- /* HTML5 display-role reset for older browsers */
2699
- article, aside, details, figcaption, figure,
2700
- footer, header, hgroup, menu, nav, section {
2701
- display: block;
2712
+ abbr:where([title]) {
2713
+ -webkit-text-decoration: underline dotted;
2714
+ text-decoration: underline dotted;
2702
2715
  }
2703
2716
 
2704
- /* Additional full resets */
2705
- html {
2706
- line-height: 1.15;
2707
- -webkit-text-size-adjust: 100%;
2708
- -ms-text-size-adjust: 100%;
2709
- /* Tailwind 4.1.13 root font (app --default-font-family / --font-sans win) */
2710
- font-family: var(--default-font-family, var(--font-sans, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', 'Noto Sans', Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'));
2711
- font-feature-settings: var(--default-font-feature-settings, normal);
2712
- font-variation-settings: var(--default-font-variation-settings, normal);
2717
+ h1,
2718
+ h2,
2719
+ h3,
2720
+ h4,
2721
+ h5,
2722
+ h6 {
2723
+ font-size: inherit;
2724
+ font-weight: inherit;
2713
2725
  }
2714
2726
 
2715
- /* Remove the gray background on active links in IE 10 */
2716
2727
  a {
2717
- background-color: transparent;
2718
- text-decoration: none;
2719
2728
  color: inherit;
2729
+ -webkit-text-decoration: inherit;
2730
+ text-decoration: inherit;
2720
2731
  }
2721
2732
 
2722
- /* Add the correct font weight in Chrome, Edge, and Safari */
2723
2733
  b,
2724
2734
  strong {
2725
2735
  font-weight: bolder;
2726
2736
  }
2727
2737
 
2728
- /* Prevent sub and sup elements from affecting the line height */
2738
+ code,
2739
+ kbd,
2740
+ samp,
2741
+ pre {
2742
+ font-family: var(--default-mono-font-family, var(--font-mono, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace));
2743
+ font-feature-settings: var(--default-mono-font-feature-settings, normal);
2744
+ font-variation-settings: var(--default-mono-font-variation-settings, normal);
2745
+ font-size: 1em;
2746
+ }
2747
+
2748
+ small {
2749
+ font-size: 80%;
2750
+ }
2751
+
2729
2752
  sub,
2730
2753
  sup {
2731
2754
  font-size: 75%;
@@ -2742,265 +2765,49 @@ sup {
2742
2765
  top: -0.5em;
2743
2766
  }
2744
2767
 
2745
- /* Improve media defaults */
2746
- svg {
2747
- vertical-align: middle;
2748
- }
2749
-
2750
- /* Remove border on iframe */
2751
- iframe {
2752
- border: 0;
2753
- }
2754
-
2755
- /* Table defaults */
2756
2768
  table {
2769
+ text-indent: 0;
2770
+ border-color: inherit;
2757
2771
  border-collapse: collapse;
2758
- border-spacing: 0;
2759
2772
  }
2760
2773
 
2761
- /* Form element defaults */
2762
- button,
2763
- input,
2764
- optgroup,
2765
- select,
2766
- textarea {
2767
- font-family: inherit;
2768
- font-size: 100%;
2769
- line-height: 1.15;
2770
- margin: 0;
2774
+ :-moz-focusring:where(:not(iframe)) {
2775
+ outline: auto;
2771
2776
  }
2772
2777
 
2773
- button,
2774
- select {
2775
- text-transform: none;
2776
- }
2777
-
2778
- button,
2779
- [type="button"],
2780
- [type="reset"],
2781
- [type="submit"] {
2782
- -webkit-appearance: button;
2783
- }
2784
-
2785
- button::-moz-focus-inner,
2786
- [type="button"]::-moz-focus-inner,
2787
- [type="reset"]::-moz-focus-inner,
2788
- [type="submit"]::-moz-focus-inner {
2789
- border-style: none;
2790
- padding: 0;
2791
- }
2792
-
2793
- button:-moz-focusring,
2794
- [type="button"]:-moz-focusring,
2795
- [type="reset"]:-moz-focusring,
2796
- [type="submit"]:-moz-focusring {
2797
- outline: 1px dotted ButtonText;
2798
- }
2799
-
2800
- /* Remove the inner border and padding in Firefox */
2801
- button::-moz-focus-inner,
2802
- [type="button"]::-moz-focus-inner,
2803
- [type="reset"]::-moz-focus-inner,
2804
- [type="submit"]::-moz-focus-inner {
2805
- border-style: none;
2806
- padding: 0;
2807
- }
2808
-
2809
- /* Restore the focus styles unset by the previous rule */
2810
- button:-moz-focusring,
2811
- [type="button"]:-moz-focusring,
2812
- [type="reset"]:-moz-focusring,
2813
- [type="submit"]:-moz-focusring {
2814
- outline: 1px dotted ButtonText;
2815
- }
2816
-
2817
- /* Correct the padding in Firefox */
2818
- fieldset {
2819
- padding: 0.35em 0.75em 0.625em;
2820
- }
2821
-
2822
- /* Remove padding so developers aren't caught out when they zero out fieldset elements */
2823
- legend {
2824
- box-sizing: border-box;
2825
- color: inherit;
2826
- display: table;
2827
- max-width: 100%;
2828
- padding: 0;
2829
- white-space: normal;
2830
- }
2831
-
2832
- /* Add the correct vertical alignment in Chrome, Firefox, and Opera */
2833
2778
  progress {
2834
2779
  vertical-align: baseline;
2835
2780
  }
2836
2781
 
2837
- /* Remove the default vertical scrollbar in IE */
2838
- textarea {
2839
- overflow: auto;
2840
- }
2841
-
2842
- /* Correct the cursor style of increment and decrement buttons in Chrome */
2843
- [type="number"]::-webkit-inner-spin-button,
2844
- [type="number"]::-webkit-outer-spin-button {
2845
- height: auto;
2846
- }
2847
-
2848
- /* Remove the inner padding in Chrome and Safari on macOS */
2849
- [type="search"] {
2850
- -webkit-appearance: textfield;
2851
- outline-offset: -2px;
2852
- }
2853
-
2854
- /* Remove the inner padding in Chrome and Safari on macOS */
2855
- [type="search"]::-webkit-search-decoration {
2856
- -webkit-appearance: none;
2857
- }
2858
-
2859
- /* Remove the default vertical scrollbar in IE */
2860
- textarea {
2861
- overflow: auto;
2862
- }
2863
-
2864
- /* Correct the cursor style of increment and decrement buttons in Chrome */
2865
- [type="number"]::-webkit-inner-spin-button,
2866
- [type="number"]::-webkit-outer-spin-button {
2867
- height: auto;
2782
+ summary {
2783
+ display: list-item;
2868
2784
  }
2869
2785
 
2870
- /* Remove the inner padding in Chrome and Safari on macOS */
2871
- [type="search"] {
2872
- -webkit-appearance: textfield;
2873
- outline-offset: -2px;
2874
- }
2875
-
2876
- /* Remove the inner padding in Chrome and Safari on macOS */
2877
- [type="search"]::-webkit-search-decoration {
2878
- -webkit-appearance: none;
2879
- }
2880
-
2881
- /* Additional full reset styles */
2882
- abbr[title] {
2883
- border-bottom: none;
2884
- text-decoration: underline;
2885
- text-decoration: underline dotted;
2886
- }
2887
-
2888
- /* Add the correct font size in all browsers */
2889
- small {
2890
- font-size: 80%;
2891
- }
2892
-
2893
- /* Prevent overflow of the container in all browsers */
2894
- code,
2895
- kbd,
2896
- pre,
2897
- samp {
2898
- font-family: var(--default-mono-font-family, var(--font-mono, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace));
2899
- font-feature-settings: var(--default-mono-font-feature-settings, normal);
2900
- font-variation-settings: var(--default-mono-font-variation-settings, normal);
2901
- font-size: 1em;
2786
+ ol,
2787
+ ul,
2788
+ menu {
2789
+ list-style: none;
2902
2790
  }
2903
2791
 
2904
- /* Add the correct display in IE 9 */
2792
+ img,
2793
+ svg,
2794
+ video,
2795
+ canvas,
2905
2796
  audio,
2906
- video {
2907
- display: inline-block;
2908
- }
2909
-
2910
- /* Add the correct display in IE */
2911
- template {
2912
- display: none;
2913
- }
2914
-
2915
- /* Hidden attribute */
2916
- [hidden] {
2917
- display: none;
2918
- }
2919
-
2920
- /* Focus styles */
2921
- :focus {
2922
- outline: 2px solid #3b82f6;
2923
- outline-offset: 2px;
2924
- }
2925
-
2926
- /* Skip link for accessibility */
2927
- .skip-link {
2928
- position: absolute;
2929
- top: -40px;
2930
- left: 6px;
2931
- background: #000;
2932
- color: white;
2933
- padding: 8px;
2934
- text-decoration: none;
2935
- z-index: 100;
2936
- }
2937
-
2938
- .skip-link:focus {
2939
- top: 6px;
2797
+ iframe,
2798
+ embed,
2799
+ object {
2800
+ display: block;
2801
+ vertical-align: middle;
2940
2802
  }
2941
2803
 
2942
- /* Print styles */
2943
- @media print {
2944
- *,
2945
- *::before,
2946
- *::after {
2947
- background: transparent !important;
2948
- color: #000 !important;
2949
- box-shadow: none !important;
2950
- text-shadow: none !important;
2951
- }
2952
-
2953
- a,
2954
- a:visited {
2955
- text-decoration: underline;
2956
- }
2957
-
2958
- a[href]:after {
2959
- content: " (" attr(href) ")";
2960
- }
2961
-
2962
- abbr[title]:after {
2963
- content: " (" attr(title) ")";
2964
- }
2965
-
2966
- a[href^="#"]:after,
2967
- a[href^="javascript:"]:after {
2968
- content: "";
2969
- }
2970
-
2971
- pre,
2972
- blockquote {
2973
- border: 1px solid #999;
2974
- page-break-inside: avoid;
2975
- }
2976
-
2977
- thead {
2978
- display: table-header-group;
2979
- }
2980
-
2981
- tr,
2982
- img {
2983
- page-break-inside: avoid;
2984
- }
2985
-
2986
- img {
2987
- max-width: 100% !important;
2988
- }
2989
-
2990
- p,
2991
- h2,
2992
- h3 {
2993
- orphans: 3;
2994
- widows: 3;
2995
- }
2996
-
2997
- h2,
2998
- h3 {
2999
- page-break-after: avoid;
3000
- }
2804
+ img,
2805
+ video {
2806
+ max-width: 100%;
2807
+ height: auto;
3001
2808
  }
3002
2809
 
3003
- /* Tailwind 4.1.13 form-control reset: inherit typography and colour, drop native radius/background (#228) */
2810
+ /* form-control reset */
3004
2811
  button,
3005
2812
  input,
3006
2813
  select,
@@ -3033,7 +2840,8 @@ textarea,
3033
2840
  opacity: 1;
3034
2841
  }
3035
2842
 
3036
- @supports (not (-webkit-appearance: -apple-pay-button)) or (contain-intrinsic-size: 1px) {
2843
+ @supports (not (-webkit-appearance: -apple-pay-button)) or
2844
+ (contain-intrinsic-size: 1px) {
3037
2845
  ::placeholder {
3038
2846
  color: color-mix(in oklab, currentcolor 50%, transparent);
3039
2847
  }
@@ -3042,6 +2850,58 @@ textarea,
3042
2850
  textarea {
3043
2851
  resize: vertical;
3044
2852
  }
2853
+
2854
+ ::-webkit-search-decoration {
2855
+ -webkit-appearance: none;
2856
+ }
2857
+
2858
+ ::-webkit-date-and-time-value {
2859
+ min-height: 1lh;
2860
+ text-align: inherit;
2861
+ }
2862
+
2863
+ ::-webkit-datetime-edit {
2864
+ display: inline-flex;
2865
+ }
2866
+
2867
+ ::-webkit-datetime-edit-fields-wrapper {
2868
+ padding: 0;
2869
+ }
2870
+
2871
+ ::-webkit-datetime-edit,
2872
+ ::-webkit-datetime-edit-year-field,
2873
+ ::-webkit-datetime-edit-month-field,
2874
+ ::-webkit-datetime-edit-day-field,
2875
+ ::-webkit-datetime-edit-hour-field,
2876
+ ::-webkit-datetime-edit-minute-field,
2877
+ ::-webkit-datetime-edit-second-field,
2878
+ ::-webkit-datetime-edit-millisecond-field,
2879
+ ::-webkit-datetime-edit-meridiem-field {
2880
+ padding-block: 0;
2881
+ }
2882
+
2883
+ ::-webkit-calendar-picker-indicator {
2884
+ line-height: 1;
2885
+ }
2886
+
2887
+ :-moz-ui-invalid {
2888
+ box-shadow: none;
2889
+ }
2890
+
2891
+ button,
2892
+ input:where([type='button'], [type='reset'], [type='submit']),
2893
+ ::file-selector-button {
2894
+ appearance: button;
2895
+ }
2896
+
2897
+ ::-webkit-inner-spin-button,
2898
+ ::-webkit-outer-spin-button {
2899
+ height: auto;
2900
+ }
2901
+
2902
+ [hidden]:where(:not([hidden='until-found'])) {
2903
+ display: none !important;
2904
+ }
3045
2905
  `;
3046
2906
  //#endregion
3047
2907
  //#region src/core/context.ts
@@ -3277,6 +3137,7 @@ function jsonToAst(input, ctx) {
3277
3137
  variantChain: [],
3278
3138
  index: i
3279
3139
  });
3140
+ if (result == null) continue;
3280
3141
  if (plugin.wrap && (result === "&" || typeof result === "object" && !Array.isArray(result) && result.selector === "&" || Array.isArray(result) && result.length === 1 && result[0].selector === "&")) {} else if (typeof result === "string" && result.includes("&")) wrappers.push({
3281
3142
  type: "rule",
3282
3143
  selector: result
@@ -3953,6 +3814,7 @@ functionalUtility({
3953
3814
  prop: "transition-timing-function",
3954
3815
  supportsArbitrary: true,
3955
3816
  supportsCustomProperty: true,
3817
+ handleBareValue: ({ value, ctx }) => themeKeyVar(ctx, "transitionTimingFunction", value, "ease") ?? (/^(\d|\.\d)/.test(value) ? value : null),
3956
3818
  handle: (value, _ctx, _token) => {
3957
3819
  return [decl("transition-timing-function", value)];
3958
3820
  },
@@ -4137,6 +3999,7 @@ functionalUtility({
4137
3999
  prop: "filter",
4138
4000
  supportsArbitrary: true,
4139
4001
  supportsCustomProperty: true,
4002
+ handleBareValue: ({ value, ctx }) => themeKeyVar(ctx, "blur", value, "blur") ?? (/^(\d|\.\d)/.test(value) ? value : null),
4140
4003
  handle: (value, _ctx, token) => {
4141
4004
  if (token.customProperty) return [decl("--baro-blur", `blur(var(${value}))`), filters$1()];
4142
4005
  return [decl("--baro-blur", `blur(${value})`), filters$1()];
@@ -4232,13 +4095,14 @@ functionalUtility({
4232
4095
  transparent: "transparent"
4233
4096
  }[extra?.realThemeValue ?? value];
4234
4097
  if (keyword) return dropShadowColor(keyword, opacity);
4098
+ const key = extra?.realThemeValue ?? value;
4099
+ const named = token.arbitrary ? null : namedDropShadow(ctx, key);
4100
+ if (named) return dropShadowValue(named, opacity, `drop-shadow(var(--drop-shadow-${key}))`);
4235
4101
  if (extra?.realThemeValue) return dropShadowColor(value, opacity, `var(--color-${extra.realThemeValue})`);
4236
4102
  if (token.arbitrary) {
4237
4103
  if (parseColor(value)) return dropShadowColor(value, opacity);
4238
4104
  return dropShadowValue(value, opacity);
4239
4105
  }
4240
- const named = namedDropShadow(ctx, value);
4241
- if (named) return dropShadowValue(named, opacity, `drop-shadow(var(--drop-shadow-${value}))`);
4242
4106
  return null;
4243
4107
  },
4244
4108
  handleCustomProperty: (value) => {
@@ -4356,6 +4220,7 @@ functionalUtility({
4356
4220
  prop: "backdrop-filter",
4357
4221
  supportsArbitrary: true,
4358
4222
  supportsCustomProperty: true,
4223
+ handleBareValue: ({ value, ctx }) => themeKeyVar(ctx, "blur", value, "blur") ?? (/^(\d|\.\d)/.test(value) ? value : null),
4359
4224
  handle: (value, _ctx, token) => {
4360
4225
  if (token.customProperty) return [decl("--baro-backdrop-blur", `blur(var(${value}))`), ...filters()];
4361
4226
  return [decl("--baro-backdrop-blur", `blur(${value})`), ...filters()];
@@ -4511,11 +4376,15 @@ function boxShadowLayer(layer, value, opacity) {
4511
4376
  decl("box-shadow", SHADOW_COMPOSITE)
4512
4377
  ];
4513
4378
  }
4514
- function namedBoxShadow(layer, name, opacity) {
4515
- if (layer === "shadow") return own(NAMED_SHADOWS, name) ? boxShadowLayer(layer, NAMED_SHADOWS[name], opacity) : null;
4516
- if (own(NAMED_INSET_SHADOWS, name)) return boxShadowLayer(layer, NAMED_INSET_SHADOWS[name], opacity);
4517
- if (!opacity && own(INSET_EXTENSIONS, name)) return boxShadowLayer(layer, INSET_EXTENSIONS[name], void 0);
4518
- return null;
4379
+ function namedBoxShadow(layer, name, opacity, ctx) {
4380
+ if (layer === "shadow") {
4381
+ if (own(NAMED_SHADOWS, name)) return boxShadowLayer(layer, NAMED_SHADOWS[name], opacity);
4382
+ } else {
4383
+ if (own(NAMED_INSET_SHADOWS, name)) return boxShadowLayer(layer, NAMED_INSET_SHADOWS[name], opacity);
4384
+ if (!opacity && own(INSET_EXTENSIONS, name)) return boxShadowLayer(layer, INSET_EXTENSIONS[name], void 0);
4385
+ }
4386
+ const custom = ctx && name !== "none" ? themeKeyValue(ctx, layer === "shadow" ? "boxShadow" : "insetShadow", name) : null;
4387
+ return custom ? boxShadowLayer(layer, custom, opacity) : null;
4519
4388
  }
4520
4389
  staticUtility("shadow-none", [
4521
4390
  ringShadowProperties,
@@ -4555,10 +4424,10 @@ for (const layer of ["shadow", "inset-shadow"]) functionalUtility({
4555
4424
  supportsCustomProperty: true,
4556
4425
  supportsOpacity: true,
4557
4426
  themeKeys: ["colors"],
4558
- handleBareValue: ({ value, extra }) => namedBoxShadow(layer, value, extra?.opacity) ? value : null,
4559
- handle: (value, _ctx, token, extra) => {
4427
+ handleBareValue: ({ value, ctx, extra }) => namedBoxShadow(layer, value, extra?.opacity, ctx) ? value : null,
4428
+ handle: (value, ctx, token, extra) => {
4560
4429
  const opacity = extra?.opacity;
4561
- const named = !extra?.realThemeValue && !token.arbitrary ? namedBoxShadow(layer, value, opacity) : null;
4430
+ const named = !token.arbitrary ? namedBoxShadow(layer, extra?.realThemeValue ?? value, opacity, ctx) : null;
4562
4431
  if (named) return named;
4563
4432
  const color = layerColor(layer, value, opacity, token, extra?.realThemeValue);
4564
4433
  if (color !== void 0) return color;
@@ -4590,8 +4459,8 @@ functionalUtility({
4590
4459
  handleBareValue: ({ value, ctx }) => namedTextShadow(ctx, value) ? value : null,
4591
4460
  handle: (value, ctx, token, extra) => {
4592
4461
  const opacity = extra?.opacity;
4593
- if (!extra?.realThemeValue && !token.arbitrary) {
4594
- const named = namedTextShadow(ctx, value);
4462
+ if (!token.arbitrary) {
4463
+ const named = namedTextShadow(ctx, extra?.realThemeValue ?? value);
4595
4464
  if (named) return textShadowValue(named, opacity);
4596
4465
  }
4597
4466
  const color = layerColor("text-shadow", value, opacity, token, extra?.realThemeValue);
@@ -4632,6 +4501,22 @@ function ringShadowValue(width) {
4632
4501
  ["--baro-ring-offset-shadow", `var(--baro-ring-inset,) 0 0 0 var(--baro-ring-offset-width) var(--baro-ring-offset-color)`]
4633
4502
  ], { category: "effects" });
4634
4503
  });
4504
+ var ringOffsetWidth = (width) => [decl("--baro-ring-offset-width", width), decl("--baro-ring-offset-shadow", "var(--baro-ring-inset,) 0 0 0 var(--baro-ring-offset-width) var(--baro-ring-offset-color)")];
4505
+ functionalUtility({
4506
+ name: "ring-offset",
4507
+ themeKeys: ["ringOffsetWidth", "colors"],
4508
+ supportsArbitrary: true,
4509
+ supportsOpacity: true,
4510
+ handleBareValue: ({ value }) => /^\d+$/.test(value) ? `${value}px` : null,
4511
+ handle: (value, _ctx, token, extra) => {
4512
+ if (extra?.themeNamespace === "ringOffsetWidth") return ringOffsetWidth(value);
4513
+ if (extra?.realThemeValue) return themeColorDecls("--baro-ring-offset-color", value, extra);
4514
+ if (token.arbitrary) return parseColor(value) ? [decl("--baro-ring-offset-color", value)] : parseLength(value) ? ringOffsetWidth(value) : null;
4515
+ if (/^\d+px$/.test(value)) return ringOffsetWidth(value);
4516
+ return null;
4517
+ },
4518
+ category: "effects"
4519
+ });
4635
4520
  [
4636
4521
  ["inset-ring", "1px"],
4637
4522
  ["inset-ring-0", "0px"],
@@ -4663,9 +4548,14 @@ functionalUtility({
4663
4548
  supportsArbitrary: true,
4664
4549
  supportsCustomProperty: true,
4665
4550
  supportsOpacity: true,
4666
- themeKeys: ["colors"],
4551
+ themeKeys: ["colors", "ringWidth"],
4667
4552
  handle: (value, ctx, token, extra) => {
4668
4553
  const main = value;
4554
+ if (extra?.themeNamespace === "ringWidth") return [
4555
+ ringShadowProperties(),
4556
+ decl("--baro-ring-shadow", ringShadowValue(value)),
4557
+ decl("box-shadow", SHADOW_COMPOSITE)
4558
+ ];
4669
4559
  const opacity = extra?.opacity;
4670
4560
  const realThemeValue = extra?.realThemeValue;
4671
4561
  if (realThemeValue) return createRingColorDecls("--baro-ring-color", main, opacity, realThemeValue);
@@ -4961,6 +4851,7 @@ functionalUtility({
4961
4851
  supportsArbitrary: true,
4962
4852
  supportsCustomProperty: true,
4963
4853
  supportsFraction: true,
4854
+ handleBareValue: ({ value, ctx }) => themeKeyVar(ctx, "aspect", value, "aspect") ?? (/^(\d|\.\d)/.test(value) ? value : null),
4964
4855
  description: "aspect-ratio utility (theme, arbitrary, custom property, fraction supported)",
4965
4856
  category: "layout"
4966
4857
  });
@@ -4984,7 +4875,7 @@ functionalUtility({
4984
4875
  supportsArbitrary: true,
4985
4876
  supportsCustomProperty: true,
4986
4877
  supportsFraction: true,
4987
- handleBareValue: ({ value }) => parseNumber(value),
4878
+ handleBareValue: ({ value, ctx }) => parseNumber(value) ?? themeKeyVar(ctx, "container", value, "container"),
4988
4879
  description: "columns utility (theme, arbitrary, custom property, fraction supported)",
4989
4880
  category: "layout"
4990
4881
  });
@@ -6033,10 +5924,10 @@ functionalUtility({
6033
5924
  supportsArbitrary: true,
6034
5925
  supportsCustomProperty: true,
6035
5926
  supportsFraction: true,
6036
- handleBareValue: ({ value }) => {
5927
+ handleBareValue: ({ value, ctx }) => {
6037
5928
  if (parseNumber(value)) return `calc(var(--spacing) * ${value})`;
6038
5929
  if (parseFractionOrNumber(value)) return `calc(${value} * 100%)`;
6039
- return null;
5930
+ return themeKeyVar(ctx, "container", value, "container");
6040
5931
  },
6041
5932
  description: "max-width utility (spacing, fraction, arbitrary, custom property, static supported)",
6042
5933
  category: "sizing"
@@ -6146,11 +6037,11 @@ functionalUtility({
6146
6037
  supportsArbitrary: true,
6147
6038
  supportsCustomProperty: true,
6148
6039
  supportsFraction: true,
6149
- handleBareValue: ({ value, token }) => {
6040
+ handleBareValue: ({ value, token, ctx }) => {
6150
6041
  if (token.negative) return null;
6151
6042
  if (parseNumber(value)) return `calc(var(--spacing) * ${value})`;
6152
6043
  if (parseFractionOrNumber(value)) return `calc(${value} * 100%)`;
6153
- return null;
6044
+ return name.includes("inline") ? themeKeyVar(ctx, "container", value, "container") : null;
6154
6045
  },
6155
6046
  description: `${prop} utility (spacing, fraction, arbitrary, custom property, keywords)`,
6156
6047
  category: "sizing"
@@ -6176,21 +6067,34 @@ staticUtility("text-6xl", [["font-size", "var(--text-6xl)"], ["line-height", "va
6176
6067
  staticUtility("text-7xl", [["font-size", "var(--text-7xl)"], ["line-height", "var(--baro-leading, var(--text-7xl--line-height))"]], { category: "typography" });
6177
6068
  staticUtility("text-8xl", [["font-size", "var(--text-8xl)"], ["line-height", "var(--baro-leading, var(--text-8xl--line-height))"]], { category: "typography" });
6178
6069
  staticUtility("text-9xl", [["font-size", "var(--text-9xl)"], ["line-height", "var(--baro-leading, var(--text-9xl--line-height))"]], { category: "typography" });
6179
- staticUtility("font-thin", [["font-weight", "var(--font-weight-thin)"]], { category: "typography" });
6180
- staticUtility("font-extralight", [["font-weight", "var(--font-weight-extralight)"]], { category: "typography" });
6181
- staticUtility("font-light", [["font-weight", "var(--font-weight-light)"]], { category: "typography" });
6182
- staticUtility("font-normal", [["font-weight", "var(--font-weight-normal)"]], { category: "typography" });
6183
- staticUtility("font-medium", [["font-weight", "var(--font-weight-medium)"]], { category: "typography" });
6184
- staticUtility("font-semibold", [["font-weight", "var(--font-weight-semibold)"]], { category: "typography" });
6185
- staticUtility("font-bold", [["font-weight", "var(--font-weight-bold)"]], { category: "typography" });
6186
- staticUtility("font-extrabold", [["font-weight", "var(--font-weight-extrabold)"]], { category: "typography" });
6187
- staticUtility("font-black", [["font-weight", "var(--font-weight-black)"]], { category: "typography" });
6070
+ function fontWeightUtility(name) {
6071
+ registerUtility({
6072
+ name: `font-${name}`,
6073
+ match: (className) => className === `font-${name}`,
6074
+ handler: (_value, ctx) => {
6075
+ const family = themeKeyVar(ctx, "fontFamily", name, "font");
6076
+ return family ? [decl("font-family", family)] : [decl("font-weight", `var(--font-weight-${name})`)];
6077
+ },
6078
+ category: "typography"
6079
+ });
6080
+ }
6081
+ fontWeightUtility("thin");
6082
+ fontWeightUtility("extralight");
6083
+ fontWeightUtility("light");
6084
+ fontWeightUtility("normal");
6085
+ fontWeightUtility("medium");
6086
+ fontWeightUtility("semibold");
6087
+ fontWeightUtility("bold");
6088
+ fontWeightUtility("extrabold");
6089
+ fontWeightUtility("black");
6188
6090
  functionalUtility({
6189
6091
  name: "font",
6190
6092
  supportsArbitrary: true,
6191
6093
  supportsCustomProperty: true,
6094
+ handleBareValue: ({ value, ctx }) => themeKeyVar(ctx, "fontFamily", value, "font") ?? themeKeyVar(ctx, "fontWeight", value, "font-weight") ?? (/^(\d|\.\d)/.test(value) ? value : null),
6192
6095
  handle: (value, _ctx, token) => {
6193
6096
  if (token.prefix !== "font") return null;
6097
+ if (!token.arbitrary && value.startsWith("var(--font-weight-")) return [decl("font-weight", value)];
6194
6098
  if (parseNumber(value)) return [decl("font-weight", value)];
6195
6099
  return [decl("font-family", value)];
6196
6100
  },
@@ -6213,9 +6117,9 @@ staticUtility("tracking-widest", [["letter-spacing", "var(--letter-spacing-wides
6213
6117
  functionalUtility({
6214
6118
  name: "tracking",
6215
6119
  prop: "letter-spacing",
6216
- themeKey: "letterSpacing",
6217
6120
  supportsArbitrary: true,
6218
6121
  supportsCustomProperty: true,
6122
+ handleBareValue: ({ value, ctx }) => themeKeyVar(ctx, "letterSpacing", value, "letter-spacing") ?? (/^(\d|\.\d)/.test(value) ? value : null),
6219
6123
  description: "letter-spacing utility (theme, arbitrary, custom property supported)",
6220
6124
  category: "typography"
6221
6125
  });
@@ -6251,11 +6155,14 @@ staticUtility("leading-loose", [
6251
6155
  ], { category: "typography" });
6252
6156
  functionalUtility({
6253
6157
  name: "leading",
6254
- prop: "line-height",
6255
- themeKey: "lineHeight",
6256
6158
  supportsArbitrary: true,
6257
6159
  supportsCustomProperty: true,
6258
- handleBareValue: ({ value }) => parseNumber(value),
6160
+ handleBareValue: ({ value, ctx }) => {
6161
+ const v = themeKeyValue(ctx, "lineHeight", value);
6162
+ if (v != null) return `var(--leading-${value}, ${v})`;
6163
+ const numbered = ctx.theme("lineHeight", value);
6164
+ return typeof numbered === "string" ? numbered : parseNumber(value);
6165
+ },
6259
6166
  handle: (value) => [
6260
6167
  decl("--baro-leading", value),
6261
6168
  decl("line-height", value),
@@ -6312,8 +6219,11 @@ functionalUtility({
6312
6219
  supportsArbitrary: true,
6313
6220
  supportsCustomProperty: true,
6314
6221
  supportsOpacity: true,
6222
+ handleBareValue: ({ value, ctx, extra }) => (extra?.opacity ? null : themeKeyVar(ctx, "fontSize", value, "text")) ?? (/^(\d|\.\d)/.test(value) ? value : null),
6315
6223
  handle: (value, ctx, token, extra) => {
6316
6224
  if (extra?.realThemeValue) return themeColorDecls("color", value, extra);
6225
+ const sizeKey = !token.arbitrary && !token.customProperty ? /^var\(--text-([\w-]+)\)$/.exec(value)?.[1] : void 0;
6226
+ if (sizeKey) return fontSizeLineHeight(ctx.theme("fontSize", sizeKey)) ? [decl("font-size", value), decl("line-height", `var(--baro-leading, var(--text-${sizeKey}--line-height))`)] : [decl("font-size", value)];
6317
6227
  const kind = textArbitraryKind(value);
6318
6228
  return [decl(kind.fontSize ? "font-size" : "color", kind.value)];
6319
6229
  },
@@ -6436,11 +6346,12 @@ functionalUtility({
6436
6346
  });
6437
6347
  functionalUtility({
6438
6348
  name: "decoration",
6439
- themeKey: "colors",
6349
+ themeKeys: ["textDecorationThickness", "colors"],
6440
6350
  supportsArbitrary: true,
6441
6351
  supportsCustomProperty: true,
6442
6352
  supportsOpacity: true,
6443
6353
  handle: (value, ctx, token, extra) => {
6354
+ if (extra?.themeNamespace === "textDecorationThickness") return [decl("text-decoration-thickness", value)];
6444
6355
  if (extra?.realThemeValue) return themeColorDecls("text-decoration-color", value, extra);
6445
6356
  return [decl("text-decoration-color", value)];
6446
6357
  },
@@ -6524,7 +6435,7 @@ functionalUtility({
6524
6435
  prop: "content",
6525
6436
  supportsArbitrary: true,
6526
6437
  supportsCustomProperty: true,
6527
- handle: (value) => [decl("--baro-content", `"${value}"`), decl("content", "var(--baro-content)")],
6438
+ handle: (value) => [decl("--baro-content", value), decl("content", "var(--baro-content)")],
6528
6439
  handleCustomProperty: (value) => [decl("--baro-content", `var(${value})`), decl("content", "var(--baro-content)")],
6529
6440
  description: "content utility (arbitrary, custom property supported)",
6530
6441
  category: "typography"
@@ -6804,7 +6715,20 @@ staticUtility("rounded-2xl", [["border-radius", "var(--radius-2xl)"]], { categor
6804
6715
  staticUtility("rounded-3xl", [["border-radius", "var(--radius-3xl)"]], { category: "borders" });
6805
6716
  staticUtility("rounded-4xl", [["border-radius", "var(--radius-4xl)"]], { category: "borders" });
6806
6717
  staticUtility("rounded-xs", [["border-radius", "var(--radius-xs)"]], { category: "borders" });
6807
- staticUtility("rounded-full", [["border-radius", "9999px"]], { category: "borders" });
6718
+ var FULL = "calc(infinity * 1px)";
6719
+ function roundedFull(name, props) {
6720
+ registerUtility({
6721
+ name,
6722
+ match: (className) => className === name,
6723
+ handler: (_value, ctx) => {
6724
+ const own = themeKeyValue(ctx, "borderRadius", "full");
6725
+ const value = own != null && own !== "9999px" && own !== FULL ? "var(--radius-full)" : FULL;
6726
+ return props.map((prop) => decl(prop, value));
6727
+ },
6728
+ category: "borders"
6729
+ });
6730
+ }
6731
+ roundedFull("rounded-full", ["border-radius"]);
6808
6732
  [
6809
6733
  ["rounded-t", ["border-top-left-radius", "border-top-right-radius"]],
6810
6734
  ["rounded-r", ["border-top-right-radius", "border-bottom-right-radius"]],
@@ -6833,14 +6757,14 @@ staticUtility("rounded-full", [["border-radius", "9999px"]], { category: "border
6833
6757
  staticUtility(`${name}-3xl`, propList.map((prop) => [prop, "var(--radius-3xl)"]), { category: "borders" });
6834
6758
  staticUtility(`${name}-4xl`, propList.map((prop) => [prop, "var(--radius-4xl)"]), { category: "borders" });
6835
6759
  staticUtility(`${name}-xs`, propList.map((prop) => [prop, "var(--radius-xs)"]), { category: "borders" });
6836
- staticUtility(`${name}-full`, propList.map((prop) => [prop, logical ? "calc(infinity * 1px)" : "9999px"]), { category: "borders" });
6760
+ roundedFull(`${name}-full`, propList);
6837
6761
  functionalUtility({
6838
6762
  name,
6839
6763
  supportsArbitrary: true,
6840
6764
  supportsCustomProperty: true,
6841
- handleBareValue: ({ value }) => {
6765
+ handleBareValue: ({ value, ctx }) => {
6842
6766
  if (!logical && parseNumber(value)) return `calc(var(--spacing) * ${value})`;
6843
- return null;
6767
+ return themeKeyVar(ctx, "borderRadius", value, "radius");
6844
6768
  },
6845
6769
  handle: (value) => propList.map((prop) => decl(prop, value)),
6846
6770
  description: `${name} utility (spacing, arbitrary, custom property support)`,
@@ -6852,9 +6776,9 @@ functionalUtility({
6852
6776
  handle: (value, _ctx, token) => token.prefix === "rounded" ? [decl("border-radius", value)] : null,
6853
6777
  supportsArbitrary: true,
6854
6778
  supportsCustomProperty: true,
6855
- handleBareValue: ({ value }) => {
6779
+ handleBareValue: ({ value, ctx }) => {
6856
6780
  if (parseNumber(value)) return `calc(var(--spacing) * ${value})`;
6857
- return null;
6781
+ return themeKeyVar(ctx, "borderRadius", value, "radius");
6858
6782
  },
6859
6783
  description: "border-radius utility (spacing, arbitrary, custom property support)",
6860
6784
  category: "borders"
@@ -6903,7 +6827,7 @@ var withBorderStyle = (props, width) => [
6903
6827
  staticUtility(`${name}`, styled("1px"));
6904
6828
  functionalUtility({
6905
6829
  name,
6906
- themeKeys: ["borderWidth", "colors"],
6830
+ themeKeys: ["colors", "borderWidth"],
6907
6831
  supportsOpacity: true,
6908
6832
  supportsArbitrary: true,
6909
6833
  supportsCustomProperty: true,
@@ -6912,6 +6836,7 @@ var withBorderStyle = (props, width) => [
6912
6836
  return null;
6913
6837
  },
6914
6838
  handle: (value, ctx, token, extra) => {
6839
+ if (extra?.themeNamespace === "borderWidth") return withBorderStyle(propList, value);
6915
6840
  if (extra?.realThemeValue) return propList.flatMap((prop) => themeColorDecls(prop.replace("width", "color"), value, extra));
6916
6841
  if (parseColor(value)) return propList.map((prop) => decl(prop.replace("width", "color"), value));
6917
6842
  if (token.arbitrary) return withBorderStyle(propList, value);
@@ -6958,6 +6883,7 @@ Object.entries({
6958
6883
  staticUtility(`divide-${axis}-reverse`, [rule(":where(& > :not(:last-child))", [decl(rev, "1")])], { category: "borders" });
6959
6884
  functionalUtility({
6960
6885
  name: `divide-${axis}`,
6886
+ themeKeys: ["divideWidth", "borderWidth"],
6961
6887
  supportsArbitrary: true,
6962
6888
  handleBareValue: ({ value }) => /^\d+$/.test(value) ? `${value}px` : null,
6963
6889
  handle: (value) => divide(value),
@@ -6972,6 +6898,7 @@ functionalUtility({
6972
6898
  supportsCustomProperty: true,
6973
6899
  supportsOpacity: true,
6974
6900
  handle: (value, ctx, token, extra) => {
6901
+ if (extra?.themeNamespace === "borderWidth") return withBorderStyle(["border-width"], value);
6975
6902
  if (extra?.realThemeValue) return themeColorDecls("border-color", value, extra);
6976
6903
  if (token.arbitrary) {
6977
6904
  if (parseLength(value)) return withBorderStyle(["border-width"], value);
@@ -7048,11 +6975,12 @@ functionalUtility({
7048
6975
  });
7049
6976
  functionalUtility({
7050
6977
  name: "outline",
7051
- themeKeys: ["colors", "borderWidth"],
6978
+ themeKeys: ["colors", "outlineWidth"],
7052
6979
  supportsArbitrary: true,
7053
6980
  supportsCustomProperty: true,
7054
6981
  supportsOpacity: true,
7055
6982
  handle: (value, ctx, token, extra) => {
6983
+ if (extra?.themeNamespace === "outlineWidth") return withOutlineStyle(value);
7056
6984
  if (extra?.realThemeValue) return themeColorDecls("outline-color", value, extra);
7057
6985
  if (parseColor(value)) return [decl("outline-color", value)];
7058
6986
  if (parseNumber(value)) return withOutlineStyle(`${value}px`);
@@ -7525,11 +7453,11 @@ staticUtility("stroke-black", [["stroke", "#000"]], { category: "svg" });
7525
7453
  staticUtility("stroke-white", [["stroke", "#fff"]], { category: "svg" });
7526
7454
  functionalUtility({
7527
7455
  name: "stroke",
7528
- themeKeys: ["colors"],
7456
+ themeKeys: ["colors", "strokeWidth"],
7529
7457
  supportsArbitrary: true,
7530
7458
  supportsCustomProperty: true,
7531
7459
  handle: (value, ctx, token, extra) => {
7532
- if (parseNumber(value)) return [decl("stroke-width", value)];
7460
+ if (parseNumber(value) || extra?.themeNamespace === "strokeWidth") return [decl("stroke-width", value)];
7533
7461
  if (extra?.realThemeValue) return [decl("stroke", `var(--color-${extra.realThemeValue})`)];
7534
7462
  return [decl("stroke", value)];
7535
7463
  },
@@ -7685,7 +7613,7 @@ staticModifier("open", ["&:is([open], :popover-open, :open)"], {
7685
7613
  var withPseudoContent = (ast) => [
7686
7614
  atRoot([property("--baro-content", "\"\"")]),
7687
7615
  ...ast,
7688
- decl("content", "var(--baro-content)")
7616
+ ...ast.some((n) => n.type === "decl" && n.prop === "content") ? [] : [decl("content", "var(--baro-content)")]
7689
7617
  ];
7690
7618
  staticModifier("before", ["&::before"], {
7691
7619
  source: "pseudo",
@@ -7695,19 +7623,14 @@ staticModifier("after", ["&::after"], {
7695
7623
  source: "pseudo",
7696
7624
  astHandler: withPseudoContent
7697
7625
  });
7698
- staticModifier("placeholder", [
7699
- "&::placeholder",
7700
- "&::-webkit-input-placeholder",
7701
- "&::-moz-placeholder",
7702
- "&:-ms-input-placeholder"
7703
- ], { source: "pseudo" });
7704
- staticModifier("selection", ["&::selection", "&::-moz-selection"], { source: "pseudo" });
7705
- staticModifier("file", ["&::file-selector-button", "&::-webkit-file-upload-button"], { source: "pseudo" });
7626
+ staticModifier("placeholder", ["&::placeholder"], { source: "pseudo" });
7627
+ staticModifier("selection", ["& *::selection", "&::selection"], { source: "pseudo" });
7628
+ staticModifier("file", ["&::file-selector-button"], { source: "pseudo" });
7706
7629
  staticModifier("marker", [
7630
+ "& *::marker",
7707
7631
  "&::marker",
7708
- "&::-webkit-details-marker",
7709
- "&::-moz-list-bullet",
7710
- "&::-moz-list-number"
7632
+ "& *::-webkit-details-marker",
7633
+ "&::-webkit-details-marker"
7711
7634
  ], { source: "pseudo" });
7712
7635
  staticModifier("details-content", ["&::details-content"], { source: "pseudo" });
7713
7636
  staticModifier("first-line", ["&::first-line"], { source: "pseudo" });
@@ -7765,7 +7688,9 @@ function attributeVariantSelector(variant) {
7765
7688
  return `[${kind}-${key}=${/^(["']).*\1$/.test(raw) ? raw : `"${decodeArbitrarySelector(raw)}"`}]`;
7766
7689
  }
7767
7690
  const bare = /^data-([a-zA-Z0-9_-]+)$/.exec(variant);
7768
- return bare ? `[data-${bare[1]}]` : void 0;
7691
+ if (bare) return `[data-${bare[1]}]`;
7692
+ const aria = /^aria-([a-zA-Z0-9_-]+)$/.exec(variant);
7693
+ return aria ? `[aria-${aria[1]}="true"]` : void 0;
7769
7694
  }
7770
7695
  /**
7771
7696
  * The argument of a `:has()`/`:not()` built from an arbitrary value: a selector list is wrapped as `*:is(…)`
@@ -7786,6 +7711,80 @@ function hasTopLevelComma(value) {
7786
7711
  }
7787
7712
  return false;
7788
7713
  }
7714
+ /**
7715
+ * #335: the pseudo-class selector (`:hover`, `:first-child`, `:nth-child(odd)`) of a registered static
7716
+ * variant, for compounding in not-/group-/peer-/has- forms, or null when the variant is unknown or is not a
7717
+ * single pseudo-class (pseudo-elements, at-rules, multi-selector variants). Tailwind 4.3.3 emits nothing
7718
+ * for a compound variant whose inner variant it cannot compound (`not-foo`, `group-before`, `peer-has-foo`).
7719
+ */
7720
+ function pseudoClassOf(name, ctx) {
7721
+ const plugin = getModifier(ctx).find((p) => p.name === name && p.match(name, ctx));
7722
+ if (!plugin?.modifySelector) return null;
7723
+ const r = plugin.modifySelector({
7724
+ selector: "&",
7725
+ fullClassName: "",
7726
+ mod: { type: name },
7727
+ context: ctx
7728
+ });
7729
+ const list = Array.isArray(r) ? r : r && typeof r === "object" ? [r] : typeof r === "string" ? [{ selector: r }] : [];
7730
+ if (list.length !== 1) return null;
7731
+ const m = /^&(:(?!:)[a-zA-Z-]+(?:\(.*\))?)$/.exec(list[0].selector);
7732
+ return m ? m[1] : null;
7733
+ }
7734
+ /**
7735
+ * #352: the selector `not-<v>` / `group-not-<v>` negates: an attribute variant (`data-*`, `aria-*`), a
7736
+ * pseudo-class (#335), or a wrap-free `has-*` variant (`has-[…]`, `has-aria-*`), as Tailwind 4.3.3 compounds
7737
+ * them. Null when `<v>` is unknown or is not a single compound on `&`.
7738
+ */
7739
+ function negatableSelectorOf(name, ctx) {
7740
+ const attr = attributeVariantSelector(name);
7741
+ if (attr) return attr;
7742
+ const pc = pseudoClassOf(name, ctx);
7743
+ if (pc || !name.startsWith("has-")) return pc;
7744
+ const plugin = getModifier(ctx).find((p) => p.match(name, ctx));
7745
+ if (!plugin?.modifySelector || plugin.wrap || plugin.astHandler) return null;
7746
+ const r = plugin.modifySelector({
7747
+ selector: "&",
7748
+ fullClassName: "",
7749
+ mod: { type: name },
7750
+ context: ctx
7751
+ });
7752
+ const list = Array.isArray(r) ? r : r && typeof r === "object" ? [r] : typeof r === "string" ? [{ selector: r }] : [];
7753
+ if (list.length !== 1) return null;
7754
+ const m = /^&(:has\(.+\))$/.exec(list[0].selector);
7755
+ return m && !m[1].includes("&") ? m[1] : null;
7756
+ }
7757
+ /**
7758
+ * #352: `not-<v>` for a wrap-only at-rule variant (`md`, `max-md`, `min-[…]`, `print`, `motion-safe`,
7759
+ * `supports-[…]`, `dark` in media mode): the same at-rule with its condition negated (`@media not (…)`,
7760
+ * `@supports not (…)`), as Tailwind 4.3.3 emits it. Null for anything else, and for a prelude that is a list
7761
+ * or already combines conditions, where a leading `not` would not negate the whole query.
7762
+ */
7763
+ function negatedAtRuleOf(name, ctx) {
7764
+ if (name.startsWith("not-")) return null;
7765
+ const plugin = getModifier(ctx).find((p) => p.match(name, ctx));
7766
+ if (!plugin?.wrap || plugin.astHandler) return null;
7767
+ if (plugin.modifySelector) {
7768
+ const r = plugin.modifySelector({
7769
+ selector: "&",
7770
+ fullClassName: "",
7771
+ mod: { type: name },
7772
+ context: ctx
7773
+ });
7774
+ if ((typeof r === "string" ? r : Array.isArray(r) ? r.length === 1 ? r[0].selector : null : r?.selector) !== "&") return null;
7775
+ }
7776
+ const items = plugin.wrap({ type: name }, ctx);
7777
+ if (items.length !== 1) return null;
7778
+ const node = items[0];
7779
+ if (node.type !== "at-rule" || node.name !== "media" && node.name !== "supports" || node.nodes?.length) return null;
7780
+ const params = (node.params ?? "").trim();
7781
+ if (!params || /^not\b|,|\s(and|or)\s/i.test(params)) return null;
7782
+ return {
7783
+ ...node,
7784
+ params: `not ${params}`,
7785
+ nodes: []
7786
+ };
7787
+ }
7789
7788
  //#endregion
7790
7789
  //#region src/presets/variants/responsive.ts
7791
7790
  functionalModifier((mod, context) => {
@@ -7936,6 +7935,7 @@ function innerCompound(variant, ctx) {
7936
7935
  mod: { type: variant },
7937
7936
  context: ctx
7938
7937
  });
7938
+ if (out == null) return void 0;
7939
7939
  const list = typeof out === "string" ? [{ selector: out }] : Array.isArray(out) ? out : [out];
7940
7940
  if (list.length !== 1) return void 0;
7941
7941
  const sel = list[0].selector;
@@ -8030,6 +8030,10 @@ functionalModifier((mod, ctx) => {
8030
8030
  }, groupHasSelector);
8031
8031
  //#endregion
8032
8032
  //#region src/presets/variants/negation-variants.ts
8033
+ functionalModifier((mod, context) => /^not-(?!@)/.test(mod) && !!negatedAtRuleOf(mod.slice(4), context), () => "&", (mod, context) => {
8034
+ const node = negatedAtRuleOf(mod.type.slice(4), context);
8035
+ return node ? [node] : [];
8036
+ });
8033
8037
  functionalModifier((mod) => /^not-\[.*\]$/.test(mod), ({ selector, mod }) => {
8034
8038
  const m = /^not-\[(.+)\]$/.exec(mod.type);
8035
8039
  if (m) {
@@ -8051,10 +8055,12 @@ functionalModifier((mod) => /^not-\[.*\]$/.test(mod), ({ selector, mod }) => {
8051
8055
  source: "attribute"
8052
8056
  };
8053
8057
  });
8054
- functionalModifier((mod) => /^not-/.test(mod) && !mod.startsWith("not-@"), ({ selector, mod }) => {
8058
+ functionalModifier((mod) => /^not-/.test(mod) && !mod.startsWith("not-@"), ({ selector, mod, context }) => {
8055
8059
  const m = /^not-(.+)$/.exec(mod.type);
8060
+ const inner = m ? negatableSelectorOf(m[1], context) : null;
8061
+ if (m && !inner) return null;
8056
8062
  return {
8057
- selector: m ? `&:not(:${m[1]})` : selector,
8063
+ selector: inner ? `&:not(${inner})` : selector,
8058
8064
  flatten: false,
8059
8065
  wrappingType: "rule",
8060
8066
  source: "attribute"
@@ -8114,7 +8120,7 @@ functionalModifier((mod) => /^aria-/.test(mod), ({ selector, mod }) => {
8114
8120
  source: "aria"
8115
8121
  };
8116
8122
  }, void 0);
8117
- functionalModifier((mod) => mod.startsWith("not-") && !mod.startsWith("not-@"), ({ selector, mod }) => {
8123
+ functionalModifier((mod) => mod.startsWith("not-") && !mod.startsWith("not-@"), ({ selector, mod, context }) => {
8118
8124
  const pseudo = mod.type.replace("not-", "");
8119
8125
  if (pseudo.startsWith("[")) {
8120
8126
  const inner = pseudo.slice(1, -1);
@@ -8126,10 +8132,14 @@ functionalModifier((mod) => mod.startsWith("not-") && !mod.startsWith("not-@"),
8126
8132
  selector: `&:not(${functionalArgument(inner)})`,
8127
8133
  source: "attribute"
8128
8134
  };
8129
- } else return {
8130
- selector: `&:not(:${pseudo})`,
8131
- source: "attribute"
8132
- };
8135
+ } else {
8136
+ const inner = negatableSelectorOf(pseudo, context);
8137
+ if (!inner) return null;
8138
+ return {
8139
+ selector: `&:not(${inner})`,
8140
+ source: "attribute"
8141
+ };
8142
+ }
8133
8143
  }, void 0);
8134
8144
  functionalModifier((mod) => /^data-/.test(mod), ({ selector, mod }) => {
8135
8145
  const bracket = /^data-\[([a-zA-Z0-9_-]+)(?:=([^\]]+))?\]$/.exec(mod.type);
@@ -8242,11 +8252,13 @@ functionalModifier((mod) => /^(group|peer)-hover(\/[a-zA-Z0-9_-]+)?$/.test(mod),
8242
8252
  source: kind
8243
8253
  };
8244
8254
  }, () => [atRule("media", "(hover: hover)", [])]);
8245
- function negated(value) {
8255
+ function negated(value, ctx) {
8246
8256
  const v = value.slice(4);
8247
- return v.startsWith("[") && v.endsWith("]") ? `:not(*:is(${decodeArbitrarySelector(v.slice(1, -1))}))` : `:not(:${v})`;
8257
+ if (v.startsWith("[") && v.endsWith("]")) return `:not(*:is(${decodeArbitrarySelector(v.slice(1, -1))}))`;
8258
+ const inner = negatableSelectorOf(v, ctx);
8259
+ return inner ? `:not(${inner})` : null;
8248
8260
  }
8249
- functionalModifier((mod) => /^group-(.+)$/.test(mod) && !atRuleHas(mod), ({ selector, mod }) => {
8261
+ functionalModifier((mod) => /^group-(.+)$/.test(mod) && !atRuleHas(mod), ({ selector, mod, context }) => {
8250
8262
  const raw = /^group-(.+)$/.exec(mod.type);
8251
8263
  const [variant, base] = splitGroupName("group", raw?.[1] ?? "");
8252
8264
  const m = raw ? [raw[0], variant] : null;
@@ -8262,11 +8274,14 @@ functionalModifier((mod) => /^group-(.+)$/.test(mod) && !atRuleHas(mod), ({ sele
8262
8274
  wrappingType: "rule",
8263
8275
  source: "group"
8264
8276
  };
8265
- if (m?.[1]?.startsWith("not-")) return {
8266
- selector: `&:is(${g}${negated(m[1])} *)`,
8267
- wrappingType: "rule",
8268
- source: "group"
8269
- };
8277
+ if (m?.[1]?.startsWith("not-")) {
8278
+ const neg = negated(m[1], context);
8279
+ return neg ? {
8280
+ selector: `&:is(${g}${neg} *)`,
8281
+ wrappingType: "rule",
8282
+ source: "group"
8283
+ } : null;
8284
+ }
8270
8285
  if (m?.[1]?.startsWith("has-")) {
8271
8286
  const pattern = /^has-\[([a-zA-Z0-9_-]+)\]$/.exec(m?.[1]);
8272
8287
  if (pattern) return {
@@ -8292,8 +8307,10 @@ functionalModifier((mod) => /^group-(.+)$/.test(mod) && !atRuleHas(mod), ({ sele
8292
8307
  };
8293
8308
  }
8294
8309
  }
8310
+ const pc = m ? pseudoClassOf(m[1], context) : null;
8311
+ if (m && !pc) return null;
8295
8312
  return m ? {
8296
- selector: `&:is(${g}:${m[1]} *)`,
8313
+ selector: `&:is(${g}${pc} *)`,
8297
8314
  wrappingType: "rule",
8298
8315
  source: "group"
8299
8316
  } : {
@@ -8301,7 +8318,7 @@ functionalModifier((mod) => /^group-(.+)$/.test(mod) && !atRuleHas(mod), ({ sele
8301
8318
  source: "group"
8302
8319
  };
8303
8320
  }, void 0);
8304
- functionalModifier((mod) => /^peer-(.+)$/.test(mod) && !atRuleHas(mod), ({ selector, mod }) => {
8321
+ functionalModifier((mod) => /^peer-(.+)$/.test(mod) && !atRuleHas(mod), ({ selector, mod, context }) => {
8305
8322
  const raw = /^peer-(.+)$/.exec(mod.type);
8306
8323
  const [variant, base] = splitGroupName("peer", raw?.[1] ?? "");
8307
8324
  const m = raw ? [raw[0], variant] : null;
@@ -8322,14 +8339,22 @@ functionalModifier((mod) => /^peer-(.+)$/.test(mod) && !atRuleHas(mod), ({ selec
8322
8339
  selector: `&:is(${g}:has(${functionalArgument(value.slice(5, -1))}) ~ *)`,
8323
8340
  source: "peer"
8324
8341
  };
8325
- if (value?.startsWith("has-")) return {
8326
- selector: `&:is(${g}:has(:${value.slice(4)})~*)`,
8327
- source: "peer"
8328
- };
8329
- if (value?.startsWith("not-")) return {
8330
- selector: `&:is(${g}${negated(value)} ~ *)`,
8331
- source: "peer"
8332
- };
8342
+ if (value?.startsWith("has-")) {
8343
+ const pc = pseudoClassOf(value.slice(4), context);
8344
+ if (!pc) return null;
8345
+ return {
8346
+ selector: `&:is(${g}:has(${pc})~*)`,
8347
+ source: "peer"
8348
+ };
8349
+ }
8350
+ if (value?.startsWith("not-")) {
8351
+ const neg = negated(value, context);
8352
+ if (!neg) return null;
8353
+ return {
8354
+ selector: `&:is(${g}${neg} ~ *)`,
8355
+ source: "peer"
8356
+ };
8357
+ }
8333
8358
  if (value?.startsWith("aria-")) {
8334
8359
  let pattern = /^aria-([a-zA-Z0-9_]+)$/.exec(value);
8335
8360
  if (pattern) return {
@@ -8350,8 +8375,10 @@ functionalModifier((mod) => /^peer-(.+)$/.test(mod) && !atRuleHas(mod), ({ selec
8350
8375
  };
8351
8376
  }
8352
8377
  }
8378
+ const pc = m ? pseudoClassOf(value, context) : null;
8379
+ if (m && !pc) return null;
8353
8380
  return m ? {
8354
- selector: `&:is(${g}:${value}~*)`,
8381
+ selector: `&:is(${g}${pc}~*)`,
8355
8382
  source: "peer"
8356
8383
  } : {
8357
8384
  selector,
@@ -8400,6 +8427,7 @@ function toPx(n, unit) {
8400
8427
  }
8401
8428
  function preludeKey(kind, prelude) {
8402
8429
  const container = kind === "container";
8430
+ if (!container && /^\s*not\b/i.test(prelude)) return [0, 0];
8403
8431
  const min = MIN_W.exec(prelude);
8404
8432
  if (min) return [container ? 4 : 2, toPx(min[1], min[2])];
8405
8433
  const max = MAX_W.exec(prelude);
@@ -8499,6 +8527,8 @@ exports.staticModifier = staticModifier;
8499
8527
  exports.staticUtility = staticUtility;
8500
8528
  exports.styleRule = styleRule;
8501
8529
  exports.themeGetter = themeGetter;
8530
+ exports.themeKeyValue = themeKeyValue;
8531
+ exports.themeKeyVar = themeKeyVar;
8502
8532
  exports.themeToCssVars = themeToCssVars;
8503
8533
  exports.tokenize = tokenize;
8504
8534
  exports.upperBound = upperBound;