@barocss/kit 0.7.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -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) => ({
@@ -1215,6 +1216,8 @@ function themeToCssVarsAll(theme) {
1215
1216
  ...transitionDurationToCssVars(theme.transitionDuration),
1216
1217
  ...transitionDelayToCssVars(theme.transitionDelay),
1217
1218
  ...blurToCssVars(theme.blur),
1219
+ ...Object.fromEntries(Object.entries(theme.textShadow ?? {}).map(([k, v2]) => [`--text-shadow-${escapeKey(k)}`, v2])),
1220
+ ...Object.fromEntries(Object.entries(theme.dropShadow ?? {}).map(([k, v2]) => [`--drop-shadow-${escapeKey(k)}`, v2])),
1218
1221
  ...Object.fromEntries(Object.entries(theme.aspect ?? {}).map(([k, v2]) => [`--aspect-${escapeKey(k)}`, v2]))
1219
1222
  // keyframes handled separately
1220
1223
  };
@@ -2106,7 +2109,7 @@ html {
2106
2109
  line-height: 1.15;
2107
2110
  -webkit-text-size-adjust: 100%;
2108
2111
  /* 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'));
2112
+ 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
2113
  font-feature-settings: var(--default-font-feature-settings, normal);
2111
2114
  font-variation-settings: var(--default-font-variation-settings, normal);
2112
2115
  }
@@ -2409,7 +2412,7 @@ html {
2409
2412
  -webkit-text-size-adjust: 100%;
2410
2413
  -ms-text-size-adjust: 100%;
2411
2414
  /* 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'));
2415
+ 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
2416
  font-feature-settings: var(--default-font-feature-settings, normal);
2414
2417
  font-variation-settings: var(--default-font-variation-settings, normal);
2415
2418
  }
@@ -3488,6 +3491,9 @@ staticUtility("snap-both", [["scroll-snap-type", "both var(--baro-scroll-snap-st
3488
3491
  staticUtility("snap-mandatory", [["--baro-scroll-snap-strictness", "mandatory"]], { category: "interactivity" });
3489
3492
  staticUtility("snap-proximity", [["--baro-scroll-snap-strictness", "proximity"]], { category: "interactivity" });
3490
3493
  [
3494
+ ["mbs", "scroll-margin-block-start"],
3495
+ // #311 (Tailwind 4.3), before `mb`
3496
+ ["mbe", "scroll-margin-block-end"],
3491
3497
  ["mt", "scroll-margin-top"],
3492
3498
  ["mr", "scroll-margin-right"],
3493
3499
  ["mb", "scroll-margin-bottom"],
@@ -3498,6 +3504,8 @@ staticUtility("snap-proximity", [["--baro-scroll-snap-strictness", "proximity"]]
3498
3504
  ["me", "scroll-margin-inline-end"],
3499
3505
  ["m", "scroll-margin"]
3500
3506
  ].forEach(([name, prop]) => {
3507
+ staticUtility(`scroll-${name}-px`, [[prop, "1px"]], { category: "interactivity" });
3508
+ staticUtility(`-scroll-${name}-px`, [[prop, "-1px"]], { category: "interactivity" });
3501
3509
  functionalUtility({
3502
3510
  name: `scroll-${name}`,
3503
3511
  spacingKeys: true,
@@ -3516,6 +3524,9 @@ staticUtility("snap-proximity", [["--baro-scroll-snap-strictness", "proximity"]]
3516
3524
  });
3517
3525
  });
3518
3526
  [
3527
+ ["pbs", "scroll-padding-block-start"],
3528
+ // #311 (Tailwind 4.3), before `pb`
3529
+ ["pbe", "scroll-padding-block-end"],
3519
3530
  ["pt", "scroll-padding-top"],
3520
3531
  ["pr", "scroll-padding-right"],
3521
3532
  ["pb", "scroll-padding-bottom"],
@@ -3532,13 +3543,15 @@ staticUtility("snap-proximity", [["--baro-scroll-snap-strictness", "proximity"]]
3532
3543
  prop,
3533
3544
  supportsArbitrary: true,
3534
3545
  supportsCustomProperty: true,
3546
+ handleBareValue: ({ value }) => value === "px" ? "1px" : /^(\d|\.\d)/.test(value) ? value : null,
3535
3547
  handle: (value, _ctx, token, _extra) => {
3536
- if (parseNumber(value) || token.negative) {
3548
+ if (token.negative) return [];
3549
+ if (parseNumber(value)) {
3537
3550
  return [decl(prop, `calc(var(--spacing) * ${value})`)];
3538
3551
  }
3539
3552
  return [decl(prop, value)];
3540
3553
  },
3541
- handleCustomProperty: (value) => [decl(prop, `var(${value})`)],
3554
+ handleCustomProperty: (value, _ctx, token) => token.negative ? [] : [decl(prop, `var(${value})`)],
3542
3555
  description: `scroll-${name} utility (static, arbitrary, custom property supported)`,
3543
3556
  category: "interactivity"
3544
3557
  });
@@ -3569,6 +3582,40 @@ functionalUtility({
3569
3582
  description: "will-change utility (static, arbitrary, custom property supported)",
3570
3583
  category: "interactivity"
3571
3584
  });
3585
+ staticUtility("scrollbar-auto", [["scrollbar-width", "auto"]], { category: "interactivity" });
3586
+ staticUtility("scrollbar-thin", [["scrollbar-width", "thin"]], { category: "interactivity" });
3587
+ staticUtility("scrollbar-none", [["scrollbar-width", "none"]], { category: "interactivity" });
3588
+ staticUtility("scrollbar-gutter-auto", [["scrollbar-gutter", "auto"]], { category: "interactivity" });
3589
+ staticUtility("scrollbar-gutter-stable", [["scrollbar-gutter", "stable"]], { category: "interactivity" });
3590
+ staticUtility("scrollbar-gutter-both", [["scrollbar-gutter", "stable both-edges"]], { category: "interactivity" });
3591
+ const SCROLLBAR_COLOR = "var(--baro-scrollbar-thumb) var(--baro-scrollbar-track)";
3592
+ const scrollbarProperties = () => atRoot([
3593
+ property("--baro-scrollbar-thumb", "#0000", "<color>"),
3594
+ property("--baro-scrollbar-track", "#0000", "<color>")
3595
+ ]);
3596
+ const stripColorHint = (v) => v.replace(/^color:/, "");
3597
+ for (const part of ["thumb", "track"]) {
3598
+ const key = `--baro-scrollbar-${part}`;
3599
+ const compose = (inner) => [scrollbarProperties(), ...inner, decl("scrollbar-color", SCROLLBAR_COLOR)];
3600
+ const withOpacity = (color, opacity) => opacity ? [decl(key, `color-mix(in oklab, ${color} ${opacity.replace(/^\[(.*)\]$/, "$1").replace(/%$/, "")}%, transparent)`)] : [decl(key, color)];
3601
+ functionalUtility({
3602
+ name: `scrollbar-${part}`,
3603
+ themeKeys: ["colors"],
3604
+ supportsOpacity: true,
3605
+ supportsArbitrary: true,
3606
+ supportsCustomProperty: true,
3607
+ handle: (value, _ctx, token, extra) => {
3608
+ if (extra?.realThemeValue) return compose(withOpacity(`var(--color-${extra.realThemeValue})`, extra.opacity));
3609
+ if (token.arbitrary) return compose(withOpacity(stripColorHint(value), extra?.opacity));
3610
+ if (value === "inherit" || value === "transparent") return compose([decl(key, value)]);
3611
+ if (value === "current") return compose(withOpacity("currentcolor", extra?.opacity));
3612
+ return null;
3613
+ },
3614
+ handleCustomProperty: (value, _ctx, _token, extra) => compose(withOpacity(`var(${stripColorHint(value)})`, extra?.opacity)),
3615
+ description: `scrollbar-color ${part} utility (theme, arbitrary, custom property, opacity)`,
3616
+ category: "interactivity"
3617
+ });
3618
+ }
3572
3619
  const defaultTiming = "var(--default-transition-timing-function)";
3573
3620
  const defaultDuration = "var(--default-transition-duration)";
3574
3621
  staticUtility("transition", [
@@ -3706,53 +3753,99 @@ staticUtility("border-collapse", [["border-collapse", "collapse"]], { category:
3706
3753
  staticUtility("border-separate", [["border-collapse", "separate"]], { category: "table" });
3707
3754
  staticUtility("table-auto", [["table-layout", "auto"]], { category: "table" });
3708
3755
  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"
3756
+ const borderSpacingProperties = () => atRoot([
3757
+ property("--baro-border-spacing-x", "0", "<length>"),
3758
+ property("--baro-border-spacing-y", "0", "<length>")
3759
+ ]);
3760
+ const BORDER_SPACING = "var(--baro-border-spacing-x) var(--baro-border-spacing-y)";
3761
+ const borderSpacing = (axes, v) => [
3762
+ borderSpacingProperties(),
3763
+ ...axes.map((a) => decl(`--baro-border-spacing-${a}`, v)),
3764
+ decl("border-spacing", BORDER_SPACING)
3765
+ ];
3766
+ [
3767
+ ["border-spacing-x", ["x"]],
3768
+ ["border-spacing-y", ["y"]],
3769
+ ["border-spacing", ["x", "y"]]
3770
+ ].forEach(([name, axes]) => {
3771
+ staticUtility(`${name}-px`, [
3772
+ borderSpacingProperties,
3773
+ ...axes.map((a) => [`--baro-border-spacing-${a}`, "1px"]),
3774
+ ["border-spacing", BORDER_SPACING]
3775
+ ], { category: "table" });
3776
+ functionalUtility({
3777
+ name,
3778
+ prop: "border-spacing",
3779
+ supportsArbitrary: true,
3780
+ supportsCustomProperty: true,
3781
+ handle: (value) => borderSpacing(axes, parseNumber(value) ? `calc(var(--spacing) * ${value})` : value),
3782
+ handleCustomProperty: (value) => borderSpacing(axes, `var(${value})`),
3783
+ description: `${name} utility (number, px, arbitrary, custom property supported)`,
3784
+ category: "table"
3785
+ });
3753
3786
  });
3754
3787
  staticUtility("caption-top", [["caption-side", "top"]], { category: "table" });
3755
3788
  staticUtility("caption-bottom", [["caption-side", "bottom"]], { category: "table" });
3789
+ function parseAlpha(op) {
3790
+ if (!op) return null;
3791
+ if (/^\d+(\.\d+)?$/.test(op)) return { alpha: `${op}%`, isVar: false };
3792
+ const pct = /^\[(\d+(?:\.\d+)?)%\]$/.exec(op);
3793
+ if (pct) return { alpha: `${pct[1]}%`, isVar: false };
3794
+ const cp = /^\((--[\w-]+)\)$/.exec(op);
3795
+ if (cp) return { alpha: `var(${cp[1]})`, isVar: true };
3796
+ return null;
3797
+ }
3798
+ function splitTop(value, sep) {
3799
+ const out = [];
3800
+ let depth = 0;
3801
+ let cur = "";
3802
+ for (const ch of value) {
3803
+ if (ch === "(") depth++;
3804
+ else if (ch === ")") depth--;
3805
+ if (depth === 0 && (sep === " " ? /\s/.test(ch) : ch === sep)) {
3806
+ if (cur.trim()) out.push(cur.trim());
3807
+ cur = "";
3808
+ } else cur += ch;
3809
+ }
3810
+ if (cur.trim()) out.push(cur.trim());
3811
+ return out;
3812
+ }
3813
+ const LENGTH = /^-?(\d*\.)?\d+([a-z]+|%)?$/i;
3814
+ function shadowLayers(value, layer, alpha) {
3815
+ return splitTop(value, ",").map((l) => {
3816
+ const parts = splitTop(l, " ");
3817
+ const i = parts.findIndex((p) => p !== "inset" && !LENGTH.test(p));
3818
+ const c = i < 0 ? "currentcolor" : parts[i];
3819
+ parts[i < 0 ? parts.length : i] = `var(--baro-${layer}-color, ${alpha ? `oklab(from ${c} l a b / ${alpha})` : c})`;
3820
+ return parts.join(" ");
3821
+ });
3822
+ }
3823
+ function shadowValueDecls(layer, prop, value, opacity, render = (l) => l.join(", ")) {
3824
+ const a = parseAlpha(opacity);
3825
+ if (opacity && !a) return null;
3826
+ if (!a) return [decl(prop, render(shadowLayers(value, layer)))];
3827
+ const alphaDecl = decl(`--baro-${layer}-alpha`, a.alpha);
3828
+ if (!a.isVar) return [alphaDecl, decl(prop, render(shadowLayers(value, layer, a.alpha)))];
3829
+ return [
3830
+ alphaDecl,
3831
+ decl(prop, render(shadowLayers(value, layer))),
3832
+ atRule("supports", "(color: lab(from red l a b))", [decl(prop, render(shadowLayers(value, layer, a.alpha)))])
3833
+ ];
3834
+ }
3835
+ function shadowColorDecls(layer, color, opacity, ref = color) {
3836
+ const key = `--baro-${layer}-color`;
3837
+ if (color === "inherit") return [decl(key, "inherit")];
3838
+ const a = parseAlpha(opacity);
3839
+ if (opacity && !a) return null;
3840
+ const inner = a ? `color-mix(in oklab, ${ref} ${a.alpha}, transparent)` : ref;
3841
+ const fallback = a ? `color-mix(in srgb, ${color} ${a.alpha}, transparent)` : color;
3842
+ return [
3843
+ decl(key, fallback),
3844
+ atRule("supports", "(color: color-mix(in lab, red, red))", [
3845
+ decl(key, `color-mix(in oklab, ${inner} var(--baro-${layer}-alpha), transparent)`)
3846
+ ])
3847
+ ];
3848
+ }
3756
3849
  staticUtility("filter-none", [["filter", "none"]], { category: "effects" });
3757
3850
  functionalUtility({
3758
3851
  name: "filter",
@@ -3837,57 +3930,68 @@ functionalUtility({
3837
3930
  description: "contrast filter utility (static, number, arbitrary, custom property supported)",
3838
3931
  category: "effects"
3839
3932
  });
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
- ]);
3933
+ const dropShadowProperties = () => atRoot([
3934
+ property("--baro-drop-shadow"),
3935
+ property("--baro-drop-shadow-color"),
3936
+ property("--baro-drop-shadow-alpha", "100%", "<percentage>"),
3937
+ property("--baro-drop-shadow-size")
3938
+ ]);
3939
+ const wrapDropShadow = (layers) => layers.map((l) => `drop-shadow(${l})`).join(" ");
3940
+ const DROP_SHADOW_DEFAULT = "0 1px 2px rgb(0 0 0 / 0.1), 0 1px 1px rgb(0 0 0 / 0.06)";
3941
+ const namedDropShadow = (ctx, name) => {
3942
+ const v = ctx.theme("dropShadow", name);
3943
+ return typeof v === "string" && /^[\w.-]+$/.test(name) ? v : null;
3944
+ };
3945
+ function dropShadowValue(value, opacity, named, keepNamed = false) {
3946
+ const decls = shadowValueDecls("drop-shadow", "--baro-drop-shadow-size", value, opacity, wrapDropShadow);
3947
+ if (!decls) return null;
3948
+ const composed = named !== void 0 && (!opacity || keepNamed) ? named : "var(--baro-drop-shadow-size)";
3949
+ return [dropShadowProperties(), ...decls, decl("--baro-drop-shadow", composed), filters$1()];
3950
+ }
3951
+ staticUtility("drop-shadow-none", [decl("--baro-drop-shadow", " "), filters$1()]);
3952
+ registerUtility({
3953
+ name: "drop-shadow",
3954
+ match: (className) => /^drop-shadow(\/.+)?$/.test(className),
3955
+ handler: (value, _ctx, token) => {
3956
+ const full = value ? `${token.prefix}-${value}` : token.prefix;
3957
+ const cut = full.indexOf("/");
3958
+ const opacity = cut < 0 ? void 0 : full.slice(cut + 1);
3959
+ const literal = "drop-shadow(0 1px 2px rgb(0 0 0 / 0.1)) drop-shadow( 0 1px 1px rgb(0 0 0 / 0.06))";
3960
+ return dropShadowValue(DROP_SHADOW_DEFAULT, opacity, literal, true) ?? [];
3961
+ },
3962
+ category: "effects"
3864
3963
  });
3964
+ const dropShadowColor = (color, opacity, ref) => {
3965
+ const decls = shadowColorDecls("drop-shadow", color, opacity, ref);
3966
+ return decls && [dropShadowProperties(), ...decls, decl("--baro-drop-shadow", "var(--baro-drop-shadow-size)")];
3967
+ };
3865
3968
  functionalUtility({
3866
3969
  name: "drop-shadow",
3867
3970
  themeKeys: ["colors"],
3868
3971
  supportsArbitrary: true,
3869
3972
  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)];
3973
+ supportsOpacity: true,
3974
+ handleBareValue: ({ value, ctx }) => namedDropShadow(ctx, value) ? value : null,
3975
+ handle: (value, ctx, token, extra) => {
3976
+ const opacity = extra?.opacity;
3977
+ const keyword = token.arbitrary ? void 0 : { inherit: "inherit", current: "currentcolor", transparent: "transparent" }[extra?.realThemeValue ?? value];
3978
+ if (keyword) return dropShadowColor(keyword, opacity);
3979
+ if (extra?.realThemeValue) return dropShadowColor(value, opacity, `var(--color-${extra.realThemeValue})`);
3980
+ if (token.arbitrary) {
3981
+ if (parseColor(value)) return dropShadowColor(value, opacity);
3982
+ return dropShadowValue(value, opacity);
3876
3983
  }
3877
- return [
3878
- decl("--baro-drop-shadow-size", `drop-shadow(${value})`),
3879
- decl("--baro-drop-shadow", `var(--baro-drop-shadow-size)`)
3880
- ];
3984
+ const named = namedDropShadow(ctx, value);
3985
+ if (named) return dropShadowValue(named, opacity, `drop-shadow(var(--drop-shadow-${value}))`);
3986
+ return null;
3881
3987
  },
3882
3988
  handleCustomProperty: (value) => {
3883
- if (value.startsWith("color:")) {
3884
- return [
3885
- decl("--baro-drop-shadow-color", `var(${value.replace("color:", "")})`)
3886
- ];
3887
- }
3989
+ if (value.startsWith("color:")) return dropShadowColor(`var(${value.slice(6)})`, void 0) ?? [];
3888
3990
  return [
3991
+ dropShadowProperties(),
3889
3992
  decl("--baro-drop-shadow-size", `drop-shadow(var(${value}))`),
3890
- decl("--baro-drop-shadow", `var(--baro-drop-shadow-size)`)
3993
+ decl("--baro-drop-shadow", `var(--baro-drop-shadow-size)`),
3994
+ filters$1()
3891
3995
  ];
3892
3996
  },
3893
3997
  description: "drop-shadow filter utility (static, arbitrary, custom property supported)",
@@ -4257,166 +4361,119 @@ const ringShadowProperties = () => atRoot([
4257
4361
  property("--baro-ring-offset-width", "0px", "<length>"),
4258
4362
  property("--baro-ring-offset-color", "#fff")
4259
4363
  ]);
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
- ];
4364
+ const shadowColorProperties = (layer) => atRoot([
4365
+ property(`--baro-${layer}-color`),
4366
+ property(`--baro-${layer}-alpha`, "100%", "<percentage>")
4367
+ ]);
4368
+ const NAMED_SHADOWS = {
4369
+ "": "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)",
4370
+ "2xs": "0 1px rgb(0 0 0 / 0.05)",
4371
+ xs: "0 1px 2px 0 rgb(0 0 0 / 0.05)",
4372
+ sm: "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)",
4373
+ md: "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)",
4374
+ lg: "0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)",
4375
+ xl: "0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)",
4376
+ "2xl": "0 25px 50px -12px rgb(0 0 0 / 0.25)",
4377
+ inner: "inset 0 2px 4px 0 rgb(0 0 0 / 0.05)"
4378
+ };
4379
+ const NAMED_INSET_SHADOWS = {
4380
+ "2xs": "inset 0 1px rgb(0 0 0 / 0.05)",
4381
+ xs: "inset 0 1px 1px rgb(0 0 0 / 0.05)",
4382
+ sm: "inset 0 2px 4px rgb(0 0 0 / 0.05)"
4383
+ };
4384
+ const INSET_EXTENSIONS = {
4385
+ md: "inset 0 4px 6px -1px rgb(0 0 0 / 0.05)",
4386
+ lg: "inset 0 10px 15px -3px rgb(0 0 0 / 0.05)",
4387
+ xl: "inset 0 20px 25px -5px rgb(0 0 0 / 0.05)",
4388
+ "2xl": "inset 0 25px 50px -12px rgb(0 0 0 / 0.05)"
4389
+ };
4390
+ const insetEach = (value) => value.split(/,(?![^(]*\))/).map((l) => `inset ${l.trim()}`).join(", ");
4391
+ const own = (table, key) => Object.prototype.hasOwnProperty.call(table, key);
4392
+ function boxShadowLayer(layer, value, opacity) {
4393
+ const decls = shadowValueDecls(layer, `--baro-${layer}`, value, opacity);
4394
+ if (!decls) return null;
4395
+ return [ringShadowProperties(), shadowColorProperties(layer), ...decls, decl("box-shadow", SHADOW_COMPOSITE)];
4396
+ }
4397
+ function namedBoxShadow(layer, name, opacity) {
4398
+ if (layer === "shadow") return own(NAMED_SHADOWS, name) ? boxShadowLayer(layer, NAMED_SHADOWS[name], opacity) : null;
4399
+ if (own(NAMED_INSET_SHADOWS, name)) return boxShadowLayer(layer, NAMED_INSET_SHADOWS[name], opacity);
4400
+ if (!opacity && own(INSET_EXTENSIONS, name)) return boxShadowLayer(layer, INSET_EXTENSIONS[name], void 0);
4401
+ return null;
4319
4402
  }
4320
- functionalUtility({
4403
+ staticUtility("shadow-none", [ringShadowProperties, ["--baro-shadow", "0 0 #0000"], ["box-shadow", SHADOW_COMPOSITE]], { category: "effects" });
4404
+ staticUtility("inset-shadow-none", [ringShadowProperties, ["--baro-inset-shadow", "inset 0 0 #0000"], ["box-shadow", SHADOW_COMPOSITE]], { category: "effects" });
4405
+ registerUtility({
4321
4406
  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;
4407
+ match: (className) => /^shadow(\/.+)?$/.test(className),
4408
+ handler: (value, _ctx, token) => {
4409
+ const full = value ? `${token.prefix}-${value}` : token.prefix;
4410
+ const cut = full.indexOf("/");
4411
+ return namedBoxShadow("shadow", "", cut < 0 ? void 0 : full.slice(cut + 1)) ?? [];
4370
4412
  },
4371
- handleCustomProperty: (value) => shadowLayer(`var(${value})`)
4413
+ category: "effects"
4372
4414
  });
4415
+ const KEYWORD_COLORS = { inherit: "inherit", current: "currentcolor", transparent: "transparent" };
4416
+ function layerColor(layer, main, opacity, token, realThemeValue) {
4417
+ const keyword = token.arbitrary ? void 0 : KEYWORD_COLORS[realThemeValue ?? main];
4418
+ if (keyword) return shadowColorDecls(layer, keyword, opacity);
4419
+ if (realThemeValue) return shadowColorDecls(layer, main, opacity, `var(--color-${realThemeValue})`);
4420
+ if (main.startsWith("color:")) return shadowColorDecls(layer, `var(${main.slice(6)})`, opacity);
4421
+ if (token.arbitrary && parseColor(main)) return shadowColorDecls(layer, main, opacity);
4422
+ return void 0;
4423
+ }
4424
+ for (const layer of ["shadow", "inset-shadow"]) {
4425
+ functionalUtility({
4426
+ name: layer,
4427
+ supportsArbitrary: true,
4428
+ supportsCustomProperty: true,
4429
+ supportsOpacity: true,
4430
+ themeKeys: ["colors"],
4431
+ handleBareValue: ({ value, extra }) => namedBoxShadow(layer, value, extra?.opacity) ? value : null,
4432
+ handle: (value, _ctx, token, extra) => {
4433
+ const opacity = extra?.opacity;
4434
+ const named = !extra?.realThemeValue && !token.arbitrary ? namedBoxShadow(layer, value, opacity) : null;
4435
+ if (named) return named;
4436
+ const color = layerColor(layer, value, opacity, token, extra?.realThemeValue);
4437
+ if (color !== void 0) return color;
4438
+ if (token.arbitrary) return boxShadowLayer(layer, layer === "inset-shadow" ? insetEach(value) : value, opacity);
4439
+ return null;
4440
+ },
4441
+ 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)]
4442
+ });
4443
+ }
4444
+ const textShadowProperties = () => atRoot([
4445
+ property("--baro-text-shadow-color"),
4446
+ property("--baro-text-shadow-alpha", "100%", "<percentage>")
4447
+ ]);
4448
+ const namedTextShadow = (ctx, name) => {
4449
+ const v = ctx.theme("textShadow", name);
4450
+ return typeof v === "string" && /^[\w.-]+$/.test(name) ? v : null;
4451
+ };
4452
+ const textShadowValue = (value, opacity) => {
4453
+ const decls = shadowValueDecls("text-shadow", "text-shadow", value, opacity);
4454
+ return decls ? [textShadowProperties(), ...decls] : null;
4455
+ };
4456
+ staticUtility("text-shadow-none", [textShadowProperties, ["text-shadow", "none"]], { category: "effects" });
4373
4457
  functionalUtility({
4374
- name: "inset-shadow",
4458
+ name: "text-shadow",
4375
4459
  supportsArbitrary: true,
4376
4460
  supportsCustomProperty: true,
4377
4461
  supportsOpacity: true,
4378
- themeKeys: ["colors", "shadows"],
4462
+ themeKeys: ["colors"],
4463
+ handleBareValue: ({ value, ctx }) => namedTextShadow(ctx, value) ? value : null,
4379
4464
  handle: (value, ctx, token, extra) => {
4380
- const main = value;
4381
4465
  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
- ];
4466
+ if (!extra?.realThemeValue && !token.arbitrary) {
4467
+ const named = namedTextShadow(ctx, value);
4468
+ if (named) return textShadowValue(named, opacity);
4416
4469
  }
4470
+ const color = layerColor("text-shadow", value, opacity, token, extra?.realThemeValue);
4471
+ if (color !== void 0) return color && [textShadowProperties(), ...color];
4472
+ if (token.arbitrary) return textShadowValue(value, opacity);
4417
4473
  return null;
4418
4474
  },
4419
- handleCustomProperty: (value) => [decl("box-shadow", `var(${value})`)]
4475
+ handleCustomProperty: (value) => value.startsWith("color:") ? [textShadowProperties(), ...shadowColorDecls("text-shadow", `var(${value.slice(6)})`, void 0) ?? []] : [textShadowProperties(), decl("text-shadow", `var(${value})`)],
4476
+ category: "effects"
4420
4477
  });
4421
4478
  [
4422
4479
  ["ring", "1px"],
@@ -4959,12 +5016,15 @@ staticUtility("not-sr-only", [
4959
5016
  ], { category: "layout" });
4960
5017
  staticUtility("@container", [["container-type", "inline-size"]], { category: "layout" });
4961
5018
  staticUtility("@container-normal", [["container-type", "normal"]], { category: "layout" });
5019
+ staticUtility("@container-size", [["container-type", "size"]], { category: "layout" });
5020
+ const NAMED_CONTAINER = /^@container(-normal|-size)?\/([a-zA-Z0-9_-]+)$/;
5021
+ const CONTAINER_TYPE = { "": "inline-size", "-normal": "normal", "-size": "size" };
4962
5022
  registerUtility({
4963
5023
  name: "@container",
4964
- match: (className) => /^@container\/[a-zA-Z0-9_-]+$/.test(className),
5024
+ match: (className) => NAMED_CONTAINER.test(className),
4965
5025
  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;
5026
+ const m = NAMED_CONTAINER.exec(`${token.prefix}${token.value ? `-${token.value}` : ""}`);
5027
+ return m ? [decl("container-type", CONTAINER_TYPE[m[1] ?? ""]), decl("container-name", m[2])] : null;
4968
5028
  },
4969
5029
  category: "layout"
4970
5030
  });
@@ -5049,6 +5109,11 @@ staticUtility("sticky", [["position", "sticky"]], { category: "layout" });
5049
5109
  [
5050
5110
  ["inset-x", "inset-inline"],
5051
5111
  ["inset-y", "inset-block"],
5112
+ // Tailwind 4.3 logical sides; registered before `inset` so their handler runs first for `inset-s-*` etc.
5113
+ ["inset-s", "inset-inline-start"],
5114
+ ["inset-e", "inset-inline-end"],
5115
+ ["inset-bs", "inset-block-start"],
5116
+ ["inset-be", "inset-block-end"],
5052
5117
  ["inset", "inset"],
5053
5118
  ["start", "inset-inline-start"],
5054
5119
  ["end", "inset-inline-end"],
@@ -5144,6 +5209,15 @@ functionalUtility({
5144
5209
  description: "gap utility (number, arbitrary, custom property supported)",
5145
5210
  category: "layout"
5146
5211
  });
5212
+ functionalUtility({
5213
+ name: "zoom",
5214
+ prop: "zoom",
5215
+ supportsArbitrary: true,
5216
+ supportsCustomProperty: true,
5217
+ handleBareValue: ({ value }) => /^\d+$/.test(value) ? `${value}%` : null,
5218
+ description: "zoom utility (integer percent, arbitrary, custom property)",
5219
+ category: "layout"
5220
+ });
5147
5221
  staticUtility("basis-full", [["flex-basis", "100%"]], { category: "flex-grid" });
5148
5222
  staticUtility("basis-auto", [["flex-basis", "auto"]], { category: "flex-grid" });
5149
5223
  staticUtility("basis-3xs", [["flex-basis", "var(--container-3xs)"]], { category: "flex-grid" });
@@ -5418,6 +5492,8 @@ functionalUtility({
5418
5492
  // auto-cols-[minmax(0,2fr)]
5419
5493
  supportsCustomProperty: true,
5420
5494
  // auto-cols-(--my-auto-cols)
5495
+ handleBareValue: ({ value }) => parseNumber(value) ? `calc(var(--spacing) * ${value})` : null,
5496
+ // #310: auto-cols-4
5421
5497
  handle: (value) => {
5422
5498
  if (typeof value === "string") return [decl("grid-auto-columns", value)];
5423
5499
  return null;
@@ -5437,6 +5513,8 @@ functionalUtility({
5437
5513
  // auto-rows-[minmax(0,2fr)]
5438
5514
  supportsCustomProperty: true,
5439
5515
  // auto-rows-(--my-auto-rows)
5516
+ handleBareValue: ({ value }) => parseNumber(value) ? `calc(var(--spacing) * ${value})` : null,
5517
+ // #310: auto-rows-12
5440
5518
  handle: (value) => {
5441
5519
  if (typeof value === "string") return [decl("grid-auto-rows", value)];
5442
5520
  return null;
@@ -5639,6 +5717,8 @@ functionalUtility({
5639
5717
  ["py", "padding-block"],
5640
5718
  ["ps", "padding-inline-start"],
5641
5719
  ["pe", "padding-inline-end"],
5720
+ ["pbs", "padding-block-start"],
5721
+ ["pbe", "padding-block-end"],
5642
5722
  ["pt", "padding-top"],
5643
5723
  ["pr", "padding-right"],
5644
5724
  ["pb", "padding-bottom"],
@@ -5662,6 +5742,8 @@ functionalUtility({
5662
5742
  ["my", "margin-block"],
5663
5743
  ["ms", "margin-inline-start"],
5664
5744
  ["me", "margin-inline-end"],
5745
+ ["mbs", "margin-block-start"],
5746
+ ["mbe", "margin-block-end"],
5665
5747
  ["mt", "margin-top"],
5666
5748
  ["mr", "margin-right"],
5667
5749
  ["mb", "margin-bottom"],
@@ -5987,6 +6069,41 @@ functionalUtility({
5987
6069
  description: "max-width utility (spacing, fraction, arbitrary, custom property, static supported)",
5988
6070
  category: "sizing"
5989
6071
  });
6072
+ {
6073
+ const containers = ["3xs", "2xs", "xs", "sm", "md", "lg", "xl", "2xl", "3xl", "4xl", "5xl", "6xl", "7xl"].map(
6074
+ (k) => [k, `var(--container-${k})`]
6075
+ );
6076
+ const common = [["0", "0px"], ["px", "1px"], ["full", "100%"], ["min", "min-content"], ["max", "max-content"], ["fit", "fit-content"]];
6077
+ const inlineVp = [["screen", "100vw"], ["dvw", "100dvw"], ["lvw", "100lvw"], ["svw", "100svw"]];
6078
+ const blockVp = [["screen", "100vh"], ["dvh", "100dvh"], ["lvh", "100lvh"], ["svh", "100svh"], ["lh", "1lh"]];
6079
+ const families = [
6080
+ ["inline", "inline-size", [...common, ["auto", "auto"], ...inlineVp, ...containers]],
6081
+ ["min-inline", "min-inline-size", [...common, ["auto", "auto"], ...inlineVp, ...containers]],
6082
+ ["max-inline", "max-inline-size", [...common, ["none", "none"], ...inlineVp, ...containers]],
6083
+ ["block", "block-size", [...common, ["auto", "auto"], ...blockVp]],
6084
+ ["min-block", "min-block-size", [...common, ["auto", "auto"], ...blockVp]],
6085
+ ["max-block", "max-block-size", [...common, ["none", "none"], ...blockVp]]
6086
+ ];
6087
+ for (const [name, prop, statics] of families) {
6088
+ for (const [key, value] of statics) staticUtility(`${name}-${key}`, [[prop, value]], { category: "sizing" });
6089
+ functionalUtility({
6090
+ spacingKeys: true,
6091
+ name,
6092
+ prop,
6093
+ supportsArbitrary: true,
6094
+ supportsCustomProperty: true,
6095
+ supportsFraction: true,
6096
+ handleBareValue: ({ value, token }) => {
6097
+ if (token.negative) return null;
6098
+ if (parseNumber(value)) return `calc(var(--spacing) * ${value})`;
6099
+ if (parseFractionOrNumber(value)) return `calc(${value} * 100%)`;
6100
+ return null;
6101
+ },
6102
+ description: `${prop} utility (spacing, fraction, arbitrary, custom property, keywords)`,
6103
+ category: "sizing"
6104
+ });
6105
+ }
6106
+ }
5990
6107
  const leadingProperty = () => atRoot([property("--baro-leading")]);
5991
6108
  staticUtility("font-sans", [["font-family", "var(--font-sans)"]], { category: "typography" });
5992
6109
  staticUtility("font-serif", [["font-family", "var(--font-serif)"]], { category: "typography" });
@@ -6017,13 +6134,15 @@ functionalUtility({
6017
6134
  name: "font",
6018
6135
  supportsArbitrary: true,
6019
6136
  supportsCustomProperty: true,
6020
- handle: (value) => {
6137
+ handle: (value, _ctx, token) => {
6138
+ if (token.prefix !== "font") return null;
6021
6139
  if (parseNumber(value)) {
6022
6140
  return [decl("font-weight", value)];
6023
6141
  }
6024
6142
  return [decl("font-family", value)];
6025
6143
  },
6026
- handleCustomProperty: (value) => {
6144
+ handleCustomProperty: (value, _ctx, token) => {
6145
+ if (token.prefix !== "font") return null;
6027
6146
  if (value.startsWith("font-name:")) {
6028
6147
  return [decl("font-family", `var(${value.replace("font-name:", "")})`)];
6029
6148
  }
@@ -6322,6 +6441,42 @@ functionalUtility({
6322
6441
  description: "content utility (arbitrary, custom property supported)",
6323
6442
  category: "typography"
6324
6443
  });
6444
+ const placeholderColor = (value) => [rule("&::placeholder", [decl("color", value)])];
6445
+ staticUtility("placeholder-inherit", placeholderColor("inherit"), { category: "typography" });
6446
+ staticUtility("placeholder-current", placeholderColor("currentcolor"), { category: "typography" });
6447
+ staticUtility("placeholder-transparent", placeholderColor("transparent"), { category: "typography" });
6448
+ functionalUtility({
6449
+ name: "placeholder",
6450
+ themeKeys: ["colors"],
6451
+ supportsArbitrary: true,
6452
+ supportsCustomProperty: true,
6453
+ supportsOpacity: true,
6454
+ handle: (value, _ctx, _token, extra) => {
6455
+ if (extra?.realThemeValue) return [rule("&::placeholder", themeColorDecls("color", value, extra))];
6456
+ if (parseColor(value)) return placeholderColor(value);
6457
+ return null;
6458
+ },
6459
+ handleCustomProperty: (value) => placeholderColor(`var(${value})`),
6460
+ description: "placeholder color utility (theme, alpha, arbitrary, custom property)"
6461
+ });
6462
+ functionalUtility({
6463
+ name: "font-features",
6464
+ supportsArbitrary: true,
6465
+ supportsCustomProperty: true,
6466
+ handle: (value, _ctx, token) => token.arbitrary ? [decl("font-feature-settings", value)] : null,
6467
+ handleCustomProperty: (value) => [decl("font-feature-settings", `var(${value.replace(/^[a-z-]+:(?=--)/, "")})`)],
6468
+ description: "font-feature-settings utility (arbitrary, custom property)",
6469
+ category: "typography"
6470
+ });
6471
+ functionalUtility({
6472
+ name: "tab",
6473
+ prop: "tab-size",
6474
+ supportsArbitrary: true,
6475
+ supportsCustomProperty: true,
6476
+ handleBareValue: ({ value }) => /^\d+$/.test(value) ? value : null,
6477
+ description: "tab-size utility (integer, arbitrary, custom property)",
6478
+ category: "typography"
6479
+ });
6325
6480
  const gradientStopProperties = () => {
6326
6481
  return atRoot([
6327
6482
  property("--baro-gradient-position"),
@@ -6653,6 +6808,11 @@ const withBorderStyle = (props, width) => [
6653
6808
  [
6654
6809
  ["border-x", ["border-left-width", "border-right-width"]],
6655
6810
  ["border-y", ["border-top-width", "border-bottom-width"]],
6811
+ ["border-bs", ["border-block-start-width"]],
6812
+ ["border-be", ["border-block-end-width"]],
6813
+ ["border-s", ["border-inline-start-width"]],
6814
+ // #311 (Tailwind 4.3)
6815
+ ["border-e", ["border-inline-end-width"]],
6656
6816
  ["border-t", ["border-top-width"]],
6657
6817
  ["border-r", ["border-right-width"]],
6658
6818
  ["border-b", ["border-bottom-width"]],
@@ -6672,6 +6832,7 @@ const withBorderStyle = (props, width) => [
6672
6832
  functionalUtility({
6673
6833
  name,
6674
6834
  themeKeys: ["borderWidth", "colors"],
6835
+ supportsOpacity: true,
6675
6836
  supportsArbitrary: true,
6676
6837
  supportsCustomProperty: true,
6677
6838
  handleBareValue: ({ value }) => {
@@ -7652,9 +7813,10 @@ staticModifier("starting", ["&"], {
7652
7813
  wrap: () => [atRule("starting-style", "", [], "starting")],
7653
7814
  source: "starting"
7654
7815
  });
7655
- function createContainerParams(type, value, name) {
7816
+ function createContainerParams(type, value, name, negate = false) {
7656
7817
  const condition = type === "min" ? "width >=" : "width <";
7657
- return name ? `${name} (${condition} ${value})` : `(${condition} ${value})`;
7818
+ const query = `${negate ? "not " : ""}(${condition} ${value})`;
7819
+ return name ? `${name} ${query}` : query;
7658
7820
  }
7659
7821
  function createContainerRule(params, ast) {
7660
7822
  return {
@@ -7823,17 +7985,17 @@ functionalModifier(
7823
7985
  return result;
7824
7986
  }
7825
7987
  );
7826
- const SIZE_VARIANT = /^@(?:(min|max)-)?(\[[^\]]+\]|[a-zA-Z0-9.]+)(?:\/([a-zA-Z0-9_-]+))?$/;
7988
+ const SIZE_VARIANT = /^(not-)?@(?:(min|max)-)?(\[[^\]]+\]|[a-zA-Z0-9.]+)(?:\/([a-zA-Z0-9_-]+))?$/;
7827
7989
  functionalModifier(
7828
- (mod) => SIZE_VARIANT.test(mod) && !/^@container(?:\/|$)/.test(mod),
7990
+ (mod) => SIZE_VARIANT.test(mod) && !/^(?:not-)?@container(?:\/|$)/.test(mod),
7829
7991
  void 0,
7830
7992
  (mod, context) => {
7831
7993
  const m = SIZE_VARIANT.exec(mod.type);
7832
7994
  if (!m) return [];
7833
- const [, type, size, name] = m;
7995
+ const [, not, type, size, name] = m;
7834
7996
  const value = size.startsWith("[") ? size.slice(1, -1).replace(/_/g, " ") : context.theme("container." + size);
7835
7997
  if (!value) return [];
7836
- return [createContainerRule(createContainerParams(type === "max" ? "max" : "min", value, name), [])];
7998
+ return [createContainerRule(createContainerParams(type === "max" ? "max" : "min", value, name, !!not), [])];
7837
7999
  }
7838
8000
  );
7839
8001
  const startsAtRule = (bracket) => /^[\s_]*@/.test(bracket);
@@ -7973,7 +8135,7 @@ functionalModifier(
7973
8135
  }
7974
8136
  );
7975
8137
  functionalModifier(
7976
- (mod) => /^not-/.test(mod),
8138
+ (mod) => /^not-/.test(mod) && !mod.startsWith("not-@"),
7977
8139
  ({ selector, mod }) => {
7978
8140
  const m = /^not-(.+)$/.exec(mod.type);
7979
8141
  return {
@@ -8040,7 +8202,8 @@ functionalModifier(
8040
8202
  void 0
8041
8203
  );
8042
8204
  functionalModifier(
8043
- (mod) => mod.startsWith("not-"),
8205
+ (mod) => mod.startsWith("not-") && !mod.startsWith("not-@"),
8206
+ // not-@… is container negation (#311)
8044
8207
  ({ selector, mod }) => {
8045
8208
  const pseudo = mod.type.replace("not-", "");
8046
8209
  if (pseudo.startsWith("[")) {