@barocss/kit 0.7.0 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -249,6 +249,7 @@ function getUtility(ctx) {
249
249
  const modifierRegistry = [];
250
250
  function staticModifier(name, selectors, options = {}, ctx) {
251
251
  registerModifier({
252
+ name,
252
253
  match: (mod) => mod === name,
253
254
  modifySelector: ({ ..._rest }) => {
254
255
  return selectors.map((sel) => ({
@@ -656,6 +657,9 @@ function hasCommentDelimiter(text) {
656
657
  }
657
658
  return false;
658
659
  }
660
+ function hasHtmlEndTagOpener(text) {
661
+ return text.includes("</");
662
+ }
659
663
  function isStructureSafeValue(value) {
660
664
  if (hasCommentToken(value)) return false;
661
665
  return isSafeVariantValue(value, true);
@@ -803,8 +807,11 @@ function parseUtility(value, ctx) {
803
807
  priority
804
808
  };
805
809
  }
806
- const isSafePrelude = (text) => !hasCommentDelimiter(String(text ?? ""));
807
- const isSafeDecl = (prop, value) => isStructureSafeValue(String(prop)) && isStructureSafeValue(String(value ?? ""));
810
+ const isSafePrelude = (text) => {
811
+ const t = String(text ?? "");
812
+ return !hasCommentDelimiter(t) && !hasHtmlEndTagOpener(t);
813
+ };
814
+ const isSafeDecl = (prop, value) => isStructureSafeValue(String(prop)) && isStructureSafeValue(String(value ?? "")) && !hasHtmlEndTagOpener(String(prop)) && !hasHtmlEndTagOpener(String(value ?? ""));
808
815
  const importantPrefix = "!important";
809
816
  function astToCss(ast, baseSelector, opts, _indent = "") {
810
817
  const minify = opts?.minify;
@@ -1108,7 +1115,7 @@ function animationToCssVars(animations) {
1108
1115
  }
1109
1116
  return result;
1110
1117
  }
1111
- const COMMENT_OR_BLOCK = /\/\*|\*\/|[{};]/;
1118
+ const COMMENT_OR_BLOCK = /\/\*|\*\/|[{};]|<\//;
1112
1119
  function keyframesBlock(name, frames) {
1113
1120
  if (!name || COMMENT_OR_BLOCK.test(name) || /\s/.test(name) || !frames || typeof frames !== "object") return "";
1114
1121
  let body = "";
@@ -1215,6 +1222,8 @@ function themeToCssVarsAll(theme) {
1215
1222
  ...transitionDurationToCssVars(theme.transitionDuration),
1216
1223
  ...transitionDelayToCssVars(theme.transitionDelay),
1217
1224
  ...blurToCssVars(theme.blur),
1225
+ ...Object.fromEntries(Object.entries(theme.textShadow ?? {}).map(([k, v2]) => [`--text-shadow-${escapeKey(k)}`, v2])),
1226
+ ...Object.fromEntries(Object.entries(theme.dropShadow ?? {}).map(([k, v2]) => [`--drop-shadow-${escapeKey(k)}`, v2])),
1218
1227
  ...Object.fromEntries(Object.entries(theme.aspect ?? {}).map(([k, v2]) => [`--aspect-${escapeKey(k)}`, v2]))
1219
1228
  // keyframes handled separately
1220
1229
  };
@@ -1224,8 +1233,15 @@ function isSelfReferencingVar(name, value) {
1224
1233
  const m = /^var\(\s*(--[\w-]+)\s*(?:,[\s\S]*)?\)$/.exec(value.trim());
1225
1234
  return !!m && m[1] === name.trim();
1226
1235
  }
1236
+ const SAFE_VAR_NAME = /^--(?:[\w-]|\\\.)+$/;
1237
+ function isSafeThemeVar(name, value) {
1238
+ if (typeof name !== "string" || !SAFE_VAR_NAME.test(name) || hasHtmlEndTagOpener(name)) return false;
1239
+ if (typeof value !== "string" && typeof value !== "number") return false;
1240
+ const v2 = String(value);
1241
+ return v2.trim() !== "" && isStructureSafeValue(v2) && !hasCommentDelimiter(v2) && !hasHtmlEndTagOpener(v2);
1242
+ }
1227
1243
  function toCssVarsBlock(vars, extra = "") {
1228
- return ":root,:host {\n" + Object.entries(vars).filter(([k, v2]) => !isSelfReferencingVar(k, v2)).map(([k, v2]) => ` ${k}: ${v2};`).join("\n") + "\n}\n" + extra + "\n";
1244
+ return ":root,:host {\n" + Object.entries(vars).filter(([k, v2]) => isSafeThemeVar(k, v2) && !isSelfReferencingVar(k, v2)).map(([k, v2]) => ` ${k}: ${v2};`).join("\n") + "\n}\n" + extra + "\n";
1229
1245
  }
1230
1246
  const BARO_VAR = /--baro-/g;
1231
1247
  const PREFIXED_KEYS = /* @__PURE__ */ new Set(["prop", "value", "params", "selector", "nodes", "items"]);
@@ -2106,7 +2122,7 @@ html {
2106
2122
  line-height: 1.15;
2107
2123
  -webkit-text-size-adjust: 100%;
2108
2124
  /* Tailwind 4.1.13 root font (app --default-font-family / --font-sans win) */
2109
- 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'));
2125
+ 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'));
2110
2126
  font-feature-settings: var(--default-font-feature-settings, normal);
2111
2127
  font-variation-settings: var(--default-font-variation-settings, normal);
2112
2128
  }
@@ -2409,7 +2425,7 @@ html {
2409
2425
  -webkit-text-size-adjust: 100%;
2410
2426
  -ms-text-size-adjust: 100%;
2411
2427
  /* Tailwind 4.1.13 root font (app --default-font-family / --font-sans win) */
2412
- 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'));
2428
+ 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'));
2413
2429
  font-feature-settings: var(--default-font-feature-settings, normal);
2414
2430
  font-variation-settings: var(--default-font-variation-settings, normal);
2415
2431
  }
@@ -3488,6 +3504,9 @@ staticUtility("snap-both", [["scroll-snap-type", "both var(--baro-scroll-snap-st
3488
3504
  staticUtility("snap-mandatory", [["--baro-scroll-snap-strictness", "mandatory"]], { category: "interactivity" });
3489
3505
  staticUtility("snap-proximity", [["--baro-scroll-snap-strictness", "proximity"]], { category: "interactivity" });
3490
3506
  [
3507
+ ["mbs", "scroll-margin-block-start"],
3508
+ // #311 (Tailwind 4.3), before `mb`
3509
+ ["mbe", "scroll-margin-block-end"],
3491
3510
  ["mt", "scroll-margin-top"],
3492
3511
  ["mr", "scroll-margin-right"],
3493
3512
  ["mb", "scroll-margin-bottom"],
@@ -3498,6 +3517,8 @@ staticUtility("snap-proximity", [["--baro-scroll-snap-strictness", "proximity"]]
3498
3517
  ["me", "scroll-margin-inline-end"],
3499
3518
  ["m", "scroll-margin"]
3500
3519
  ].forEach(([name, prop]) => {
3520
+ staticUtility(`scroll-${name}-px`, [[prop, "1px"]], { category: "interactivity" });
3521
+ staticUtility(`-scroll-${name}-px`, [[prop, "-1px"]], { category: "interactivity" });
3501
3522
  functionalUtility({
3502
3523
  name: `scroll-${name}`,
3503
3524
  spacingKeys: true,
@@ -3516,6 +3537,9 @@ staticUtility("snap-proximity", [["--baro-scroll-snap-strictness", "proximity"]]
3516
3537
  });
3517
3538
  });
3518
3539
  [
3540
+ ["pbs", "scroll-padding-block-start"],
3541
+ // #311 (Tailwind 4.3), before `pb`
3542
+ ["pbe", "scroll-padding-block-end"],
3519
3543
  ["pt", "scroll-padding-top"],
3520
3544
  ["pr", "scroll-padding-right"],
3521
3545
  ["pb", "scroll-padding-bottom"],
@@ -3532,13 +3556,15 @@ staticUtility("snap-proximity", [["--baro-scroll-snap-strictness", "proximity"]]
3532
3556
  prop,
3533
3557
  supportsArbitrary: true,
3534
3558
  supportsCustomProperty: true,
3559
+ handleBareValue: ({ value }) => value === "px" ? "1px" : /^(\d|\.\d)/.test(value) ? value : null,
3535
3560
  handle: (value, _ctx, token, _extra) => {
3536
- if (parseNumber(value) || token.negative) {
3561
+ if (token.negative) return [];
3562
+ if (parseNumber(value)) {
3537
3563
  return [decl(prop, `calc(var(--spacing) * ${value})`)];
3538
3564
  }
3539
3565
  return [decl(prop, value)];
3540
3566
  },
3541
- handleCustomProperty: (value) => [decl(prop, `var(${value})`)],
3567
+ handleCustomProperty: (value, _ctx, token) => token.negative ? [] : [decl(prop, `var(${value})`)],
3542
3568
  description: `scroll-${name} utility (static, arbitrary, custom property supported)`,
3543
3569
  category: "interactivity"
3544
3570
  });
@@ -3569,6 +3595,40 @@ functionalUtility({
3569
3595
  description: "will-change utility (static, arbitrary, custom property supported)",
3570
3596
  category: "interactivity"
3571
3597
  });
3598
+ staticUtility("scrollbar-auto", [["scrollbar-width", "auto"]], { category: "interactivity" });
3599
+ staticUtility("scrollbar-thin", [["scrollbar-width", "thin"]], { category: "interactivity" });
3600
+ staticUtility("scrollbar-none", [["scrollbar-width", "none"]], { category: "interactivity" });
3601
+ staticUtility("scrollbar-gutter-auto", [["scrollbar-gutter", "auto"]], { category: "interactivity" });
3602
+ staticUtility("scrollbar-gutter-stable", [["scrollbar-gutter", "stable"]], { category: "interactivity" });
3603
+ staticUtility("scrollbar-gutter-both", [["scrollbar-gutter", "stable both-edges"]], { category: "interactivity" });
3604
+ const SCROLLBAR_COLOR = "var(--baro-scrollbar-thumb) var(--baro-scrollbar-track)";
3605
+ const scrollbarProperties = () => atRoot([
3606
+ property("--baro-scrollbar-thumb", "#0000", "<color>"),
3607
+ property("--baro-scrollbar-track", "#0000", "<color>")
3608
+ ]);
3609
+ const stripColorHint = (v) => v.replace(/^color:/, "");
3610
+ for (const part of ["thumb", "track"]) {
3611
+ const key = `--baro-scrollbar-${part}`;
3612
+ const compose = (inner) => [scrollbarProperties(), ...inner, decl("scrollbar-color", SCROLLBAR_COLOR)];
3613
+ const withOpacity = (color, opacity) => opacity ? [decl(key, `color-mix(in oklab, ${color} ${opacity.replace(/^\[(.*)\]$/, "$1").replace(/%$/, "")}%, transparent)`)] : [decl(key, color)];
3614
+ functionalUtility({
3615
+ name: `scrollbar-${part}`,
3616
+ themeKeys: ["colors"],
3617
+ supportsOpacity: true,
3618
+ supportsArbitrary: true,
3619
+ supportsCustomProperty: true,
3620
+ handle: (value, _ctx, token, extra) => {
3621
+ if (extra?.realThemeValue) return compose(withOpacity(`var(--color-${extra.realThemeValue})`, extra.opacity));
3622
+ if (token.arbitrary) return compose(withOpacity(stripColorHint(value), extra?.opacity));
3623
+ if (value === "inherit" || value === "transparent") return compose([decl(key, value)]);
3624
+ if (value === "current") return compose(withOpacity("currentcolor", extra?.opacity));
3625
+ return null;
3626
+ },
3627
+ handleCustomProperty: (value, _ctx, _token, extra) => compose(withOpacity(`var(${stripColorHint(value)})`, extra?.opacity)),
3628
+ description: `scrollbar-color ${part} utility (theme, arbitrary, custom property, opacity)`,
3629
+ category: "interactivity"
3630
+ });
3631
+ }
3572
3632
  const defaultTiming = "var(--default-transition-timing-function)";
3573
3633
  const defaultDuration = "var(--default-transition-duration)";
3574
3634
  staticUtility("transition", [
@@ -3706,53 +3766,99 @@ staticUtility("border-collapse", [["border-collapse", "collapse"]], { category:
3706
3766
  staticUtility("border-separate", [["border-collapse", "separate"]], { category: "table" });
3707
3767
  staticUtility("table-auto", [["table-layout", "auto"]], { category: "table" });
3708
3768
  staticUtility("table-fixed", [["table-layout", "fixed"]], { category: "table" });
3709
- functionalUtility({
3710
- name: "border-spacing-x",
3711
- prop: "border-spacing",
3712
- supportsArbitrary: true,
3713
- supportsCustomProperty: true,
3714
- handle: (value, _ctx, _token) => {
3715
- if (parseNumber(value)) {
3716
- return [decl("border-spacing", `calc(var(--spacing) * ${value}) var(--baro-border-spacing-y)`)];
3717
- }
3718
- return [decl("border-spacing", `${value} var(--baro-border-spacing-y)`)];
3719
- },
3720
- handleCustomProperty: (value) => [decl("border-spacing", `var(${value}) var(--baro-border-spacing-y)`)],
3721
- description: "border-spacing-x utility (static, number, arbitrary, custom property supported)",
3722
- category: "table"
3723
- });
3724
- functionalUtility({
3725
- name: "border-spacing-y",
3726
- prop: "border-spacing",
3727
- supportsArbitrary: true,
3728
- supportsCustomProperty: true,
3729
- handle: (value, _ctx, _token) => {
3730
- if (parseNumber(value)) {
3731
- return [decl("border-spacing", `var(--baro-border-spacing-x) calc(var(--spacing) * ${value})`)];
3732
- }
3733
- return [decl("border-spacing", `var(--baro-border-spacing-x) ${value}`)];
3734
- },
3735
- handleCustomProperty: (value) => [decl("border-spacing", `var(--baro-border-spacing-x) var(${value})`)],
3736
- description: "border-spacing-y utility (static, number, arbitrary, custom property supported)",
3737
- category: "table"
3738
- });
3739
- functionalUtility({
3740
- name: "border-spacing",
3741
- prop: "border-spacing",
3742
- supportsArbitrary: true,
3743
- supportsCustomProperty: true,
3744
- handle: (value, _ctx, _token) => {
3745
- if (parseNumber(value)) {
3746
- return [decl("border-spacing", `calc(var(--spacing) * ${value})`)];
3747
- }
3748
- return [decl("border-spacing", value)];
3749
- },
3750
- handleCustomProperty: (value) => [decl("border-spacing", `var(${value})`)],
3751
- description: "border-spacing utility (static, number, arbitrary, custom property supported)",
3752
- category: "table"
3769
+ const borderSpacingProperties = () => atRoot([
3770
+ property("--baro-border-spacing-x", "0", "<length>"),
3771
+ property("--baro-border-spacing-y", "0", "<length>")
3772
+ ]);
3773
+ const BORDER_SPACING = "var(--baro-border-spacing-x) var(--baro-border-spacing-y)";
3774
+ const borderSpacing = (axes, v) => [
3775
+ borderSpacingProperties(),
3776
+ ...axes.map((a) => decl(`--baro-border-spacing-${a}`, v)),
3777
+ decl("border-spacing", BORDER_SPACING)
3778
+ ];
3779
+ [
3780
+ ["border-spacing-x", ["x"]],
3781
+ ["border-spacing-y", ["y"]],
3782
+ ["border-spacing", ["x", "y"]]
3783
+ ].forEach(([name, axes]) => {
3784
+ staticUtility(`${name}-px`, [
3785
+ borderSpacingProperties,
3786
+ ...axes.map((a) => [`--baro-border-spacing-${a}`, "1px"]),
3787
+ ["border-spacing", BORDER_SPACING]
3788
+ ], { category: "table" });
3789
+ functionalUtility({
3790
+ name,
3791
+ prop: "border-spacing",
3792
+ supportsArbitrary: true,
3793
+ supportsCustomProperty: true,
3794
+ handle: (value) => borderSpacing(axes, parseNumber(value) ? `calc(var(--spacing) * ${value})` : value),
3795
+ handleCustomProperty: (value) => borderSpacing(axes, `var(${value})`),
3796
+ description: `${name} utility (number, px, arbitrary, custom property supported)`,
3797
+ category: "table"
3798
+ });
3753
3799
  });
3754
3800
  staticUtility("caption-top", [["caption-side", "top"]], { category: "table" });
3755
3801
  staticUtility("caption-bottom", [["caption-side", "bottom"]], { category: "table" });
3802
+ function parseAlpha(op) {
3803
+ if (!op) return null;
3804
+ if (/^\d+(\.\d+)?$/.test(op)) return { alpha: `${op}%`, isVar: false };
3805
+ const pct = /^\[(\d+(?:\.\d+)?)%\]$/.exec(op);
3806
+ if (pct) return { alpha: `${pct[1]}%`, isVar: false };
3807
+ const cp = /^\((--[\w-]+)\)$/.exec(op);
3808
+ if (cp) return { alpha: `var(${cp[1]})`, isVar: true };
3809
+ return null;
3810
+ }
3811
+ function splitTop(value, sep) {
3812
+ const out = [];
3813
+ let depth = 0;
3814
+ let cur = "";
3815
+ for (const ch of value) {
3816
+ if (ch === "(") depth++;
3817
+ else if (ch === ")") depth--;
3818
+ if (depth === 0 && (sep === " " ? /\s/.test(ch) : ch === sep)) {
3819
+ if (cur.trim()) out.push(cur.trim());
3820
+ cur = "";
3821
+ } else cur += ch;
3822
+ }
3823
+ if (cur.trim()) out.push(cur.trim());
3824
+ return out;
3825
+ }
3826
+ const LENGTH = /^-?(\d*\.)?\d+([a-z]+|%)?$/i;
3827
+ function shadowLayers(value, layer, alpha) {
3828
+ return splitTop(value, ",").map((l) => {
3829
+ const parts = splitTop(l, " ");
3830
+ const i = parts.findIndex((p) => p !== "inset" && !LENGTH.test(p));
3831
+ const c = i < 0 ? "currentcolor" : parts[i];
3832
+ parts[i < 0 ? parts.length : i] = `var(--baro-${layer}-color, ${alpha ? `oklab(from ${c} l a b / ${alpha})` : c})`;
3833
+ return parts.join(" ");
3834
+ });
3835
+ }
3836
+ function shadowValueDecls(layer, prop, value, opacity, render = (l) => l.join(", ")) {
3837
+ const a = parseAlpha(opacity);
3838
+ if (opacity && !a) return null;
3839
+ if (!a) return [decl(prop, render(shadowLayers(value, layer)))];
3840
+ const alphaDecl = decl(`--baro-${layer}-alpha`, a.alpha);
3841
+ if (!a.isVar) return [alphaDecl, decl(prop, render(shadowLayers(value, layer, a.alpha)))];
3842
+ return [
3843
+ alphaDecl,
3844
+ decl(prop, render(shadowLayers(value, layer))),
3845
+ atRule("supports", "(color: lab(from red l a b))", [decl(prop, render(shadowLayers(value, layer, a.alpha)))])
3846
+ ];
3847
+ }
3848
+ function shadowColorDecls(layer, color, opacity, ref = color) {
3849
+ const key = `--baro-${layer}-color`;
3850
+ if (color === "inherit") return [decl(key, "inherit")];
3851
+ const a = parseAlpha(opacity);
3852
+ if (opacity && !a) return null;
3853
+ const inner = a ? `color-mix(in oklab, ${ref} ${a.alpha}, transparent)` : ref;
3854
+ const fallback = a ? `color-mix(in srgb, ${color} ${a.alpha}, transparent)` : color;
3855
+ return [
3856
+ decl(key, fallback),
3857
+ atRule("supports", "(color: color-mix(in lab, red, red))", [
3858
+ decl(key, `color-mix(in oklab, ${inner} var(--baro-${layer}-alpha), transparent)`)
3859
+ ])
3860
+ ];
3861
+ }
3756
3862
  staticUtility("filter-none", [["filter", "none"]], { category: "effects" });
3757
3863
  functionalUtility({
3758
3864
  name: "filter",
@@ -3837,57 +3943,68 @@ functionalUtility({
3837
3943
  description: "contrast filter utility (static, number, arbitrary, custom property supported)",
3838
3944
  category: "effects"
3839
3945
  });
3840
- [
3841
- ["drop-shadow-xs", "xs", "0 1px 1px var(--baro-drop-shadow-color, #0000001a)"],
3842
- ["drop-shadow-sm", "sm", "0 1px 2px var(--baro-drop-shadow-color, #0000001a)"],
3843
- ["drop-shadow-md", "md", "0 3px 3px var(--baro-drop-shadow-color, #0000001a)"],
3844
- ["drop-shadow-lg", "lg", "0 4px 4px var(--baro-drop-shadow-color, #0000001a)"],
3845
- ["drop-shadow-xl", "xl", "0 9px 7px var(--baro-drop-shadow-color, #0000001a)"],
3846
- ["drop-shadow-2xl", "2xl", "0 25px 25px var(--baro-drop-shadow-color, #0000001a)"]
3847
- ].forEach(([name, size, sizeValue]) => {
3848
- staticUtility(name, [
3849
- decl("--baro-drop-shadow-size", `drop-shadow(${sizeValue})`),
3850
- decl("--baro-drop-shadow", `var(--drop-shadow-${size})`),
3851
- filters$1()
3852
- ]);
3853
- });
3854
- staticUtility("drop-shadow-none", [decl("--baro-drop-shadow", "drop-shadow(0 0 #0000)"), filters$1()]);
3855
- ["inherit", "current", "transparent"].forEach((name) => {
3856
- staticUtility(`drop-shadow-${name}`, [
3857
- decl("--baro-drop-shadow-color", name === "current" ? "currentColor" : name)
3858
- ]);
3859
- });
3860
- ["black", "white"].forEach((name) => {
3861
- staticUtility(`drop-shadow-${name}`, [
3862
- decl("--baro-drop-shadow-color", `var(--color-${name})`)
3863
- ]);
3946
+ const dropShadowProperties = () => atRoot([
3947
+ property("--baro-drop-shadow"),
3948
+ property("--baro-drop-shadow-color"),
3949
+ property("--baro-drop-shadow-alpha", "100%", "<percentage>"),
3950
+ property("--baro-drop-shadow-size")
3951
+ ]);
3952
+ const wrapDropShadow = (layers) => layers.map((l) => `drop-shadow(${l})`).join(" ");
3953
+ const DROP_SHADOW_DEFAULT = "0 1px 2px rgb(0 0 0 / 0.1), 0 1px 1px rgb(0 0 0 / 0.06)";
3954
+ const namedDropShadow = (ctx, name) => {
3955
+ const v = ctx.theme("dropShadow", name);
3956
+ return typeof v === "string" && /^[\w.-]+$/.test(name) ? v : null;
3957
+ };
3958
+ function dropShadowValue(value, opacity, named, keepNamed = false) {
3959
+ const decls = shadowValueDecls("drop-shadow", "--baro-drop-shadow-size", value, opacity, wrapDropShadow);
3960
+ if (!decls) return null;
3961
+ const composed = named !== void 0 && (!opacity || keepNamed) ? named : "var(--baro-drop-shadow-size)";
3962
+ return [dropShadowProperties(), ...decls, decl("--baro-drop-shadow", composed), filters$1()];
3963
+ }
3964
+ staticUtility("drop-shadow-none", [decl("--baro-drop-shadow", " "), filters$1()]);
3965
+ registerUtility({
3966
+ name: "drop-shadow",
3967
+ match: (className) => /^drop-shadow(\/.+)?$/.test(className),
3968
+ handler: (value, _ctx, token) => {
3969
+ const full = value ? `${token.prefix}-${value}` : token.prefix;
3970
+ const cut = full.indexOf("/");
3971
+ const opacity = cut < 0 ? void 0 : full.slice(cut + 1);
3972
+ const literal = "drop-shadow(0 1px 2px rgb(0 0 0 / 0.1)) drop-shadow( 0 1px 1px rgb(0 0 0 / 0.06))";
3973
+ return dropShadowValue(DROP_SHADOW_DEFAULT, opacity, literal, true) ?? [];
3974
+ },
3975
+ category: "effects"
3864
3976
  });
3977
+ const dropShadowColor = (color, opacity, ref) => {
3978
+ const decls = shadowColorDecls("drop-shadow", color, opacity, ref);
3979
+ return decls && [dropShadowProperties(), ...decls, decl("--baro-drop-shadow", "var(--baro-drop-shadow-size)")];
3980
+ };
3865
3981
  functionalUtility({
3866
3982
  name: "drop-shadow",
3867
3983
  themeKeys: ["colors"],
3868
3984
  supportsArbitrary: true,
3869
3985
  supportsCustomProperty: true,
3870
- handle: (value, _ctx, _token, extra) => {
3871
- if (extra?.realThemeValue) {
3872
- return [decl("--baro-drop-shadow-color", `var(--color-${extra.realThemeValue})`)];
3873
- }
3874
- if (parseColor(value)) {
3875
- return [decl("--baro-drop-shadow-color", value)];
3986
+ supportsOpacity: true,
3987
+ handleBareValue: ({ value, ctx }) => namedDropShadow(ctx, value) ? value : null,
3988
+ handle: (value, ctx, token, extra) => {
3989
+ const opacity = extra?.opacity;
3990
+ const keyword = token.arbitrary ? void 0 : { inherit: "inherit", current: "currentcolor", transparent: "transparent" }[extra?.realThemeValue ?? value];
3991
+ if (keyword) return dropShadowColor(keyword, opacity);
3992
+ if (extra?.realThemeValue) return dropShadowColor(value, opacity, `var(--color-${extra.realThemeValue})`);
3993
+ if (token.arbitrary) {
3994
+ if (parseColor(value)) return dropShadowColor(value, opacity);
3995
+ return dropShadowValue(value, opacity);
3876
3996
  }
3877
- return [
3878
- decl("--baro-drop-shadow-size", `drop-shadow(${value})`),
3879
- decl("--baro-drop-shadow", `var(--baro-drop-shadow-size)`)
3880
- ];
3997
+ const named = namedDropShadow(ctx, value);
3998
+ if (named) return dropShadowValue(named, opacity, `drop-shadow(var(--drop-shadow-${value}))`);
3999
+ return null;
3881
4000
  },
3882
4001
  handleCustomProperty: (value) => {
3883
- if (value.startsWith("color:")) {
3884
- return [
3885
- decl("--baro-drop-shadow-color", `var(${value.replace("color:", "")})`)
3886
- ];
3887
- }
4002
+ if (value.startsWith("color:")) return dropShadowColor(`var(${value.slice(6)})`, void 0) ?? [];
3888
4003
  return [
4004
+ dropShadowProperties(),
3889
4005
  decl("--baro-drop-shadow-size", `drop-shadow(var(${value}))`),
3890
- decl("--baro-drop-shadow", `var(--baro-drop-shadow-size)`)
4006
+ decl("--baro-drop-shadow", `var(--baro-drop-shadow-size)`),
4007
+ filters$1()
3891
4008
  ];
3892
4009
  },
3893
4010
  description: "drop-shadow filter utility (static, arbitrary, custom property supported)",
@@ -4257,166 +4374,119 @@ const ringShadowProperties = () => atRoot([
4257
4374
  property("--baro-ring-offset-width", "0px", "<length>"),
4258
4375
  property("--baro-ring-offset-color", "#fff")
4259
4376
  ]);
4260
- const shadowLayer = (value) => [
4261
- ringShadowProperties(),
4262
- decl("--baro-shadow", value),
4263
- decl("box-shadow", SHADOW_COMPOSITE)
4264
- ];
4265
- [
4266
- ["shadow-2xs", "var(--shadow-2xs)"],
4267
- ["shadow-xs", "var(--shadow-xs)"],
4268
- ["shadow-sm", "var(--shadow-sm)"],
4269
- ["shadow", "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)"],
4270
- ["shadow-md", "var(--shadow-md)"],
4271
- ["shadow-lg", "var(--shadow-lg)"],
4272
- ["shadow-xl", "var(--shadow-xl)"],
4273
- ["shadow-2xl", "var(--shadow-2xl)"],
4274
- ["shadow-none", "0 0 #0000"]
4275
- ].forEach(([name, value]) => {
4276
- staticUtility(name, [
4277
- ringShadowProperties,
4278
- ["--baro-shadow", value],
4279
- ["box-shadow", SHADOW_COMPOSITE]
4280
- ], { category: "effects" });
4281
- });
4282
- [
4283
- ["inset-shadow-2xs", "inset 0 1px var(--baro-inset-shadow-color, rgb(0 0 0 / 0.05))"],
4284
- ["inset-shadow-xs", "inset 0 1px 1px var(--baro-inset-shadow-color, rgb(0 0 0 / 0.05))"],
4285
- ["inset-shadow-sm", "inset 0 2px 4px var(--baro-inset-shadow-color, rgb(0 0 0 / 0.05))"],
4286
- ["inset-shadow-md", "inset 0 4px 6px -1px var(--baro-inset-shadow-color, rgb(0 0 0 / 0.05))"],
4287
- ["inset-shadow-lg", "inset 0 10px 15px -3px var(--baro-inset-shadow-color, rgb(0 0 0 / 0.05))"],
4288
- ["inset-shadow-xl", "inset 0 20px 25px -5px var(--baro-inset-shadow-color, rgb(0 0 0 / 0.05))"],
4289
- ["inset-shadow-2xl", "inset 0 25px 50px -12px var(--baro-inset-shadow-color, rgb(0 0 0 / 0.05))"],
4290
- ["inset-shadow-none", "0 0 #0000"]
4291
- ].forEach(([name, value]) => {
4292
- staticUtility(name, [
4293
- ringShadowProperties,
4294
- ["--baro-inset-shadow", value],
4295
- ["box-shadow", SHADOW_COMPOSITE]
4296
- ], { category: "effects" });
4297
- });
4298
- function createShadowThemeColor(key, main, opacity, realThemeValue) {
4299
- let fallbackColor = main;
4300
- const colorVar = `var(--color-${realThemeValue})`;
4301
- let colorValue = colorVar;
4302
- if (opacity) {
4303
- colorValue = `color-mix(in oklab, color-mix(in oklab, ${colorVar} ${opacity}%, transparent) var(--baro-shadow-alpha),transparent)`;
4304
- if (parseColor(main)) {
4305
- if (main.startsWith("#")) {
4306
- const opacityValue = Math.round(Number(opacity) / 100 * 255);
4307
- fallbackColor = `${main}${opacityValue.toString(16).padStart(2, "0")}`;
4308
- } else {
4309
- fallbackColor = `color-mix(in oklab, ${main} ${opacity}%, transparent)`;
4310
- }
4311
- }
4312
- }
4313
- return [
4314
- atRule("supports", "(color:color-mix(in lab, red, red))", [
4315
- decl(key, colorValue)
4316
- ]),
4317
- decl(key, fallbackColor)
4318
- ];
4377
+ const shadowColorProperties = (layer) => atRoot([
4378
+ property(`--baro-${layer}-color`),
4379
+ property(`--baro-${layer}-alpha`, "100%", "<percentage>")
4380
+ ]);
4381
+ const NAMED_SHADOWS = {
4382
+ "": "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)",
4383
+ "2xs": "0 1px rgb(0 0 0 / 0.05)",
4384
+ xs: "0 1px 2px 0 rgb(0 0 0 / 0.05)",
4385
+ sm: "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)",
4386
+ md: "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)",
4387
+ lg: "0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)",
4388
+ xl: "0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)",
4389
+ "2xl": "0 25px 50px -12px rgb(0 0 0 / 0.25)",
4390
+ inner: "inset 0 2px 4px 0 rgb(0 0 0 / 0.05)"
4391
+ };
4392
+ const NAMED_INSET_SHADOWS = {
4393
+ "2xs": "inset 0 1px rgb(0 0 0 / 0.05)",
4394
+ xs: "inset 0 1px 1px rgb(0 0 0 / 0.05)",
4395
+ sm: "inset 0 2px 4px rgb(0 0 0 / 0.05)"
4396
+ };
4397
+ const INSET_EXTENSIONS = {
4398
+ md: "inset 0 4px 6px -1px rgb(0 0 0 / 0.05)",
4399
+ lg: "inset 0 10px 15px -3px rgb(0 0 0 / 0.05)",
4400
+ xl: "inset 0 20px 25px -5px rgb(0 0 0 / 0.05)",
4401
+ "2xl": "inset 0 25px 50px -12px rgb(0 0 0 / 0.05)"
4402
+ };
4403
+ const insetEach = (value) => value.split(/,(?![^(]*\))/).map((l) => `inset ${l.trim()}`).join(", ");
4404
+ const own = (table, key) => Object.prototype.hasOwnProperty.call(table, key);
4405
+ function boxShadowLayer(layer, value, opacity) {
4406
+ const decls = shadowValueDecls(layer, `--baro-${layer}`, value, opacity);
4407
+ if (!decls) return null;
4408
+ return [ringShadowProperties(), shadowColorProperties(layer), ...decls, decl("box-shadow", SHADOW_COMPOSITE)];
4409
+ }
4410
+ function namedBoxShadow(layer, name, opacity) {
4411
+ if (layer === "shadow") return own(NAMED_SHADOWS, name) ? boxShadowLayer(layer, NAMED_SHADOWS[name], opacity) : null;
4412
+ if (own(NAMED_INSET_SHADOWS, name)) return boxShadowLayer(layer, NAMED_INSET_SHADOWS[name], opacity);
4413
+ if (!opacity && own(INSET_EXTENSIONS, name)) return boxShadowLayer(layer, INSET_EXTENSIONS[name], void 0);
4414
+ return null;
4319
4415
  }
4320
- functionalUtility({
4416
+ staticUtility("shadow-none", [ringShadowProperties, ["--baro-shadow", "0 0 #0000"], ["box-shadow", SHADOW_COMPOSITE]], { category: "effects" });
4417
+ staticUtility("inset-shadow-none", [ringShadowProperties, ["--baro-inset-shadow", "inset 0 0 #0000"], ["box-shadow", SHADOW_COMPOSITE]], { category: "effects" });
4418
+ registerUtility({
4321
4419
  name: "shadow",
4322
- supportsArbitrary: true,
4323
- supportsCustomProperty: true,
4324
- supportsOpacity: true,
4325
- themeKeys: ["colors", "shadows"],
4326
- handle: (value, ctx, token, extra) => {
4327
- const main = value;
4328
- const opacity = extra?.opacity;
4329
- const realThemeValue = extra?.realThemeValue;
4330
- if (realThemeValue) {
4331
- return createShadowThemeColor(
4332
- "--baro-shadow-color",
4333
- main,
4334
- opacity,
4335
- realThemeValue
4336
- );
4337
- }
4338
- if (main.startsWith("color:")) {
4339
- const cp = main.replace("color:", "");
4340
- if (opacity) {
4341
- return [
4342
- decl(
4343
- "--baro-shadow-color",
4344
- `color-mix(in oklab, var(${cp}) ${opacity}%, transparent)`
4345
- )
4346
- ];
4347
- }
4348
- return [decl("--baro-shadow-color", `var(${cp})`)];
4349
- }
4350
- if (token.arbitrary) {
4351
- if (parseColor(main)) {
4352
- if (opacity) {
4353
- return [
4354
- decl(
4355
- "--baro-shadow-color",
4356
- `color-mix(in oklab, ${main} ${opacity}%, transparent)`
4357
- )
4358
- ];
4359
- }
4360
- return [decl("--baro-shadow-color", main)];
4361
- }
4362
- return shadowLayer(main);
4363
- }
4364
- if (main === "inherit" || main === "current" || main === "transparent") {
4365
- return [
4366
- decl("--baro-shadow-color", main === "current" ? "currentColor" : main)
4367
- ];
4368
- }
4369
- return null;
4420
+ match: (className) => /^shadow(\/.+)?$/.test(className),
4421
+ handler: (value, _ctx, token) => {
4422
+ const full = value ? `${token.prefix}-${value}` : token.prefix;
4423
+ const cut = full.indexOf("/");
4424
+ return namedBoxShadow("shadow", "", cut < 0 ? void 0 : full.slice(cut + 1)) ?? [];
4370
4425
  },
4371
- handleCustomProperty: (value) => shadowLayer(`var(${value})`)
4426
+ category: "effects"
4372
4427
  });
4428
+ const KEYWORD_COLORS = { inherit: "inherit", current: "currentcolor", transparent: "transparent" };
4429
+ function layerColor(layer, main, opacity, token, realThemeValue) {
4430
+ const keyword = token.arbitrary ? void 0 : KEYWORD_COLORS[realThemeValue ?? main];
4431
+ if (keyword) return shadowColorDecls(layer, keyword, opacity);
4432
+ if (realThemeValue) return shadowColorDecls(layer, main, opacity, `var(--color-${realThemeValue})`);
4433
+ if (main.startsWith("color:")) return shadowColorDecls(layer, `var(${main.slice(6)})`, opacity);
4434
+ if (token.arbitrary && parseColor(main)) return shadowColorDecls(layer, main, opacity);
4435
+ return void 0;
4436
+ }
4437
+ for (const layer of ["shadow", "inset-shadow"]) {
4438
+ functionalUtility({
4439
+ name: layer,
4440
+ supportsArbitrary: true,
4441
+ supportsCustomProperty: true,
4442
+ supportsOpacity: true,
4443
+ themeKeys: ["colors"],
4444
+ handleBareValue: ({ value, extra }) => namedBoxShadow(layer, value, extra?.opacity) ? value : null,
4445
+ handle: (value, _ctx, token, extra) => {
4446
+ const opacity = extra?.opacity;
4447
+ const named = !extra?.realThemeValue && !token.arbitrary ? namedBoxShadow(layer, value, opacity) : null;
4448
+ if (named) return named;
4449
+ const color = layerColor(layer, value, opacity, token, extra?.realThemeValue);
4450
+ if (color !== void 0) return color;
4451
+ if (token.arbitrary) return boxShadowLayer(layer, layer === "inset-shadow" ? insetEach(value) : value, opacity);
4452
+ return null;
4453
+ },
4454
+ handleCustomProperty: (value) => value.startsWith("color:") ? shadowColorDecls(layer, `var(${value.slice(6)})`, void 0) ?? [] : [ringShadowProperties(), decl(`--baro-${layer}`, layer === "inset-shadow" ? `inset var(${value})` : `var(${value})`), decl("box-shadow", SHADOW_COMPOSITE)]
4455
+ });
4456
+ }
4457
+ const textShadowProperties = () => atRoot([
4458
+ property("--baro-text-shadow-color"),
4459
+ property("--baro-text-shadow-alpha", "100%", "<percentage>")
4460
+ ]);
4461
+ const namedTextShadow = (ctx, name) => {
4462
+ const v = ctx.theme("textShadow", name);
4463
+ return typeof v === "string" && /^[\w.-]+$/.test(name) ? v : null;
4464
+ };
4465
+ const textShadowValue = (value, opacity) => {
4466
+ const decls = shadowValueDecls("text-shadow", "text-shadow", value, opacity);
4467
+ return decls ? [textShadowProperties(), ...decls] : null;
4468
+ };
4469
+ staticUtility("text-shadow-none", [textShadowProperties, ["text-shadow", "none"]], { category: "effects" });
4373
4470
  functionalUtility({
4374
- name: "inset-shadow",
4471
+ name: "text-shadow",
4375
4472
  supportsArbitrary: true,
4376
4473
  supportsCustomProperty: true,
4377
4474
  supportsOpacity: true,
4378
- themeKeys: ["colors", "shadows"],
4475
+ themeKeys: ["colors"],
4476
+ handleBareValue: ({ value, ctx }) => namedTextShadow(ctx, value) ? value : null,
4379
4477
  handle: (value, ctx, token, extra) => {
4380
- const main = value;
4381
4478
  const opacity = extra?.opacity;
4382
- const realThemeValue = extra?.realThemeValue;
4383
- if (realThemeValue) {
4384
- return createShadowThemeColor(
4385
- "--baro-inset-shadow-color",
4386
- main,
4387
- opacity,
4388
- realThemeValue
4389
- );
4390
- }
4391
- if (main.startsWith("color:")) {
4392
- const cp = main.replace("color:", "");
4393
- let colorValue = `var(${cp})`;
4394
- if (opacity) {
4395
- colorValue = `color-mix(in oklab, var(${cp}) ${opacity}%, transparent)`;
4396
- }
4397
- return [decl("--baro-inset-shadow-color", colorValue)];
4398
- }
4399
- if (token.arbitrary) {
4400
- if (parseColor(main)) {
4401
- let colorValue = main;
4402
- if (opacity) {
4403
- colorValue = `color-mix(in oklab, ${main} ${opacity}%, transparent)`;
4404
- }
4405
- return [decl("--baro-inset-shadow-color", colorValue)];
4406
- }
4407
- return [decl("box-shadow", `inset ${main}`)];
4408
- }
4409
- if (main === "inherit" || main === "current" || main === "transparent") {
4410
- return [
4411
- decl(
4412
- "--baro-inset-shadow-color",
4413
- main === "current" ? "currentColor" : main
4414
- )
4415
- ];
4479
+ if (!extra?.realThemeValue && !token.arbitrary) {
4480
+ const named = namedTextShadow(ctx, value);
4481
+ if (named) return textShadowValue(named, opacity);
4416
4482
  }
4483
+ const color = layerColor("text-shadow", value, opacity, token, extra?.realThemeValue);
4484
+ if (color !== void 0) return color && [textShadowProperties(), ...color];
4485
+ if (token.arbitrary) return textShadowValue(value, opacity);
4417
4486
  return null;
4418
4487
  },
4419
- handleCustomProperty: (value) => [decl("box-shadow", `var(${value})`)]
4488
+ handleCustomProperty: (value) => value.startsWith("color:") ? [textShadowProperties(), ...shadowColorDecls("text-shadow", `var(${value.slice(6)})`, void 0) ?? []] : [textShadowProperties(), decl("text-shadow", `var(${value})`)],
4489
+ category: "effects"
4420
4490
  });
4421
4491
  [
4422
4492
  ["ring", "1px"],
@@ -4959,12 +5029,15 @@ staticUtility("not-sr-only", [
4959
5029
  ], { category: "layout" });
4960
5030
  staticUtility("@container", [["container-type", "inline-size"]], { category: "layout" });
4961
5031
  staticUtility("@container-normal", [["container-type", "normal"]], { category: "layout" });
5032
+ staticUtility("@container-size", [["container-type", "size"]], { category: "layout" });
5033
+ const NAMED_CONTAINER = /^@container(-normal|-size)?\/([a-zA-Z0-9_-]+)$/;
5034
+ const CONTAINER_TYPE = { "": "inline-size", "-normal": "normal", "-size": "size" };
4962
5035
  registerUtility({
4963
5036
  name: "@container",
4964
- match: (className) => /^@container\/[a-zA-Z0-9_-]+$/.test(className),
5037
+ match: (className) => NAMED_CONTAINER.test(className),
4965
5038
  handler: (_value, _ctx, token) => {
4966
- const name = /^@container\/([a-zA-Z0-9_-]+)$/.exec(`${token.prefix}${token.value ? `-${token.value}` : ""}`)?.[1];
4967
- return name ? [decl("container-type", "inline-size"), decl("container-name", name)] : null;
5039
+ const m = NAMED_CONTAINER.exec(`${token.prefix}${token.value ? `-${token.value}` : ""}`);
5040
+ return m ? [decl("container-type", CONTAINER_TYPE[m[1] ?? ""]), decl("container-name", m[2])] : null;
4968
5041
  },
4969
5042
  category: "layout"
4970
5043
  });
@@ -5049,6 +5122,11 @@ staticUtility("sticky", [["position", "sticky"]], { category: "layout" });
5049
5122
  [
5050
5123
  ["inset-x", "inset-inline"],
5051
5124
  ["inset-y", "inset-block"],
5125
+ // Tailwind 4.3 logical sides; registered before `inset` so their handler runs first for `inset-s-*` etc.
5126
+ ["inset-s", "inset-inline-start"],
5127
+ ["inset-e", "inset-inline-end"],
5128
+ ["inset-bs", "inset-block-start"],
5129
+ ["inset-be", "inset-block-end"],
5052
5130
  ["inset", "inset"],
5053
5131
  ["start", "inset-inline-start"],
5054
5132
  ["end", "inset-inline-end"],
@@ -5144,6 +5222,15 @@ functionalUtility({
5144
5222
  description: "gap utility (number, arbitrary, custom property supported)",
5145
5223
  category: "layout"
5146
5224
  });
5225
+ functionalUtility({
5226
+ name: "zoom",
5227
+ prop: "zoom",
5228
+ supportsArbitrary: true,
5229
+ supportsCustomProperty: true,
5230
+ handleBareValue: ({ value }) => /^\d+$/.test(value) ? `${value}%` : null,
5231
+ description: "zoom utility (integer percent, arbitrary, custom property)",
5232
+ category: "layout"
5233
+ });
5147
5234
  staticUtility("basis-full", [["flex-basis", "100%"]], { category: "flex-grid" });
5148
5235
  staticUtility("basis-auto", [["flex-basis", "auto"]], { category: "flex-grid" });
5149
5236
  staticUtility("basis-3xs", [["flex-basis", "var(--container-3xs)"]], { category: "flex-grid" });
@@ -5418,6 +5505,8 @@ functionalUtility({
5418
5505
  // auto-cols-[minmax(0,2fr)]
5419
5506
  supportsCustomProperty: true,
5420
5507
  // auto-cols-(--my-auto-cols)
5508
+ handleBareValue: ({ value }) => parseNumber(value) ? `calc(var(--spacing) * ${value})` : null,
5509
+ // #310: auto-cols-4
5421
5510
  handle: (value) => {
5422
5511
  if (typeof value === "string") return [decl("grid-auto-columns", value)];
5423
5512
  return null;
@@ -5437,6 +5526,8 @@ functionalUtility({
5437
5526
  // auto-rows-[minmax(0,2fr)]
5438
5527
  supportsCustomProperty: true,
5439
5528
  // auto-rows-(--my-auto-rows)
5529
+ handleBareValue: ({ value }) => parseNumber(value) ? `calc(var(--spacing) * ${value})` : null,
5530
+ // #310: auto-rows-12
5440
5531
  handle: (value) => {
5441
5532
  if (typeof value === "string") return [decl("grid-auto-rows", value)];
5442
5533
  return null;
@@ -5639,6 +5730,8 @@ functionalUtility({
5639
5730
  ["py", "padding-block"],
5640
5731
  ["ps", "padding-inline-start"],
5641
5732
  ["pe", "padding-inline-end"],
5733
+ ["pbs", "padding-block-start"],
5734
+ ["pbe", "padding-block-end"],
5642
5735
  ["pt", "padding-top"],
5643
5736
  ["pr", "padding-right"],
5644
5737
  ["pb", "padding-bottom"],
@@ -5662,6 +5755,8 @@ functionalUtility({
5662
5755
  ["my", "margin-block"],
5663
5756
  ["ms", "margin-inline-start"],
5664
5757
  ["me", "margin-inline-end"],
5758
+ ["mbs", "margin-block-start"],
5759
+ ["mbe", "margin-block-end"],
5665
5760
  ["mt", "margin-top"],
5666
5761
  ["mr", "margin-right"],
5667
5762
  ["mb", "margin-bottom"],
@@ -5987,6 +6082,41 @@ functionalUtility({
5987
6082
  description: "max-width utility (spacing, fraction, arbitrary, custom property, static supported)",
5988
6083
  category: "sizing"
5989
6084
  });
6085
+ {
6086
+ const containers = ["3xs", "2xs", "xs", "sm", "md", "lg", "xl", "2xl", "3xl", "4xl", "5xl", "6xl", "7xl"].map(
6087
+ (k) => [k, `var(--container-${k})`]
6088
+ );
6089
+ const common = [["0", "0px"], ["px", "1px"], ["full", "100%"], ["min", "min-content"], ["max", "max-content"], ["fit", "fit-content"]];
6090
+ const inlineVp = [["screen", "100vw"], ["dvw", "100dvw"], ["lvw", "100lvw"], ["svw", "100svw"]];
6091
+ const blockVp = [["screen", "100vh"], ["dvh", "100dvh"], ["lvh", "100lvh"], ["svh", "100svh"], ["lh", "1lh"]];
6092
+ const families = [
6093
+ ["inline", "inline-size", [...common, ["auto", "auto"], ...inlineVp, ...containers]],
6094
+ ["min-inline", "min-inline-size", [...common, ["auto", "auto"], ...inlineVp, ...containers]],
6095
+ ["max-inline", "max-inline-size", [...common, ["none", "none"], ...inlineVp, ...containers]],
6096
+ ["block", "block-size", [...common, ["auto", "auto"], ...blockVp]],
6097
+ ["min-block", "min-block-size", [...common, ["auto", "auto"], ...blockVp]],
6098
+ ["max-block", "max-block-size", [...common, ["none", "none"], ...blockVp]]
6099
+ ];
6100
+ for (const [name, prop, statics] of families) {
6101
+ for (const [key, value] of statics) staticUtility(`${name}-${key}`, [[prop, value]], { category: "sizing" });
6102
+ functionalUtility({
6103
+ spacingKeys: true,
6104
+ name,
6105
+ prop,
6106
+ supportsArbitrary: true,
6107
+ supportsCustomProperty: true,
6108
+ supportsFraction: true,
6109
+ handleBareValue: ({ value, token }) => {
6110
+ if (token.negative) return null;
6111
+ if (parseNumber(value)) return `calc(var(--spacing) * ${value})`;
6112
+ if (parseFractionOrNumber(value)) return `calc(${value} * 100%)`;
6113
+ return null;
6114
+ },
6115
+ description: `${prop} utility (spacing, fraction, arbitrary, custom property, keywords)`,
6116
+ category: "sizing"
6117
+ });
6118
+ }
6119
+ }
5990
6120
  const leadingProperty = () => atRoot([property("--baro-leading")]);
5991
6121
  staticUtility("font-sans", [["font-family", "var(--font-sans)"]], { category: "typography" });
5992
6122
  staticUtility("font-serif", [["font-family", "var(--font-serif)"]], { category: "typography" });
@@ -6017,13 +6147,15 @@ functionalUtility({
6017
6147
  name: "font",
6018
6148
  supportsArbitrary: true,
6019
6149
  supportsCustomProperty: true,
6020
- handle: (value) => {
6150
+ handle: (value, _ctx, token) => {
6151
+ if (token.prefix !== "font") return null;
6021
6152
  if (parseNumber(value)) {
6022
6153
  return [decl("font-weight", value)];
6023
6154
  }
6024
6155
  return [decl("font-family", value)];
6025
6156
  },
6026
- handleCustomProperty: (value) => {
6157
+ handleCustomProperty: (value, _ctx, token) => {
6158
+ if (token.prefix !== "font") return null;
6027
6159
  if (value.startsWith("font-name:")) {
6028
6160
  return [decl("font-family", `var(${value.replace("font-name:", "")})`)];
6029
6161
  }
@@ -6322,6 +6454,42 @@ functionalUtility({
6322
6454
  description: "content utility (arbitrary, custom property supported)",
6323
6455
  category: "typography"
6324
6456
  });
6457
+ const placeholderColor = (value) => [rule("&::placeholder", [decl("color", value)])];
6458
+ staticUtility("placeholder-inherit", placeholderColor("inherit"), { category: "typography" });
6459
+ staticUtility("placeholder-current", placeholderColor("currentcolor"), { category: "typography" });
6460
+ staticUtility("placeholder-transparent", placeholderColor("transparent"), { category: "typography" });
6461
+ functionalUtility({
6462
+ name: "placeholder",
6463
+ themeKeys: ["colors"],
6464
+ supportsArbitrary: true,
6465
+ supportsCustomProperty: true,
6466
+ supportsOpacity: true,
6467
+ handle: (value, _ctx, _token, extra) => {
6468
+ if (extra?.realThemeValue) return [rule("&::placeholder", themeColorDecls("color", value, extra))];
6469
+ if (parseColor(value)) return placeholderColor(value);
6470
+ return null;
6471
+ },
6472
+ handleCustomProperty: (value) => placeholderColor(`var(${value})`),
6473
+ description: "placeholder color utility (theme, alpha, arbitrary, custom property)"
6474
+ });
6475
+ functionalUtility({
6476
+ name: "font-features",
6477
+ supportsArbitrary: true,
6478
+ supportsCustomProperty: true,
6479
+ handle: (value, _ctx, token) => token.arbitrary ? [decl("font-feature-settings", value)] : null,
6480
+ handleCustomProperty: (value) => [decl("font-feature-settings", `var(${value.replace(/^[a-z-]+:(?=--)/, "")})`)],
6481
+ description: "font-feature-settings utility (arbitrary, custom property)",
6482
+ category: "typography"
6483
+ });
6484
+ functionalUtility({
6485
+ name: "tab",
6486
+ prop: "tab-size",
6487
+ supportsArbitrary: true,
6488
+ supportsCustomProperty: true,
6489
+ handleBareValue: ({ value }) => /^\d+$/.test(value) ? value : null,
6490
+ description: "tab-size utility (integer, arbitrary, custom property)",
6491
+ category: "typography"
6492
+ });
6325
6493
  const gradientStopProperties = () => {
6326
6494
  return atRoot([
6327
6495
  property("--baro-gradient-position"),
@@ -6653,6 +6821,11 @@ const withBorderStyle = (props, width) => [
6653
6821
  [
6654
6822
  ["border-x", ["border-left-width", "border-right-width"]],
6655
6823
  ["border-y", ["border-top-width", "border-bottom-width"]],
6824
+ ["border-bs", ["border-block-start-width"]],
6825
+ ["border-be", ["border-block-end-width"]],
6826
+ ["border-s", ["border-inline-start-width"]],
6827
+ // #311 (Tailwind 4.3)
6828
+ ["border-e", ["border-inline-end-width"]],
6656
6829
  ["border-t", ["border-top-width"]],
6657
6830
  ["border-r", ["border-right-width"]],
6658
6831
  ["border-b", ["border-bottom-width"]],
@@ -6672,6 +6845,7 @@ const withBorderStyle = (props, width) => [
6672
6845
  functionalUtility({
6673
6846
  name,
6674
6847
  themeKeys: ["borderWidth", "colors"],
6848
+ supportsOpacity: true,
6675
6849
  supportsArbitrary: true,
6676
6850
  supportsCustomProperty: true,
6677
6851
  handleBareValue: ({ value }) => {
@@ -7652,9 +7826,10 @@ staticModifier("starting", ["&"], {
7652
7826
  wrap: () => [atRule("starting-style", "", [], "starting")],
7653
7827
  source: "starting"
7654
7828
  });
7655
- function createContainerParams(type, value, name) {
7829
+ function createContainerParams(type, value, name, negate = false) {
7656
7830
  const condition = type === "min" ? "width >=" : "width <";
7657
- return name ? `${name} (${condition} ${value})` : `(${condition} ${value})`;
7831
+ const query = `${negate ? "not " : ""}(${condition} ${value})`;
7832
+ return name ? `${name} ${query}` : query;
7658
7833
  }
7659
7834
  function createContainerRule(params, ast) {
7660
7835
  return {
@@ -7823,17 +7998,17 @@ functionalModifier(
7823
7998
  return result;
7824
7999
  }
7825
8000
  );
7826
- const SIZE_VARIANT = /^@(?:(min|max)-)?(\[[^\]]+\]|[a-zA-Z0-9.]+)(?:\/([a-zA-Z0-9_-]+))?$/;
8001
+ const SIZE_VARIANT = /^(not-)?@(?:(min|max)-)?(\[[^\]]+\]|[a-zA-Z0-9.]+)(?:\/([a-zA-Z0-9_-]+))?$/;
7827
8002
  functionalModifier(
7828
- (mod) => SIZE_VARIANT.test(mod) && !/^@container(?:\/|$)/.test(mod),
8003
+ (mod) => SIZE_VARIANT.test(mod) && !/^(?:not-)?@container(?:\/|$)/.test(mod),
7829
8004
  void 0,
7830
8005
  (mod, context) => {
7831
8006
  const m = SIZE_VARIANT.exec(mod.type);
7832
8007
  if (!m) return [];
7833
- const [, type, size, name] = m;
8008
+ const [, not, type, size, name] = m;
7834
8009
  const value = size.startsWith("[") ? size.slice(1, -1).replace(/_/g, " ") : context.theme("container." + size);
7835
8010
  if (!value) return [];
7836
- return [createContainerRule(createContainerParams(type === "max" ? "max" : "min", value, name), [])];
8011
+ return [createContainerRule(createContainerParams(type === "max" ? "max" : "min", value, name, !!not), [])];
7837
8012
  }
7838
8013
  );
7839
8014
  const startsAtRule = (bracket) => /^[\s_]*@/.test(bracket);
@@ -7973,7 +8148,7 @@ functionalModifier(
7973
8148
  }
7974
8149
  );
7975
8150
  functionalModifier(
7976
- (mod) => /^not-/.test(mod),
8151
+ (mod) => /^not-/.test(mod) && !mod.startsWith("not-@"),
7977
8152
  ({ selector, mod }) => {
7978
8153
  const m = /^not-(.+)$/.exec(mod.type);
7979
8154
  return {
@@ -8040,7 +8215,8 @@ functionalModifier(
8040
8215
  void 0
8041
8216
  );
8042
8217
  functionalModifier(
8043
- (mod) => mod.startsWith("not-"),
8218
+ (mod) => mod.startsWith("not-") && !mod.startsWith("not-@"),
8219
+ // not-@… is container negation (#311)
8044
8220
  ({ selector, mod }) => {
8045
8221
  const pseudo = mod.type.replace("not-", "");
8046
8222
  if (pseudo.startsWith("[")) {
@@ -8475,6 +8651,7 @@ export {
8475
8651
  getUtility,
8476
8652
  hasCommentDelimiter,
8477
8653
  hasCommentToken,
8654
+ hasHtmlEndTagOpener,
8478
8655
  hasPreset,
8479
8656
  isDebug,
8480
8657
  isSafeVariantToken,