@barocss/kit 0.10.2 → 0.11.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
@@ -270,250 +270,574 @@ function clearContextCaches(ctx) {
270
270
  state.failures.clear();
271
271
  }
272
272
  //#endregion
273
- //#region src/core/registry.ts
274
- var utilityRegistry = [];
275
- function registerUtility(util, ctx) {
276
- const state = ctx && getContextState(ctx);
277
- if (ctx && !state) throw new Error("Utility registration requires a context from createContext");
278
- (state?.utilities || utilityRegistry).push(util);
279
- if (ctx) clearContextCaches(ctx);
280
- else {
281
- parseResultCache.clear();
282
- utilityCache.clear();
283
- }
284
- }
285
- function getUtility(ctx) {
286
- return ctx && getContextState(ctx)?.utilities || utilityRegistry;
287
- }
288
- var modifierRegistry = [];
273
+ //#region src/core/utils.ts
289
274
  /**
290
- * staticModifier: A helper that registers a modifier name and an array of CSS selectors directly to the registry
291
- *
292
- * @example
293
- * ```
294
- * staticModifier('disabled', ['&:disabled'], { source: 'pseudo' });
295
- * ```
296
- *
297
- * @param name The name of the modifier
298
- * @param selectors The selectors of the modifier
299
- * @param options The options of the modifier
300
- *
301
- * @returns {void}
275
+ * Parses a fraction string (e.g., '1/2') and returns a percentage string (e.g., '50%'), or null if not a valid fraction.
302
276
  */
303
- function staticModifier(name, selectors, options = {}, ctx) {
304
- registerModifier({
305
- name,
306
- match: (mod) => mod === name,
307
- modifySelector: ({ ..._rest }) => {
308
- return selectors.map((sel) => ({
309
- selector: sel,
310
- source: options.source
311
- }));
312
- },
313
- ...options
314
- }, ctx);
315
- }
316
- function functionalModifier(match, modifySelector, wrap, options = {}, ctx) {
317
- registerModifier({
318
- match,
319
- modifySelector,
320
- wrap,
321
- ...options
322
- }, ctx);
323
- }
324
- function registerModifier(modifier, ctx) {
325
- const state = ctx && getContextState(ctx);
326
- if (ctx && !state) throw new Error("Modifier registration requires a context from createContext");
327
- (state?.modifiers || modifierRegistry).push(modifier);
328
- if (ctx) clearContextCaches(ctx);
329
- }
330
- function getModifier(ctx) {
331
- return ctx && getContextState(ctx)?.modifiers || modifierRegistry;
332
- }
333
- var ESCAPE_REGEX = /[^A-Za-z0-9_-]/g;
334
- function escapeClassName(className) {
335
- if (className === "-") return "\\-";
336
- const lead = /^-?[0-9]/.exec(className);
337
- if (lead) {
338
- const i = lead[0].length - 1;
339
- return className.slice(0, i) + "\\" + className.charCodeAt(i).toString(16) + " " + escapeRest(className.slice(i + 1));
277
+ function parseFraction(input) {
278
+ if (input.includes("/")) {
279
+ const [num, denom] = input.split("/").map(Number);
280
+ if (!isNaN(num) && !isNaN(denom) && denom !== 0) return `${num / denom * 100}%`;
340
281
  }
341
- return escapeRest(className);
342
- }
343
- function escapeRest(className) {
344
- return className.replace(ESCAPE_REGEX, (c) => {
345
- if (c === " ") return "\\x20 ";
346
- if (c === ".") return "\\.";
347
- if (c === "/") return "\\/";
348
- if (c === ":") return "\\:";
349
- if (c === "[") return "\\[";
350
- if (c === "]") return "\\]";
351
- if (c === "(") return "\\(";
352
- if (c === ")") return "\\)";
353
- if (c === "%") return "\\%";
354
- if (c === "#") return "\\#";
355
- if (c === ",") return "\\,";
356
- if (c === "=") return "\\=";
357
- if (c === "&") return "\\&";
358
- if (c === "~") return "\\~";
359
- if (c === "*") return "\\*";
360
- if (c === "$") return "\\$";
361
- if (c === "^") return "\\^";
362
- if (c === "+") return "\\+";
363
- if (c === "?") return "\\?";
364
- if (c === "!") return "\\!";
365
- if (c === "@") return "\\@";
366
- if (c === "'") return "\\'";
367
- if (c === "\"") return "\\\"";
368
- if (c === "`") return "\\`";
369
- if (c === ";") return "\\;";
370
- if (c === "<") return "\\<";
371
- if (c === ">") return "\\>";
372
- if (c === "{") return "\\{";
373
- if (c === "}") return "\\}";
374
- if (c === "|") return "\\|";
375
- if (c === "\\") return "\\\\";
376
- return "\\" + c;
377
- });
282
+ return null;
378
283
  }
379
284
  /**
380
- * staticUtility: A helper that registers a utility name and an array of CSS declaration pairs directly to the registry
381
- *
382
- * @example
383
- * ```
384
- * staticUtility('block', [['display', 'block']]);
385
- * staticUtility('hidden', [['display', 'none']]);
386
- * staticUtility('space-x-px', [
387
- * [
388
- * '& > :not([hidden]) ~ :not([hidden])', // selector
389
- * [
390
- * ['margin-inline-start', '1px'], // [prop, value]
391
- * ['margin-inline-end', '1px'], // [prop, value]
392
- * ],
393
- * ],
394
- * ]);
395
- * ```
396
- *
397
- * @param name The name of the utility
398
- * @param decls The declarations of the utility
399
- * @param opts The options of the utility
285
+ * Returns the input if it is a valid non-negative integer string, else null.
400
286
  *
401
- * @returns {void}
287
+ * @example
288
+ * parseNumber("10") // "10"
289
+ * parseNumber("-10") // "-10"
290
+ * parseNumber("10.5") // "10.5"
402
291
  */
403
- function staticUtility(name, decls, opts, ctx) {
404
- registerUtility({
405
- name,
406
- match: (className) => {
407
- return className === name;
408
- },
409
- handler: (value) => {
410
- return decls.flatMap((params) => {
411
- if (params.type) return [params];
412
- if (typeof params === "function") return [params(value)];
413
- const [a, b] = params;
414
- if (typeof b === "string") return [decl(a, b)];
415
- else if (Array.isArray(b)) return [rule(a, b.map(([prop, value]) => decl(prop, value)))];
416
- return [];
417
- });
418
- },
419
- description: opts?.description,
420
- category: opts?.category,
421
- priority: opts?.priority
422
- }, ctx);
292
+ function parseNumber(input) {
293
+ return /^-?\d+(?:\.\d+)?$/.test(input) ? input : null;
423
294
  }
424
295
  /**
425
- * functionalUtility: A helper that registers dynamic utilities (theme, arbitrary, custom, negative, fraction, etc.) directly
426
- *
427
- * Example:
428
- * functionalUtility({
429
- * name: 'z',
430
- * supportsNegative: true,
431
- * themeKeys: ['--z-index'],
432
- * handleBareValue: ({ value }) => isPositiveInteger(value) ? value : null,
433
- * handle: (value) => [decl('z-index', value)],
434
- * description: 'z-index utility',
435
- * category: 'layout',
436
- * });
296
+ * Returns the input if it is a valid length string, else null.
437
297
  */
298
+ function parseLength(input) {
299
+ return /^\d+(px|em|rem|vh|vw|vmin|vmax|%|in|cm|mm|pt|pc|ex|ch|fr)$/.test(input) ? input : null;
300
+ }
438
301
  /**
439
- * #300: a theme key that no built-in utility names (`theme.extend.borderRadius.card`) still resolves, as in
440
- * Tailwind 4 where `--radius-card` gives `rounded-card`. Only word keys that start with a letter (numbers stay
441
- * bare values), never `DEFAULT`; unknown keys return null so the utility emits nothing (#213).
302
+ * Unified parser for fraction or number, with options for percent or repeat syntax.
303
+ * - percent: if true, returns percentage for fraction (e.g., '1/2' -> '50%')
304
+ * - repeat: if true, returns repeat() for number (e.g., '3' -> 'repeat(3, minmax(0, 1fr))')
442
305
  */
443
- function themeKeyEntry(ctx, namespace, key) {
444
- if (key === "DEFAULT" || !/^[a-zA-Z][\w-]*$/.test(key) || typeof ctx?.theme !== "function") return void 0;
445
- const table = ctx.theme(namespace);
446
- if (!table || typeof table !== "object" || !Object.prototype.hasOwnProperty.call(table, key)) return void 0;
447
- return table[key] ?? void 0;
448
- }
449
- /** #300: the literal value of `theme.<namespace>.<key>` when it is a string, else null. */
450
- function themeKeyValue(ctx, namespace, key) {
451
- const v = themeKeyEntry(ctx, namespace, key);
452
- return typeof v === "string" ? v : null;
453
- }
454
- /** #300: `var(--<varPrefix>-<key>)` when `theme.<namespace>.<key>` exists (the :root var BaroCSS emits for it), else null. */
455
- function themeKeyVar(ctx, namespace, key, varPrefix) {
456
- return themeKeyEntry(ctx, namespace, key) === void 0 ? null : `var(--${varPrefix}-${key})`;
457
- }
458
- /** #261: `var(--spacing-<key>)` for a named (non-numeric) `theme.spacing` key, else null. */
459
- function spacingKeyValue(ctx, key, negative) {
460
- if (key === "px" || !/^[a-zA-Z][\w-]*$/.test(key) || ctx.theme("spacing", key) == null) return null;
461
- const ref = `var(--spacing-${key})`;
462
- return negative ? `calc(${ref} * -1)` : ref;
306
+ function parseFractionOrNumber(value, opts = {}) {
307
+ if (/^\d+$/.test(value)) {
308
+ if (opts.repeat) return `repeat(${value}, minmax(0, 1fr))`;
309
+ return value;
310
+ }
311
+ if (value.includes("/")) {
312
+ const [numerator, denominator] = value.split("/").map(Number);
313
+ if (!isNaN(numerator) && !isNaN(denominator) && denominator !== 0) {
314
+ const result = numerator / denominator;
315
+ if (opts.percent) return `${result * 100}%`;
316
+ return result.toString();
317
+ }
318
+ }
319
+ return null;
463
320
  }
464
- function functionalUtility(opts, ctx) {
465
- registerUtility({
466
- name: opts.name,
467
- match: (className) => className.startsWith(opts.name + "-"),
468
- handler: (value, ctx, token, _options) => {
469
- let finalValue = value;
470
- const parsedUtility = token;
471
- const extra = { opacity: token.opacity };
472
- if (opts.supportsOpacity && !token.arbitrary && !token.customProperty && value.includes("/")) {
473
- const list = value.split("/");
474
- if (list.length >= 2) {
475
- extra.opacity = list.pop();
476
- finalValue = list.join("/");
477
- }
478
- }
479
- if (opts.supportsArbitrary && parsedUtility.arbitrary) {
480
- const processedValue = normalizeMathSpacing(expandThemeFunctions(finalValue.replace(/_/g, " ")));
481
- if (opts.handle) {
482
- const result = opts.handle(processedValue, ctx, token, extra);
483
- if (result) return result;
484
- }
485
- if (opts.prop) return [decl(opts.prop, processedValue)];
486
- return [];
487
- }
488
- if (opts.supportsCustomProperty && parsedUtility.customProperty) {
489
- if (opts.handleCustomProperty) return opts.handleCustomProperty(finalValue, ctx, token, extra);
490
- const customValue = `var(${finalValue})`;
491
- if (opts.handle) {
492
- const result = opts.handle(customValue, ctx, token, extra);
493
- if (result) return result;
494
- }
495
- if (opts.prop) return [decl(opts.prop, customValue)];
496
- return [];
497
- }
498
- let themeValue;
499
- if (opts.themeKey && ctx.theme) themeValue = themeScalar(ctx.theme(opts.themeKey, finalValue));
500
- let namespace = themeValue !== void 0 ? opts.themeKey : void 0;
501
- if (!themeValue && opts.themeKeys && ctx.theme) for (const key of opts.themeKeys) {
502
- themeValue = themeScalar(ctx.theme(key, finalValue));
503
- if (themeValue !== void 0) {
504
- namespace = key;
505
- break;
506
- }
507
- }
508
- if (themeValue !== void 0) {
509
- extra.themeNamespace = namespace;
510
- extra.themeKey = finalValue;
511
- if (namespace === "colors" || !(opts.themeKeys ?? [opts.themeKey]).includes("colors")) extra.realThemeValue = finalValue;
512
- finalValue = themeValue;
513
- if (opts.prop) return [decl(opts.prop, finalValue)];
514
- if (opts.handle) {
515
- const result = opts.handle(finalValue, ctx, token, extra);
516
- if (result) return result;
321
+ var CSS_COLOR_NAMES = /* @__PURE__ */ new Set([
322
+ "aliceblue",
323
+ "antiquewhite",
324
+ "aqua",
325
+ "aquamarine",
326
+ "azure",
327
+ "beige",
328
+ "bisque",
329
+ "black",
330
+ "blanchedalmond",
331
+ "blue",
332
+ "blueviolet",
333
+ "brown",
334
+ "burlywood",
335
+ "cadetblue",
336
+ "chartreuse",
337
+ "chocolate",
338
+ "coral",
339
+ "cornflowerblue",
340
+ "cornsilk",
341
+ "crimson",
342
+ "cyan",
343
+ "darkblue",
344
+ "darkcyan",
345
+ "darkgoldenrod",
346
+ "darkgray",
347
+ "darkgreen",
348
+ "darkgrey",
349
+ "darkkhaki",
350
+ "darkmagenta",
351
+ "darkolivegreen",
352
+ "darkorange",
353
+ "darkorchid",
354
+ "darkred",
355
+ "darksalmon",
356
+ "darkseagreen",
357
+ "darkslateblue",
358
+ "darkslategray",
359
+ "darkslategrey",
360
+ "darkturquoise",
361
+ "darkviolet",
362
+ "deeppink",
363
+ "deepskyblue",
364
+ "dimgray",
365
+ "dimgrey",
366
+ "dodgerblue",
367
+ "firebrick",
368
+ "floralwhite",
369
+ "forestgreen",
370
+ "fuchsia",
371
+ "gainsboro",
372
+ "ghostwhite",
373
+ "gold",
374
+ "goldenrod",
375
+ "gray",
376
+ "grey",
377
+ "green",
378
+ "greenyellow",
379
+ "honeydew",
380
+ "hotpink",
381
+ "indianred",
382
+ "indigo",
383
+ "ivory",
384
+ "khaki",
385
+ "lavender",
386
+ "lavenderblush",
387
+ "lawngreen",
388
+ "lemonchiffon",
389
+ "lightblue",
390
+ "lightcoral",
391
+ "lightcyan",
392
+ "lightgoldenrodyellow",
393
+ "lightgray",
394
+ "lightgreen",
395
+ "lightgrey",
396
+ "lightpink",
397
+ "lightsalmon",
398
+ "lightseagreen",
399
+ "lightskyblue",
400
+ "lightslategray",
401
+ "lightslategrey",
402
+ "lightsteelblue",
403
+ "lightyellow",
404
+ "lime",
405
+ "limegreen",
406
+ "linen",
407
+ "magenta",
408
+ "maroon",
409
+ "mediumaquamarine",
410
+ "mediumblue",
411
+ "mediumorchid",
412
+ "mediumpurple",
413
+ "mediumseagreen",
414
+ "mediumslateblue",
415
+ "mediumspringgreen",
416
+ "mediumturquoise",
417
+ "mediumvioletred",
418
+ "midnightblue",
419
+ "mintcream",
420
+ "mistyrose",
421
+ "moccasin",
422
+ "navajowhite",
423
+ "navy",
424
+ "oldlace",
425
+ "olive",
426
+ "olivedrab",
427
+ "orange",
428
+ "orangered",
429
+ "orchid",
430
+ "palegoldenrod",
431
+ "palegreen",
432
+ "paleturquoise",
433
+ "palevioletred",
434
+ "papayawhip",
435
+ "peachpuff",
436
+ "peru",
437
+ "pink",
438
+ "plum",
439
+ "powderblue",
440
+ "purple",
441
+ "red",
442
+ "rosybrown",
443
+ "royalblue",
444
+ "saddlebrown",
445
+ "salmon",
446
+ "sandybrown",
447
+ "seagreen",
448
+ "seashell",
449
+ "sienna",
450
+ "silver",
451
+ "skyblue",
452
+ "slateblue",
453
+ "slategray",
454
+ "slategrey",
455
+ "snow",
456
+ "springgreen",
457
+ "steelblue",
458
+ "tan",
459
+ "teal",
460
+ "thistle",
461
+ "tomato",
462
+ "turquoise",
463
+ "violet",
464
+ "wheat",
465
+ "white",
466
+ "whitesmoke",
467
+ "yellow",
468
+ "yellowgreen"
469
+ ]);
470
+ /**
471
+ * Returns the input if it is a valid color string, else null.
472
+ *
473
+ * #rgb, #rgba, #rrggbb, #rrggbbaa, rgb(r, g, b), rgb(r, g, b, a), hsl(h, s, l), hsl(h, s, l, a), hwb(h, w, b), hwb(h, w, b, a), lab(l, a, b), lab(l, a, b, a), lch(l, c, h), lch(l, c, h, a), oklab(l, a, b), oklab(l, a, b, a), oklch(l, c, h), oklch(l, c, h, a), color-mix(in oklab, var(--color-blue-500) 60%, transparent)
474
+ */
475
+ function parseColor(input) {
476
+ if (CSS_COLOR_NAMES.has(input.toLowerCase())) return input;
477
+ if (input.startsWith("color:var(")) return input.slice(6);
478
+ if (input.startsWith("color:")) return parseColor(input.slice(6));
479
+ if (input.startsWith("#") && input.length === 4) return `#${input.slice(1)}`;
480
+ if (input.startsWith("#") && input.length === 5) return `#${input.slice(1)}`;
481
+ if (input.startsWith("#") && input.length === 7) return `#${input.slice(1)}`;
482
+ if (input.startsWith("#") && input.length === 9) return `#${input.slice(1)}`;
483
+ if (input.startsWith("rgb(")) return input.slice(4, -1);
484
+ if (input.startsWith("rgba(")) return input.slice(5, -1);
485
+ if (input.startsWith("hsl(")) return input.slice(4, -1);
486
+ if (input.startsWith("hsla(")) return input.slice(5, -1);
487
+ if (input.startsWith("hwb(")) return input.slice(4, -1);
488
+ if (input.startsWith("lab(")) return input.slice(4, -1);
489
+ if (input.startsWith("lch(")) return input.slice(4, -1);
490
+ if (input.startsWith("oklab(")) return input.slice(5, -1);
491
+ if (input.startsWith("oklch(")) return input.slice(6, -1);
492
+ if (input.startsWith("color-mix(")) return input.slice(9, -1);
493
+ return null;
494
+ }
495
+ var COLOR_KEYWORDS = /* @__PURE__ */ new Set([
496
+ "inherit",
497
+ "currentcolor",
498
+ "transparent"
499
+ ]);
500
+ /**
501
+ * Declarations for a theme colour (#228), as Tailwind v4 emits them: `var(--color-<key>)` so runtime theme
502
+ * overrides apply; with an opacity modifier, a literal srgb color-mix fallback plus an oklab color-mix of the var.
503
+ */
504
+ function themeColorDecls(prop, value, extra) {
505
+ const key = String(extra.realThemeValue);
506
+ const ref = COLOR_KEYWORDS.has(value.toLowerCase()) || value.startsWith("var(") || !/^[\w-]+$/.test(key) ? value : `var(--color-${key})`;
507
+ if (!extra.opacity) return [decl(prop, ref)];
508
+ const alpha = normalizeAlpha(String(extra.opacity));
509
+ if (!alpha) return [];
510
+ const supports = (amount) => atRule("supports", "(color:color-mix(in lab, red, red))", [decl(prop, `color-mix(in oklab, ${ref} ${amount}, transparent)`)]);
511
+ if (alpha.isVar) return [decl(prop, value), supports(alpha.amount)];
512
+ return [decl(prop, `color-mix(in srgb, ${value} ${alpha.amount}, transparent)`), supports(alpha.amount)];
513
+ }
514
+ /**
515
+ * Opacity modifier → color-mix amount, as Tailwind v4 does: `50` → `50%`, `[37%]` → `37%`, `[0.5]` / `[.8]` → `50%` /
516
+ * `80%` (a bracketed number ≤ 1 is a fraction), `[var(--a)]` / `(--a)` → `var(--a)`.
517
+ */
518
+ function normalizeAlpha(raw) {
519
+ const v = raw.trim();
520
+ const cp = /^\((--[\w-]+)\)$/.exec(v) ?? /^\[var\((--[\w-]+)\)\]$/.exec(v);
521
+ if (cp) return {
522
+ amount: `var(${cp[1]})`,
523
+ isVar: true
524
+ };
525
+ const m = /^(\[)?(\d+(?:\.\d+)?|\.\d+)(%)?(\])?$/.exec(v);
526
+ if (!m || !!m[1] !== !!m[4] || m[3] && !m[1]) return null;
527
+ const n = Number(m[2]);
528
+ return {
529
+ amount: `${+(m[3] ? n : m[1] && n <= 1 ? n * 100 : n).toFixed(4)}%`,
530
+ isVar: false
531
+ };
532
+ }
533
+ var MIX_SUPPORTS = "(color:color-mix(in lab, red, red))";
534
+ var COLOR_PROP = /(^|-)color$|^(fill|stroke)$|^--baro-gradient-(from|via|to)$/;
535
+ /**
536
+ * #393: an arbitrary or custom-property colour with an opacity modifier, as Tailwind 4.3.3 emits it: a literal
537
+ * colour with a literal alpha mixes directly (`color-mix(in oklab, #f00 50%, transparent)`); a var colour or a var
538
+ * alpha keeps the plain colour and mixes only under `@supports`. Returns null for an alpha it can't express.
539
+ */
540
+ function colorAlphaDecls(prop, color, opacity) {
541
+ const alpha = normalizeAlpha(opacity);
542
+ if (!alpha) return null;
543
+ const mix = `color-mix(in oklab, ${color} ${alpha.amount}, transparent)`;
544
+ if (alpha.isVar || color.startsWith("var(")) return [decl(prop, color), atRule("supports", MIX_SUPPORTS, [decl(prop, mix)])];
545
+ return [decl(prop, mix)];
546
+ }
547
+ /**
548
+ * #393: applies an opacity modifier to every declaration of `nodes` whose value is one of `colors` (the colour an
549
+ * arbitrary / custom-property utility emitted without the modifier). Returns null when none matched or the alpha
550
+ * is invalid, so the caller emits nothing rather than dropping the modifier or writing a malformed value.
551
+ */
552
+ function applyColorAlpha(nodes, colors, opacity) {
553
+ let matched = false;
554
+ let invalid = false;
555
+ const walk = (list) => list.flatMap((n) => {
556
+ if (n.type === "decl" && typeof n.value === "string" && colors.includes(n.value)) {
557
+ matched = true;
558
+ const out = COLOR_PROP.test(n.prop) ? colorAlphaDecls(n.prop, n.value, opacity) : null;
559
+ if (!out) invalid = true;
560
+ return out ?? [];
561
+ }
562
+ if (n.type === "at-rule" || n.type === "rule" || n.type === "style-rule" || n.type === "at-root") return [{
563
+ ...n,
564
+ nodes: walk(n.nodes)
565
+ }];
566
+ if (n.type === "wrap") return [{
567
+ ...n,
568
+ items: walk(n.items)
569
+ }];
570
+ return [n];
571
+ });
572
+ const out = walk(nodes);
573
+ return matched && !invalid ? out : null;
574
+ }
575
+ //#endregion
576
+ //#region src/core/registry.ts
577
+ /** #393: a handler result meaning "this class is invalid": the engine stops trying other registrations. */
578
+ var REJECT_CLASS = Object.freeze([]);
579
+ var utilityRegistry = [];
580
+ function registerUtility(util, ctx) {
581
+ const state = ctx && getContextState(ctx);
582
+ if (ctx && !state) throw new Error("Utility registration requires a context from createContext");
583
+ (state?.utilities || utilityRegistry).push(util);
584
+ if (ctx) clearContextCaches(ctx);
585
+ else {
586
+ parseResultCache.clear();
587
+ utilityCache.clear();
588
+ }
589
+ }
590
+ function getUtility(ctx) {
591
+ return ctx && getContextState(ctx)?.utilities || utilityRegistry;
592
+ }
593
+ var modifierRegistry = [];
594
+ /**
595
+ * staticModifier: A helper that registers a modifier name and an array of CSS selectors directly to the registry
596
+ *
597
+ * @example
598
+ * ```
599
+ * staticModifier('disabled', ['&:disabled'], { source: 'pseudo' });
600
+ * ```
601
+ *
602
+ * @param name The name of the modifier
603
+ * @param selectors The selectors of the modifier
604
+ * @param options The options of the modifier
605
+ *
606
+ * @returns {void}
607
+ */
608
+ function staticModifier(name, selectors, options = {}, ctx) {
609
+ registerModifier({
610
+ name,
611
+ match: (mod) => mod === name,
612
+ modifySelector: ({ ..._rest }) => {
613
+ return selectors.map((sel) => ({
614
+ selector: sel,
615
+ source: options.source
616
+ }));
617
+ },
618
+ ...options
619
+ }, ctx);
620
+ }
621
+ function functionalModifier(match, modifySelector, wrap, options = {}, ctx) {
622
+ registerModifier({
623
+ match,
624
+ modifySelector,
625
+ wrap,
626
+ ...options
627
+ }, ctx);
628
+ }
629
+ function registerModifier(modifier, ctx) {
630
+ const state = ctx && getContextState(ctx);
631
+ if (ctx && !state) throw new Error("Modifier registration requires a context from createContext");
632
+ (state?.modifiers || modifierRegistry).push(modifier);
633
+ if (ctx) clearContextCaches(ctx);
634
+ }
635
+ function getModifier(ctx) {
636
+ return ctx && getContextState(ctx)?.modifiers || modifierRegistry;
637
+ }
638
+ var ESCAPE_REGEX = /[^A-Za-z0-9_-]/gu;
639
+ var UNSAFE_RAW = /^[\s\p{C}\p{Z}]$/u;
640
+ function escapeClassName(className) {
641
+ if (className === "-") return "\\-";
642
+ const lead = /^-?[0-9]/.exec(className);
643
+ if (lead) {
644
+ const i = lead[0].length - 1;
645
+ return className.slice(0, i) + "\\" + className.charCodeAt(i).toString(16) + " " + escapeRest(className.slice(i + 1));
646
+ }
647
+ return escapeRest(className);
648
+ }
649
+ function escapeRest(className) {
650
+ return className.replace(ESCAPE_REGEX, (c) => {
651
+ if (c === " ") return "\\x20 ";
652
+ if (c === ".") return "\\.";
653
+ if (c === "/") return "\\/";
654
+ if (c === ":") return "\\:";
655
+ if (c === "[") return "\\[";
656
+ if (c === "]") return "\\]";
657
+ if (c === "(") return "\\(";
658
+ if (c === ")") return "\\)";
659
+ if (c === "%") return "\\%";
660
+ if (c === "#") return "\\#";
661
+ if (c === ",") return "\\,";
662
+ if (c === "=") return "\\=";
663
+ if (c === "&") return "\\&";
664
+ if (c === "~") return "\\~";
665
+ if (c === "*") return "\\*";
666
+ if (c === "$") return "\\$";
667
+ if (c === "^") return "\\^";
668
+ if (c === "+") return "\\+";
669
+ if (c === "?") return "\\?";
670
+ if (c === "!") return "\\!";
671
+ if (c === "@") return "\\@";
672
+ if (c === "'") return "\\'";
673
+ if (c === "\"") return "\\\"";
674
+ if (c === "`") return "\\`";
675
+ if (c === ";") return "\\;";
676
+ if (c === "<") return "\\<";
677
+ if (c === ">") return "\\>";
678
+ if (c === "{") return "\\{";
679
+ if (c === "}") return "\\}";
680
+ if (c === "|") return "\\|";
681
+ if (c === "\\") return "\\\\";
682
+ if (UNSAFE_RAW.test(c)) return "\\" + c.codePointAt(0).toString(16) + " ";
683
+ return "\\" + c;
684
+ });
685
+ }
686
+ /**
687
+ * staticUtility: A helper that registers a utility name and an array of CSS declaration pairs directly to the registry
688
+ *
689
+ * @example
690
+ * ```
691
+ * staticUtility('block', [['display', 'block']]);
692
+ * staticUtility('hidden', [['display', 'none']]);
693
+ * staticUtility('space-x-px', [
694
+ * [
695
+ * '& > :not([hidden]) ~ :not([hidden])', // selector
696
+ * [
697
+ * ['margin-inline-start', '1px'], // [prop, value]
698
+ * ['margin-inline-end', '1px'], // [prop, value]
699
+ * ],
700
+ * ],
701
+ * ]);
702
+ * ```
703
+ *
704
+ * @param name The name of the utility
705
+ * @param decls The declarations of the utility
706
+ * @param opts The options of the utility
707
+ *
708
+ * @returns {void}
709
+ */
710
+ function staticUtility(name, decls, opts, ctx) {
711
+ registerUtility({
712
+ name,
713
+ match: (className) => {
714
+ return className === name;
715
+ },
716
+ handler: (value) => {
717
+ return decls.flatMap((params) => {
718
+ if (params.type) return [params];
719
+ if (typeof params === "function") return [params(value)];
720
+ const [a, b] = params;
721
+ if (typeof b === "string") return [decl(a, b)];
722
+ else if (Array.isArray(b)) return [rule(a, b.map(([prop, value]) => decl(prop, value)))];
723
+ return [];
724
+ });
725
+ },
726
+ description: opts?.description,
727
+ category: opts?.category,
728
+ priority: opts?.priority
729
+ }, ctx);
730
+ }
731
+ /**
732
+ * functionalUtility: A helper that registers dynamic utilities (theme, arbitrary, custom, negative, fraction, etc.) directly
733
+ *
734
+ * Example:
735
+ * functionalUtility({
736
+ * name: 'z',
737
+ * supportsNegative: true,
738
+ * themeKeys: ['--z-index'],
739
+ * handleBareValue: ({ value }) => isPositiveInteger(value) ? value : null,
740
+ * handle: (value) => [decl('z-index', value)],
741
+ * description: 'z-index utility',
742
+ * category: 'layout',
743
+ * });
744
+ */
745
+ /**
746
+ * #300: a theme key that no built-in utility names (`theme.extend.borderRadius.card`) still resolves, as in
747
+ * Tailwind 4 where `--radius-card` gives `rounded-card`. Only word keys that start with a letter (numbers stay
748
+ * bare values), never `DEFAULT`; unknown keys return null so the utility emits nothing (#213).
749
+ */
750
+ function themeKeyEntry(ctx, namespace, key) {
751
+ if (key === "DEFAULT" || !/^[a-zA-Z][\w-]*$/.test(key) || typeof ctx?.theme !== "function") return void 0;
752
+ const table = ctx.theme(namespace);
753
+ if (!table || typeof table !== "object" || !Object.prototype.hasOwnProperty.call(table, key)) return void 0;
754
+ return table[key] ?? void 0;
755
+ }
756
+ /** #300: the literal value of `theme.<namespace>.<key>` when it is a string, else null. */
757
+ function themeKeyValue(ctx, namespace, key) {
758
+ const v = themeKeyEntry(ctx, namespace, key);
759
+ return typeof v === "string" ? v : null;
760
+ }
761
+ /** #300: `var(--<varPrefix>-<key>)` when `theme.<namespace>.<key>` exists (the :root var BaroCSS emits for it), else null. */
762
+ function themeKeyVar(ctx, namespace, key, varPrefix) {
763
+ return themeKeyEntry(ctx, namespace, key) === void 0 ? null : `var(--${varPrefix}-${key})`;
764
+ }
765
+ /** #261: `var(--spacing-<key>)` for a named (non-numeric) `theme.spacing` key, else null. */
766
+ function spacingKeyValue(ctx, key, negative) {
767
+ if (key === "px" || !/^[a-zA-Z][\w-]*$/.test(key) || ctx.theme("spacing", key) == null) return null;
768
+ const ref = `var(--spacing-${key})`;
769
+ return negative ? `calc(${ref} * -1)` : ref;
770
+ }
771
+ function functionalUtility(opts, ctx) {
772
+ registerUtility({
773
+ name: opts.name,
774
+ match: (className) => className.startsWith(opts.name + "-"),
775
+ handler: (value, ctx, token, _options) => {
776
+ let finalValue = value;
777
+ const parsedUtility = token;
778
+ const extra = { opacity: token.opacity };
779
+ if (opts.supportsOpacity && !token.arbitrary && !token.customProperty && value.includes("/")) {
780
+ const list = value.split("/");
781
+ if (list.length >= 2) {
782
+ extra.opacity = list.pop();
783
+ finalValue = list.join("/");
784
+ }
785
+ }
786
+ const splitModifier = !token.arbitrary && !token.customProperty && value.includes("/");
787
+ if (opts.supportsOpacity && (extra.opacity || splitModifier) && !normalizeAlpha(String(extra.opacity ?? ""))) {
788
+ const v = parsedUtility.arbitrary ? finalValue.replace(/_/g, " ") : finalValue;
789
+ return (parsedUtility.customProperty ? !/^[\w-]+:/.test(v) || v.startsWith("color:") : parsedUtility.arbitrary ? !!parseColor(v) || /^var\(--/.test(v) || v.startsWith("color:") : false) ? REJECT_CLASS : [];
790
+ }
791
+ const direct = (x) => {
792
+ if (opts.supportsArbitrary && parsedUtility.arbitrary) {
793
+ const processedValue = normalizeMathSpacing(expandThemeFunctions(finalValue.replace(/_/g, " ")));
794
+ if (opts.handle) {
795
+ const result = opts.handle(processedValue, ctx, token, x);
796
+ if (result) return result;
797
+ }
798
+ if (opts.prop) return [decl(opts.prop, processedValue)];
799
+ return [];
800
+ }
801
+ if (opts.supportsCustomProperty && parsedUtility.customProperty) {
802
+ if (opts.handleCustomProperty) return opts.handleCustomProperty(finalValue, ctx, token, x) ?? null;
803
+ const customValue = `var(${finalValue})`;
804
+ if (opts.handle) {
805
+ const result = opts.handle(customValue, ctx, token, x);
806
+ if (result) return result;
807
+ }
808
+ if (opts.prop) return [decl(opts.prop, customValue)];
809
+ return [];
810
+ }
811
+ return null;
812
+ };
813
+ if (opts.supportsArbitrary && parsedUtility.arbitrary || opts.supportsCustomProperty && parsedUtility.customProperty) {
814
+ const result = direct(extra);
815
+ if (opts.supportsOpacity && !opts.ownsOpacity && extra.opacity && result?.length) {
816
+ const raw = parsedUtility.arbitrary ? normalizeMathSpacing(expandThemeFunctions(finalValue.replace(/_/g, " "))) : `var(${finalValue})`;
817
+ const hint = parsedUtility.arbitrary ? /^color:(.+)$/.exec(raw)?.[1] : /^color:(--.+)$/.exec(finalValue)?.[1];
818
+ return applyColorAlpha(result, [raw, ...hint ? [hint, `var(${hint})`] : []], String(extra.opacity)) ?? [];
819
+ }
820
+ return result;
821
+ }
822
+ let themeValue;
823
+ if (opts.themeKey && ctx.theme) themeValue = themeScalar(ctx.theme(opts.themeKey, finalValue));
824
+ let namespace = themeValue !== void 0 ? opts.themeKey : void 0;
825
+ if (!themeValue && opts.themeKeys && ctx.theme) for (const key of opts.themeKeys) {
826
+ themeValue = themeScalar(ctx.theme(key, finalValue));
827
+ if (themeValue !== void 0) {
828
+ namespace = key;
829
+ break;
830
+ }
831
+ }
832
+ if (themeValue !== void 0) {
833
+ extra.themeNamespace = namespace;
834
+ extra.themeKey = finalValue;
835
+ if (namespace === "colors" || !(opts.themeKeys ?? [opts.themeKey]).includes("colors")) extra.realThemeValue = finalValue;
836
+ finalValue = themeValue;
837
+ if (opts.prop) return [decl(opts.prop, finalValue)];
838
+ if (opts.handle) {
839
+ const result = opts.handle(finalValue, ctx, token, extra);
840
+ if (result) return result;
517
841
  }
518
842
  return [];
519
843
  }
@@ -911,6 +1235,46 @@ function isBalancedPrelude(text) {
911
1235
  return stack.length === 0 && !quote;
912
1236
  }
913
1237
  /**
1238
+ * #392: true when every top-level comma part of an emitted selector names `escapedClass` (a class selector
1239
+ * already escaped with escapeClassName, including its leading dot) as a whole class token, or, when
1240
+ * `allowNesting` is set, uses the nesting selector `&`. Escapes, quoted strings and bracket groups are skipped
1241
+ * when splitting. Used as a defence-in-depth serializer check: a rule scoped to no generating class is dropped.
1242
+ */
1243
+ function isScopedSelector(selector, escapedClass, allowNesting = false) {
1244
+ const parts = [];
1245
+ let depth = 0;
1246
+ let quote = "";
1247
+ let start = 0;
1248
+ for (let i = 0; i < selector.length; i++) {
1249
+ const c = selector[i];
1250
+ if (c === "\\") {
1251
+ i++;
1252
+ continue;
1253
+ }
1254
+ if (quote) {
1255
+ if (c === quote) quote = "";
1256
+ continue;
1257
+ }
1258
+ if (c === "\"" || c === "'") quote = c;
1259
+ else if (c === "(" || c === "[") depth++;
1260
+ else if (c === ")" || c === "]") depth--;
1261
+ else if (c === "," && depth === 0) {
1262
+ parts.push(selector.slice(start, i));
1263
+ start = i + 1;
1264
+ }
1265
+ }
1266
+ parts.push(selector.slice(start));
1267
+ return parts.every((part) => {
1268
+ if (allowNesting && part.includes("&")) return true;
1269
+ for (let at = part.indexOf(escapedClass); at !== -1; at = part.indexOf(escapedClass, at + 1)) {
1270
+ if (at > 0 && part[at - 1] === "\\") continue;
1271
+ const next = part[at + escapedClass.length];
1272
+ if (escapedClass.endsWith(" ") || next === void 0 || !/[\w\-\\\u0080-\uffff]/.test(next)) return true;
1273
+ }
1274
+ return false;
1275
+ });
1276
+ }
1277
+ /**
914
1278
  * #323: true when emitted text contains a markup end-tag opener (less-than then slash). Generated CSS can be
915
1279
  * placed inside an HTML style element, where that sequence could end the element early. CSS escapes in the
916
1280
  * output never form it, and a lone less-than (range media queries) stays allowed.
@@ -1002,6 +1366,13 @@ function parseModifier(value) {
1002
1366
  function nameSort(a, b) {
1003
1367
  return b.name.length - a.name.length;
1004
1368
  }
1369
+ /** #393: index of the `close` that balances the value opened just before `s` (depth starts at 1), or -1. */
1370
+ function matchingClose(s, open, close) {
1371
+ let depth = 1;
1372
+ for (let i = 0; i < s.length; i++) if (s[i] === open) depth++;
1373
+ else if (s[i] === close && --depth === 0) return i;
1374
+ return -1;
1375
+ }
1005
1376
  /**
1006
1377
  * Parse utility token
1007
1378
  */
@@ -1030,15 +1401,27 @@ function parseUtility(value, ctx) {
1030
1401
  if (value.startsWith("-")) negative = true;
1031
1402
  if (value.includes("-[")) {
1032
1403
  [prefix, utilityValue] = value.split("-[");
1033
- const closeIdx = utilityValue.lastIndexOf("]");
1404
+ const closeIdx = matchingClose(utilityValue, "[", "]");
1034
1405
  if (closeIdx !== -1 && closeIdx < utilityValue.length - 1 && utilityValue[closeIdx + 1] === "/") {
1035
1406
  opacity = utilityValue.slice(closeIdx + 2);
1407
+ if (!opacity) return {
1408
+ prefix: "",
1409
+ value: ""
1410
+ };
1036
1411
  utilityValue = utilityValue.slice(0, closeIdx);
1037
1412
  } else utilityValue = utilityValue.replace(/]$/, "");
1038
1413
  arbitrary = true;
1039
1414
  } else if (value.includes("-(")) {
1040
1415
  [prefix, utilityValue] = value.split("-(");
1041
- utilityValue = utilityValue.replace(/\)$/, "");
1416
+ const closeIdx = matchingClose(utilityValue, "(", ")");
1417
+ if (closeIdx !== -1 && closeIdx < utilityValue.length - 1 && utilityValue[closeIdx + 1] === "/") {
1418
+ opacity = utilityValue.slice(closeIdx + 2);
1419
+ if (!opacity) return {
1420
+ prefix: "",
1421
+ value: ""
1422
+ };
1423
+ utilityValue = utilityValue.slice(0, closeIdx);
1424
+ } else utilityValue = utilityValue.replace(/\)$/, "");
1042
1425
  customProperty = true;
1043
1426
  } else {
1044
1427
  const sortedUtilities = [...getUtility(ctx)].sort(nameSort);
@@ -1090,6 +1473,13 @@ var uniqueDescriptors = (node) => {
1090
1473
  const seen = /* @__PURE__ */ new Set();
1091
1474
  return node.nodes.filter((c) => c.type !== "decl" || !seen.has(c.prop) && !!seen.add(c.prop));
1092
1475
  };
1476
+ var NO_IMPORTANT_AT = /* @__PURE__ */ new Set([
1477
+ "property",
1478
+ "font-face",
1479
+ "keyframes",
1480
+ "-webkit-keyframes",
1481
+ "counter-style"
1482
+ ]);
1093
1483
  var isSafeDecl = (prop, value) => isStructureSafeValue(String(prop)) && isStructureSafeValue(String(value ?? "")) && !hasHtmlEndTagOpener(String(prop)) && !hasHtmlEndTagOpener(String(value ?? ""));
1094
1484
  var importantPrefix = "!important";
1095
1485
  /**
@@ -1104,6 +1494,12 @@ function astToCss(ast, baseSelector, opts, _indent = "") {
1104
1494
  const indent = _indent;
1105
1495
  const nextIndent = _indent + " ";
1106
1496
  const importantString = opts?.important ?? false ? ` ${importantPrefix}` : "";
1497
+ const nestedOpts = opts ? {
1498
+ ...opts,
1499
+ nested: true
1500
+ } : opts;
1501
+ const scopeClass = opts?.scope ? "." + escapeClassName(opts.scope) : "";
1502
+ const inScope = (sel) => !scopeClass || isScopedSelector(sel, scopeClass, !!opts?.nested);
1107
1503
  if (!ast || ast.length === 0) {
1108
1504
  debugWarn("[astToCss] Empty AST received:", {
1109
1505
  ast,
@@ -1146,18 +1542,23 @@ function astToCss(ast, baseSelector, opts, _indent = "") {
1146
1542
  else return escBase + (sel.startsWith(".") ? "" : " ") + sel;
1147
1543
  }).join(", ");
1148
1544
  }
1149
- if (!isSafePrelude(selector)) return "";
1150
- if (minify) return `${indent}${selector}{${astToCss(node.nodes, baseSelector, opts, nextIndent)}}`;
1151
- else return `${indent}${selector} {\n${astToCss(node.nodes, baseSelector, opts, nextIndent)}${indent}}`;
1545
+ if (!isSafePrelude(selector) || !inScope(selector)) return "";
1546
+ if (minify) return `${indent}${selector}{${astToCss(node.nodes, baseSelector, nestedOpts, nextIndent)}}`;
1547
+ else return `${indent}${selector} {\n${astToCss(node.nodes, baseSelector, nestedOpts, nextIndent)}${indent}}`;
1152
1548
  }
1153
1549
  case "style-rule":
1154
- if (!isSafePrelude(node.selector)) return "";
1155
- if (minify) return `${indent}${node.selector} {${astToCss(node.nodes, baseSelector, opts, nextIndent)}}`;
1156
- else return `${indent}${node.selector} {\n${astToCss(node.nodes, baseSelector, opts, nextIndent)}${indent}}`;
1157
- case "at-rule":
1550
+ if (!isSafePrelude(node.selector) || !inScope(node.selector)) return "";
1551
+ if (minify) return `${indent}${node.selector} {${astToCss(node.nodes, baseSelector, nestedOpts, nextIndent)}}`;
1552
+ else return `${indent}${node.selector} {\n${astToCss(node.nodes, baseSelector, nestedOpts, nextIndent)}${indent}}`;
1553
+ case "at-rule": {
1158
1554
  if (!isSafePrelude(node.name) || !isSafePrelude(node.params)) return "";
1159
- if (minify) return `${indent}@${node.name} ${node.params}{${astToCss(node.nodes, baseSelector, opts, nextIndent)}}`;
1160
- else return `${indent}@${node.name} ${node.params} {\n${astToCss(node.nodes, baseSelector, opts, nextIndent)}${indent}}`;
1555
+ const atOpts = opts?.important && NO_IMPORTANT_AT.has(node.name) ? {
1556
+ ...opts,
1557
+ important: false
1558
+ } : opts;
1559
+ if (minify) return `${indent}@${node.name} ${node.params}{${astToCss(node.nodes, baseSelector, atOpts, nextIndent)}}`;
1560
+ else return `${indent}@${node.name} ${node.params} {\n${astToCss(node.nodes, baseSelector, atOpts, nextIndent)}${indent}}`;
1561
+ }
1161
1562
  case "comment": return minify ? "" : `${indent}/* ${node.text} */`;
1162
1563
  case "raw": return `${indent}${node.value}`;
1163
1564
  default:
@@ -1516,6 +1917,552 @@ function applyVarPrefix(ast, ctx) {
1516
1917
  return walk(ast);
1517
1918
  }
1518
1919
  //#endregion
1920
+ //#region src/core/tw-property-order.ts
1921
+ var TW_PROPERTY_ORDER = [
1922
+ "container-type",
1923
+ "pointer-events",
1924
+ "visibility",
1925
+ "position",
1926
+ "inset",
1927
+ "inset-inline",
1928
+ "inset-block",
1929
+ "inset-inline-start",
1930
+ "inset-inline-end",
1931
+ "inset-block-start",
1932
+ "inset-block-end",
1933
+ "top",
1934
+ "right",
1935
+ "bottom",
1936
+ "left",
1937
+ "isolation",
1938
+ "z-index",
1939
+ "order",
1940
+ "grid-column",
1941
+ "grid-column-start",
1942
+ "grid-column-end",
1943
+ "grid-row",
1944
+ "grid-row-start",
1945
+ "grid-row-end",
1946
+ "float",
1947
+ "clear",
1948
+ "--tw-container-component",
1949
+ "margin",
1950
+ "margin-inline",
1951
+ "margin-block",
1952
+ "margin-inline-start",
1953
+ "margin-inline-end",
1954
+ "margin-block-start",
1955
+ "margin-block-end",
1956
+ "margin-top",
1957
+ "margin-right",
1958
+ "margin-bottom",
1959
+ "margin-left",
1960
+ "box-sizing",
1961
+ "display",
1962
+ "field-sizing",
1963
+ "aspect-ratio",
1964
+ "height",
1965
+ "max-height",
1966
+ "min-height",
1967
+ "width",
1968
+ "max-width",
1969
+ "min-width",
1970
+ "flex",
1971
+ "flex-shrink",
1972
+ "flex-grow",
1973
+ "flex-basis",
1974
+ "table-layout",
1975
+ "caption-side",
1976
+ "border-collapse",
1977
+ "border-spacing",
1978
+ "transform-origin",
1979
+ "translate",
1980
+ "--tw-translate-x",
1981
+ "--tw-translate-y",
1982
+ "--tw-translate-z",
1983
+ "scale",
1984
+ "--tw-scale-x",
1985
+ "--tw-scale-y",
1986
+ "--tw-scale-z",
1987
+ "rotate",
1988
+ "--tw-rotate-x",
1989
+ "--tw-rotate-y",
1990
+ "--tw-rotate-z",
1991
+ "--tw-skew-x",
1992
+ "--tw-skew-y",
1993
+ "transform",
1994
+ "zoom",
1995
+ "animation",
1996
+ "cursor",
1997
+ "touch-action",
1998
+ "--tw-pan-x",
1999
+ "--tw-pan-y",
2000
+ "--tw-pinch-zoom",
2001
+ "resize",
2002
+ "scroll-snap-type",
2003
+ "--tw-scroll-snap-strictness",
2004
+ "scroll-snap-align",
2005
+ "scroll-snap-stop",
2006
+ "scroll-margin",
2007
+ "scroll-margin-inline",
2008
+ "scroll-margin-block",
2009
+ "scroll-margin-inline-start",
2010
+ "scroll-margin-inline-end",
2011
+ "scroll-margin-block-start",
2012
+ "scroll-margin-block-end",
2013
+ "scroll-margin-top",
2014
+ "scroll-margin-right",
2015
+ "scroll-margin-bottom",
2016
+ "scroll-margin-left",
2017
+ "scroll-padding",
2018
+ "scroll-padding-inline",
2019
+ "scroll-padding-block",
2020
+ "scroll-padding-inline-start",
2021
+ "scroll-padding-inline-end",
2022
+ "scroll-padding-block-start",
2023
+ "scroll-padding-block-end",
2024
+ "scroll-padding-top",
2025
+ "scroll-padding-right",
2026
+ "scroll-padding-bottom",
2027
+ "scroll-padding-left",
2028
+ "scrollbar-width",
2029
+ "scrollbar-color",
2030
+ "scrollbar-gutter",
2031
+ "list-style-position",
2032
+ "list-style-type",
2033
+ "list-style-image",
2034
+ "appearance",
2035
+ "columns",
2036
+ "break-before",
2037
+ "break-inside",
2038
+ "break-after",
2039
+ "grid-auto-columns",
2040
+ "grid-auto-flow",
2041
+ "grid-auto-rows",
2042
+ "grid-template-columns",
2043
+ "grid-template-rows",
2044
+ "flex-direction",
2045
+ "flex-wrap",
2046
+ "place-content",
2047
+ "place-items",
2048
+ "align-content",
2049
+ "align-items",
2050
+ "justify-content",
2051
+ "justify-items",
2052
+ "gap",
2053
+ "column-gap",
2054
+ "row-gap",
2055
+ "--tw-space-x-reverse",
2056
+ "--tw-space-y-reverse",
2057
+ "divide-x-width",
2058
+ "divide-y-width",
2059
+ "--tw-divide-y-reverse",
2060
+ "divide-style",
2061
+ "divide-color",
2062
+ "place-self",
2063
+ "align-self",
2064
+ "justify-self",
2065
+ "overflow",
2066
+ "overflow-x",
2067
+ "overflow-y",
2068
+ "overscroll-behavior",
2069
+ "overscroll-behavior-x",
2070
+ "overscroll-behavior-y",
2071
+ "scroll-behavior",
2072
+ "border-radius",
2073
+ "border-start-radius",
2074
+ "border-end-radius",
2075
+ "border-top-radius",
2076
+ "border-right-radius",
2077
+ "border-bottom-radius",
2078
+ "border-left-radius",
2079
+ "border-start-start-radius",
2080
+ "border-start-end-radius",
2081
+ "border-end-end-radius",
2082
+ "border-end-start-radius",
2083
+ "border-top-left-radius",
2084
+ "border-top-right-radius",
2085
+ "border-bottom-right-radius",
2086
+ "border-bottom-left-radius",
2087
+ "border-width",
2088
+ "border-inline-width",
2089
+ "border-block-width",
2090
+ "border-inline-start-width",
2091
+ "border-inline-end-width",
2092
+ "border-block-start-width",
2093
+ "border-block-end-width",
2094
+ "border-top-width",
2095
+ "border-right-width",
2096
+ "border-bottom-width",
2097
+ "border-left-width",
2098
+ "border-style",
2099
+ "border-inline-style",
2100
+ "border-block-style",
2101
+ "border-inline-start-style",
2102
+ "border-inline-end-style",
2103
+ "border-block-start-style",
2104
+ "border-block-end-style",
2105
+ "border-top-style",
2106
+ "border-right-style",
2107
+ "border-bottom-style",
2108
+ "border-left-style",
2109
+ "border-color",
2110
+ "border-inline-color",
2111
+ "border-block-color",
2112
+ "border-inline-start-color",
2113
+ "border-inline-end-color",
2114
+ "border-block-start-color",
2115
+ "border-block-end-color",
2116
+ "border-top-color",
2117
+ "border-right-color",
2118
+ "border-bottom-color",
2119
+ "border-left-color",
2120
+ "background-color",
2121
+ "background-image",
2122
+ "--tw-gradient-position",
2123
+ "--tw-gradient-stops",
2124
+ "--tw-gradient-via-stops",
2125
+ "--tw-gradient-from",
2126
+ "--tw-gradient-from-position",
2127
+ "--tw-gradient-via",
2128
+ "--tw-gradient-via-position",
2129
+ "--tw-gradient-to",
2130
+ "--tw-gradient-to-position",
2131
+ "mask-image",
2132
+ "--tw-mask-top",
2133
+ "--tw-mask-top-from-color",
2134
+ "--tw-mask-top-from-position",
2135
+ "--tw-mask-top-to-color",
2136
+ "--tw-mask-top-to-position",
2137
+ "--tw-mask-right",
2138
+ "--tw-mask-right-from-color",
2139
+ "--tw-mask-right-from-position",
2140
+ "--tw-mask-right-to-color",
2141
+ "--tw-mask-right-to-position",
2142
+ "--tw-mask-bottom",
2143
+ "--tw-mask-bottom-from-color",
2144
+ "--tw-mask-bottom-from-position",
2145
+ "--tw-mask-bottom-to-color",
2146
+ "--tw-mask-bottom-to-position",
2147
+ "--tw-mask-left",
2148
+ "--tw-mask-left-from-color",
2149
+ "--tw-mask-left-from-position",
2150
+ "--tw-mask-left-to-color",
2151
+ "--tw-mask-left-to-position",
2152
+ "--tw-mask-linear",
2153
+ "--tw-mask-linear-position",
2154
+ "--tw-mask-linear-from-color",
2155
+ "--tw-mask-linear-from-position",
2156
+ "--tw-mask-linear-to-color",
2157
+ "--tw-mask-linear-to-position",
2158
+ "--tw-mask-radial",
2159
+ "--tw-mask-radial-shape",
2160
+ "--tw-mask-radial-size",
2161
+ "--tw-mask-radial-position",
2162
+ "--tw-mask-radial-from-color",
2163
+ "--tw-mask-radial-from-position",
2164
+ "--tw-mask-radial-to-color",
2165
+ "--tw-mask-radial-to-position",
2166
+ "--tw-mask-conic",
2167
+ "--tw-mask-conic-position",
2168
+ "--tw-mask-conic-from-color",
2169
+ "--tw-mask-conic-from-position",
2170
+ "--tw-mask-conic-to-color",
2171
+ "--tw-mask-conic-to-position",
2172
+ "box-decoration-break",
2173
+ "background-size",
2174
+ "background-attachment",
2175
+ "background-clip",
2176
+ "background-position",
2177
+ "background-repeat",
2178
+ "background-origin",
2179
+ "mask-composite",
2180
+ "mask-mode",
2181
+ "mask-type",
2182
+ "mask-size",
2183
+ "mask-clip",
2184
+ "mask-position",
2185
+ "mask-repeat",
2186
+ "mask-origin",
2187
+ "fill",
2188
+ "stroke",
2189
+ "stroke-width",
2190
+ "object-fit",
2191
+ "object-position",
2192
+ "padding",
2193
+ "padding-inline",
2194
+ "padding-block",
2195
+ "padding-inline-start",
2196
+ "padding-inline-end",
2197
+ "padding-block-start",
2198
+ "padding-block-end",
2199
+ "padding-top",
2200
+ "padding-right",
2201
+ "padding-bottom",
2202
+ "padding-left",
2203
+ "text-align",
2204
+ "text-indent",
2205
+ "vertical-align",
2206
+ "font-family",
2207
+ "font-feature-settings",
2208
+ "font-size",
2209
+ "line-height",
2210
+ "font-weight",
2211
+ "letter-spacing",
2212
+ "text-wrap",
2213
+ "overflow-wrap",
2214
+ "word-break",
2215
+ "text-overflow",
2216
+ "hyphens",
2217
+ "white-space",
2218
+ "tab-size",
2219
+ "color",
2220
+ "text-transform",
2221
+ "font-style",
2222
+ "font-stretch",
2223
+ "font-variant-numeric",
2224
+ "text-decoration-line",
2225
+ "text-decoration-color",
2226
+ "text-decoration-style",
2227
+ "text-decoration-thickness",
2228
+ "text-underline-offset",
2229
+ "-webkit-font-smoothing",
2230
+ "placeholder-color",
2231
+ "caret-color",
2232
+ "accent-color",
2233
+ "color-scheme",
2234
+ "opacity",
2235
+ "background-blend-mode",
2236
+ "mix-blend-mode",
2237
+ "box-shadow",
2238
+ "--tw-shadow",
2239
+ "--tw-shadow-color",
2240
+ "--tw-ring-shadow",
2241
+ "--tw-ring-color",
2242
+ "--tw-inset-shadow",
2243
+ "--tw-inset-shadow-color",
2244
+ "--tw-inset-ring-shadow",
2245
+ "--tw-inset-ring-color",
2246
+ "--tw-ring-offset-width",
2247
+ "--tw-ring-offset-color",
2248
+ "outline",
2249
+ "outline-width",
2250
+ "outline-offset",
2251
+ "outline-color",
2252
+ "--tw-blur",
2253
+ "--tw-brightness",
2254
+ "--tw-contrast",
2255
+ "--tw-drop-shadow",
2256
+ "--tw-grayscale",
2257
+ "--tw-hue-rotate",
2258
+ "--tw-invert",
2259
+ "--tw-saturate",
2260
+ "--tw-sepia",
2261
+ "filter",
2262
+ "--tw-backdrop-blur",
2263
+ "--tw-backdrop-brightness",
2264
+ "--tw-backdrop-contrast",
2265
+ "--tw-backdrop-grayscale",
2266
+ "--tw-backdrop-hue-rotate",
2267
+ "--tw-backdrop-invert",
2268
+ "--tw-backdrop-opacity",
2269
+ "--tw-backdrop-saturate",
2270
+ "--tw-backdrop-sepia",
2271
+ "backdrop-filter",
2272
+ "transition-property",
2273
+ "transition-behavior",
2274
+ "transition-delay",
2275
+ "transition-duration",
2276
+ "transition-timing-function",
2277
+ "will-change",
2278
+ "contain",
2279
+ "content",
2280
+ "forced-color-adjust"
2281
+ ];
2282
+ //#endregion
2283
+ //#region src/core/rule-order.ts
2284
+ /**
2285
+ * Tailwind-compatible cascade order for runtime-inserted rules (#254); shared by @barocss/server (#267).
2286
+ *
2287
+ * The runtime discovers classes in DOM order, so without sorting `lg:px-8`
2288
+ * seen before `sm:px-6` would land earlier and lose at >= 1024px. Each rule
2289
+ * gets a sort key derived from its leading `@media` / `@container` preludes:
2290
+ *
2291
+ * 0 base, negated media (`not-md:` → `@media not (…)`, as Tailwind 4.3.3 orders them, #352),
2292
+ * state media (hover), motion/contrast, unknown
2293
+ * 1 max-* breakpoints (larger width first)
2294
+ * 2 min-* breakpoints (smaller width first)
2295
+ * 3 @max-* container queries (larger width first)
2296
+ * 4 @min-* container queries (smaller width first)
2297
+ * 5 orientation, dark (prefers-color-scheme), print, forced-colors
2298
+ *
2299
+ * Nested at-rules (e.g. `sm:dark:`) contribute one key pair per level, so
2300
+ * `sm:` < `sm:dark:` < `md:`.
2301
+ *
2302
+ * #401: within one variant key, rules follow Tailwind 4's property order (the candidate sort of
2303
+ * Tailwind 4.3.3's `compile()`): compare the sorted TW property indices of each rule's declarations up
2304
+ * to the first difference (a rule that runs out of indices sorts last), then more declarations first,
2305
+ * then the class name (Tailwind's numeric-aware compare). Equal keys keep discovery order.
2306
+ */
2307
+ var LEADING_AT = /^\s*@(media|container)\s+([^{]*)\{/;
2308
+ var LATE_MEDIA = /prefers-color-scheme|\bprint\b|forced-colors|orientation/;
2309
+ var MIN_W = /(?:min-width\s*:\s*|width\s*>=?\s*)([\d.]+)(px|rem|em)?/;
2310
+ var MAX_W = /(?:max-width\s*:\s*|width\s*<=?\s*)([\d.]+)(px|rem|em)?/;
2311
+ /** Separates the variant pairs (whose first slot is >= 0) from the property part of a key. */
2312
+ var PROPERTY_PART = -1;
2313
+ /** A rule that has run out of property indices sorts after every real index (TW: `?? Infinity`). */
2314
+ var NO_MORE = Number.MAX_SAFE_INTEGER;
2315
+ var PROPERTY_INDEX = new Map(TW_PROPERTY_ORDER.map((p, i) => [p, i]));
2316
+ var DECL = /(?:^|[{;])\s*(-{0,2}[a-zA-Z][\w-]*)\s*:[^;{}]*(?=[;}])/g;
2317
+ var AT_PRELUDE = /^\s*@[\w-]+[^{]*\{/;
2318
+ var CLASS = /\.((?:\\.|[\w-])+)/;
2319
+ function toPx(n, unit) {
2320
+ const v = parseFloat(n);
2321
+ return unit === "rem" || unit === "em" ? v * 16 : v;
2322
+ }
2323
+ function preludeKey(kind, prelude) {
2324
+ const container = kind === "container";
2325
+ if (!container && /^\s*not\b/i.test(prelude)) return [0, 0];
2326
+ const min = MIN_W.exec(prelude);
2327
+ if (min) return [container ? 4 : 2, toPx(min[1], min[2])];
2328
+ const max = MAX_W.exec(prelude);
2329
+ if (max) return [container ? 3 : 1, -toPx(max[1], max[2])];
2330
+ if (!container && LATE_MEDIA.test(prelude)) return [5, 0];
2331
+ return [0, 0];
2332
+ }
2333
+ /** The rule text after its leading at-rule preludes, up to its first `{` (the selector). */
2334
+ function ruleSelector(rule) {
2335
+ let rest = rule;
2336
+ let m;
2337
+ while (m = AT_PRELUDE.exec(rest)) rest = rest.slice(m[0].length);
2338
+ const end = rest.indexOf("{");
2339
+ return end === -1 ? "" : rest.slice(0, end);
2340
+ }
2341
+ /**
2342
+ * Tailwind's `--tw-sort` overrides (a utility sorts as one pseudo-property), recognised from BaroCSS's
2343
+ * output for the same utilities: space-x/y, divide-*, placeholder colour, gradient stops, container.
2344
+ * (TW's `size-*` override names no listed property, so Tailwind ignores it, and so does this.)
2345
+ */
2346
+ function sortOverride(selector, props, candidate) {
2347
+ const first = props[0];
2348
+ if (first === "--tw-space-x-reverse") return "row-gap";
2349
+ if (first === "--tw-space-y-reverse") return "column-gap";
2350
+ if (first === "--tw-divide-x-reverse") return "divide-x-width";
2351
+ if (first === "--tw-divide-y-reverse") return "divide-y-width";
2352
+ if (selector.includes(":not(:last-child)")) {
2353
+ if (props.includes("border-color")) return "divide-color";
2354
+ if (props.includes("border-style")) return "divide-style";
2355
+ }
2356
+ if (selector.includes("::placeholder") && props.includes("color")) return "placeholder-color";
2357
+ for (const stop of [
2358
+ "from",
2359
+ "via",
2360
+ "to"
2361
+ ]) if (props.includes(`--tw-gradient-${stop}`)) return `--tw-gradient-${stop}`;
2362
+ if (candidate.slice(candidate.lastIndexOf(":") + 1) === "container") return "--tw-container-component";
2363
+ return null;
2364
+ }
2365
+ /**
2366
+ * Tailwind's per-candidate property sort (#401): the sorted, de-duplicated TW property-order indices of
2367
+ * the rule's declarations (at any depth), and the declaration count. `--baro-*` vars count as `--tw-*`.
2368
+ */
2369
+ /** @internal (#401) */ function rulePropertySort(rule, candidate = ruleCandidate(rule)) {
2370
+ const props = [];
2371
+ for (const d of rule.matchAll(DECL)) props.push(d[1].startsWith("--baro-") ? "--tw-" + d[1].slice(7) : d[1]);
2372
+ const override = sortOverride(ruleSelector(rule), props, candidate);
2373
+ const overrideIndex = override === null ? void 0 : PROPERTY_INDEX.get(override);
2374
+ if (overrideIndex !== void 0) return {
2375
+ order: [overrideIndex],
2376
+ count: props.length + 1
2377
+ };
2378
+ const set = /* @__PURE__ */ new Set();
2379
+ for (const p of props) {
2380
+ const i = PROPERTY_INDEX.get(p);
2381
+ if (i !== void 0) set.add(i);
2382
+ }
2383
+ return {
2384
+ order: Array.from(set).sort((a, b) => a - b),
2385
+ count: props.length
2386
+ };
2387
+ }
2388
+ /** The (unescaped) first class in the rule's selector, e.g. `sm:px-2`. */
2389
+ /** @internal (#401) */ function ruleCandidate(rule) {
2390
+ const c = CLASS.exec(ruleSelector(rule));
2391
+ return c ? c[1].replace(/\\(.)/g, "$1") : "";
2392
+ }
2393
+ /** Tailwind's candidate compare: runs of digits compare by value, other chars by code. */
2394
+ /** @internal (#401) */ function compareCandidates(a, b) {
2395
+ const n = Math.min(a.length, b.length);
2396
+ for (let i = 0; i < n; i++) {
2397
+ let x = a.charCodeAt(i);
2398
+ let y = b.charCodeAt(i);
2399
+ if (x >= 48 && x <= 57 && y >= 48 && y <= 57) {
2400
+ let ae = i + 1;
2401
+ let be = i + 1;
2402
+ for (x = a.charCodeAt(ae); x >= 48 && x <= 57;) x = a.charCodeAt(++ae);
2403
+ for (y = b.charCodeAt(be); y >= 48 && y <= 57;) y = b.charCodeAt(++be);
2404
+ const as = a.slice(i, ae);
2405
+ const bs = b.slice(i, be);
2406
+ const diff = Number(as) - Number(bs);
2407
+ if (diff) return diff;
2408
+ if (as < bs) return -1;
2409
+ if (as > bs) return 1;
2410
+ continue;
2411
+ }
2412
+ if (x !== y) return x - y;
2413
+ }
2414
+ return a.length - b.length;
2415
+ }
2416
+ /** The #254 variant part of the key (leading `@media` / `@container` preludes). */
2417
+ /** @internal (#401) */ function ruleVariantKey(rule) {
2418
+ const key = [];
2419
+ let rest = rule;
2420
+ let m;
2421
+ while (m = LEADING_AT.exec(rest)) {
2422
+ const [g, v] = preludeKey(m[1], m[2]);
2423
+ key.push(g, v);
2424
+ rest = rest.slice(m[0].length);
2425
+ }
2426
+ return key;
2427
+ }
2428
+ /**
2429
+ * Full sort key: the #254 variant pairs, then (#401) Tailwind's property sort and the class name.
2430
+ * `candidate` defaults to the rule's first class.
2431
+ */
2432
+ function ruleSortKey(rule, candidate) {
2433
+ const name = candidate ?? ruleCandidate(rule);
2434
+ const { order, count } = rulePropertySort(rule, name);
2435
+ const key = ruleVariantKey(rule);
2436
+ key.push(PROPERTY_PART, ...order, NO_MORE, -count, name);
2437
+ return key;
2438
+ }
2439
+ function compareKeys(a, b) {
2440
+ const n = Math.min(a.length, b.length);
2441
+ for (let i = 0; i < n; i++) {
2442
+ const x = a[i];
2443
+ const y = b[i];
2444
+ if (x === y) continue;
2445
+ if (typeof x === "string" || typeof y === "string") {
2446
+ const d = compareCandidates(String(x), String(y));
2447
+ if (d) return d;
2448
+ continue;
2449
+ }
2450
+ return x - y;
2451
+ }
2452
+ return a.length - b.length;
2453
+ }
2454
+ /** Index after the last key <= `key` (stable upper bound) in sorted `keys`. */
2455
+ function upperBound(keys, key) {
2456
+ let lo = 0;
2457
+ let hi = keys.length;
2458
+ while (lo < hi) {
2459
+ const mid = lo + hi >> 1;
2460
+ if (compareKeys(keys[mid], key) <= 0) lo = mid + 1;
2461
+ else hi = mid;
2462
+ }
2463
+ return lo;
2464
+ }
2465
+ //#endregion
1519
2466
  //#region src/core/engine.ts
1520
2467
  var failureCache = /* @__PURE__ */ new Set();
1521
2468
  /**
@@ -1714,6 +2661,10 @@ function parseClassToAst(fullClassName, ctx) {
1714
2661
  let ast = [];
1715
2662
  for (const utilReg of utilRegs) {
1716
2663
  ast = utilReg.handler(value, ctx, utility, utilReg) || [];
2664
+ if (ast === REJECT_CLASS) {
2665
+ ast = [];
2666
+ break;
2667
+ }
1717
2668
  if (ast.length > 0) break;
1718
2669
  }
1719
2670
  const wrappers = [];
@@ -1838,7 +2789,7 @@ var CLASS_SEPARATOR = /[ \t\n\f\r]+/;
1838
2789
  function generateCss(classList, ctx, opts) {
1839
2790
  const seen = /* @__PURE__ */ new Set();
1840
2791
  const allAtRootNodes = [];
1841
- const results = classList.split(CLASS_SEPARATOR).filter((cls) => {
2792
+ const generated = classList.split(CLASS_SEPARATOR).filter((cls) => {
1842
2793
  if (!cls) return false;
1843
2794
  if (opts?.dedup) {
1844
2795
  if (seen.has(cls)) return false;
@@ -1847,12 +2798,31 @@ function generateCss(classList, ctx, opts) {
1847
2798
  return true;
1848
2799
  }).map((cls) => {
1849
2800
  try {
1850
- return generateOne(cls);
2801
+ return {
2802
+ cls,
2803
+ css: generateOne(cls)
2804
+ };
1851
2805
  } catch (err) {
1852
2806
  debugWarn("[generateCss] class generation failed:", cls, err);
1853
- return "";
2807
+ return {
2808
+ cls,
2809
+ css: ""
2810
+ };
1854
2811
  }
1855
- }).join(opts?.minify ? "" : "\n");
2812
+ });
2813
+ const slots = generated.flatMap((g, i) => g.css ? [i] : []);
2814
+ const sorted = slots.map((i) => ({
2815
+ i,
2816
+ css: generated[i].css,
2817
+ key: ruleSortKey(generated[i].css, generated[i].cls)
2818
+ })).sort((a, b) => compareKeys(a.key, b.key) || a.i - b.i);
2819
+ slots.forEach((slot, j) => {
2820
+ generated[slot] = {
2821
+ cls: generated[slot].cls,
2822
+ css: sorted[j].css
2823
+ };
2824
+ });
2825
+ const results = generated.map((g) => g.css).join(opts?.minify ? "" : "\n");
1856
2826
  function generateOne(cls) {
1857
2827
  const ast = parseClassToAst(cls, ctx);
1858
2828
  const parsedResult = (getContextState(ctx)?.parseResultCache || parseResultCache).get(cls);
@@ -1863,7 +2833,8 @@ function generateCss(classList, ctx, opts) {
1863
2833
  const hasStyleRule = cleanAst.some((node) => node.type === "style-rule");
1864
2834
  const css = astToCss(cleanAst.filter((node) => node.type !== "at-root"), hasStyleRule ? void 0 : cls, {
1865
2835
  minify: opts?.minify,
1866
- important: parsedResult?.utility?.important ?? false
2836
+ important: parsedResult?.utility?.important ?? false,
2837
+ scope: cls
1867
2838
  });
1868
2839
  const result = css;
1869
2840
  if (!result || result.trim() === "") debugWarn("[generateCss] Empty CSS generated for class:", {
@@ -1921,7 +2892,10 @@ function generateCssRules(classList, ctx, opts) {
1921
2892
  cssList.push(css);
1922
2893
  });
1923
2894
  else {
1924
- const css = astToCss([node], cls, options);
2895
+ const css = astToCss([node], cls, {
2896
+ ...options,
2897
+ scope: cls
2898
+ });
1925
2899
  cssList.push(css);
1926
2900
  }
1927
2901
  const rootCssList = [];
@@ -2997,500 +3971,232 @@ function configGetter(config, ...path) {
2997
3971
  else keys = path;
2998
3972
  return keys.reduce((acc, key) => acc ? acc[key] : void 0, config);
2999
3973
  }
3000
- function hasPreset(themeObj, category, preset) {
3001
- return themeObj[category]?.includes?.(preset);
3002
- }
3003
- function resolveTheme(config) {
3004
- let theme = {};
3005
- if (config.presets) {
3006
- for (const preset of config.presets) if (preset.theme) theme = deepMerge(theme, preset.theme);
3007
- }
3008
- if (config.theme) {
3009
- const { extend, ...overrideTheme } = config.theme;
3010
- theme = deepMerge(theme, overrideTheme);
3011
- if (extend) theme = deepMerge(theme, extend);
3012
- }
3013
- return theme;
3014
- }
3015
- function themeToCssVars(theme) {
3016
- return toCssVarsBlock(themeToCssVarsAll(theme));
3017
- }
3018
- function createContext(configObj) {
3019
- if (configObj.debug !== void 0) setDebug(!!configObj.debug);
3020
- const configWithDefaults = {
3021
- presets: [{ theme: defaultTheme }, ...configObj.presets || []],
3022
- ...configObj
3023
- };
3024
- const themeObj = resolveTheme(configWithDefaults);
3025
- const ctx = {
3026
- hasPreset: (category, preset) => {
3027
- return hasPreset(themeObj, category, preset);
3028
- },
3029
- theme: (...args) => {
3030
- return themeGetter(themeObj, ...args);
3031
- },
3032
- config: (...args) => {
3033
- return configGetter(configWithDefaults, ...args);
3034
- },
3035
- themeToCssVars: () => themeToCssVars(themeObj),
3036
- extendTheme: (category, values) => {
3037
- if (typeof values === "function") {
3038
- const result = values(ctx.theme);
3039
- if (result && typeof result === "object") {
3040
- const existingValues = themeObj[category] || {};
3041
- themeObj[category] = {
3042
- ...existingValues,
3043
- ...result
3044
- };
3045
- }
3046
- } else if (typeof values === "object" && values !== null && !Array.isArray(values)) {
3047
- const existingValues = themeObj[category] || {};
3048
- themeObj[category] = {
3049
- ...existingValues,
3050
- ...values
3051
- };
3052
- }
3053
- clearContextCaches(ctx);
3054
- },
3055
- getPreflightCSS: (level = true) => {
3056
- return getPreflightCSS(level);
3057
- }
3058
- };
3059
- initializeContextState(ctx, getUtility(), getModifier());
3060
- registerCustomUtilities(ctx, configObj.utilities);
3061
- return ctx;
3062
- }
3063
- //#endregion
3064
- //#region src/core/jsonToAst.ts
3065
- /**
3066
- * Converts a single BaroJsonInput object into an AST tree.
3067
- * Bypasses string parsing and directly invokes utility/modifier handlers.
3068
- *
3069
- * @param input BaroJsonInput object
3070
- * @param ctx Context
3071
- * @returns AstNode[]
3072
- */
3073
- function jsonToAst(input, ctx) {
3074
- if ((input.variants || []).some((v) => typeof v === "string" ? !isSafeVariantToken(v) : !isSafeVariantValue(v.name || "") || !isSafeVariantValue(v.value || "") || hasCommentToken(v.name || "") || hasCommentToken(v.value || ""))) return [];
3075
- let utilReg = getUtility(ctx).find((u) => u.name === input.utility.name);
3076
- if (input.utility.value && !input.utility.arbitrary && !input.utility.customProperty) {
3077
- const fullName = `${input.utility.name}-${input.utility.value}`;
3078
- const exactMatch = getUtility(ctx).find((u) => u.name === fullName);
3079
- if (exactMatch) utilReg = exactMatch;
3080
- }
3081
- if (!utilReg) {
3082
- debugWarn(`[jsonToAst] Unknown utility: "${input.utility.name}"`);
3083
- return [];
3084
- }
3085
- const parsedUtility = {
3086
- prefix: input.utility.name,
3087
- value: input.utility.value,
3088
- arbitrary: input.utility.arbitrary,
3089
- negative: input.utility.negative,
3090
- opacity: input.utility.opacity,
3091
- important: input.utility.important,
3092
- customProperty: input.utility.customProperty,
3093
- category: utilReg.category,
3094
- priority: utilReg.priority
3095
- };
3096
- let value = input.utility.value;
3097
- if (input.utility.negative && value) value = "-" + value;
3098
- let ast = utilReg.handler(value || "", ctx, parsedUtility, utilReg) || [];
3099
- if (input.variants && input.variants.length > 0) {
3100
- const wrappers = [];
3101
- const selector = "&";
3102
- for (let i = input.variants.length - 1; i >= 0; i--) {
3103
- const variantInput = input.variants[i];
3104
- const variantName = typeof variantInput === "string" ? variantInput : variantInput.name;
3105
- const variantValue = typeof variantInput === "string" ? void 0 : variantInput.value;
3106
- const variantArbitrary = typeof variantInput === "string" ? false : variantInput.arbitrary;
3107
- const parsedModifier = {
3108
- type: variantName,
3109
- value: variantValue,
3110
- arbitrary: variantArbitrary
3111
- };
3112
- let matchKey = variantName;
3113
- if (variantArbitrary && variantValue) {
3114
- if (variantName) {
3115
- matchKey = `${variantName}-[${variantValue}]`;
3116
- parsedModifier.type = matchKey;
3117
- } else {
3118
- matchKey = `[${variantValue}]`;
3119
- parsedModifier.type = matchKey;
3120
- }
3121
- } else if (variantValue) {
3122
- matchKey = `${variantName}-[${variantValue}]`;
3123
- parsedModifier.type = matchKey;
3124
- }
3125
- const plugin = getModifier(ctx).find((p) => p.match(matchKey, ctx));
3126
- if (!plugin) {
3127
- debugWarn(`[jsonToAst] Unknown variant: "${matchKey}"`);
3128
- continue;
3129
- }
3130
- if (plugin.astHandler) ast = plugin.astHandler(ast, parsedModifier, ctx, [], i);
3131
- if (plugin.modifySelector) {
3132
- const result = plugin.modifySelector({
3133
- selector,
3134
- fullClassName: "JSON_GENERATED",
3135
- mod: parsedModifier,
3136
- context: ctx,
3137
- variantChain: [],
3138
- index: i
3139
- });
3140
- if (result == null) continue;
3141
- if (plugin.wrap && (result === "&" || typeof result === "object" && !Array.isArray(result) && result.selector === "&" || Array.isArray(result) && result.length === 1 && result[0].selector === "&")) {} else if (typeof result === "string" && result.includes("&")) wrappers.push({
3142
- type: "rule",
3143
- selector: result
3144
- });
3145
- else if (typeof result === "object" && !Array.isArray(result) && result.selector) {
3146
- const r = result;
3147
- const wrappingType = r.wrappingType || "rule";
3148
- wrappers.push({
3149
- type: wrappingType,
3150
- selector: r.selector,
3151
- flatten: r.flatten,
3152
- source: r.source
3153
- });
3154
- } else if (Array.isArray(result)) wrappers.push({
3155
- type: "wrap",
3156
- items: result.map((r) => ({
3157
- type: r.wrappingType || "rule",
3158
- selector: r.selector,
3159
- source: r.source,
3160
- nodes: []
3161
- }))
3162
- });
3163
- }
3164
- if (plugin.wrap) wrappers.push({
3165
- type: "wrap",
3166
- items: plugin.wrap(parsedModifier, ctx)
3167
- });
3168
- }
3169
- for (let i = 0; i < wrappers.length; i++) {
3170
- const wrap = wrappers[i];
3171
- if (wrap.type === "wrap") ast = wrap.items.map((item) => item.type === "rule" || item.type === "style-rule" || item.type === "at-rule" || item.type === "at-root" ? {
3172
- ...item,
3173
- nodes: [...item.nodes || [], ...ast]
3174
- } : item);
3175
- else if (wrap.type === "style-rule") ast = [{
3176
- type: "style-rule",
3177
- selector: wrap.selector,
3178
- source: wrap.source,
3179
- nodes: Array.isArray(ast) ? ast : [ast]
3180
- }];
3181
- else if (wrap.type === "at-rule") ast = [{
3182
- type: "at-rule",
3183
- name: wrap.name || "media",
3184
- params: wrap.params,
3185
- source: wrap.source,
3186
- nodes: Array.isArray(ast) ? ast : [ast]
3187
- }];
3188
- else if (wrap.type === "rule") ast = [{
3189
- type: "rule",
3190
- selector: wrap.selector,
3191
- source: wrap.source,
3192
- nodes: Array.isArray(ast) ? ast : [ast]
3193
- }];
3194
- }
3195
- }
3196
- return applyVarPrefix(ast, ctx);
3197
- }
3198
- /**
3199
- * Generates CSS from a list of BaroJsonInput objects.
3200
- *
3201
- * @param inputs Array of BaroJsonInput
3202
- * @param ctx Context
3203
- * @param opts Options (minify, etc.)
3204
- * @returns CSS string
3205
- */
3206
- function generateCssFromJson(inputs, ctx, opts) {
3207
- const allAtRootNodes = [];
3208
- const cssList = [];
3209
- inputs.forEach((input) => {
3210
- const cleanAst = optimizeAst(jsonToAst(input, ctx));
3211
- cleanAst.forEach((node) => {
3212
- if (node.type === "at-root") allAtRootNodes.push(...node.nodes);
3213
- });
3214
- let reconstructedName = input.utility.name;
3215
- if (input.utility.value) reconstructedName += `-${input.utility.value}`;
3216
- if (input.utility.arbitrary) reconstructedName = `${input.utility.name}-[${input.utility.value}]`;
3217
- if (input.variants) reconstructedName = `${input.variants.map((v) => typeof v === "string" ? v : v.name).join(":")}:${reconstructedName}`;
3218
- const css = astToCss(cleanAst, cleanAst.some((node) => node.type === "style-rule") ? void 0 : `.${reconstructedName.replace(/[^a-zA-Z0-9-_]/g, "\\$&")}`, {
3219
- minify: opts?.minify,
3220
- important: input.utility.important ?? false
3221
- });
3222
- if (css) cssList.push(css);
3223
- });
3224
- const rootCss = rootToCss(allAtRootNodes);
3225
- return `${rootCss ? `:root,:host {${rootCss}}` : ""}${cssList.join(opts?.minify ? "" : "\n")}`;
3226
- }
3227
- //#endregion
3228
- //#region src/core/utils.ts
3229
- /**
3230
- * Parses a fraction string (e.g., '1/2') and returns a percentage string (e.g., '50%'), or null if not a valid fraction.
3231
- */
3232
- function parseFraction(input) {
3233
- if (input.includes("/")) {
3234
- const [num, denom] = input.split("/").map(Number);
3235
- if (!isNaN(num) && !isNaN(denom) && denom !== 0) return `${num / denom * 100}%`;
3236
- }
3237
- return null;
3238
- }
3239
- /**
3240
- * Returns the input if it is a valid non-negative integer string, else null.
3241
- *
3242
- * @example
3243
- * parseNumber("10") // "10"
3244
- * parseNumber("-10") // "-10"
3245
- * parseNumber("10.5") // "10.5"
3246
- */
3247
- function parseNumber(input) {
3248
- return /^-?\d+(?:\.\d+)?$/.test(input) ? input : null;
3249
- }
3250
- /**
3251
- * Returns the input if it is a valid length string, else null.
3252
- */
3253
- function parseLength(input) {
3254
- return /^\d+(px|em|rem|vh|vw|vmin|vmax|%|in|cm|mm|pt|pc|ex|ch|fr)$/.test(input) ? input : null;
3255
- }
3256
- /**
3257
- * Unified parser for fraction or number, with options for percent or repeat syntax.
3258
- * - percent: if true, returns percentage for fraction (e.g., '1/2' -> '50%')
3259
- * - repeat: if true, returns repeat() for number (e.g., '3' -> 'repeat(3, minmax(0, 1fr))')
3260
- */
3261
- function parseFractionOrNumber(value, opts = {}) {
3262
- if (/^\d+$/.test(value)) {
3263
- if (opts.repeat) return `repeat(${value}, minmax(0, 1fr))`;
3264
- return value;
3974
+ function hasPreset(themeObj, category, preset) {
3975
+ return themeObj[category]?.includes?.(preset);
3976
+ }
3977
+ function resolveTheme(config) {
3978
+ let theme = {};
3979
+ if (config.presets) {
3980
+ for (const preset of config.presets) if (preset.theme) theme = deepMerge(theme, preset.theme);
3265
3981
  }
3266
- if (value.includes("/")) {
3267
- const [numerator, denominator] = value.split("/").map(Number);
3268
- if (!isNaN(numerator) && !isNaN(denominator) && denominator !== 0) {
3269
- const result = numerator / denominator;
3270
- if (opts.percent) return `${result * 100}%`;
3271
- return result.toString();
3272
- }
3982
+ if (config.theme) {
3983
+ const { extend, ...overrideTheme } = config.theme;
3984
+ theme = deepMerge(theme, overrideTheme);
3985
+ if (extend) theme = deepMerge(theme, extend);
3273
3986
  }
3274
- return null;
3987
+ return theme;
3275
3988
  }
3276
- var CSS_COLOR_NAMES = /* @__PURE__ */ new Set([
3277
- "aliceblue",
3278
- "antiquewhite",
3279
- "aqua",
3280
- "aquamarine",
3281
- "azure",
3282
- "beige",
3283
- "bisque",
3284
- "black",
3285
- "blanchedalmond",
3286
- "blue",
3287
- "blueviolet",
3288
- "brown",
3289
- "burlywood",
3290
- "cadetblue",
3291
- "chartreuse",
3292
- "chocolate",
3293
- "coral",
3294
- "cornflowerblue",
3295
- "cornsilk",
3296
- "crimson",
3297
- "cyan",
3298
- "darkblue",
3299
- "darkcyan",
3300
- "darkgoldenrod",
3301
- "darkgray",
3302
- "darkgreen",
3303
- "darkgrey",
3304
- "darkkhaki",
3305
- "darkmagenta",
3306
- "darkolivegreen",
3307
- "darkorange",
3308
- "darkorchid",
3309
- "darkred",
3310
- "darksalmon",
3311
- "darkseagreen",
3312
- "darkslateblue",
3313
- "darkslategray",
3314
- "darkslategrey",
3315
- "darkturquoise",
3316
- "darkviolet",
3317
- "deeppink",
3318
- "deepskyblue",
3319
- "dimgray",
3320
- "dimgrey",
3321
- "dodgerblue",
3322
- "firebrick",
3323
- "floralwhite",
3324
- "forestgreen",
3325
- "fuchsia",
3326
- "gainsboro",
3327
- "ghostwhite",
3328
- "gold",
3329
- "goldenrod",
3330
- "gray",
3331
- "grey",
3332
- "green",
3333
- "greenyellow",
3334
- "honeydew",
3335
- "hotpink",
3336
- "indianred",
3337
- "indigo",
3338
- "ivory",
3339
- "khaki",
3340
- "lavender",
3341
- "lavenderblush",
3342
- "lawngreen",
3343
- "lemonchiffon",
3344
- "lightblue",
3345
- "lightcoral",
3346
- "lightcyan",
3347
- "lightgoldenrodyellow",
3348
- "lightgray",
3349
- "lightgreen",
3350
- "lightgrey",
3351
- "lightpink",
3352
- "lightsalmon",
3353
- "lightseagreen",
3354
- "lightskyblue",
3355
- "lightslategray",
3356
- "lightslategrey",
3357
- "lightsteelblue",
3358
- "lightyellow",
3359
- "lime",
3360
- "limegreen",
3361
- "linen",
3362
- "magenta",
3363
- "maroon",
3364
- "mediumaquamarine",
3365
- "mediumblue",
3366
- "mediumorchid",
3367
- "mediumpurple",
3368
- "mediumseagreen",
3369
- "mediumslateblue",
3370
- "mediumspringgreen",
3371
- "mediumturquoise",
3372
- "mediumvioletred",
3373
- "midnightblue",
3374
- "mintcream",
3375
- "mistyrose",
3376
- "moccasin",
3377
- "navajowhite",
3378
- "navy",
3379
- "oldlace",
3380
- "olive",
3381
- "olivedrab",
3382
- "orange",
3383
- "orangered",
3384
- "orchid",
3385
- "palegoldenrod",
3386
- "palegreen",
3387
- "paleturquoise",
3388
- "palevioletred",
3389
- "papayawhip",
3390
- "peachpuff",
3391
- "peru",
3392
- "pink",
3393
- "plum",
3394
- "powderblue",
3395
- "purple",
3396
- "red",
3397
- "rosybrown",
3398
- "royalblue",
3399
- "saddlebrown",
3400
- "salmon",
3401
- "sandybrown",
3402
- "seagreen",
3403
- "seashell",
3404
- "sienna",
3405
- "silver",
3406
- "skyblue",
3407
- "slateblue",
3408
- "slategray",
3409
- "slategrey",
3410
- "snow",
3411
- "springgreen",
3412
- "steelblue",
3413
- "tan",
3414
- "teal",
3415
- "thistle",
3416
- "tomato",
3417
- "turquoise",
3418
- "violet",
3419
- "wheat",
3420
- "white",
3421
- "whitesmoke",
3422
- "yellow",
3423
- "yellowgreen"
3424
- ]);
3425
- /**
3426
- * Returns the input if it is a valid color string, else null.
3427
- *
3428
- * #rgb, #rgba, #rrggbb, #rrggbbaa, rgb(r, g, b), rgb(r, g, b, a), hsl(h, s, l), hsl(h, s, l, a), hwb(h, w, b), hwb(h, w, b, a), lab(l, a, b), lab(l, a, b, a), lch(l, c, h), lch(l, c, h, a), oklab(l, a, b), oklab(l, a, b, a), oklch(l, c, h), oklch(l, c, h, a), color-mix(in oklab, var(--color-blue-500) 60%, transparent)
3429
- */
3430
- function parseColor(input) {
3431
- if (CSS_COLOR_NAMES.has(input.toLowerCase())) return input;
3432
- if (input.startsWith("color:var(")) return input.slice(6);
3433
- if (input.startsWith("color:")) return parseColor(input.slice(6));
3434
- if (input.startsWith("#") && input.length === 4) return `#${input.slice(1)}`;
3435
- if (input.startsWith("#") && input.length === 5) return `#${input.slice(1)}`;
3436
- if (input.startsWith("#") && input.length === 7) return `#${input.slice(1)}`;
3437
- if (input.startsWith("#") && input.length === 9) return `#${input.slice(1)}`;
3438
- if (input.startsWith("rgb(")) return input.slice(4, -1);
3439
- if (input.startsWith("rgba(")) return input.slice(5, -1);
3440
- if (input.startsWith("hsl(")) return input.slice(4, -1);
3441
- if (input.startsWith("hsla(")) return input.slice(5, -1);
3442
- if (input.startsWith("hwb(")) return input.slice(4, -1);
3443
- if (input.startsWith("lab(")) return input.slice(4, -1);
3444
- if (input.startsWith("lch(")) return input.slice(4, -1);
3445
- if (input.startsWith("oklab(")) return input.slice(5, -1);
3446
- if (input.startsWith("oklch(")) return input.slice(6, -1);
3447
- if (input.startsWith("color-mix(")) return input.slice(9, -1);
3448
- return null;
3989
+ function themeToCssVars(theme) {
3990
+ return toCssVarsBlock(themeToCssVarsAll(theme));
3449
3991
  }
3450
- var COLOR_KEYWORDS = /* @__PURE__ */ new Set([
3451
- "inherit",
3452
- "currentcolor",
3453
- "transparent"
3454
- ]);
3992
+ function createContext(configObj) {
3993
+ if (configObj.debug !== void 0) setDebug(!!configObj.debug);
3994
+ const configWithDefaults = {
3995
+ presets: [{ theme: defaultTheme }, ...configObj.presets || []],
3996
+ ...configObj
3997
+ };
3998
+ const themeObj = resolveTheme(configWithDefaults);
3999
+ const ctx = {
4000
+ hasPreset: (category, preset) => {
4001
+ return hasPreset(themeObj, category, preset);
4002
+ },
4003
+ theme: (...args) => {
4004
+ return themeGetter(themeObj, ...args);
4005
+ },
4006
+ config: (...args) => {
4007
+ return configGetter(configWithDefaults, ...args);
4008
+ },
4009
+ themeToCssVars: () => themeToCssVars(themeObj),
4010
+ extendTheme: (category, values) => {
4011
+ if (typeof values === "function") {
4012
+ const result = values(ctx.theme);
4013
+ if (result && typeof result === "object") {
4014
+ const existingValues = themeObj[category] || {};
4015
+ themeObj[category] = {
4016
+ ...existingValues,
4017
+ ...result
4018
+ };
4019
+ }
4020
+ } else if (typeof values === "object" && values !== null && !Array.isArray(values)) {
4021
+ const existingValues = themeObj[category] || {};
4022
+ themeObj[category] = {
4023
+ ...existingValues,
4024
+ ...values
4025
+ };
4026
+ }
4027
+ clearContextCaches(ctx);
4028
+ },
4029
+ getPreflightCSS: (level = true) => {
4030
+ return getPreflightCSS(level);
4031
+ }
4032
+ };
4033
+ initializeContextState(ctx, getUtility(), getModifier());
4034
+ registerCustomUtilities(ctx, configObj.utilities);
4035
+ return ctx;
4036
+ }
4037
+ //#endregion
4038
+ //#region src/core/jsonToAst.ts
3455
4039
  /**
3456
- * Declarations for a theme colour (#228), as Tailwind v4 emits them: `var(--color-<key>)` so runtime theme
3457
- * overrides apply; with an opacity modifier, a literal srgb color-mix fallback plus an oklab color-mix of the var.
4040
+ * Converts a single BaroJsonInput object into an AST tree.
4041
+ * Bypasses string parsing and directly invokes utility/modifier handlers.
4042
+ *
4043
+ * @param input BaroJsonInput object
4044
+ * @param ctx Context
4045
+ * @returns AstNode[]
3458
4046
  */
3459
- function themeColorDecls(prop, value, extra) {
3460
- const key = String(extra.realThemeValue);
3461
- const ref = COLOR_KEYWORDS.has(value.toLowerCase()) || value.startsWith("var(") || !/^[\w-]+$/.test(key) ? value : `var(--color-${key})`;
3462
- if (!extra.opacity) return [decl(prop, ref)];
3463
- const alpha = normalizeAlpha(String(extra.opacity));
3464
- const supports = (amount) => atRule("supports", "(color:color-mix(in lab, red, red))", [decl(prop, `color-mix(in oklab, ${ref} ${amount}, transparent)`)]);
3465
- if (alpha.isVar) return [decl(prop, value), supports(alpha.amount)];
3466
- return [decl(prop, `color-mix(in srgb, ${value} ${alpha.amount}, transparent)`), supports(alpha.amount)];
4047
+ function jsonToAst(input, ctx) {
4048
+ if ((input.variants || []).some((v) => typeof v === "string" ? !isSafeVariantToken(v) : !isSafeVariantValue(v.name || "") || !isSafeVariantValue(v.value || "") || hasCommentToken(v.name || "") || hasCommentToken(v.value || ""))) return [];
4049
+ let utilReg = getUtility(ctx).find((u) => u.name === input.utility.name);
4050
+ if (input.utility.value && !input.utility.arbitrary && !input.utility.customProperty) {
4051
+ const fullName = `${input.utility.name}-${input.utility.value}`;
4052
+ const exactMatch = getUtility(ctx).find((u) => u.name === fullName);
4053
+ if (exactMatch) utilReg = exactMatch;
4054
+ }
4055
+ if (!utilReg) {
4056
+ debugWarn(`[jsonToAst] Unknown utility: "${input.utility.name}"`);
4057
+ return [];
4058
+ }
4059
+ const parsedUtility = {
4060
+ prefix: input.utility.name,
4061
+ value: input.utility.value,
4062
+ arbitrary: input.utility.arbitrary,
4063
+ negative: input.utility.negative,
4064
+ opacity: input.utility.opacity,
4065
+ important: input.utility.important,
4066
+ customProperty: input.utility.customProperty,
4067
+ category: utilReg.category,
4068
+ priority: utilReg.priority
4069
+ };
4070
+ let value = input.utility.value;
4071
+ if (input.utility.negative && value) value = "-" + value;
4072
+ let ast = utilReg.handler(value || "", ctx, parsedUtility, utilReg) || [];
4073
+ if (input.variants && input.variants.length > 0) {
4074
+ const wrappers = [];
4075
+ const selector = "&";
4076
+ for (let i = input.variants.length - 1; i >= 0; i--) {
4077
+ const variantInput = input.variants[i];
4078
+ const variantName = typeof variantInput === "string" ? variantInput : variantInput.name;
4079
+ const variantValue = typeof variantInput === "string" ? void 0 : variantInput.value;
4080
+ const variantArbitrary = typeof variantInput === "string" ? false : variantInput.arbitrary;
4081
+ const parsedModifier = {
4082
+ type: variantName,
4083
+ value: variantValue,
4084
+ arbitrary: variantArbitrary
4085
+ };
4086
+ let matchKey = variantName;
4087
+ if (variantArbitrary && variantValue) {
4088
+ if (variantName) {
4089
+ matchKey = `${variantName}-[${variantValue}]`;
4090
+ parsedModifier.type = matchKey;
4091
+ } else {
4092
+ matchKey = `[${variantValue}]`;
4093
+ parsedModifier.type = matchKey;
4094
+ }
4095
+ } else if (variantValue) {
4096
+ matchKey = `${variantName}-[${variantValue}]`;
4097
+ parsedModifier.type = matchKey;
4098
+ }
4099
+ const plugin = getModifier(ctx).find((p) => p.match(matchKey, ctx));
4100
+ if (!plugin) {
4101
+ debugWarn(`[jsonToAst] Unknown variant: "${matchKey}"`);
4102
+ continue;
4103
+ }
4104
+ if (plugin.astHandler) ast = plugin.astHandler(ast, parsedModifier, ctx, [], i);
4105
+ if (plugin.modifySelector) {
4106
+ const result = plugin.modifySelector({
4107
+ selector,
4108
+ fullClassName: "JSON_GENERATED",
4109
+ mod: parsedModifier,
4110
+ context: ctx,
4111
+ variantChain: [],
4112
+ index: i
4113
+ });
4114
+ if (result == null) continue;
4115
+ if (plugin.wrap && (result === "&" || typeof result === "object" && !Array.isArray(result) && result.selector === "&" || Array.isArray(result) && result.length === 1 && result[0].selector === "&")) {} else if (typeof result === "string" && result.includes("&")) wrappers.push({
4116
+ type: "rule",
4117
+ selector: result
4118
+ });
4119
+ else if (typeof result === "object" && !Array.isArray(result) && result.selector) {
4120
+ const r = result;
4121
+ const wrappingType = r.wrappingType || "rule";
4122
+ wrappers.push({
4123
+ type: wrappingType,
4124
+ selector: r.selector,
4125
+ flatten: r.flatten,
4126
+ source: r.source
4127
+ });
4128
+ } else if (Array.isArray(result)) wrappers.push({
4129
+ type: "wrap",
4130
+ items: result.map((r) => ({
4131
+ type: r.wrappingType || "rule",
4132
+ selector: r.selector,
4133
+ source: r.source,
4134
+ nodes: []
4135
+ }))
4136
+ });
4137
+ }
4138
+ if (plugin.wrap) wrappers.push({
4139
+ type: "wrap",
4140
+ items: plugin.wrap(parsedModifier, ctx)
4141
+ });
4142
+ }
4143
+ for (let i = 0; i < wrappers.length; i++) {
4144
+ const wrap = wrappers[i];
4145
+ if (wrap.type === "wrap") ast = wrap.items.map((item) => item.type === "rule" || item.type === "style-rule" || item.type === "at-rule" || item.type === "at-root" ? {
4146
+ ...item,
4147
+ nodes: [...item.nodes || [], ...ast]
4148
+ } : item);
4149
+ else if (wrap.type === "style-rule") ast = [{
4150
+ type: "style-rule",
4151
+ selector: wrap.selector,
4152
+ source: wrap.source,
4153
+ nodes: Array.isArray(ast) ? ast : [ast]
4154
+ }];
4155
+ else if (wrap.type === "at-rule") ast = [{
4156
+ type: "at-rule",
4157
+ name: wrap.name || "media",
4158
+ params: wrap.params,
4159
+ source: wrap.source,
4160
+ nodes: Array.isArray(ast) ? ast : [ast]
4161
+ }];
4162
+ else if (wrap.type === "rule") ast = [{
4163
+ type: "rule",
4164
+ selector: wrap.selector,
4165
+ source: wrap.source,
4166
+ nodes: Array.isArray(ast) ? ast : [ast]
4167
+ }];
4168
+ }
4169
+ }
4170
+ return applyVarPrefix(ast, ctx);
3467
4171
  }
3468
4172
  /**
3469
- * Opacity modifier → color-mix amount, as Tailwind v4 does: `50` → `50%`, `[37%]` → `37%`, `[0.5]` / `[.8]` → `50%` /
3470
- * `80%` (a bracketed number ≤ 1 is a fraction), `[var(--a)]` / `(--a)` → `var(--a)`.
4173
+ * Generates CSS from a list of BaroJsonInput objects.
4174
+ *
4175
+ * @param inputs Array of BaroJsonInput
4176
+ * @param ctx Context
4177
+ * @param opts Options (minify, etc.)
4178
+ * @returns CSS string
3471
4179
  */
3472
- function normalizeAlpha(raw) {
3473
- let v = raw.trim();
3474
- const bracketed = v.startsWith("[") && v.endsWith("]");
3475
- if (bracketed) v = v.slice(1, -1).trim();
3476
- if (v.startsWith("(") && v.endsWith(")")) v = `var(${v.slice(1, -1).trim()})`;
3477
- if (v.startsWith("var(")) return {
3478
- amount: v,
3479
- isVar: true
3480
- };
3481
- if (v.endsWith("%")) return {
3482
- amount: v,
3483
- isVar: false
3484
- };
3485
- const n = Number(v);
3486
- if (v !== "" && Number.isFinite(n)) return {
3487
- amount: `${+(bracketed && n <= 1 ? n * 100 : n).toFixed(4)}%`,
3488
- isVar: false
3489
- };
3490
- return {
3491
- amount: v,
3492
- isVar: false
3493
- };
4180
+ function generateCssFromJson(inputs, ctx, opts) {
4181
+ const allAtRootNodes = [];
4182
+ const cssList = [];
4183
+ inputs.forEach((input) => {
4184
+ const cleanAst = optimizeAst(jsonToAst(input, ctx));
4185
+ cleanAst.forEach((node) => {
4186
+ if (node.type === "at-root") allAtRootNodes.push(...node.nodes);
4187
+ });
4188
+ let reconstructedName = input.utility.name;
4189
+ if (input.utility.value) reconstructedName += `-${input.utility.value}`;
4190
+ if (input.utility.arbitrary) reconstructedName = `${input.utility.name}-[${input.utility.value}]`;
4191
+ if (input.variants) reconstructedName = `${input.variants.map((v) => typeof v === "string" ? v : v.name).join(":")}:${reconstructedName}`;
4192
+ const css = astToCss(cleanAst, cleanAst.some((node) => node.type === "style-rule") ? void 0 : `.${reconstructedName.replace(/[^a-zA-Z0-9-_]/g, "\\$&")}`, {
4193
+ minify: opts?.minify,
4194
+ important: input.utility.important ?? false
4195
+ });
4196
+ if (css) cssList.push(css);
4197
+ });
4198
+ const rootCss = rootToCss(allAtRootNodes);
4199
+ return `${rootCss ? `:root,:host {${rootCss}}` : ""}${cssList.join(opts?.minify ? "" : "\n")}`;
3494
4200
  }
3495
4201
  //#endregion
3496
4202
  //#region src/presets/interactivity.ts
@@ -3504,10 +4210,7 @@ functionalUtility({
3504
4210
  supportsArbitrary: true,
3505
4211
  supportsCustomProperty: true,
3506
4212
  handle: (value, _ctx, _token, extra) => {
3507
- if (extra?.realThemeValue) {
3508
- if (extra.opacity) return [atRule("supports", `(color:color-mix(in lab, red, red))`, [decl("accent-color", `color-mix(in lab, ${value} ${extra.opacity}%, transparent)`)]), decl("accent-color", value)];
3509
- return [decl("accent-color", `var(--color-${extra.realThemeValue})`)];
3510
- }
4213
+ if (extra?.realThemeValue) return themeColorDecls("accent-color", value, extra);
3511
4214
  return [decl("accent-color", value)];
3512
4215
  },
3513
4216
  handleCustomProperty: (value) => [decl("accent-color", `var(${value})`)],
@@ -3526,10 +4229,7 @@ functionalUtility({
3526
4229
  supportsArbitrary: true,
3527
4230
  supportsCustomProperty: true,
3528
4231
  handle: (value, ctx, token, extra) => {
3529
- if (extra?.realThemeValue) {
3530
- if (extra.opacity) return [atRule("supports", `(color:color-mix(in lab, red, red))`, [decl("caret-color", `color-mix(in lab, ${value} ${extra.opacity}%, transparent)`)]), decl("caret-color", value)];
3531
- return [decl("caret-color", `var(--color-${extra.realThemeValue})`)];
3532
- }
4232
+ if (extra?.realThemeValue) return themeColorDecls("caret-color", value, extra);
3533
4233
  return [decl("caret-color", value)];
3534
4234
  },
3535
4235
  handleCustomProperty: (value) => [decl("caret-color", `var(${value})`)],
@@ -3894,22 +4594,11 @@ staticUtility("caption-bottom", [["caption-side", "bottom"]], { category: "table
3894
4594
  //#region src/presets/shadow-color.ts
3895
4595
  /** Opacity modifier to an alpha: `50` → 50%, `[20%]` → 20%, `(--o)` → var(--o); anything else is invalid. */
3896
4596
  function parseAlpha(op) {
3897
- if (!op) return null;
3898
- if (/^\d+(\.\d+)?$/.test(op)) return {
3899
- alpha: `${op}%`,
3900
- isVar: false
3901
- };
3902
- const pct = /^\[(\d+(?:\.\d+)?)%\]$/.exec(op);
3903
- if (pct) return {
3904
- alpha: `${pct[1]}%`,
3905
- isVar: false
3906
- };
3907
- const cp = /^\((--[\w-]+)\)$/.exec(op);
3908
- if (cp) return {
3909
- alpha: `var(${cp[1]})`,
3910
- isVar: true
4597
+ const a = op ? normalizeAlpha(op) : null;
4598
+ return a && {
4599
+ alpha: a.amount,
4600
+ isVar: a.isVar
3911
4601
  };
3912
- return null;
3913
4602
  }
3914
4603
  function splitTop(value, sep) {
3915
4604
  const out = [];
@@ -4418,6 +5107,11 @@ function layerColor(layer, main, opacity, token, realThemeValue) {
4418
5107
  if (main.startsWith("color:")) return shadowColorDecls(layer, `var(${main.slice(6)})`, opacity);
4419
5108
  if (token.arbitrary && parseColor(main)) return shadowColorDecls(layer, main, opacity);
4420
5109
  }
5110
+ function customShadowAlpha(layer, opacity) {
5111
+ if (!opacity) return [];
5112
+ const a = parseAlpha(opacity);
5113
+ return a ? [decl(`--baro-${layer}-alpha`, a.alpha)] : null;
5114
+ }
4421
5115
  for (const layer of ["shadow", "inset-shadow"]) functionalUtility({
4422
5116
  name: layer,
4423
5117
  supportsArbitrary: true,
@@ -4434,11 +5128,17 @@ for (const layer of ["shadow", "inset-shadow"]) functionalUtility({
4434
5128
  if (token.arbitrary) return boxShadowLayer(layer, layer === "inset-shadow" ? insetEach(value) : value, opacity);
4435
5129
  return null;
4436
5130
  },
4437
- handleCustomProperty: (value) => value.startsWith("color:") ? shadowColorDecls(layer, `var(${value.slice(6)})`, void 0) ?? [] : [
4438
- ringShadowProperties(),
4439
- decl(`--baro-${layer}`, layer === "inset-shadow" ? `inset var(${value})` : `var(${value})`),
4440
- decl("box-shadow", SHADOW_COMPOSITE)
4441
- ]
5131
+ ownsOpacity: true,
5132
+ handleCustomProperty: (value, _ctx, _token, extra) => {
5133
+ if (value.startsWith("color:")) return shadowColorDecls(layer, `var(${value.slice(6)})`, extra?.opacity) ?? [];
5134
+ const alpha = customShadowAlpha(layer, extra?.opacity);
5135
+ return alpha ? [
5136
+ ringShadowProperties(),
5137
+ ...alpha,
5138
+ decl(`--baro-${layer}`, layer === "inset-shadow" ? `inset var(${value})` : `var(${value})`),
5139
+ decl("box-shadow", SHADOW_COMPOSITE)
5140
+ ] : [];
5141
+ }
4442
5142
  });
4443
5143
  var textShadowProperties = () => atRoot([property("--baro-text-shadow-color"), property("--baro-text-shadow-alpha", "100%", "<percentage>")]);
4444
5144
  var namedTextShadow = (ctx, name) => {
@@ -4468,7 +5168,19 @@ functionalUtility({
4468
5168
  if (token.arbitrary) return textShadowValue(value, opacity);
4469
5169
  return null;
4470
5170
  },
4471
- handleCustomProperty: (value) => value.startsWith("color:") ? [textShadowProperties(), ...shadowColorDecls("text-shadow", `var(${value.slice(6)})`, void 0) ?? []] : [textShadowProperties(), decl("text-shadow", `var(${value})`)],
5171
+ ownsOpacity: true,
5172
+ handleCustomProperty: (value, _ctx, _token, extra) => {
5173
+ if (value.startsWith("color:")) {
5174
+ const color = shadowColorDecls("text-shadow", `var(${value.slice(6)})`, extra?.opacity);
5175
+ return color ? [textShadowProperties(), ...color] : [];
5176
+ }
5177
+ const alpha = customShadowAlpha("text-shadow", extra?.opacity);
5178
+ return alpha ? [
5179
+ textShadowProperties(),
5180
+ ...alpha,
5181
+ decl("text-shadow", `var(${value})`)
5182
+ ] : [];
5183
+ },
4472
5184
  category: "effects"
4473
5185
  });
4474
5186
  [
@@ -4532,17 +5244,6 @@ functionalUtility({
4532
5244
  ], { category: "effects" });
4533
5245
  });
4534
5246
  staticUtility("ring-inset", [["--baro-ring-inset", "inset"]], { category: "effects" });
4535
- function createRingColorDecls(key, main, opacity, realThemeValue) {
4536
- const colorVar = `var(--color-${realThemeValue})`;
4537
- let colorMix = colorVar;
4538
- let fallback = colorVar;
4539
- if (opacity) {
4540
- colorMix = `color-mix(in oklab, ${colorVar} ${opacity}%, transparent)`;
4541
- if (parseColor(main) && main.startsWith("#")) fallback = `${main}${Math.round(Number(opacity) / 100 * 255).toString(16).padStart(2, "0")}`;
4542
- else fallback = colorMix;
4543
- }
4544
- return [atRule("supports", "(color:color-mix(in lab, red, red))", [decl(key, colorMix)]), decl(key, fallback)];
4545
- }
4546
5247
  functionalUtility({
4547
5248
  name: "ring",
4548
5249
  supportsArbitrary: true,
@@ -4556,28 +5257,9 @@ functionalUtility({
4556
5257
  decl("--baro-ring-shadow", ringShadowValue(value)),
4557
5258
  decl("box-shadow", SHADOW_COMPOSITE)
4558
5259
  ];
4559
- const opacity = extra?.opacity;
4560
- const realThemeValue = extra?.realThemeValue;
4561
- if (realThemeValue) return createRingColorDecls("--baro-ring-color", main, opacity, realThemeValue);
4562
- if (main.startsWith("color:")) {
4563
- const cp = main.replace("color:", "");
4564
- let colorMix = `var(${cp})`;
4565
- let fallback = colorMix;
4566
- if (opacity) {
4567
- colorMix = `color-mix(in oklab, var(${cp}) ${opacity}%, transparent)`;
4568
- fallback = colorMix;
4569
- }
4570
- return [atRule("supports", "(color:color-mix(in lab, red, red))", [decl("--baro-ring-color", colorMix)]), decl("--baro-ring-color", fallback)];
4571
- }
5260
+ if (extra?.realThemeValue) return themeColorDecls("--baro-ring-color", main, extra);
5261
+ if (main.startsWith("color:")) return [decl("--baro-ring-color", `var(${main.slice(6)})`)];
4572
5262
  if (token.arbitrary) {
4573
- let colorMix = main;
4574
- let fallback = main;
4575
- if (opacity) {
4576
- colorMix = `color-mix(in oklab, ${main} ${opacity}%, transparent)`;
4577
- if (parseColor(main) && main.startsWith("#")) fallback = `${main}${Math.round(Number(opacity) / 100 * 255).toString(16).padStart(2, "0")}`;
4578
- else fallback = colorMix;
4579
- return [atRule("supports", "(color:color-mix(in lab, red, red))", [decl("--baro-ring-color", colorMix)]), decl("--baro-ring-color", fallback)];
4580
- }
4581
5263
  if (!parseColor(main) && /^(-?(\d+\.?\d*|\.\d+)(px|rem|em|%|vw|vh|vmin|vmax|ch|ex|pt|cm|mm|in|pc)|0|(length:.+)|calc\(.+\))$/i.test(main)) {
4582
5264
  const width = main.startsWith("length:") ? main.slice(7) : main;
4583
5265
  return [
@@ -4586,7 +5268,7 @@ functionalUtility({
4586
5268
  decl("box-shadow", SHADOW_COMPOSITE)
4587
5269
  ];
4588
5270
  }
4589
- return [parseColor(main) ? decl("--baro-ring-color", main) : decl("box-shadow", main)];
5271
+ return [parseColor(main) || /^var\(--[^)]+\)$/.test(main) ? decl("--baro-ring-color", main) : decl("box-shadow", main)];
4590
5272
  }
4591
5273
  if (main === "inherit" || main === "current" || main === "transparent") return [decl("--baro-ring-color", main === "current" ? "currentColor" : main)];
4592
5274
  return null;
@@ -4604,30 +5286,9 @@ functionalUtility({
4604
5286
  themeKeys: ["colors", "shadows"],
4605
5287
  handle: (value, ctx, token, extra) => {
4606
5288
  const main = value;
4607
- const opacity = extra?.opacity;
4608
- const realThemeValue = extra?.realThemeValue;
4609
- if (realThemeValue) return createRingColorDecls("--baro-inset-ring-color", main, opacity, realThemeValue);
4610
- if (main.startsWith("color:")) {
4611
- const cp = main.replace("color:", "");
4612
- let colorMix = `var(${cp})`;
4613
- let fallback = colorMix;
4614
- if (opacity) {
4615
- colorMix = `color-mix(in oklab, var(${cp}) ${opacity}%, transparent)`;
4616
- fallback = colorMix;
4617
- }
4618
- return [atRule("supports", "(color:color-mix(in lab, red, red))", [decl("--baro-inset-ring-color", colorMix)]), decl("--baro-inset-ring-color", fallback)];
4619
- }
4620
- if (token.arbitrary) {
4621
- let colorMix = main;
4622
- let fallback = main;
4623
- if (opacity) {
4624
- colorMix = `color-mix(in oklab, ${main} ${opacity}%, transparent)`;
4625
- if (parseColor(main) && main.startsWith("#")) fallback = `${main}${Math.round(Number(opacity) / 100 * 255).toString(16).padStart(2, "0")}`;
4626
- else fallback = colorMix;
4627
- return [atRule("supports", "(color:color-mix(in lab, red, red))", [decl("--baro-inset-ring-color", colorMix)]), decl("--baro-inset-ring-color", fallback)];
4628
- }
4629
- return [decl("box-shadow", `inset ${main}`)];
4630
- }
5289
+ if (extra?.realThemeValue) return themeColorDecls("--baro-inset-ring-color", main, extra);
5290
+ if (main.startsWith("color:")) return [decl("--baro-inset-ring-color", `var(${main.slice(6)})`)];
5291
+ if (token.arbitrary) return [parseColor(main) || /^var\(--[^)]+\)$/.test(main) ? decl("--baro-inset-ring-color", main) : decl("box-shadow", `inset ${main}`)];
4631
5292
  if (main === "inherit" || main === "current" || main === "transparent") return [decl("--baro-inset-ring-color", main === "current" ? "currentColor" : main)];
4632
5293
  return null;
4633
5294
  },
@@ -6452,7 +7113,7 @@ functionalUtility({
6452
7113
  supportsOpacity: true,
6453
7114
  handle: (value, _ctx, _token, extra) => {
6454
7115
  if (extra?.realThemeValue) return [rule("&::placeholder", themeColorDecls("color", value, extra))];
6455
- if (parseColor(value)) return placeholderColor(value);
7116
+ if (parseColor(value) || /^var\(--[\w-]+\)$/.test(value)) return placeholderColor(value);
6456
7117
  return null;
6457
7118
  },
6458
7119
  handleCustomProperty: (value) => placeholderColor(`var(${value})`),
@@ -6658,7 +7319,7 @@ var stopsDecls = (stop, color) => {
6658
7319
  if (parseColor(value)) return stopsDecls(stop, value);
6659
7320
  return null;
6660
7321
  },
6661
- handleCustomProperty: (value) => [decl(`--baro-gradient-${stop}`, `var(${value})`)],
7322
+ handleCustomProperty: (value) => value.startsWith("color:") ? stopsDecls(stop, `var(${value.slice(6)})`) : [decl(`--baro-gradient-${stop}`, `var(${value})`)],
6662
7323
  description: `${stop} gradient stop utility (color, percent, custom property, arbitrary supported)`,
6663
7324
  category: "background"
6664
7325
  });
@@ -6712,6 +7373,7 @@ functionalUtility({
6712
7373
  return [decl("background-color", value)];
6713
7374
  }
6714
7375
  if (parseLength(value)) return [decl("background-size", value)];
7376
+ if (/^var\(--[^)]+\)$/.test(value)) return [decl("background-color", value)];
6715
7377
  return null;
6716
7378
  },
6717
7379
  handleCustomProperty: (value) => {
@@ -6839,11 +7501,11 @@ var withBorderStyle = (props, width) => [
6839
7501
  ...propList.map((prop) => [prop.replace("width", "style"), "var(--baro-border-style)"]),
6840
7502
  ...propList.map((prop) => [prop, width])
6841
7503
  ];
6842
- staticUtility(`${name}-0`, styled("0px"));
6843
- staticUtility(`${name}-2`, styled("2px"));
6844
- staticUtility(`${name}-4`, styled("4px"));
6845
- staticUtility(`${name}-8`, styled("8px"));
6846
- staticUtility(`${name}`, styled("1px"));
7504
+ staticUtility(`${name}-0`, styled("0px"), { category: "borders" });
7505
+ staticUtility(`${name}-2`, styled("2px"), { category: "borders" });
7506
+ staticUtility(`${name}-4`, styled("4px"), { category: "borders" });
7507
+ staticUtility(`${name}-8`, styled("8px"), { category: "borders" });
7508
+ staticUtility(`${name}`, styled("1px"), { category: "borders" });
6847
7509
  functionalUtility({
6848
7510
  name,
6849
7511
  themeKeys: ["colors", "borderWidth"],
@@ -7013,7 +7675,7 @@ functionalUtility({
7013
7675
  return null;
7014
7676
  },
7015
7677
  handleCustomProperty: (value) => {
7016
- if (value.startsWith("color:")) return [decl("outline-color", value.replace("color:", ""))];
7678
+ if (value.startsWith("color:")) return [decl("outline-color", `var(${value.slice(6)})`)];
7017
7679
  if (value.startsWith("length:")) return withOutlineStyle(`var(${value.replace("length:", "")})`);
7018
7680
  return [decl("outline-color", `var(${value})`)];
7019
7681
  },
@@ -7045,7 +7707,7 @@ functionalUtility({
7045
7707
  handle: (value, _ctx, token, extra) => {
7046
7708
  if (token.prefix !== "divide") return null;
7047
7709
  if (extra?.realThemeValue) return [rule(":where(& > :not(:last-child))", themeColorDecls("border-color", value, extra))];
7048
- if (parseColor(value)) return divideColor(value);
7710
+ if (parseColor(value) || /^var\(--[\w-]+\)$/.test(value)) return divideColor(value);
7049
7711
  return null;
7050
7712
  },
7051
7713
  handleCustomProperty: (value, _ctx, token) => token.prefix === "divide" ? divideColor(`var(${value})`) : [],
@@ -7464,8 +8126,9 @@ functionalUtility({
7464
8126
  themeKeys: ["colors"],
7465
8127
  supportsArbitrary: true,
7466
8128
  supportsCustomProperty: true,
8129
+ supportsOpacity: true,
7467
8130
  handle: (value, ctx, token, extra) => {
7468
- if (extra?.realThemeValue) return [decl("fill", `var(--color-${extra.realThemeValue})`)];
8131
+ if (extra?.realThemeValue) return themeColorDecls("fill", value, extra);
7469
8132
  return [decl("fill", value)];
7470
8133
  },
7471
8134
  description: "fill utility (static, theme, arbitrary, custom property supported)",
@@ -7481,6 +8144,7 @@ functionalUtility({
7481
8144
  themeKeys: ["colors", "strokeWidth"],
7482
8145
  supportsArbitrary: true,
7483
8146
  supportsCustomProperty: true,
8147
+ supportsOpacity: true,
7484
8148
  handle: (value, ctx, token, extra) => {
7485
8149
  if (parseNumber(value) || extra?.themeNamespace === "strokeWidth") return [decl("stroke-width", value)];
7486
8150
  if (token.arbitrary) {
@@ -7488,7 +8152,7 @@ functionalUtility({
7488
8152
  if (hint) return [decl("stroke-width", hint[2])];
7489
8153
  if (!parseColor(value) && (STROKE_LENGTH.test(value) || /^calc\(/.test(value))) return [decl("stroke-width", value)];
7490
8154
  }
7491
- if (extra?.realThemeValue) return [decl("stroke", `var(--color-${extra.realThemeValue})`)];
8155
+ if (extra?.realThemeValue) return themeColorDecls("stroke", value, extra);
7492
8156
  return [decl("stroke", value)];
7493
8157
  },
7494
8158
  handleCustomProperty: (value) => {
@@ -8497,53 +9161,6 @@ functionalModifier((mod) => /^child-(.+)$/.test(mod), ({ selector, mod }) => {
8497
9161
  };
8498
9162
  }, void 0);
8499
9163
  //#endregion
8500
- //#region src/core/rule-order.ts
8501
- var LEADING_AT = /^\s*@(media|container)\s+([^{]*)\{/;
8502
- var LATE_MEDIA = /prefers-color-scheme|\bprint\b|forced-colors|orientation/;
8503
- var MIN_W = /(?:min-width\s*:\s*|width\s*>=?\s*)([\d.]+)(px|rem|em)?/;
8504
- var MAX_W = /(?:max-width\s*:\s*|width\s*<=?\s*)([\d.]+)(px|rem|em)?/;
8505
- function toPx(n, unit) {
8506
- const v = parseFloat(n);
8507
- return unit === "rem" || unit === "em" ? v * 16 : v;
8508
- }
8509
- function preludeKey(kind, prelude) {
8510
- const container = kind === "container";
8511
- if (!container && /^\s*not\b/i.test(prelude)) return [0, 0];
8512
- const min = MIN_W.exec(prelude);
8513
- if (min) return [container ? 4 : 2, toPx(min[1], min[2])];
8514
- const max = MAX_W.exec(prelude);
8515
- if (max) return [container ? 3 : 1, -toPx(max[1], max[2])];
8516
- if (!container && LATE_MEDIA.test(prelude)) return [5, 0];
8517
- return [0, 0];
8518
- }
8519
- function ruleSortKey(rule) {
8520
- const key = [];
8521
- let rest = rule;
8522
- let m;
8523
- while (m = LEADING_AT.exec(rest)) {
8524
- const [g, v] = preludeKey(m[1], m[2]);
8525
- key.push(g, v);
8526
- rest = rest.slice(m[0].length);
8527
- }
8528
- return key;
8529
- }
8530
- function compareKeys(a, b) {
8531
- const n = Math.min(a.length, b.length);
8532
- for (let i = 0; i < n; i++) if (a[i] !== b[i]) return a[i] - b[i];
8533
- return a.length - b.length;
8534
- }
8535
- /** Index after the last key <= `key` (stable upper bound) in sorted `keys`. */
8536
- function upperBound(keys, key) {
8537
- let lo = 0;
8538
- let hi = keys.length;
8539
- while (lo < hi) {
8540
- const mid = lo + hi >> 1;
8541
- if (compareKeys(keys[mid], key) <= 0) lo = mid + 1;
8542
- else hi = mid;
8543
- }
8544
- return lo;
8545
- }
8546
- //#endregion
8547
- export { AstCache, IncrementalParser, ParseResultCache, UtilityCache, WeakCache, arbitraryPropertyRegistration, astCache, astToCss, atRoot, atRule, clearAllCaches, clearAstCache, collectDeclPaths, comment, compareKeys, configGetter, createContext, decl, declPathToAst, deepMerge, defaultConfig, escapeClassName, expandThemeFunctions, functionalModifier, functionalUtility, generateCss, generateCssFromJson, generateCssRules, getAstCacheStats, getModifier, getPreflightCSS, getUtility, hasCommentDelimiter, hasCommentToken, hasHtmlEndTagOpener, hasPreset, isBalancedPrelude, isDebug, isSafeVariantToken, isSafeVariantValue, isStructureSafeValue, isWellFormedVariantBrackets, jsonToAst, mergeAstTreeList, modifierRegistry, normalizeMathSpacing, optimizeAst, parseClassName, parseClassToAst, parseResultCache, property, raw, registerModifier, registerUtility, resolveTheme, rootToCss, rule, ruleSortKey, setContextCacheReset, setDebug, staticModifier, staticUtility, styleRule, themeGetter, themeKeyValue, themeKeyVar, themeToCssVars, tokenize, upperBound, utilityCache };
9164
+ export { AstCache, IncrementalParser, ParseResultCache, REJECT_CLASS, UtilityCache, WeakCache, arbitraryPropertyRegistration, astCache, astToCss, atRoot, atRule, clearAllCaches, clearAstCache, collectDeclPaths, comment, compareKeys, configGetter, createContext, decl, declPathToAst, deepMerge, defaultConfig, escapeClassName, expandThemeFunctions, functionalModifier, functionalUtility, generateCss, generateCssFromJson, generateCssRules, getAstCacheStats, getModifier, getPreflightCSS, getUtility, hasCommentDelimiter, hasCommentToken, hasHtmlEndTagOpener, hasPreset, isBalancedPrelude, isDebug, isSafeVariantToken, isSafeVariantValue, isScopedSelector, isStructureSafeValue, isWellFormedVariantBrackets, jsonToAst, mergeAstTreeList, modifierRegistry, normalizeMathSpacing, optimizeAst, parseClassName, parseClassToAst, parseResultCache, property, raw, registerModifier, registerUtility, resolveTheme, rootToCss, rule, ruleSortKey, setContextCacheReset, setDebug, staticModifier, staticUtility, styleRule, themeGetter, themeKeyValue, themeKeyVar, themeToCssVars, tokenize, upperBound, utilityCache };
8548
9165
 
8549
9166
  //# sourceMappingURL=index.js.map