@barocss/browser 0.0.3 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -11,9 +11,6 @@ function atRoot(nodes, source) {
11
11
  function atRule(name, params, nodes, source) {
12
12
  return { type: "at-rule", name, params, nodes, source };
13
13
  }
14
- function styleRule(selector, nodes, source) {
15
- return { type: "style-rule", selector, nodes, source };
16
- }
17
14
  function rule(selector, nodes, source) {
18
15
  return { type: "rule", selector, nodes, source };
19
16
  }
@@ -27,16 +24,172 @@ function property(name, initialValue, syntax, source) {
27
24
  }
28
25
  return atRule("property", name, nodes, source);
29
26
  }
27
+ let debugEnabled = false;
28
+ function setDebug(enabled) {
29
+ debugEnabled = enabled;
30
+ }
31
+ function debugLog(...args) {
32
+ if (debugEnabled) console.log(...args);
33
+ }
34
+ function debugWarn(...args) {
35
+ if (debugEnabled) console.warn(...args);
36
+ }
37
+ class AstCache {
38
+ constructor() {
39
+ this.cache = /* @__PURE__ */ new Map();
40
+ this.maxSize = 1e3;
41
+ }
42
+ // Prevent memory leaks
43
+ set(key, ast) {
44
+ if (this.cache.size >= this.maxSize) {
45
+ const firstKey = this.cache.keys().next().value;
46
+ if (firstKey) {
47
+ this.cache.delete(firstKey);
48
+ }
49
+ }
50
+ this.cache.set(key, ast);
51
+ }
52
+ get(key) {
53
+ return this.cache.get(key);
54
+ }
55
+ has(key) {
56
+ return this.cache.has(key);
57
+ }
58
+ clear() {
59
+ this.cache.clear();
60
+ }
61
+ getStats() {
62
+ return {
63
+ size: this.cache.size,
64
+ maxSize: this.maxSize,
65
+ hitRate: this.cache.size / this.maxSize
66
+ };
67
+ }
68
+ }
69
+ const astCache = new AstCache();
70
+ class ParseResultCache {
71
+ constructor() {
72
+ this.cache = /* @__PURE__ */ new Map();
73
+ this.maxSize = 2e3;
74
+ }
75
+ // Prevent memory leaks
76
+ set(key, result) {
77
+ if (this.cache.size >= this.maxSize) {
78
+ const firstKey = this.cache.keys().next().value;
79
+ if (firstKey) {
80
+ this.cache.delete(firstKey);
81
+ }
82
+ }
83
+ this.cache.set(key, result);
84
+ }
85
+ get(key) {
86
+ return this.cache.get(key);
87
+ }
88
+ has(key) {
89
+ return this.cache.has(key);
90
+ }
91
+ clear() {
92
+ this.cache.clear();
93
+ }
94
+ getStats() {
95
+ return {
96
+ size: this.cache.size,
97
+ maxSize: this.maxSize,
98
+ hitRate: this.cache.size / this.maxSize
99
+ };
100
+ }
101
+ }
102
+ const parseResultCache = new ParseResultCache();
103
+ class UtilityCache {
104
+ constructor() {
105
+ this.cache = /* @__PURE__ */ new Map();
106
+ this.maxSize = 1e3;
107
+ }
108
+ // Prevent memory leaks
109
+ set(key, value) {
110
+ if (this.cache.size >= this.maxSize) {
111
+ const firstKey = this.cache.keys().next().value;
112
+ if (firstKey) {
113
+ this.cache.delete(firstKey);
114
+ }
115
+ }
116
+ this.cache.set(key, value);
117
+ }
118
+ get(key) {
119
+ return this.cache.get(key);
120
+ }
121
+ has(key) {
122
+ return this.cache.has(key);
123
+ }
124
+ clear() {
125
+ this.cache.clear();
126
+ }
127
+ getStats() {
128
+ return {
129
+ size: this.cache.size,
130
+ maxSize: this.maxSize,
131
+ hitRate: this.cache.size / this.maxSize
132
+ };
133
+ }
134
+ }
135
+ const utilityCache = new UtilityCache();
136
+ let resetContextCaches;
137
+ function setContextCacheReset(reset) {
138
+ resetContextCaches = reset;
139
+ }
140
+ function clearAllCaches() {
141
+ astCache.clear();
142
+ parseResultCache.clear();
143
+ utilityCache.clear();
144
+ resetContextCaches?.();
145
+ debugLog("[clearAllCaches] All caches cleared");
146
+ }
147
+ const states = /* @__PURE__ */ new WeakMap();
148
+ let cacheGeneration = 0;
149
+ setContextCacheReset(() => {
150
+ cacheGeneration += 1;
151
+ });
152
+ function initializeContextState(ctx, utilities, modifiers) {
153
+ states.set(ctx, {
154
+ utilities: [...utilities],
155
+ modifiers: [...modifiers],
156
+ astCache: new AstCache(),
157
+ parseResultCache: new ParseResultCache(),
158
+ utilityCache: new UtilityCache(),
159
+ failures: /* @__PURE__ */ new Set(),
160
+ cacheGeneration
161
+ });
162
+ }
163
+ function getContextState(ctx) {
164
+ const state = states.get(ctx);
165
+ if (state && state.cacheGeneration !== cacheGeneration) {
166
+ clearContextCaches(ctx);
167
+ state.cacheGeneration = cacheGeneration;
168
+ }
169
+ return state;
170
+ }
171
+ function clearContextCaches(ctx) {
172
+ const state = states.get(ctx);
173
+ if (!state) return;
174
+ state.astCache.clear();
175
+ state.parseResultCache.clear();
176
+ state.utilityCache.clear();
177
+ state.failures.clear();
178
+ }
30
179
  const utilityRegistry = [];
31
- function registerUtility(util) {
180
+ function registerUtility(util, ctx) {
32
181
  utilityRegistry.push(util);
182
+ {
183
+ parseResultCache.clear();
184
+ utilityCache.clear();
185
+ }
33
186
  }
34
- function getUtility() {
35
- return utilityRegistry;
187
+ function getUtility(ctx) {
188
+ return ctx && getContextState(ctx)?.utilities || utilityRegistry;
36
189
  }
37
190
  const modifierRegistry = [];
38
- function staticModifier(name, selectors, options = {}) {
39
- modifierRegistry.push({
191
+ function staticModifier(name, selectors, options = {}, ctx) {
192
+ registerModifier({
40
193
  match: (mod) => mod === name,
41
194
  modifySelector: ({ ..._rest }) => {
42
195
  return selectors.map((sel) => ({
@@ -47,11 +200,14 @@ function staticModifier(name, selectors, options = {}) {
47
200
  ...options
48
201
  });
49
202
  }
50
- function functionalModifier(match, modifySelector, wrap, options = {}) {
51
- modifierRegistry.push({ match, modifySelector, wrap, ...options });
203
+ function functionalModifier(match, modifySelector, wrap, options = {}, ctx) {
204
+ registerModifier({ match, modifySelector, wrap, ...options });
52
205
  }
53
- function getModifier() {
54
- return modifierRegistry;
206
+ function registerModifier(modifier, ctx) {
207
+ modifierRegistry.push(modifier);
208
+ }
209
+ function getModifier(ctx) {
210
+ return ctx && getContextState(ctx)?.modifiers || modifierRegistry;
55
211
  }
56
212
  const ESCAPE_REGEX = /[^A-Za-z0-9_-]/g;
57
213
  function escapeClassName(className) {
@@ -90,7 +246,7 @@ function escapeClassName(className) {
90
246
  return "\\" + c;
91
247
  });
92
248
  }
93
- function staticUtility(name, decls, opts) {
249
+ function staticUtility(name, decls, opts, ctx) {
94
250
  registerUtility({
95
251
  name,
96
252
  match: (className) => {
@@ -119,11 +275,11 @@ function staticUtility(name, decls, opts) {
119
275
  priority: opts?.priority
120
276
  });
121
277
  }
122
- function functionalUtility(opts) {
278
+ function functionalUtility(opts, ctx) {
123
279
  registerUtility({
124
280
  name: opts.name,
125
281
  match: (className) => className.startsWith(opts.name + "-"),
126
- handler: (value, ctx, token, _options) => {
282
+ handler: (value, ctx2, token, _options) => {
127
283
  let finalValue = value;
128
284
  const parsedUtility = token;
129
285
  const extra = {
@@ -137,9 +293,9 @@ function functionalUtility(opts) {
137
293
  }
138
294
  }
139
295
  if (opts.supportsArbitrary && parsedUtility.arbitrary) {
140
- const processedValue = finalValue.replace(/_/g, " ");
296
+ const processedValue = normalizeMathSpacing(expandThemeFunctions(finalValue.replace(/_/g, " ")));
141
297
  if (opts.handle) {
142
- const result = opts.handle(processedValue, ctx, token, extra);
298
+ const result = opts.handle(processedValue, ctx2, token, extra);
143
299
  if (result) return result;
144
300
  }
145
301
  if (opts.prop) {
@@ -149,12 +305,12 @@ function functionalUtility(opts) {
149
305
  }
150
306
  if (opts.supportsCustomProperty && parsedUtility.customProperty) {
151
307
  if (opts.handleCustomProperty) {
152
- const result = opts.handleCustomProperty(finalValue, ctx, token, extra);
308
+ const result = opts.handleCustomProperty(finalValue, ctx2, token, extra);
153
309
  return result;
154
310
  }
155
311
  const customValue = `var(${finalValue})`;
156
312
  if (opts.handle) {
157
- const result = opts.handle(customValue, ctx, token, extra);
313
+ const result = opts.handle(customValue, ctx2, token, extra);
158
314
  if (result) return result;
159
315
  }
160
316
  if (opts.prop) {
@@ -163,12 +319,12 @@ function functionalUtility(opts) {
163
319
  return [];
164
320
  }
165
321
  let themeValue;
166
- if (opts.themeKey && ctx.theme) {
167
- themeValue = ctx.theme(opts.themeKey, finalValue);
322
+ if (opts.themeKey && ctx2.theme) {
323
+ themeValue = ctx2.theme(opts.themeKey, finalValue);
168
324
  }
169
- if (!themeValue && opts.themeKeys && ctx.theme) {
325
+ if (!themeValue && opts.themeKeys && ctx2.theme) {
170
326
  for (const key of opts.themeKeys) {
171
- themeValue = ctx.theme(key, finalValue);
327
+ themeValue = ctx2.theme(key, finalValue);
172
328
  if (themeValue !== void 0) break;
173
329
  }
174
330
  }
@@ -179,7 +335,7 @@ function functionalUtility(opts) {
179
335
  return [decl(opts.prop, finalValue)];
180
336
  }
181
337
  if (opts.handle) {
182
- const result = opts.handle(finalValue, ctx, token, extra);
338
+ const result = opts.handle(finalValue, ctx2, token, extra);
183
339
  if (result) return result;
184
340
  }
185
341
  return [];
@@ -188,16 +344,18 @@ function functionalUtility(opts) {
188
344
  finalValue = value;
189
345
  }
190
346
  if (parsedUtility.negative && opts.supportsNegative && opts.handleNegativeBareValue) {
191
- const bare = opts.handleNegativeBareValue({ value: String(finalValue).replace(/^-/, ""), ctx, token, extra });
347
+ const bare = opts.handleNegativeBareValue({ value: String(finalValue).replace(/^-/, ""), ctx: ctx2, token, extra });
192
348
  if (bare == null) return [];
193
349
  finalValue = bare;
194
350
  } else if (opts.handleBareValue) {
195
- const bare = opts.handleBareValue({ value: finalValue, ctx, token, extra });
351
+ const bare = opts.handleBareValue({ value: finalValue, ctx: ctx2, token, extra });
196
352
  if (bare == null) return [];
197
353
  finalValue = bare;
354
+ } else if (!/^-?(\d|\.\d)/.test(String(finalValue))) {
355
+ return [];
198
356
  }
199
357
  if (opts.handle) {
200
- const result = opts.handle(finalValue, ctx, token, extra);
358
+ const result = opts.handle(finalValue, ctx2, token, extra);
201
359
  if (result) return result;
202
360
  }
203
361
  if (opts.prop) {
@@ -210,6 +368,62 @@ function functionalUtility(opts) {
210
368
  priority: opts.priority
211
369
  });
212
370
  }
371
+ const MATH_FNS = /* @__PURE__ */ new Set(["calc", "min", "max", "clamp"]);
372
+ function expandThemeFunctions(value) {
373
+ return value.replace(/--spacing\(\s*([^()]+?)\s*\)/g, "calc(var(--spacing) * $1)");
374
+ }
375
+ const arbitraryPropertyRegistration = {
376
+ name: "[arbitrary-property]",
377
+ match: () => false,
378
+ handler: (value, _ctx, token) => {
379
+ const prop = token.property;
380
+ if (!prop || !value) return [];
381
+ return [decl(prop, normalizeMathSpacing(expandThemeFunctions(value.replace(/_/g, " "))))];
382
+ }
383
+ };
384
+ function normalizeMathSpacing(value) {
385
+ if (!/(calc|min|max|clamp)\(/.test(value)) return value;
386
+ const stack = [];
387
+ let out = "";
388
+ for (let i = 0; i < value.length; i++) {
389
+ const ch = value[i];
390
+ if (ch === "(") {
391
+ const name = (/([a-z-]*)$/i.exec(out)?.[1] ?? "").toLowerCase();
392
+ const inMath2 = stack.length > 0 && stack[stack.length - 1];
393
+ stack.push(MATH_FNS.has(name) || name === "" && inMath2);
394
+ out += ch;
395
+ continue;
396
+ }
397
+ if (ch === ")") {
398
+ stack.pop();
399
+ out += ch;
400
+ continue;
401
+ }
402
+ const inMath = stack.length > 0 && stack[stack.length - 1];
403
+ if (!inMath) {
404
+ out += ch;
405
+ continue;
406
+ }
407
+ if (ch === ",") {
408
+ out = out.trimEnd() + ", ";
409
+ while (value[i + 1] === " ") i++;
410
+ continue;
411
+ }
412
+ if ("+-*/".includes(ch)) {
413
+ const prev = out.trimEnd();
414
+ const p = prev[prev.length - 1] ?? "";
415
+ const binary = /[\w%)]/.test(p);
416
+ const exponent = (ch === "+" || ch === "-") && /\de$/i.test(prev) && prev.length === out.length && /\d/.test(value[i + 1] ?? "");
417
+ if (binary && !exponent) {
418
+ out = prev + " " + ch + " ";
419
+ while (value[i + 1] === " ") i++;
420
+ continue;
421
+ }
422
+ }
423
+ out += ch;
424
+ }
425
+ return out;
426
+ }
213
427
  function tokenize(className) {
214
428
  const tokens = [];
215
429
  let current = "";
@@ -245,117 +459,13 @@ function tokenize(className) {
245
459
  }
246
460
  return tokens;
247
461
  }
248
- class AstCache {
249
- constructor() {
250
- this.cache = /* @__PURE__ */ new Map();
251
- this.maxSize = 1e3;
462
+ function isUtilityPrefix(str, ctx) {
463
+ const cache = ctx && getContextState(ctx)?.utilityCache || utilityCache;
464
+ if (cache.has(str)) {
465
+ return cache.get(str);
252
466
  }
253
- // Prevent memory leaks
254
- set(key, ast) {
255
- if (this.cache.size >= this.maxSize) {
256
- const firstKey = this.cache.keys().next().value;
257
- if (firstKey) {
258
- this.cache.delete(firstKey);
259
- }
260
- }
261
- this.cache.set(key, ast);
262
- }
263
- get(key) {
264
- return this.cache.get(key);
265
- }
266
- has(key) {
267
- return this.cache.has(key);
268
- }
269
- clear() {
270
- this.cache.clear();
271
- }
272
- getStats() {
273
- return {
274
- size: this.cache.size,
275
- maxSize: this.maxSize,
276
- hitRate: this.cache.size / this.maxSize
277
- };
278
- }
279
- }
280
- const astCache = new AstCache();
281
- class ParseResultCache {
282
- constructor() {
283
- this.cache = /* @__PURE__ */ new Map();
284
- this.maxSize = 2e3;
285
- }
286
- // Prevent memory leaks
287
- set(key, result) {
288
- if (this.cache.size >= this.maxSize) {
289
- const firstKey = this.cache.keys().next().value;
290
- if (firstKey) {
291
- this.cache.delete(firstKey);
292
- }
293
- }
294
- this.cache.set(key, result);
295
- }
296
- get(key) {
297
- return this.cache.get(key);
298
- }
299
- has(key) {
300
- return this.cache.has(key);
301
- }
302
- clear() {
303
- this.cache.clear();
304
- }
305
- getStats() {
306
- return {
307
- size: this.cache.size,
308
- maxSize: this.maxSize,
309
- hitRate: this.cache.size / this.maxSize
310
- };
311
- }
312
- }
313
- const parseResultCache = new ParseResultCache();
314
- class UtilityCache {
315
- constructor() {
316
- this.cache = /* @__PURE__ */ new Map();
317
- this.maxSize = 1e3;
318
- }
319
- // Prevent memory leaks
320
- set(key, value) {
321
- if (this.cache.size >= this.maxSize) {
322
- const firstKey = this.cache.keys().next().value;
323
- if (firstKey) {
324
- this.cache.delete(firstKey);
325
- }
326
- }
327
- this.cache.set(key, value);
328
- }
329
- get(key) {
330
- return this.cache.get(key);
331
- }
332
- has(key) {
333
- return this.cache.has(key);
334
- }
335
- clear() {
336
- this.cache.clear();
337
- }
338
- getStats() {
339
- return {
340
- size: this.cache.size,
341
- maxSize: this.maxSize,
342
- hitRate: this.cache.size / this.maxSize
343
- };
344
- }
345
- }
346
- const utilityCache = new UtilityCache();
347
- function clearAllCaches() {
348
- astCache.clear();
349
- parseResultCache.clear();
350
- utilityCache.clear();
351
- console.log("[clearAllCaches] All caches cleared");
352
- }
353
- function isUtilityPrefix(str) {
354
- if (utilityCache.has(str)) {
355
- return utilityCache.get(str);
356
- }
357
- const utilities = getUtility();
358
- const modifiers = getModifier();
467
+ const utilities = getUtility(ctx);
468
+ const modifiers = getModifier(ctx);
359
469
  const candidateUtilities = utilities.filter((util) => {
360
470
  const prefix = util.name;
361
471
  return str.startsWith(prefix + "-") || str === prefix || str.startsWith(prefix);
@@ -367,52 +477,66 @@ function isUtilityPrefix(str) {
367
477
  });
368
478
  const isModifier = candidateModifiers.some((mod) => mod.match(str, {}));
369
479
  const result = isUtility && !isModifier;
370
- utilityCache.set(str, result);
480
+ cache.set(str, result);
371
481
  return result;
372
482
  }
373
- function parseClassName(className) {
374
- if (parseResultCache.has(className)) {
375
- return parseResultCache.get(className);
483
+ function parseClassName(className, ctx) {
484
+ const cache = ctx && getContextState(ctx)?.parseResultCache || parseResultCache;
485
+ if (cache.has(className)) {
486
+ return cache.get(className);
376
487
  }
377
488
  let important = false;
378
489
  let realClassName = className;
379
490
  if (className.startsWith("!")) {
380
491
  important = true;
381
492
  realClassName = className.slice(1);
493
+ } else if (className.length > 1 && className.endsWith("!")) {
494
+ important = true;
495
+ realClassName = className.slice(0, -1);
382
496
  }
383
497
  const tokens = tokenize(realClassName);
384
- const result = parseTokens(tokens);
498
+ const result = parseTokens(tokens, ctx);
385
499
  if (result.utility) {
386
500
  result.utility.important = important;
387
501
  }
388
- parseResultCache.set(className, result);
502
+ cache.set(className, result);
389
503
  return result;
390
504
  }
391
- function parseTokens(tokens) {
505
+ function parseTokens(tokens, ctx) {
392
506
  const modifiers = [];
393
507
  let utility = null;
394
508
  if (tokens.length === 0) {
395
509
  return { modifiers, utility: null };
396
510
  }
511
+ if (tokens.length > 1) {
512
+ const utilityIndex = isUtilityPrefix(tokens[0].value, ctx) ? 0 : tokens.length - 1;
513
+ if (tokens.some((t, i) => i !== utilityIndex && !isSafeVariantToken(t.value))) {
514
+ return { modifiers, utility: null };
515
+ }
516
+ }
517
+ const utilityToken = tokens.length > 1 && !isUtilityPrefix(tokens[0].value, ctx) ? tokens[tokens.length - 1] : tokens[0];
518
+ if (!isStructureSafeValue(utilityToken.value)) {
519
+ return { modifiers, utility: null };
520
+ }
397
521
  if (tokens.length === 1) {
398
- utility = parseUtility(tokens[0].value);
522
+ utility = parseUtility(tokens[0].value, ctx);
399
523
  } else if (tokens.length === 2) {
400
524
  const firstToken = tokens[0];
401
525
  const secondToken = tokens[1];
402
- const isFirstUtility = isUtilityPrefix(firstToken.value);
526
+ const isFirstUtility = isUtilityPrefix(firstToken.value, ctx);
403
527
  if (isFirstUtility) {
404
- utility = parseUtility(firstToken.value);
528
+ utility = parseUtility(firstToken.value, ctx);
405
529
  const parsed = parseModifier(secondToken.value);
406
530
  if (parsed) modifiers.push(parsed);
407
531
  } else {
408
532
  const parsed = parseModifier(firstToken.value);
409
533
  if (parsed) modifiers.push(parsed);
410
- utility = parseUtility(secondToken.value);
534
+ utility = parseUtility(secondToken.value, ctx);
411
535
  }
412
536
  } else {
413
- const isFirstUtility = isUtilityPrefix(tokens[0].value);
537
+ const isFirstUtility = isUtilityPrefix(tokens[0].value, ctx);
414
538
  if (isFirstUtility) {
415
- utility = parseUtility(tokens[0].value);
539
+ utility = parseUtility(tokens[0].value, ctx);
416
540
  for (let i = 1; i < tokens.length; i++) {
417
541
  const parsed = parseModifier(tokens[i].value);
418
542
  if (parsed) modifiers.push(parsed);
@@ -422,11 +546,84 @@ function parseTokens(tokens) {
422
546
  const parsed = parseModifier(tokens[i].value);
423
547
  if (parsed) modifiers.push(parsed);
424
548
  }
425
- utility = parseUtility(tokens[tokens.length - 1].value);
549
+ utility = parseUtility(tokens[tokens.length - 1].value, ctx);
426
550
  }
427
551
  }
428
552
  return { modifiers, utility };
429
553
  }
554
+ const FUNCTIONAL_VALUE_VARIANT = /^-?(?:(?:group|peer)-)?(?:has|not)-\[(.*)\](?:\/[\w-]+)?$/;
555
+ function isSafeVariantToken(value) {
556
+ if (hasCommentToken(value)) return false;
557
+ const m = FUNCTIONAL_VALUE_VARIANT.exec(value);
558
+ if (m) return isSafeVariantValue(m[1], true);
559
+ return isSafeVariantValue(value);
560
+ }
561
+ function hasCommentToken(value) {
562
+ return value.includes("/*") || value.includes("*/");
563
+ }
564
+ function isStructureSafeValue(value) {
565
+ if (hasCommentToken(value)) return false;
566
+ return isSafeVariantValue(value, true);
567
+ }
568
+ function hasUnquotedAt(value) {
569
+ let quote = "";
570
+ for (let i = 0; i < value.length; i++) {
571
+ const c = value[i];
572
+ if (c === "\\") {
573
+ i++;
574
+ continue;
575
+ }
576
+ if (quote) {
577
+ if (c === quote) quote = "";
578
+ continue;
579
+ }
580
+ if (c === '"' || c === "'") quote = c;
581
+ else if (c === "@") return true;
582
+ }
583
+ return false;
584
+ }
585
+ function isSafeVariantValue(value, allowTopLevelComma = false) {
586
+ const stack = [];
587
+ let quote = "";
588
+ let parenDepth = 0;
589
+ for (let i = 0; i < value.length; i++) {
590
+ const c = value[i];
591
+ if (c === "\\") {
592
+ i++;
593
+ continue;
594
+ }
595
+ if (quote) {
596
+ if (c === quote) quote = "";
597
+ continue;
598
+ }
599
+ switch (c) {
600
+ case '"':
601
+ case "'":
602
+ quote = c;
603
+ break;
604
+ case "(":
605
+ stack.push(")");
606
+ parenDepth++;
607
+ break;
608
+ case "[":
609
+ stack.push("]");
610
+ break;
611
+ case ")":
612
+ case "]":
613
+ if (stack.pop() !== c) return false;
614
+ if (c === ")") parenDepth--;
615
+ break;
616
+ case "{":
617
+ case "}":
618
+ case ";":
619
+ return false;
620
+ case ",":
621
+ if (parenDepth === 0 && !allowTopLevelComma) return false;
622
+ break;
623
+ }
624
+ }
625
+ return stack.length === 0 && !quote;
626
+ }
430
627
  function parseModifier(value) {
431
628
  let negative = false;
432
629
  let modStr = value;
@@ -442,7 +639,7 @@ function parseModifier(value) {
442
639
  function nameSort(a, b) {
443
640
  return b.name.length - a.name.length;
444
641
  }
445
- function parseUtility(value) {
642
+ function parseUtility(value, ctx) {
446
643
  let prefix = "";
447
644
  let utilityValue = "";
448
645
  let arbitrary = false;
@@ -451,6 +648,11 @@ function parseUtility(value) {
451
648
  let opacity2 = "";
452
649
  let category = "";
453
650
  let priority = 0;
651
+ const prop = /^\[(--[a-zA-Z_][a-zA-Z0-9_-]*|-?[a-z][a-z-]*):(.+)\]$/.exec(value);
652
+ if (prop) {
653
+ if (!isStructureSafeValue(prop[2]) || hasUnquotedAt(prop[2])) return { prefix: "", value: "" };
654
+ return { prefix: "", value: prop[2], arbitrary: true, property: prop[1] };
655
+ }
454
656
  if (value.startsWith("-")) {
455
657
  negative = true;
456
658
  }
@@ -469,8 +671,7 @@ function parseUtility(value) {
469
671
  utilityValue = utilityValue.replace(/\)$/, "");
470
672
  customProperty = true;
471
673
  } else {
472
- const utilities = getUtility();
473
- const sortedUtilities = utilities.sort(nameSort);
674
+ const sortedUtilities = [...getUtility(ctx)].sort(nameSort);
474
675
  let matchedUtility = sortedUtilities.find((p) => value === p.name);
475
676
  if (matchedUtility) {
476
677
  prefix = matchedUtility.name;
@@ -507,6 +708,7 @@ function parseUtility(value) {
507
708
  priority
508
709
  };
509
710
  }
711
+ const isSafeDecl = (prop, value) => isStructureSafeValue(String(prop)) && isStructureSafeValue(String(value ?? ""));
510
712
  const importantPrefix = "!important";
511
713
  function astToCss(ast, baseSelector, opts, _indent = "") {
512
714
  const minify = opts?.minify;
@@ -515,7 +717,7 @@ function astToCss(ast, baseSelector, opts, _indent = "") {
515
717
  const important = opts?.important ?? false;
516
718
  const importantString = important ? ` ${importantPrefix}` : "";
517
719
  if (!ast || ast.length === 0) {
518
- console.warn("[astToCss] Empty AST received:", { ast, baseSelector, minify });
720
+ debugWarn("[astToCss] Empty AST received:", { ast, baseSelector, minify });
519
721
  return "";
520
722
  }
521
723
  const dedupedAst = [];
@@ -537,6 +739,7 @@ function astToCss(ast, baseSelector, opts, _indent = "") {
537
739
  switch (node.type) {
538
740
  case "decl": {
539
741
  const value = node.value;
742
+ if (!isSafeDecl(node.prop, value)) return "";
540
743
  if (node.prop.startsWith("--")) {
541
744
  if (minify) {
542
745
  const css = `${node.prop}: ${value}${importantString};`;
@@ -644,13 +847,13 @@ ${astToCss(
644
847
  case "raw":
645
848
  return `${indent}${node.value}`;
646
849
  default:
647
- console.warn("[astToCss] Unknown node type:", node);
850
+ debugWarn("[astToCss] Unknown node type:", node);
648
851
  return "";
649
852
  }
650
853
  }).filter(Boolean).join(minify ? "" : "\n");
651
854
  const finalResult = result + (minify ? "" : "\n");
652
855
  if (!finalResult || finalResult.trim() === "") {
653
- console.warn("[astToCss] Empty result generated:", {
856
+ debugWarn("[astToCss] Empty result generated:", {
654
857
  ast,
655
858
  baseSelector,
656
859
  minify,
@@ -661,27 +864,262 @@ ${astToCss(
661
864
  }
662
865
  return finalResult;
663
866
  }
664
- function rootToCss(nodes) {
867
+ function rootToCss(nodes, opts) {
665
868
  const result = nodes.map((node) => {
666
869
  const list = [];
667
870
  if (node.type === "decl") {
668
- list.push(`${node.prop}: ${node.value};`);
871
+ if (isSafeDecl(node.prop, node.value)) {
872
+ list.push(`${node.prop}: ${node.value};`);
873
+ }
669
874
  } else if (node.type === "at-rule") {
670
- list.push(
671
- `@${node.name} ${node.params} {
875
+ {
876
+ list.push(
877
+ `@${node.name} ${node.params} {
672
878
  ${node.nodes.map((node2) => {
673
- if (node2.type === "decl") {
674
- return ` ${node2.prop}: ${node2.value};`;
675
- }
676
- }).join("\n")}
879
+ if (node2.type === "decl" && isSafeDecl(node2.prop, node2.value)) {
880
+ return ` ${node2.prop}: ${node2.value};`;
881
+ }
882
+ }).join("\n")}
677
883
  }`
678
- );
884
+ );
885
+ }
679
886
  }
680
887
  return list.join("\n");
681
888
  }).join("\n");
682
889
  return result;
683
890
  }
684
- const failureCache = /* @__PURE__ */ new Map();
891
+ function normalizePrefix(prefix) {
892
+ let p = prefix.trim();
893
+ if (!p.startsWith("--")) p = `--${p}`;
894
+ if (!p.endsWith("-")) p = `${p}-`;
895
+ return p;
896
+ }
897
+ function escapeKey(key) {
898
+ return key.replace(".", "\\.");
899
+ }
900
+ function colorsToCssVars(colors2) {
901
+ if (!colors2) return {};
902
+ const result = {};
903
+ function walk(obj, prefix = []) {
904
+ for (const key in obj) {
905
+ const value = obj[key];
906
+ if (typeof value === "object" && value !== null) {
907
+ walk(value, [...prefix, key]);
908
+ } else {
909
+ const varName2 = "--color-" + [...prefix, key].join("-");
910
+ result[varName2] = value;
911
+ }
912
+ }
913
+ }
914
+ walk(colors2);
915
+ return result;
916
+ }
917
+ function boxShadowToCssVars(boxShadow2) {
918
+ if (!boxShadow2) return {};
919
+ const result = {};
920
+ for (const key in boxShadow2) {
921
+ result[`--shadow-${key}`] = boxShadow2[key];
922
+ }
923
+ return result;
924
+ }
925
+ function fontSizeToCssVars(fontSize2) {
926
+ if (!fontSize2) return {};
927
+ const result = {};
928
+ for (const key in fontSize2) {
929
+ const value = fontSize2[key];
930
+ if (Array.isArray(value)) {
931
+ result[`--text-${key}`] = value[0];
932
+ if (value[1]) result[`--text-${key}--line-height`] = value[1];
933
+ } else {
934
+ result[`--text-${key}`] = value;
935
+ }
936
+ }
937
+ return result;
938
+ }
939
+ function fontWeightToCssVars(fontWeight2) {
940
+ if (!fontWeight2) return {};
941
+ const result = {};
942
+ for (const key in fontWeight2) {
943
+ result[`--font-weight-${key}`] = fontWeight2[key];
944
+ }
945
+ return result;
946
+ }
947
+ function fontFamilyToCssVars(fontFamily2) {
948
+ if (!fontFamily2) return {};
949
+ const result = {};
950
+ for (const key in fontFamily2) {
951
+ const value = fontFamily2[key];
952
+ if (Array.isArray(value)) {
953
+ result[`--font-${key}`] = value.join(", ");
954
+ } else {
955
+ result[`--font-${key}`] = value;
956
+ }
957
+ }
958
+ return result;
959
+ }
960
+ function letterSpacingToCssVars(letterSpacing2) {
961
+ if (!letterSpacing2) return {};
962
+ const result = {};
963
+ for (const key in letterSpacing2) {
964
+ result[`--letter-spacing-${key}`] = letterSpacing2[key];
965
+ }
966
+ return result;
967
+ }
968
+ function spacingToCssVars(spacing2) {
969
+ if (!spacing2) return {};
970
+ const result = {};
971
+ for (const key in spacing2) {
972
+ result[`--spacing-${escapeKey(key)}`] = spacing2[key];
973
+ }
974
+ return result;
975
+ }
976
+ function borderRadiusToCssVars(borderRadius2) {
977
+ if (!borderRadius2) return {};
978
+ const result = {};
979
+ for (const key in borderRadius2) {
980
+ result[`--radius-${escapeKey(key)}`] = borderRadius2[key];
981
+ }
982
+ return result;
983
+ }
984
+ function zIndexToCssVars(zIndex2) {
985
+ if (!zIndex2) return {};
986
+ const result = {};
987
+ for (const key in zIndex2) {
988
+ result[`--z-${escapeKey(key)}`] = String(zIndex2[key]);
989
+ }
990
+ return result;
991
+ }
992
+ function opacityToCssVars(opacity2) {
993
+ if (!opacity2) return {};
994
+ const result = {};
995
+ for (const key in opacity2) {
996
+ result[`--opacity-${escapeKey(key)}`] = String(opacity2[key]);
997
+ }
998
+ return result;
999
+ }
1000
+ function animationToCssVars(animations2) {
1001
+ if (!animations2) return {};
1002
+ const result = {};
1003
+ for (const key in animations2) {
1004
+ result[`--animate-${escapeKey(key)}`] = animations2[key];
1005
+ }
1006
+ return result;
1007
+ }
1008
+ function keyframesToCss(keyframes2) {
1009
+ if (!keyframes2) return "";
1010
+ let css = "";
1011
+ for (const name in keyframes2) {
1012
+ const frames = keyframes2[name];
1013
+ css += `@keyframes ${name} {
1014
+ `;
1015
+ for (const step in frames) {
1016
+ css += ` ${step} {`;
1017
+ const props = frames[step];
1018
+ for (const prop in props) {
1019
+ css += ` ${prop}: ${props[prop]};`;
1020
+ }
1021
+ css += " }\n";
1022
+ }
1023
+ css += "}\n";
1024
+ }
1025
+ return css;
1026
+ }
1027
+ function transitionTimingFunctionToCssVars(transition) {
1028
+ const result = {};
1029
+ for (const key in transition) {
1030
+ if (key === "DEFAULT") {
1031
+ result[`--default-transition-timing-function`] = transition[key];
1032
+ } else {
1033
+ result[`--transition-timing-function-${escapeKey(key)}`] = transition[key];
1034
+ if (key !== "linear") result[`--ease-${escapeKey(key)}`] = transition[key];
1035
+ }
1036
+ }
1037
+ return result;
1038
+ }
1039
+ function transitionDurationToCssVars(transitionDuration2) {
1040
+ const result = {};
1041
+ for (const key in transitionDuration2) {
1042
+ if (key === "DEFAULT") {
1043
+ result[`--default-transition-duration`] = transitionDuration2[key];
1044
+ } else {
1045
+ result[`--transition-duration-${escapeKey(key)}`] = transitionDuration2[key];
1046
+ }
1047
+ }
1048
+ return result;
1049
+ }
1050
+ function transitionDelayToCssVars(transitionDelay2) {
1051
+ const result = {};
1052
+ for (const key in transitionDelay2) {
1053
+ if (key === "DEFAULT") {
1054
+ result[`--default-transition-delay`] = transitionDelay2[key];
1055
+ } else {
1056
+ result[`--transition-delay-${escapeKey(key)}`] = transitionDelay2[key];
1057
+ }
1058
+ }
1059
+ return result;
1060
+ }
1061
+ function blurToCssVars(blur2) {
1062
+ const result = {};
1063
+ for (const key in blur2) {
1064
+ if (key === "DEFAULT") {
1065
+ result[`--default-blur`] = blur2[key];
1066
+ } else {
1067
+ result[`--blur-${escapeKey(key)}`] = blur2[key];
1068
+ }
1069
+ }
1070
+ return result;
1071
+ }
1072
+ function containerToCssVars(container2) {
1073
+ const result = {};
1074
+ for (const key in container2) {
1075
+ result[`--container-${escapeKey(key)}`] = container2[key];
1076
+ }
1077
+ return result;
1078
+ }
1079
+ function themeToCssVarsAll(theme) {
1080
+ return {
1081
+ ...colorsToCssVars(theme.colors),
1082
+ ...boxShadowToCssVars(theme.boxShadow),
1083
+ ...fontSizeToCssVars(theme.fontSize),
1084
+ ...fontWeightToCssVars(theme.fontWeight),
1085
+ ...fontFamilyToCssVars(theme.fontFamily),
1086
+ ...letterSpacingToCssVars(theme.letterSpacing),
1087
+ "--spacing": theme.spacing["1"],
1088
+ ...spacingToCssVars(theme.spacing),
1089
+ ...containerToCssVars(theme.container),
1090
+ ...borderRadiusToCssVars(theme.borderRadius),
1091
+ ...zIndexToCssVars(theme.zIndex),
1092
+ ...opacityToCssVars(theme.opacity),
1093
+ ...animationToCssVars(theme.animations),
1094
+ ...transitionTimingFunctionToCssVars(theme.transitionTimingFunction),
1095
+ ...transitionDurationToCssVars(theme.transitionDuration),
1096
+ ...transitionDelayToCssVars(theme.transitionDelay),
1097
+ ...blurToCssVars(theme.blur),
1098
+ ...Object.fromEntries(Object.entries(theme.aspect ?? {}).map(([k, v2]) => [`--aspect-${escapeKey(k)}`, v2]))
1099
+ // keyframes handled separately
1100
+ };
1101
+ }
1102
+ function toCssVarsBlock(vars, extra = "") {
1103
+ return ":root,:host {\n" + Object.entries(vars).map(([k, v2]) => ` ${k}: ${v2};`).join("\n") + "\n}\n" + extra + "\n";
1104
+ }
1105
+ const BARO_VAR = /--baro-/g;
1106
+ const PREFIXED_KEYS = /* @__PURE__ */ new Set(["prop", "value", "params", "selector", "nodes", "items"]);
1107
+ function applyVarPrefix(ast, ctx) {
1108
+ const configured = ctx?.config("cssVarPrefix");
1109
+ if (typeof configured !== "string" || !configured.trim()) return ast;
1110
+ const prefix = normalizePrefix(configured);
1111
+ if (prefix === "--baro-") return ast;
1112
+ const walk = (node) => {
1113
+ if (typeof node === "string") return node.includes("--baro-") ? node.replace(BARO_VAR, prefix) : node;
1114
+ if (Array.isArray(node)) return node.map(walk);
1115
+ if (!node || typeof node !== "object") return node;
1116
+ const out = {};
1117
+ for (const [k, val] of Object.entries(node)) out[k] = PREFIXED_KEYS.has(k) ? walk(val) : val;
1118
+ return out;
1119
+ };
1120
+ return walk(ast);
1121
+ }
1122
+ const failureCache = /* @__PURE__ */ new Set();
685
1123
  function collectDeclPaths(nodes = [], path = []) {
686
1124
  let result = [];
687
1125
  for (const node of nodes) {
@@ -836,8 +1274,8 @@ function extractAtRootNodes(nodes, parent, atRootNodes = []) {
836
1274
  if (node.type === "at-root") {
837
1275
  atRootNodes.push(node);
838
1276
  delete nodes[i];
839
- } else if (node.type === "rule" || node.type === "style-rule") {
840
- extractAtRootNodes(node.nodes, node, atRootNodes);
1277
+ } else if (node.type === "rule" || node.type === "style-rule" || node.type === "at-rule") {
1278
+ extractAtRootNodes(node.nodes ?? [], node, atRootNodes);
841
1279
  }
842
1280
  }
843
1281
  if (parent) {
@@ -845,45 +1283,50 @@ function extractAtRootNodes(nodes, parent, atRootNodes = []) {
845
1283
  }
846
1284
  }
847
1285
  function parseClassToAst(fullClassName, ctx) {
848
- if (failureCache.has(fullClassName)) {
1286
+ const state = getContextState(ctx);
1287
+ const failures = state?.failures || failureCache;
1288
+ const cache = state?.astCache || astCache;
1289
+ if (failures.has(fullClassName)) {
849
1290
  return [];
850
1291
  }
851
- const contextHash = JSON.stringify({
852
- darkMode: ctx.config("darkMode"),
853
- darkModeSelector: ctx.config("darkModeSelector"),
854
- theme: ctx.theme
855
- });
856
- const cacheKey = `${fullClassName}:${contextHash}`;
857
- if (astCache.has(cacheKey)) {
858
- return astCache.get(cacheKey);
1292
+ if (cache.has(fullClassName)) {
1293
+ return cache.get(fullClassName);
859
1294
  }
860
- const { modifiers, utility } = parseClassName(fullClassName);
1295
+ const { modifiers, utility } = parseClassName(fullClassName, ctx);
861
1296
  if (!utility) {
862
- console.warn(`[BAROCSS] Invalid class name format: "${fullClassName}"`);
863
- failureCache.set(fullClassName, true);
1297
+ debugWarn(`[BAROCSS] Invalid class name format: "${fullClassName}"`);
1298
+ failures.add(fullClassName);
864
1299
  return [];
865
1300
  }
866
- const utilReg = getUtility().find((u) => {
1301
+ const utilRegs = utility.property ? [arbitraryPropertyRegistration] : getUtility(ctx).filter((u) => {
867
1302
  const fullClassName2 = utility.value ? `${utility.prefix}-${utility.value}` : utility.prefix;
868
1303
  return u.match(fullClassName2);
869
1304
  });
870
- if (!utilReg) {
1305
+ if (utilRegs.length === 0) {
871
1306
  const utilityName = utility.value ? `${utility.prefix}-${utility.value}` : utility.prefix;
872
- console.warn(`[BAROCSS] Unknown utility class: "${utilityName}" in "${fullClassName}"`);
873
- failureCache.set(fullClassName, true);
1307
+ debugWarn(`[BAROCSS] Unknown utility class: "${utilityName}" in "${fullClassName}"`);
1308
+ failures.add(fullClassName);
874
1309
  return [];
875
1310
  }
876
1311
  let value = utility.value;
877
1312
  if (utility.negative && value) value = "-" + value;
878
- let ast = utilReg.handler(value, ctx, utility, utilReg) || [];
1313
+ let ast = [];
1314
+ for (const utilReg of utilRegs) {
1315
+ ast = utilReg.handler(value, ctx, utility, utilReg) || [];
1316
+ if (ast.length > 0) break;
1317
+ }
879
1318
  const wrappers = [];
880
1319
  const selector = "&";
881
1320
  for (let i = 0; i < modifiers.length; i++) {
882
1321
  const variant = modifiers[i];
883
- const plugin = getModifier().find((p) => p.match(variant.type, ctx));
1322
+ const plugin = getModifier(ctx).find((p) => p.match(variant.type, ctx));
884
1323
  if (!plugin) {
885
- console.warn(`[BAROCSS] Unknown variant: "${variant.type}" in "${fullClassName}"`);
886
- continue;
1324
+ debugWarn(`[BAROCSS] Unknown variant: "${variant.type}" in "${fullClassName}"`);
1325
+ failures.add(fullClassName);
1326
+ return [];
1327
+ }
1328
+ if (plugin.astHandler) {
1329
+ ast = plugin.astHandler(ast, variant, ctx, modifiers, i);
887
1330
  }
888
1331
  if (plugin.wrap) {
889
1332
  const items = plugin.wrap(variant, ctx);
@@ -891,7 +1334,6 @@ function parseClassToAst(fullClassName, ctx) {
891
1334
  type: "wrap",
892
1335
  items
893
1336
  });
894
- continue;
895
1337
  }
896
1338
  if (plugin.modifySelector) {
897
1339
  const result = plugin.modifySelector({
@@ -902,9 +1344,10 @@ function parseClassToAst(fullClassName, ctx) {
902
1344
  variantChain: modifiers,
903
1345
  index: i
904
1346
  });
1347
+ if (plugin.wrap && (result === "&" || typeof result === "object" && !Array.isArray(result) && result.selector === "&" || Array.isArray(result) && result.length === 1 && result[0].selector === "&")) continue;
905
1348
  if (typeof result === "string" && result.includes("&")) {
906
1349
  wrappers.push({ type: "rule", selector: result });
907
- } else if (typeof result === "object" && result.selector) {
1350
+ } else if (typeof result === "object" && !Array.isArray(result) && result.selector) {
908
1351
  const wrappingType = result.wrappingType || "rule";
909
1352
  wrappers.push({
910
1353
  type: wrappingType,
@@ -928,10 +1371,7 @@ function parseClassToAst(fullClassName, ctx) {
928
1371
  for (let i = wrappers.length - 1; i >= 0; i--) {
929
1372
  const wrap = wrappers[i];
930
1373
  if (wrap.type === "wrap") {
931
- ast = wrap.items.map((item) => ({
932
- ...item,
933
- nodes: Array.isArray(ast) ? ast : [ast]
934
- }));
1374
+ ast = wrap.items.map((item) => item.type === "rule" || item.type === "style-rule" || item.type === "at-rule" || item.type === "at-root" ? { ...item, nodes: [...item.nodes || [], ...ast] } : item);
935
1375
  } else if (wrap.type === "style-rule") {
936
1376
  ast = [
937
1377
  {
@@ -964,19 +1404,29 @@ function parseClassToAst(fullClassName, ctx) {
964
1404
  }
965
1405
  const atRootNodes = [];
966
1406
  extractAtRootNodes(ast, void 0, atRootNodes);
967
- ast = [...atRootNodes, ...ast].filter(Boolean);
968
- astCache.set(cacheKey, ast);
1407
+ ast = applyVarPrefix([...atRootNodes, ...ast].filter(Boolean), ctx);
1408
+ cache.set(fullClassName, ast);
969
1409
  return ast;
970
1410
  }
1411
+ function clearAstCache(ctx) {
1412
+ if (ctx) {
1413
+ clearContextCaches(ctx);
1414
+ } else {
1415
+ clearAllCaches();
1416
+ failureCache.clear();
1417
+ }
1418
+ }
971
1419
  function generateCssRules(classList, ctx, opts) {
972
- const options = {
973
- minify: opts?.minify
974
- };
975
1420
  return classList.split(/\s+/).filter((cls) => {
976
1421
  if (!cls) return false;
977
1422
  return true;
978
1423
  }).map((cls) => {
979
1424
  const ast = parseClassToAst(cls, ctx);
1425
+ const parsedResult = (getContextState(ctx)?.parseResultCache || parseResultCache).get(cls);
1426
+ const options = {
1427
+ minify: opts?.minify,
1428
+ important: parsedResult?.utility?.important ?? false
1429
+ };
980
1430
  const cleanAst = optimizeAst(ast);
981
1431
  const allAtRootNodes = cleanAst.filter(
982
1432
  (node) => node.type === "at-root" && !node.source
@@ -1090,13 +1540,13 @@ class IncrementalParser {
1090
1540
  return null;
1091
1541
  }
1092
1542
  try {
1093
- const parseResult = parseClassName(className);
1543
+ const parseResult = parseClassName(className, this.ctx);
1094
1544
  if (!parseResult.utility) {
1095
1545
  return null;
1096
1546
  }
1097
1547
  const ast = parseClassToAst(className, this.ctx);
1098
1548
  if (ast.length === 0) {
1099
- console.warn("[IncrementalParser] ast is empty", className);
1549
+ debugWarn("[IncrementalParser] ast is empty", className);
1100
1550
  return null;
1101
1551
  }
1102
1552
  const rules = generateCssRules(className, this.ctx, { dedup: false });
@@ -1117,7 +1567,7 @@ class IncrementalParser {
1117
1567
  rootCssList: rule2.rootCssList
1118
1568
  };
1119
1569
  } catch (error) {
1120
- console.warn("[IncrementalParser] Failed to process class:", className, error);
1570
+ debugWarn("[IncrementalParser] Failed to process class:", className, error);
1121
1571
  return null;
1122
1572
  }
1123
1573
  }
@@ -1223,7 +1673,7 @@ class IncrementalParser {
1223
1673
  processedClasses: this.processedClasses.size,
1224
1674
  pendingClasses: this.pendingClasses.size,
1225
1675
  cacheStats: {
1226
- ast: astCache.getStats(),
1676
+ ast: (getContextState(this.ctx)?.astCache || astCache).getStats(),
1227
1677
  css: {}
1228
1678
  // No CSS cache, so return empty object
1229
1679
  }
@@ -1616,13 +2066,15 @@ const spacing = {
1616
2066
  };
1617
2067
  const borderRadius = {
1618
2068
  none: "0px",
1619
- sm: "0.125rem",
2069
+ xs: "0.125rem",
2070
+ sm: "0.25rem",
1620
2071
  DEFAULT: "0.25rem",
1621
2072
  md: "0.375rem",
1622
2073
  lg: "0.5rem",
1623
2074
  xl: "0.75rem",
1624
2075
  "2xl": "1rem",
1625
2076
  "3xl": "1.5rem",
2077
+ "4xl": "2rem",
1626
2078
  full: "9999px"
1627
2079
  };
1628
2080
  const fontSize = {
@@ -1699,11 +2151,13 @@ const lineHeight = {
1699
2151
  12: "3rem"
1700
2152
  };
1701
2153
  const boxShadow = {
1702
- sm: "0 1px 2px 0 rgb(0 0 0 / 0.05)",
2154
+ "2xs": "0 1px rgb(0 0 0 / 0.05)",
2155
+ xs: "0 1px 2px 0 rgb(0 0 0 / 0.05)",
2156
+ sm: "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)",
1703
2157
  DEFAULT: "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px 0 rgb(0 0 0 / 0.06)",
1704
- md: "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -1px rgb(0 0 0 / 0.06)",
1705
- lg: "0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -2px rgb(0 0 0 / 0.05)",
1706
- xl: "0 20px 25px -5px rgb(0 0 0 / 0.1), 0 10px 10px -5px rgb(0 0 0 / 0.04)",
2158
+ md: "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)",
2159
+ lg: "0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)",
2160
+ xl: "0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)",
1707
2161
  "2xl": "0 25px 50px -12px rgb(0 0 0 / 0.25)",
1708
2162
  inner: "inset 0 2px 4px 0 rgb(0 0 0 / 0.05)",
1709
2163
  none: "none"
@@ -1846,15 +2300,14 @@ const letterSpacing = {
1846
2300
  widest: "0.1em"
1847
2301
  };
1848
2302
  const blur = {
1849
- DEFAULT: "0px",
1850
- sm: "4px",
1851
- md: "8px",
1852
- lg: "12px",
1853
- xl: "16px",
1854
- "2xl": "24px",
1855
- "3xl": "32px",
1856
- "4xl": "40px",
1857
- "5xl": "48px"
2303
+ DEFAULT: "8px",
2304
+ xs: "4px",
2305
+ sm: "8px",
2306
+ md: "12px",
2307
+ lg: "16px",
2308
+ xl: "24px",
2309
+ "2xl": "40px",
2310
+ "3xl": "64px"
1858
2311
  };
1859
2312
  const defaultTheme = {
1860
2313
  colors,
@@ -1877,226 +2330,10 @@ const defaultTheme = {
1877
2330
  animations,
1878
2331
  keyframes,
1879
2332
  animationVars,
1880
- blur
2333
+ blur,
2334
+ // Tailwind 4.1.13 --aspect-* (aspect-video → var(--aspect-video))
2335
+ aspect: { video: "16 / 9" }
1881
2336
  };
1882
- function normalizePrefix(prefix) {
1883
- let p = prefix.trim();
1884
- if (!p.startsWith("--")) p = `--${p}`;
1885
- if (!p.endsWith("-")) p = `${p}-`;
1886
- return p;
1887
- }
1888
- function setVarPrefix(prefix) {
1889
- if (typeof prefix !== "string" || prefix.trim() === "") {
1890
- return;
1891
- }
1892
- normalizePrefix(prefix);
1893
- }
1894
- function escapeKey(key) {
1895
- return key.replace(".", "\\.");
1896
- }
1897
- function colorsToCssVars(colors2) {
1898
- if (!colors2) return {};
1899
- const result = {};
1900
- function walk(obj, prefix = []) {
1901
- for (const key in obj) {
1902
- const value = obj[key];
1903
- if (typeof value === "object" && value !== null) {
1904
- walk(value, [...prefix, key]);
1905
- } else {
1906
- const varName2 = "--color-" + [...prefix, key].join("-");
1907
- result[varName2] = value;
1908
- }
1909
- }
1910
- }
1911
- walk(colors2);
1912
- return result;
1913
- }
1914
- function boxShadowToCssVars(boxShadow2) {
1915
- if (!boxShadow2) return {};
1916
- const result = {};
1917
- for (const key in boxShadow2) {
1918
- result[`--shadow-${key}`] = boxShadow2[key];
1919
- }
1920
- return result;
1921
- }
1922
- function fontSizeToCssVars(fontSize2) {
1923
- if (!fontSize2) return {};
1924
- const result = {};
1925
- for (const key in fontSize2) {
1926
- const value = fontSize2[key];
1927
- if (Array.isArray(value)) {
1928
- result[`--text-${key}`] = value[0];
1929
- if (value[1]) result[`--text-${key}--line-height`] = value[1];
1930
- } else {
1931
- result[`--text-${key}`] = value;
1932
- }
1933
- }
1934
- return result;
1935
- }
1936
- function fontWeightToCssVars(fontWeight2) {
1937
- if (!fontWeight2) return {};
1938
- const result = {};
1939
- for (const key in fontWeight2) {
1940
- result[`--font-weight-${key}`] = fontWeight2[key];
1941
- }
1942
- return result;
1943
- }
1944
- function fontFamilyToCssVars(fontFamily2) {
1945
- if (!fontFamily2) return {};
1946
- const result = {};
1947
- for (const key in fontFamily2) {
1948
- const value = fontFamily2[key];
1949
- if (Array.isArray(value)) {
1950
- result[`--font-${key}`] = value.join(", ");
1951
- } else {
1952
- result[`--font-${key}`] = value;
1953
- }
1954
- }
1955
- return result;
1956
- }
1957
- function letterSpacingToCssVars(letterSpacing2) {
1958
- if (!letterSpacing2) return {};
1959
- const result = {};
1960
- for (const key in letterSpacing2) {
1961
- result[`--letter-spacing-${key}`] = letterSpacing2[key];
1962
- }
1963
- return result;
1964
- }
1965
- function spacingToCssVars(spacing2) {
1966
- if (!spacing2) return {};
1967
- const result = {};
1968
- for (const key in spacing2) {
1969
- result[`--spacing-${escapeKey(key)}`] = spacing2[key];
1970
- }
1971
- return result;
1972
- }
1973
- function borderRadiusToCssVars(borderRadius2) {
1974
- if (!borderRadius2) return {};
1975
- const result = {};
1976
- for (const key in borderRadius2) {
1977
- result[`--radius-${escapeKey(key)}`] = borderRadius2[key];
1978
- }
1979
- return result;
1980
- }
1981
- function zIndexToCssVars(zIndex2) {
1982
- if (!zIndex2) return {};
1983
- const result = {};
1984
- for (const key in zIndex2) {
1985
- result[`--z-${escapeKey(key)}`] = String(zIndex2[key]);
1986
- }
1987
- return result;
1988
- }
1989
- function opacityToCssVars(opacity2) {
1990
- if (!opacity2) return {};
1991
- const result = {};
1992
- for (const key in opacity2) {
1993
- result[`--opacity-${escapeKey(key)}`] = String(opacity2[key]);
1994
- }
1995
- return result;
1996
- }
1997
- function animationToCssVars(animations2) {
1998
- if (!animations2) return {};
1999
- const result = {};
2000
- for (const key in animations2) {
2001
- result[`--animate-${escapeKey(key)}`] = animations2[key];
2002
- }
2003
- return result;
2004
- }
2005
- function keyframesToCss(keyframes2) {
2006
- if (!keyframes2) return "";
2007
- let css = "";
2008
- for (const name in keyframes2) {
2009
- const frames = keyframes2[name];
2010
- css += `@keyframes ${name} {
2011
- `;
2012
- for (const step in frames) {
2013
- css += ` ${step} {`;
2014
- const props = frames[step];
2015
- for (const prop in props) {
2016
- css += ` ${prop}: ${props[prop]};`;
2017
- }
2018
- css += " }\n";
2019
- }
2020
- css += "}\n";
2021
- }
2022
- return css;
2023
- }
2024
- function transitionTimingFunctionToCssVars(transition) {
2025
- const result = {};
2026
- for (const key in transition) {
2027
- if (key === "DEFAULT") {
2028
- result[`--default-transition-timing-function`] = transition[key];
2029
- } else {
2030
- result[`--transition-timing-function-${escapeKey(key)}`] = transition[key];
2031
- }
2032
- }
2033
- return result;
2034
- }
2035
- function transitionDurationToCssVars(transitionDuration2) {
2036
- const result = {};
2037
- for (const key in transitionDuration2) {
2038
- if (key === "DEFAULT") {
2039
- result[`--default-transition-duration`] = transitionDuration2[key];
2040
- } else {
2041
- result[`--transition-duration-${escapeKey(key)}`] = transitionDuration2[key];
2042
- }
2043
- }
2044
- return result;
2045
- }
2046
- function transitionDelayToCssVars(transitionDelay2) {
2047
- const result = {};
2048
- for (const key in transitionDelay2) {
2049
- if (key === "DEFAULT") {
2050
- result[`--default-transition-delay`] = transitionDelay2[key];
2051
- } else {
2052
- result[`--transition-delay-${escapeKey(key)}`] = transitionDelay2[key];
2053
- }
2054
- }
2055
- return result;
2056
- }
2057
- function blurToCssVars(blur2) {
2058
- const result = {};
2059
- for (const key in blur2) {
2060
- if (key === "DEFAULT") {
2061
- result[`--default-blur`] = blur2[key];
2062
- } else {
2063
- result[`--blur-${escapeKey(key)}`] = blur2[key];
2064
- }
2065
- }
2066
- return result;
2067
- }
2068
- function containerToCssVars(container2) {
2069
- const result = {};
2070
- for (const key in container2) {
2071
- result[`--container-${escapeKey(key)}`] = container2[key];
2072
- }
2073
- return result;
2074
- }
2075
- function themeToCssVarsAll(theme) {
2076
- return {
2077
- ...colorsToCssVars(theme.colors),
2078
- ...boxShadowToCssVars(theme.boxShadow),
2079
- ...fontSizeToCssVars(theme.fontSize),
2080
- ...fontWeightToCssVars(theme.fontWeight),
2081
- ...fontFamilyToCssVars(theme.fontFamily),
2082
- ...letterSpacingToCssVars(theme.letterSpacing),
2083
- "--spacing": theme.spacing["1"],
2084
- ...spacingToCssVars(theme.spacing),
2085
- ...containerToCssVars(theme.container),
2086
- ...borderRadiusToCssVars(theme.borderRadius),
2087
- ...zIndexToCssVars(theme.zIndex),
2088
- ...opacityToCssVars(theme.opacity),
2089
- ...animationToCssVars(theme.animations),
2090
- ...transitionTimingFunctionToCssVars(theme.transitionTimingFunction),
2091
- ...transitionDurationToCssVars(theme.transitionDuration),
2092
- ...transitionDelayToCssVars(theme.transitionDelay),
2093
- ...blurToCssVars(theme.blur)
2094
- // keyframes handled separately
2095
- };
2096
- }
2097
- function toCssVarsBlock(vars, extra = "") {
2098
- return ":root,:host {\n" + Object.entries(vars).map(([k, v2]) => ` ${k}: ${v2};`).join("\n") + "\n}\n" + extra + "\n";
2099
- }
2100
2337
  const preflightMinimalCSS = `
2101
2338
  /* BaroCSS Preflight - Minimal Reset */
2102
2339
  /* ================================= */
@@ -2227,6 +2464,10 @@ select {
2227
2464
  html {
2228
2465
  line-height: 1.15;
2229
2466
  -webkit-text-size-adjust: 100%;
2467
+ /* Tailwind 4.1.13 root font (app --default-font-family / --font-sans win) */
2468
+ font-family: var(--default-font-family, var(--font-sans, ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'));
2469
+ font-feature-settings: var(--default-font-feature-settings, normal);
2470
+ font-variation-settings: var(--default-font-variation-settings, normal);
2230
2471
  }
2231
2472
 
2232
2473
  /* Remove the gray background on active links in IE 10 */
@@ -2392,6 +2633,60 @@ textarea {
2392
2633
  [type="search"]::-webkit-search-decoration {
2393
2634
  -webkit-appearance: none;
2394
2635
  }
2636
+
2637
+ /* Tailwind 4.1.13 monospace stack for code-like elements */
2638
+ code,
2639
+ kbd,
2640
+ samp,
2641
+ pre {
2642
+ font-family: var(--default-mono-font-family, var(--font-mono, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace));
2643
+ font-feature-settings: var(--default-mono-font-feature-settings, normal);
2644
+ font-variation-settings: var(--default-mono-font-variation-settings, normal);
2645
+ font-size: 1em;
2646
+ }
2647
+
2648
+ /* Tailwind 4.1.13 form-control reset: inherit typography and colour, drop native radius/background (#228) */
2649
+ button,
2650
+ input,
2651
+ select,
2652
+ optgroup,
2653
+ textarea,
2654
+ ::file-selector-button {
2655
+ font: inherit;
2656
+ font-feature-settings: inherit;
2657
+ font-variation-settings: inherit;
2658
+ letter-spacing: inherit;
2659
+ color: inherit;
2660
+ border-radius: 0;
2661
+ background-color: transparent;
2662
+ opacity: 1;
2663
+ }
2664
+
2665
+ :where(select:is([multiple], [size])) optgroup {
2666
+ font-weight: bolder;
2667
+ }
2668
+
2669
+ :where(select:is([multiple], [size])) optgroup option {
2670
+ padding-inline-start: 20px;
2671
+ }
2672
+
2673
+ ::file-selector-button {
2674
+ margin-inline-end: 4px;
2675
+ }
2676
+
2677
+ ::placeholder {
2678
+ opacity: 1;
2679
+ }
2680
+
2681
+ @supports (not (-webkit-appearance: -apple-pay-button)) or (contain-intrinsic-size: 1px) {
2682
+ ::placeholder {
2683
+ color: color-mix(in oklab, currentcolor 50%, transparent);
2684
+ }
2685
+ }
2686
+
2687
+ textarea {
2688
+ resize: vertical;
2689
+ }
2395
2690
  `;
2396
2691
  const preflightFullCSS = `
2397
2692
  /* BaroCSS Preflight - Full Reset */
@@ -2404,10 +2699,14 @@ const preflightFullCSS = `
2404
2699
  box-sizing: border-box;
2405
2700
  }
2406
2701
 
2407
- /* Remove default margin and padding */
2702
+ /* Remove default margin and padding; reset border to Tailwind v4's universal
2703
+ \`border: 0 solid\` so a bare border/border-t (width set by the utility, style
2704
+ otherwise \`none\`) renders. Width 0 keeps borders invisible until a utility
2705
+ sets one. */
2408
2706
  * {
2409
2707
  margin: 0;
2410
2708
  padding: 0;
2709
+ border: 0 solid;
2411
2710
  }
2412
2711
 
2413
2712
  /* Set core body defaults */
@@ -2468,6 +2767,10 @@ html {
2468
2767
  line-height: 1.15;
2469
2768
  -webkit-text-size-adjust: 100%;
2470
2769
  -ms-text-size-adjust: 100%;
2770
+ /* Tailwind 4.1.13 root font (app --default-font-family / --font-sans win) */
2771
+ font-family: var(--default-font-family, var(--font-sans, ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'));
2772
+ font-feature-settings: var(--default-font-feature-settings, normal);
2773
+ font-variation-settings: var(--default-font-variation-settings, normal);
2471
2774
  }
2472
2775
 
2473
2776
  /* Remove the gray background on active links in IE 10 */
@@ -2653,7 +2956,9 @@ code,
2653
2956
  kbd,
2654
2957
  pre,
2655
2958
  samp {
2656
- font-family: monospace, monospace;
2959
+ font-family: var(--default-mono-font-family, var(--font-mono, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace));
2960
+ font-feature-settings: var(--default-mono-font-feature-settings, normal);
2961
+ font-variation-settings: var(--default-mono-font-variation-settings, normal);
2657
2962
  font-size: 1em;
2658
2963
  }
2659
2964
 
@@ -2755,6 +3060,49 @@ template {
2755
3060
  page-break-after: avoid;
2756
3061
  }
2757
3062
  }
3063
+
3064
+ /* Tailwind 4.1.13 form-control reset: inherit typography and colour, drop native radius/background (#228) */
3065
+ button,
3066
+ input,
3067
+ select,
3068
+ optgroup,
3069
+ textarea,
3070
+ ::file-selector-button {
3071
+ font: inherit;
3072
+ font-feature-settings: inherit;
3073
+ font-variation-settings: inherit;
3074
+ letter-spacing: inherit;
3075
+ color: inherit;
3076
+ border-radius: 0;
3077
+ background-color: transparent;
3078
+ opacity: 1;
3079
+ }
3080
+
3081
+ :where(select:is([multiple], [size])) optgroup {
3082
+ font-weight: bolder;
3083
+ }
3084
+
3085
+ :where(select:is([multiple], [size])) optgroup option {
3086
+ padding-inline-start: 20px;
3087
+ }
3088
+
3089
+ ::file-selector-button {
3090
+ margin-inline-end: 4px;
3091
+ }
3092
+
3093
+ ::placeholder {
3094
+ opacity: 1;
3095
+ }
3096
+
3097
+ @supports (not (-webkit-appearance: -apple-pay-button)) or (contain-intrinsic-size: 1px) {
3098
+ ::placeholder {
3099
+ color: color-mix(in oklab, currentcolor 50%, transparent);
3100
+ }
3101
+ }
3102
+
3103
+ textarea {
3104
+ resize: vertical;
3105
+ }
2758
3106
  `;
2759
3107
  function getPreflightCSS(level = true) {
2760
3108
  if (level === "minimal") {
@@ -2793,7 +3141,7 @@ function deepMerge(base, override) {
2793
3141
  }
2794
3142
  return result;
2795
3143
  }
2796
- let staticInProgress;
3144
+ const themeLookupsInProgress = /* @__PURE__ */ new WeakMap();
2797
3145
  function themeGetter(themeObj, ...path) {
2798
3146
  const theme = (...args) => themeGetter(themeObj, ...args);
2799
3147
  let keys = [];
@@ -2813,26 +3161,28 @@ function themeGetter(themeObj, ...path) {
2813
3161
  }
2814
3162
  }
2815
3163
  if (keys.length === 0) return void 0;
2816
- staticInProgress = staticInProgress || /* @__PURE__ */ new Set();
2817
- const pathKey = keys.join(".");
2818
- if (staticInProgress?.has(pathKey)) return void 0;
2819
- staticInProgress?.add(pathKey);
2820
- let value = themeObj[keys[0]];
2821
- if (typeof value === "function") {
2822
- value = value(theme);
3164
+ let inProgress = themeLookupsInProgress.get(themeObj);
3165
+ if (!inProgress) {
3166
+ inProgress = /* @__PURE__ */ new Set();
3167
+ themeLookupsInProgress.set(themeObj, inProgress);
2823
3168
  }
2824
- for (let i = 1; i < keys.length; i++) {
2825
- if (value == null) {
2826
- staticInProgress?.delete(pathKey);
2827
- return void 0;
3169
+ const pathKey = keys.join(".");
3170
+ if (inProgress.has(pathKey)) return void 0;
3171
+ inProgress.add(pathKey);
3172
+ try {
3173
+ let value = themeObj[keys[0]];
3174
+ if (typeof value === "function") {
3175
+ value = value(theme);
2828
3176
  }
2829
- value = value[keys[i]];
2830
- }
2831
- staticInProgress?.delete(pathKey);
2832
- if (typeof value === "function") {
2833
- return void 0;
3177
+ for (let i = 1; i < keys.length; i++) {
3178
+ if (value == null) return void 0;
3179
+ value = value[keys[i]];
3180
+ }
3181
+ if (typeof value === "function") return void 0;
3182
+ return value;
3183
+ } finally {
3184
+ inProgress.delete(pathKey);
2834
3185
  }
2835
- return value;
2836
3186
  }
2837
3187
  function configGetter(config, ...path) {
2838
3188
  let keys = [];
@@ -2872,6 +3222,7 @@ ${keyframesToCss(theme.keyframes || {})}
2872
3222
  return result;
2873
3223
  }
2874
3224
  function createContext(configObj) {
3225
+ if (configObj.debug !== void 0) setDebug(!!configObj.debug);
2875
3226
  const configWithDefaults = {
2876
3227
  presets: [
2877
3228
  { theme: defaultTheme },
@@ -2880,11 +3231,7 @@ function createContext(configObj) {
2880
3231
  ],
2881
3232
  ...configObj
2882
3233
  };
2883
- setVarPrefix(configWithDefaults.cssVarPrefix || "--bcss-");
2884
3234
  const themeObj = resolveTheme(configWithDefaults);
2885
- if (configObj.clearCacheOnContextChange !== false) {
2886
- clearAllCaches();
2887
- }
2888
3235
  const ctx = {
2889
3236
  hasPreset: (category, preset) => {
2890
3237
  const result = hasPreset(themeObj, category, preset);
@@ -2918,11 +3265,13 @@ function createContext(configObj) {
2918
3265
  ...values
2919
3266
  };
2920
3267
  } else ;
3268
+ clearContextCaches(ctx);
2921
3269
  },
2922
3270
  getPreflightCSS: (level = true) => {
2923
3271
  return getPreflightCSS(level);
2924
3272
  }
2925
3273
  };
3274
+ initializeContextState(ctx, getUtility(), getModifier());
2926
3275
  return ctx;
2927
3276
  }
2928
3277
  function parseFraction(input) {
@@ -3158,6 +3507,30 @@ function parseColor(input) {
3158
3507
  }
3159
3508
  return null;
3160
3509
  }
3510
+ const COLOR_KEYWORDS = /* @__PURE__ */ new Set(["inherit", "currentcolor", "transparent"]);
3511
+ function themeColorDecls(prop, value, extra) {
3512
+ const key = String(extra.realThemeValue);
3513
+ const ref = COLOR_KEYWORDS.has(value.toLowerCase()) || value.startsWith("var(") || !/^[\w-]+$/.test(key) ? value : `var(--color-${key})`;
3514
+ if (!extra.opacity) return [decl(prop, ref)];
3515
+ const alpha = normalizeAlpha(String(extra.opacity));
3516
+ const supports = (amount) => atRule("supports", "(color:color-mix(in lab, red, red))", [decl(prop, `color-mix(in oklab, ${ref} ${amount}, transparent)`)]);
3517
+ if (alpha.isVar) return [decl(prop, value), supports(alpha.amount)];
3518
+ return [decl(prop, `color-mix(in srgb, ${value} ${alpha.amount}, transparent)`), supports(alpha.amount)];
3519
+ }
3520
+ function normalizeAlpha(raw) {
3521
+ let v = raw.trim();
3522
+ const bracketed = v.startsWith("[") && v.endsWith("]");
3523
+ if (bracketed) v = v.slice(1, -1).trim();
3524
+ if (v.startsWith("(") && v.endsWith(")")) v = `var(${v.slice(1, -1).trim()})`;
3525
+ if (v.startsWith("var(")) return { amount: v, isVar: true };
3526
+ if (v.endsWith("%")) return { amount: v, isVar: false };
3527
+ const n = Number(v);
3528
+ if (v !== "" && Number.isFinite(n)) {
3529
+ const pct = bracketed && n <= 1 ? n * 100 : n;
3530
+ return { amount: `${+pct.toFixed(4)}%`, isVar: false };
3531
+ }
3532
+ return { amount: v, isVar: false };
3533
+ }
3161
3534
  staticUtility("accent-inherit", [["accent-color", "inherit"]], { category: "interactivity" });
3162
3535
  staticUtility("accent-current", [["accent-color", "currentColor"]], { category: "interactivity" });
3163
3536
  staticUtility("accent-transparent", [["accent-color", "transparent"]], { category: "interactivity" });
@@ -3360,10 +3733,10 @@ staticUtility("touch-pan-up", [["touch-action", "pan-up"]], { category: "interac
3360
3733
  staticUtility("touch-pan-down", [["touch-action", "pan-down"]], { category: "interactivity" });
3361
3734
  staticUtility("touch-pinch-zoom", [["touch-action", "pinch-zoom"]], { category: "interactivity" });
3362
3735
  staticUtility("touch-manipulation", [["touch-action", "manipulation"]], { category: "interactivity" });
3363
- staticUtility("select-none", [["user-select", "none"]], { category: "interactivity" });
3364
- staticUtility("select-text", [["user-select", "text"]], { category: "interactivity" });
3365
- staticUtility("select-all", [["user-select", "all"]], { category: "interactivity" });
3366
- staticUtility("select-auto", [["user-select", "auto"]], { category: "interactivity" });
3736
+ staticUtility("select-none", [["-webkit-user-select", "none"], ["user-select", "none"]], { category: "interactivity" });
3737
+ staticUtility("select-text", [["-webkit-user-select", "text"], ["user-select", "text"]], { category: "interactivity" });
3738
+ staticUtility("select-all", [["-webkit-user-select", "all"], ["user-select", "all"]], { category: "interactivity" });
3739
+ staticUtility("select-auto", [["-webkit-user-select", "auto"], ["user-select", "auto"]], { category: "interactivity" });
3367
3740
  staticUtility("will-change-auto", [["will-change", "auto"]], { category: "interactivity" });
3368
3741
  staticUtility("will-change-scroll", [["will-change", "scroll-position"]], { category: "interactivity" });
3369
3742
  staticUtility("will-change-contents", [["will-change", "contents"]], { category: "interactivity" });
@@ -3381,7 +3754,7 @@ const defaultDuration = "var(--default-transition-duration)";
3381
3754
  staticUtility("transition", [
3382
3755
  [
3383
3756
  "transition-property",
3384
- "color, background-color, border-color, text-decoration-color, fill, stroke, --baro-gradient-from, --baro-gradient-via, --baro-gradient-to, opacity, box-shadow, transform, translate, scale, rotate, filter, -webkit-backdrop-filter, backdrop-filter"
3757
+ "color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --baro-gradient-from, --baro-gradient-via, --baro-gradient-to, opacity, box-shadow, transform, translate, scale, rotate, filter, -webkit-backdrop-filter, backdrop-filter, display, content-visibility, overlay, pointer-events"
3385
3758
  ],
3386
3759
  ["transition-timing-function", defaultTiming],
3387
3760
  ["transition-duration", defaultDuration]
@@ -3394,7 +3767,7 @@ staticUtility("transition-all", [
3394
3767
  staticUtility("transition-colors", [
3395
3768
  [
3396
3769
  "transition-property",
3397
- "color, background-color, border-color, text-decoration-color, fill, stroke, --baro-gradient-from, --baro-gradient-via, --baro-gradient-to"
3770
+ "color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --baro-gradient-from, --baro-gradient-via, --baro-gradient-to"
3398
3771
  ],
3399
3772
  ["transition-timing-function", defaultTiming],
3400
3773
  ["transition-duration", defaultDuration]
@@ -3584,6 +3957,7 @@ const filters$1 = () => {
3584
3957
  filters$1()
3585
3958
  ], { category: "effects" });
3586
3959
  });
3960
+ staticUtility("blur", [decl("--baro-blur", "blur(8px)"), filters$1()], { category: "effects" });
3587
3961
  staticUtility("blur-none", [decl("--baro-blur", ""), filters$1()], { category: "effects" });
3588
3962
  functionalUtility({
3589
3963
  name: "blur",
@@ -3822,6 +4196,7 @@ functionalUtility({
3822
4196
  { category: "effects" }
3823
4197
  );
3824
4198
  });
4199
+ staticUtility("backdrop-blur", [decl("--baro-backdrop-blur", "blur(8px)"), ...filters()], { category: "effects" });
3825
4200
  staticUtility(
3826
4201
  "backdrop-blur-none",
3827
4202
  [decl("--baro-backdrop-blur", ""), ...filters()],
@@ -4050,56 +4425,52 @@ functionalUtility({
4050
4425
  description: "sepia filter utility (static, number, arbitrary, custom property supported)",
4051
4426
  category: "effects"
4052
4427
  });
4428
+ const SHADOW_COMPOSITE = "var(--baro-inset-shadow), var(--baro-inset-ring-shadow), var(--baro-ring-offset-shadow), var(--baro-ring-shadow), var(--baro-shadow)";
4429
+ const ringShadowProperties = () => atRoot([
4430
+ property("--baro-shadow", "0 0 #0000"),
4431
+ property("--baro-inset-shadow", "0 0 #0000"),
4432
+ property("--baro-inset-ring-shadow", "0 0 #0000"),
4433
+ property("--baro-ring-offset-shadow", "0 0 #0000"),
4434
+ property("--baro-ring-shadow", "0 0 #0000"),
4435
+ property("--baro-ring-offset-width", "0px", "<length>"),
4436
+ property("--baro-ring-offset-color", "#fff")
4437
+ ]);
4438
+ const shadowLayer = (value) => [
4439
+ ringShadowProperties(),
4440
+ decl("--baro-shadow", value),
4441
+ decl("box-shadow", SHADOW_COMPOSITE)
4442
+ ];
4053
4443
  [
4054
4444
  ["shadow-2xs", "var(--shadow-2xs)"],
4055
4445
  ["shadow-xs", "var(--shadow-xs)"],
4056
4446
  ["shadow-sm", "var(--shadow-sm)"],
4057
- ["shadow", "var(--shadow-default)"],
4447
+ ["shadow", "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)"],
4058
4448
  ["shadow-md", "var(--shadow-md)"],
4059
4449
  ["shadow-lg", "var(--shadow-lg)"],
4060
4450
  ["shadow-xl", "var(--shadow-xl)"],
4061
4451
  ["shadow-2xl", "var(--shadow-2xl)"],
4062
4452
  ["shadow-none", "0 0 #0000"]
4063
4453
  ].forEach(([name, value]) => {
4064
- staticUtility(name, [["box-shadow", value]], { category: "effects" });
4454
+ staticUtility(name, [
4455
+ ringShadowProperties,
4456
+ ["--baro-shadow", value],
4457
+ ["box-shadow", SHADOW_COMPOSITE]
4458
+ ], { category: "effects" });
4065
4459
  });
4066
4460
  [
4067
- [
4068
- "inset-shadow-2xs",
4069
- "inset 0 1px 2px var(--baro-inset-shadow-color, #0000000d)"
4070
- ],
4071
- [
4072
- "inset-shadow-xs",
4073
- "inset 0 2px 4px var(--baro-inset-shadow-color, #0000000d)"
4074
- ],
4075
- [
4076
- "inset-shadow-sm",
4077
- "inset 0 2px 4px var(--baro-inset-shadow-color, #0000000d)"
4078
- ],
4079
- [
4080
- "inset-shadow-md",
4081
- "inset 0 4px 6px -1px var(--baro-inset-shadow-color, #0000000d)"
4082
- ],
4083
- [
4084
- "inset-shadow-lg",
4085
- "inset 0 10px 15px -3px var(--baro-inset-shadow-color, #0000000d)"
4086
- ],
4087
- [
4088
- "inset-shadow-xl",
4089
- "inset 0 20px 25px -5px var(--baro-inset-shadow-color, #0000000d)"
4090
- ],
4091
- [
4092
- "inset-shadow-2xl",
4093
- "inset 0 25px 50px -12px var(--baro-inset-shadow-color, #0000000d)"
4094
- ],
4461
+ ["inset-shadow-2xs", "inset 0 1px var(--baro-inset-shadow-color, rgb(0 0 0 / 0.05))"],
4462
+ ["inset-shadow-xs", "inset 0 1px 1px var(--baro-inset-shadow-color, rgb(0 0 0 / 0.05))"],
4463
+ ["inset-shadow-sm", "inset 0 2px 4px var(--baro-inset-shadow-color, rgb(0 0 0 / 0.05))"],
4464
+ ["inset-shadow-md", "inset 0 4px 6px -1px var(--baro-inset-shadow-color, rgb(0 0 0 / 0.05))"],
4465
+ ["inset-shadow-lg", "inset 0 10px 15px -3px var(--baro-inset-shadow-color, rgb(0 0 0 / 0.05))"],
4466
+ ["inset-shadow-xl", "inset 0 20px 25px -5px var(--baro-inset-shadow-color, rgb(0 0 0 / 0.05))"],
4467
+ ["inset-shadow-2xl", "inset 0 25px 50px -12px var(--baro-inset-shadow-color, rgb(0 0 0 / 0.05))"],
4095
4468
  ["inset-shadow-none", "0 0 #0000"]
4096
4469
  ].forEach(([name, value]) => {
4097
4470
  staticUtility(name, [
4471
+ ringShadowProperties,
4098
4472
  ["--baro-inset-shadow", value],
4099
- [
4100
- "box-shadow",
4101
- "var(--baro-inset-shadow), var(--baro-inset-ring-shadow), var(--baro-ring-offset-shadow), var(--baro-ring-shadow), var(--baro-shadow)"
4102
- ]
4473
+ ["box-shadow", SHADOW_COMPOSITE]
4103
4474
  ], { category: "effects" });
4104
4475
  });
4105
4476
  function createShadowThemeColor(key, main, opacity2, realThemeValue) {
@@ -4164,9 +4535,9 @@ functionalUtility({
4164
4535
  )
4165
4536
  ];
4166
4537
  }
4167
- return [decl("box-shadow", main)];
4538
+ return [decl("--baro-shadow-color", main)];
4168
4539
  }
4169
- return [decl("box-shadow", main)];
4540
+ return shadowLayer(main);
4170
4541
  }
4171
4542
  if (main === "inherit" || main === "current" || main === "transparent") {
4172
4543
  return [
@@ -4175,7 +4546,7 @@ functionalUtility({
4175
4546
  }
4176
4547
  return null;
4177
4548
  },
4178
- handleCustomProperty: (value) => [decl("box-shadow", `var(${value})`)]
4549
+ handleCustomProperty: (value) => shadowLayer(`var(${value})`)
4179
4550
  });
4180
4551
  functionalUtility({
4181
4552
  name: "inset-shadow",
@@ -4234,22 +4605,39 @@ functionalUtility({
4234
4605
  ["ring-8", "8px"]
4235
4606
  ].forEach(([name, px]) => {
4236
4607
  staticUtility(name, [
4237
- ["--baro-ring-inset", ""],
4238
- ["--baro-ring-offset-width", "0px"],
4239
- ["--baro-ring-offset-color", "#fff"],
4240
- ["--baro-ring-color", "rgb(59 130 246 / 0.5)"],
4241
- // default blue-500/50
4608
+ ringShadowProperties,
4609
+ // Like Tailwind, ring-N does not set the offset vars (they come from @property defaults and ring-offset-*),
4610
+ // so `ring-N ring-offset-M` composes the same in either rule order.
4611
+ // No hardcoded ring color: Tailwind v4's default ring color is currentColor (via the var() fallback below).
4242
4612
  [
4243
4613
  "--baro-ring-shadow",
4244
- `var(--baro-ring-inset) 0 0 0 calc(${px} + var(--baro-ring-offset-width)) var(--baro-ring-color, currentcolor)`
4614
+ ringShadowValue(px)
4245
4615
  ],
4246
- ["--baro-ring-offset-shadow", `0 0 #0000`],
4247
4616
  [
4248
4617
  "box-shadow",
4249
4618
  "var(--baro-inset-shadow), var(--baro-inset-ring-shadow), var(--baro-ring-offset-shadow), var(--baro-ring-shadow), var(--baro-shadow)"
4250
4619
  ]
4251
4620
  ]);
4252
4621
  });
4622
+ function ringShadowValue(width) {
4623
+ return `var(--baro-ring-inset,) 0 0 0 calc(${width} + var(--baro-ring-offset-width)) var(--baro-ring-color, currentcolor)`;
4624
+ }
4625
+ [
4626
+ ["ring-offset-0", "0px"],
4627
+ ["ring-offset-1", "1px"],
4628
+ ["ring-offset-2", "2px"],
4629
+ ["ring-offset-4", "4px"],
4630
+ ["ring-offset-8", "8px"]
4631
+ ].forEach(([name, px]) => {
4632
+ staticUtility(name, [
4633
+ ["--baro-ring-offset-width", px],
4634
+ ["--baro-ring-offset-color", "#fff"],
4635
+ [
4636
+ "--baro-ring-offset-shadow",
4637
+ `var(--baro-ring-inset,) 0 0 0 var(--baro-ring-offset-width) var(--baro-ring-offset-color)`
4638
+ ]
4639
+ ], { category: "effects" });
4640
+ });
4253
4641
  [
4254
4642
  ["inset-ring", "1px"],
4255
4643
  ["inset-ring-0", "0px"],
@@ -4259,20 +4647,11 @@ functionalUtility({
4259
4647
  ["inset-ring-8", "8px"]
4260
4648
  ].forEach(([name, px]) => {
4261
4649
  staticUtility(name, [
4262
- ["--baro-ring-inset", "inset"],
4263
- ["--baro-ring-offset-width", "0px"],
4264
- ["--baro-ring-offset-color", "#fff"],
4265
- ["--baro-inset-ring-color", "rgb(59 130 246 / 0.5)"],
4266
- [
4267
- "--baro-inset-ring-shadow",
4268
- `var(--baro-ring-inset) 0 0 0 calc(${px} + var(--baro-ring-offset-width)) var(--baro-inset-ring-color, currentcolor)`
4269
- ],
4270
- ["--baro-ring-offset-shadow", `0 0 #0000`],
4271
- [
4272
- "box-shadow",
4273
- "var(--baro-inset-shadow), var(--baro-inset-ring-shadow), var(--baro-ring-offset-shadow), var(--baro-ring-shadow), var(--baro-shadow)"
4274
- ]
4275
- ]);
4650
+ // Tailwind 4.1.13: only the inset-ring layer; the colour defaults to currentcolor via the var() fallback.
4651
+ ringShadowProperties,
4652
+ ["--baro-inset-ring-shadow", `inset 0 0 0 ${px} var(--baro-inset-ring-color, currentcolor)`],
4653
+ ["box-shadow", SHADOW_COMPOSITE]
4654
+ ], { category: "effects" });
4276
4655
  });
4277
4656
  staticUtility("ring-inset", [["--baro-ring-inset", "inset"]], { category: "effects" });
4278
4657
  function createRingColorDecls(key, main, opacity2, realThemeValue) {
@@ -4346,7 +4725,15 @@ functionalUtility({
4346
4725
  decl("--baro-ring-color", fallback)
4347
4726
  ];
4348
4727
  }
4349
- return [decl("box-shadow", main)];
4728
+ 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)) {
4729
+ const width = main.startsWith("length:") ? main.slice(7) : main;
4730
+ return [
4731
+ ringShadowProperties(),
4732
+ decl("--baro-ring-shadow", ringShadowValue(width)),
4733
+ decl("box-shadow", SHADOW_COMPOSITE)
4734
+ ];
4735
+ }
4736
+ return [parseColor(main) ? decl("--baro-ring-color", main) : decl("box-shadow", main)];
4350
4737
  }
4351
4738
  if (main === "inherit" || main === "current" || main === "transparent") {
4352
4739
  return [
@@ -4588,6 +4975,30 @@ functionalUtility({
4588
4975
  description: "mask-size utility (static, arbitrary, custom property supported)",
4589
4976
  category: "effects"
4590
4977
  });
4978
+ const maskProperties = () => atRoot([
4979
+ property("--baro-mask-linear", "linear-gradient(#fff, #fff)"),
4980
+ property("--baro-mask-radial", "linear-gradient(#fff, #fff)"),
4981
+ property("--baro-mask-conic", "linear-gradient(#fff, #fff)"),
4982
+ property("--baro-mask-linear-position", "0deg"),
4983
+ property("--baro-mask-linear-from-position", "0%"),
4984
+ property("--baro-mask-linear-to-position", "100%"),
4985
+ property("--baro-mask-linear-from-color", "black"),
4986
+ property("--baro-mask-linear-to-color", "transparent")
4987
+ ]);
4988
+ functionalUtility({
4989
+ name: "mask-linear-from",
4990
+ handleBareValue: ({ value }) => /^(?:100|[1-9]?\d)%$/.test(value) ? value : null,
4991
+ handle: (value) => [
4992
+ decl("mask-image", "var(--baro-mask-linear), var(--baro-mask-radial), var(--baro-mask-conic)"),
4993
+ decl("mask-composite", "intersect"),
4994
+ decl("--baro-mask-linear-stops", "var(--baro-mask-linear-position), var(--baro-mask-linear-from-color) var(--baro-mask-linear-from-position), var(--baro-mask-linear-to-color) var(--baro-mask-linear-to-position)"),
4995
+ decl("--baro-mask-linear", "linear-gradient(var(--baro-mask-linear-stops))"),
4996
+ decl("--baro-mask-linear-from-position", value),
4997
+ maskProperties()
4998
+ ],
4999
+ category: "effects"
5000
+ });
5001
+ staticUtility("mask-none", [["mask-image", "none"]], { category: "effects" });
4591
5002
  functionalUtility({
4592
5003
  name: "mask",
4593
5004
  supportsArbitrary: true,
@@ -4623,7 +5034,7 @@ functionalUtility({
4623
5034
  category: "layout"
4624
5035
  });
4625
5036
  staticUtility("aspect-square", [["aspect-ratio", "1 / 1"]], { category: "layout" });
4626
- staticUtility("aspect-video", [["aspect-ratio", "var(--aspect-ratio-video)"]], { category: "layout" });
5037
+ staticUtility("aspect-video", [["aspect-ratio", "var(--aspect-video)"]], { category: "layout" });
4627
5038
  staticUtility("aspect-auto", [["aspect-ratio", "auto"]], { category: "layout" });
4628
5039
  functionalUtility({
4629
5040
  name: "aspect",
@@ -4707,10 +5118,10 @@ staticUtility("sr-only", [
4707
5118
  ["position", "absolute"],
4708
5119
  ["width", "1px"],
4709
5120
  ["height", "1px"],
4710
- ["margin", "-1px"],
4711
5121
  ["padding", "0"],
5122
+ ["margin", "-1px"],
4712
5123
  ["overflow", "hidden"],
4713
- ["clip", "rect(0, 0, 0, 0)"],
5124
+ ["clip-path", "inset(50%)"],
4714
5125
  ["white-space", "nowrap"],
4715
5126
  ["border-width", "0"]
4716
5127
  ], { category: "layout" });
@@ -4718,12 +5129,39 @@ staticUtility("not-sr-only", [
4718
5129
  ["position", "static"],
4719
5130
  ["width", "auto"],
4720
5131
  ["height", "auto"],
4721
- ["margin", "0"],
4722
5132
  ["padding", "0"],
5133
+ ["margin", "0"],
4723
5134
  ["overflow", "visible"],
4724
- ["clip", "auto"],
5135
+ ["clip-path", "none"],
4725
5136
  ["white-space", "normal"]
4726
5137
  ], { category: "layout" });
5138
+ staticUtility("@container", [["container-type", "inline-size"]], { category: "layout" });
5139
+ staticUtility("@container-normal", [["container-type", "normal"]], { category: "layout" });
5140
+ registerUtility({
5141
+ name: "@container",
5142
+ match: (className) => /^@container\/[a-zA-Z0-9_-]+$/.test(className),
5143
+ handler: (_value, _ctx, token) => {
5144
+ const name = /^@container\/([a-zA-Z0-9_-]+)$/.exec(`${token.prefix}${token.value ? `-${token.value}` : ""}`)?.[1];
5145
+ return name ? [decl("container-type", "inline-size"), decl("container-name", name)] : null;
5146
+ },
5147
+ category: "layout"
5148
+ });
5149
+ const toRem = (v) => {
5150
+ const m = /^(-?\d*\.?\d+)(rem|px|em)$/.exec(v.trim());
5151
+ if (!m) return Number.NaN;
5152
+ return m[2] === "px" ? Number(m[1]) / 16 : Number(m[1]);
5153
+ };
5154
+ registerUtility({
5155
+ name: "container",
5156
+ match: (className) => className === "container",
5157
+ handler: (_value, ctx) => {
5158
+ const bps = ctx.theme("breakpoints") || ctx.config("theme.breakpoints") || {};
5159
+ const values = Object.values(bps).filter((v) => typeof v === "string" && !Number.isNaN(toRem(v)));
5160
+ values.sort((a, b) => toRem(a) - toRem(b));
5161
+ return [decl("width", "100%"), ...values.map((v) => atRule("media", `(width >= ${v})`, [decl("max-width", v)]))];
5162
+ },
5163
+ category: "layout"
5164
+ });
4727
5165
  staticUtility("float-right", [["float", "right"]], { category: "layout" });
4728
5166
  staticUtility("float-left", [["float", "left"]], { category: "layout" });
4729
5167
  staticUtility("float-start", [["float", "inline-start"]], { category: "layout" });
@@ -4839,7 +5277,7 @@ functionalUtility({
4839
5277
  // gap-x-[10vw]
4840
5278
  supportsCustomProperty: true,
4841
5279
  // gap-x-(--my-gap-x)
4842
- handleBareValue: ({ value }) => `calc(var(--spacing) * ${value})`,
5280
+ handleBareValue: ({ value }) => parseNumber(value) ? `calc(var(--spacing) * ${value})` : null,
4843
5281
  handle: (value) => {
4844
5282
  if (typeof value === "string") return [decl("column-gap", value)];
4845
5283
  return null;
@@ -4855,7 +5293,7 @@ functionalUtility({
4855
5293
  // gap-y-[10vw]
4856
5294
  supportsCustomProperty: true,
4857
5295
  // gap-y-(--my-gap-y)
4858
- handleBareValue: ({ value }) => `calc(var(--spacing) * ${value})`,
5296
+ handleBareValue: ({ value }) => parseNumber(value) ? `calc(var(--spacing) * ${value})` : null,
4859
5297
  handle: (value) => {
4860
5298
  if (typeof value === "string") return [decl("row-gap", value)];
4861
5299
  return null;
@@ -4871,7 +5309,7 @@ functionalUtility({
4871
5309
  // gap-[10vw]
4872
5310
  supportsCustomProperty: true,
4873
5311
  // gap-(--my-gap)
4874
- handleBareValue: ({ value }) => `calc(var(--spacing) * ${value})`,
5312
+ handleBareValue: ({ value }) => parseNumber(value) ? `calc(var(--spacing) * ${value})` : null,
4875
5313
  handle: (value) => {
4876
5314
  if (typeof value === "string") return [decl("gap", value)];
4877
5315
  return null;
@@ -4930,6 +5368,31 @@ staticUtility("flex-nowrap", [["flex-wrap", "nowrap"]], { category: "flex-grid"
4930
5368
  staticUtility("flex-auto", [["flex", "1 1 auto"]], { category: "flex-grid" });
4931
5369
  staticUtility("flex-initial", [["flex", "0 1 auto"]], { category: "flex-grid" });
4932
5370
  staticUtility("flex-none", [["flex", "none"]], { category: "flex-grid" });
5371
+ staticUtility("flex-grow", [["flex-grow", "1"]], { category: "flex-grid" });
5372
+ functionalUtility({
5373
+ name: "flex-grow",
5374
+ prop: "flex-grow",
5375
+ supportsArbitrary: true,
5376
+ // grow-[25vw], grow-[2], grow-[var(--factor)], etc.
5377
+ supportsCustomProperty: true,
5378
+ // grow-(--my-grow)
5379
+ handleBareValue: ({ value }) => parseNumber(value),
5380
+ handle: (value) => [decl("flex-grow", value)],
5381
+ description: "flex-grow utility (number, arbitrary, custom property supported)",
5382
+ category: "flex-grid"
5383
+ });
5384
+ staticUtility("flex-shrink", [["flex-shrink", "1"]], { category: "flex-grid" });
5385
+ functionalUtility({
5386
+ name: "flex-shrink",
5387
+ prop: "flex-shrink",
5388
+ supportsArbitrary: true,
5389
+ // shrink-[2], shrink-[calc(100vw-var(--sidebar))], etc.
5390
+ supportsCustomProperty: true,
5391
+ // shrink-(--my-shrink)
5392
+ handleBareValue: ({ value }) => parseNumber(value),
5393
+ description: "flex-shrink utility (number, arbitrary, custom property supported)",
5394
+ category: "flex-grid"
5395
+ });
4933
5396
  functionalUtility({
4934
5397
  name: "flex",
4935
5398
  supportsArbitrary: true,
@@ -5163,7 +5626,7 @@ functionalUtility({
5163
5626
  // gap-x-[10vw]
5164
5627
  supportsCustomProperty: true,
5165
5628
  // gap-x-(--my-gap-x)
5166
- handleBareValue: ({ value }) => `calc(var(--spacing) * ${value})`,
5629
+ handleBareValue: ({ value }) => value === "px" ? "1px" : parseNumber(value) ? `calc(var(--spacing) * ${value})` : null,
5167
5630
  handle: (value) => {
5168
5631
  if (typeof value === "string") return [decl("column-gap", value)];
5169
5632
  return null;
@@ -5179,7 +5642,7 @@ functionalUtility({
5179
5642
  // gap-y-[10vw]
5180
5643
  supportsCustomProperty: true,
5181
5644
  // gap-y-(--my-gap-y)
5182
- handleBareValue: ({ value }) => `calc(var(--spacing) * ${value})`,
5645
+ handleBareValue: ({ value }) => value === "px" ? "1px" : parseNumber(value) ? `calc(var(--spacing) * ${value})` : null,
5183
5646
  handle: (value) => {
5184
5647
  if (typeof value === "string") return [decl("row-gap", value)];
5185
5648
  return null;
@@ -5195,7 +5658,7 @@ functionalUtility({
5195
5658
  // gap-[10vw]
5196
5659
  supportsCustomProperty: true,
5197
5660
  // gap-(--my-gap)
5198
- handleBareValue: ({ value }) => `calc(var(--spacing) * ${value})`,
5661
+ handleBareValue: ({ value }) => value === "px" ? "1px" : parseNumber(value) ? `calc(var(--spacing) * ${value})` : null,
5199
5662
  handle: (value) => {
5200
5663
  if (typeof value === "string") return [decl("gap", value)];
5201
5664
  return null;
@@ -5223,11 +5686,11 @@ staticUtility("justify-items-center-safe", [["justify-items", "safe center"]], {
5223
5686
  staticUtility("justify-items-stretch", [["justify-items", "stretch"]], { category: "flex-grid" });
5224
5687
  staticUtility("justify-items-normal", [["justify-items", "normal"]], { category: "flex-grid" });
5225
5688
  staticUtility("justify-self-auto", [["justify-self", "auto"]], { category: "flex-grid" });
5226
- staticUtility("justify-self-start", [["justify-self", "start"]], { category: "flex-grid" });
5689
+ staticUtility("justify-self-start", [["justify-self", "flex-start"]], { category: "flex-grid" });
5227
5690
  staticUtility("justify-self-center", [["justify-self", "center"]], { category: "flex-grid" });
5228
5691
  staticUtility("justify-self-center-safe", [["justify-self", "safe center"]], { category: "flex-grid" });
5229
- staticUtility("justify-self-end", [["justify-self", "end"]], { category: "flex-grid" });
5230
- staticUtility("justify-self-end-safe", [["justify-self", "safe end"]], { category: "flex-grid" });
5692
+ staticUtility("justify-self-end", [["justify-self", "flex-end"]], { category: "flex-grid" });
5693
+ staticUtility("justify-self-end-safe", [["justify-self", "safe flex-end"]], { category: "flex-grid" });
5231
5694
  staticUtility("justify-self-stretch", [["justify-self", "stretch"]], { category: "flex-grid" });
5232
5695
  staticUtility("content-normal", [["align-content", "normal"]], { category: "flex-grid" });
5233
5696
  staticUtility("content-center", [["align-content", "center"]], { category: "flex-grid" });
@@ -5362,7 +5825,7 @@ functionalUtility({
5362
5825
  prop,
5363
5826
  supportsArbitrary: true,
5364
5827
  supportsCustomProperty: true,
5365
- handleBareValue: ({ value }) => `calc(var(--spacing) * ${value})`,
5828
+ handleBareValue: ({ value }) => parseNumber(value) ? `calc(var(--spacing) * ${value})` : null,
5366
5829
  description: `${name} utility (number, arbitrary, custom property supported)`,
5367
5830
  category: "spacing"
5368
5831
  });
@@ -5387,144 +5850,48 @@ functionalUtility({
5387
5850
  supportsNegative: true,
5388
5851
  supportsArbitrary: true,
5389
5852
  supportsCustomProperty: true,
5390
- handleBareValue: ({ value }) => `calc(var(--spacing) * ${value})`,
5391
- handleNegativeBareValue: ({ value }) => `calc(var(--spacing) * -${value})`,
5853
+ handleBareValue: ({ value }) => parseNumber(value) ? `calc(var(--spacing) * ${value})` : null,
5854
+ handleNegativeBareValue: ({ value }) => parseNumber(value) ? `calc(var(--spacing) * -${value})` : null,
5392
5855
  description: `${name} margin utility (number, negative, arbitrary, custom property, auto, px supported)`,
5393
5856
  category: "spacing"
5394
5857
  });
5395
5858
  });
5396
- staticUtility("space-x-px", [
5397
- [
5398
- "& > :not([hidden]) ~ :not([hidden])",
5399
- [
5400
- ["--baro-space-x-reverse", "0"],
5401
- [
5402
- "margin-inline-start",
5403
- "calc(1px * calc(1 - var(--baro-space-x-reverse)))"
5404
- ],
5405
- ["margin-inline-end", "calc(1px * var(--baro-space-x-reverse))"]
5406
- ]
5407
- ]
5408
- ], { category: "spacing" });
5409
- staticUtility("-space-x-px", [
5410
- [
5411
- "& > :not([hidden]) ~ :not([hidden])",
5412
- [
5413
- ["--baro-space-x-reverse", "0"],
5414
- [
5415
- "margin-inline-start",
5416
- "calc(-1px * calc(1 - var(--baro-space-x-reverse)))"
5417
- ],
5418
- ["margin-inline-end", "calc(-1px * var(--baro-space-x-reverse))"]
5419
- ]
5420
- ]
5421
- ], { category: "spacing" });
5422
- staticUtility("space-x-reverse", [
5423
- ["& > :not([hidden]) ~ :not([hidden])", [["--baro-space-x-reverse", "1"]]]
5424
- ], { category: "spacing" });
5425
- functionalUtility({
5426
- name: "space-x",
5427
- supportsNegative: true,
5428
- supportsArbitrary: true,
5429
- supportsCustomProperty: true,
5430
- handleBareValue: ({ value }) => `calc(var(--spacing) * ${value})`,
5431
- handleNegativeBareValue: ({ value }) => `calc(var(--spacing) * -${value})`,
5432
- handle: (value, ctx, token) => {
5433
- let v = value;
5434
- if (typeof v === "number" || /^-?\d+(\.\d+)?$/.test(v)) {
5435
- v = `calc(var(--spacing) * ${token.negative ? "-" : ""}${v})`;
5436
- }
5437
- return [
5438
- rule("& > :not([hidden]) ~ :not([hidden])", [
5439
- decl("--baro-space-x-reverse", "0"),
5440
- decl(
5441
- "margin-inline-start",
5442
- `calc(${v} * calc(1 - var(--baro-space-x-reverse)))`
5443
- ),
5444
- decl("margin-inline-end", `calc(${v} * var(--baro-space-x-reverse))`)
5445
- ])
5446
- ];
5447
- },
5448
- handleCustomProperty: (value) => [
5449
- rule("& > :not([hidden]) ~ :not([hidden])", [
5450
- decl("--baro-space-x-reverse", "0"),
5451
- decl(
5452
- "margin-inline-start",
5453
- `calc(var(${value}) * calc(1 - var(--baro-space-x-reverse)))`
5454
- ),
5455
- decl(
5456
- "margin-inline-end",
5457
- `calc(var(${value}) * var(--baro-space-x-reverse))`
5458
- )
5459
- ])
5460
- ],
5461
- description: "space-x utility (number, negative, px, arbitrary, custom property, reverse supported)",
5462
- category: "spacing"
5463
- });
5464
- staticUtility("space-y-px", [
5465
- [
5466
- "& > :not([hidden]) ~ :not([hidden])",
5467
- [
5468
- ["--baro-space-y-reverse", "0"],
5469
- ["margin-block-start", "calc(1px * calc(1 - var(--baro-space-y-reverse)))"],
5470
- ["margin-block-end", "calc(1px * var(--baro-space-y-reverse))"]
5471
- ]
5472
- ]
5473
- ], { category: "spacing" });
5474
- staticUtility("-space-y-px", [
5475
- [
5476
- "& > :not([hidden]) ~ :not([hidden])",
5477
- [
5478
- ["--baro-space-y-reverse", "0"],
5479
- [
5480
- "margin-block-start",
5481
- "calc(-1px * calc(1 - var(--baro-space-y-reverse)))"
5482
- ],
5483
- ["margin-block-end", "calc(-1px * var(--baro-space-y-reverse))"]
5484
- ]
5485
- ]
5486
- ], { category: "spacing" });
5487
- staticUtility("space-y-reverse", [
5488
- ["& > :not([hidden]) ~ :not([hidden])", [["--baro-space-y-reverse", "1"]]]
5489
- ], { category: "spacing" });
5490
- functionalUtility({
5491
- name: "space-y",
5492
- supportsNegative: true,
5493
- supportsArbitrary: true,
5494
- supportsCustomProperty: true,
5495
- handleBareValue: ({ value }) => `calc(var(--spacing) * ${value})`,
5496
- handleNegativeBareValue: ({ value }) => `calc(var(--spacing) * -${value})`,
5497
- handle: (value, ctx, token) => {
5498
- let v = value;
5499
- if (typeof v === "number" || /^-?\d+(\.\d+)?$/.test(v)) {
5500
- v = `calc(var(--spacing) * ${token.negative ? "-" : ""}${v})`;
5501
- }
5502
- return [
5503
- rule("& > :not([hidden]) ~ :not([hidden])", [
5504
- decl("--baro-space-y-reverse", "0"),
5505
- decl(
5506
- "margin-block-start",
5507
- `calc(${v} * calc(1 - var(--baro-space-y-reverse)))`
5508
- ),
5509
- decl("margin-block-end", `calc(${v} * var(--baro-space-y-reverse))`)
5510
- ])
5511
- ];
5512
- },
5513
- handleCustomProperty: (value) => [
5514
- rule("& > :not([hidden]) ~ :not([hidden])", [
5515
- decl("--baro-space-y-reverse", "0"),
5516
- decl(
5517
- "margin-block-start",
5518
- `calc(var(${value}) * calc(1 - var(--baro-space-y-reverse)))`
5519
- ),
5520
- decl(
5521
- "margin-block-end",
5522
- `calc(var(${value}) * var(--baro-space-y-reverse))`
5523
- )
5524
- ])
5525
- ],
5526
- description: "space-y utility (number, negative, px, arbitrary, custom property, reverse supported)",
5527
- category: "spacing"
5859
+ const SPACE_SELECTOR = ":where(& > :not(:last-child))";
5860
+ ["x", "y"].forEach((axis) => {
5861
+ const name = `space-${axis}`;
5862
+ const rev = `--baro-space-${axis}-reverse`;
5863
+ const [start, end] = axis === "x" ? ["margin-inline-start", "margin-inline-end"] : ["margin-block-start", "margin-block-end"];
5864
+ const reverseProperty = () => atRoot([property(rev, "0")]);
5865
+ const spaceRule = (v) => rule(SPACE_SELECTOR, [
5866
+ decl(rev, "0"),
5867
+ decl(start, `calc(${v} * var(${rev}))`),
5868
+ decl(end, `calc(${v} * calc(1 - var(${rev})))`)
5869
+ ]);
5870
+ const body = (v) => [reverseProperty(), spaceRule(v)];
5871
+ staticUtility(`${name}-px`, [reverseProperty, () => spaceRule("1px")], { category: "spacing" });
5872
+ staticUtility(`-${name}-px`, [reverseProperty, () => spaceRule("-1px")], { category: "spacing" });
5873
+ staticUtility(`${name}-reverse`, [
5874
+ reverseProperty,
5875
+ () => rule(SPACE_SELECTOR, [decl(rev, "1")])
5876
+ ], { category: "spacing" });
5877
+ functionalUtility({
5878
+ name,
5879
+ supportsNegative: true,
5880
+ supportsArbitrary: true,
5881
+ supportsCustomProperty: true,
5882
+ handleBareValue: ({ value }) => parseNumber(value) ? `calc(var(--spacing) * ${value})` : null,
5883
+ handleNegativeBareValue: ({ value }) => parseNumber(value) ? `calc(var(--spacing) * -${value})` : null,
5884
+ handle: (value, _ctx, token) => {
5885
+ let v = String(value);
5886
+ if (/^-?\d+(\.\d+)?$/.test(v)) {
5887
+ v = `calc(var(--spacing) * ${token.negative ? "-" : ""}${v})`;
5888
+ }
5889
+ return body(v);
5890
+ },
5891
+ handleCustomProperty: (value) => body(`var(${value})`),
5892
+ description: `${name} utility (number, negative, px, arbitrary, custom property, reverse supported)`,
5893
+ category: "spacing"
5894
+ });
5528
5895
  });
5529
5896
  [
5530
5897
  ["w-auto", "auto"],
@@ -5751,6 +6118,9 @@ functionalUtility({
5751
6118
  });
5752
6119
  [
5753
6120
  ["max-w-none", "none"],
6121
+ ["max-w-min", "min-content"],
6122
+ ["max-w-max", "max-content"],
6123
+ ["max-w-fit", "fit-content"],
5754
6124
  ["max-w-xs", "var(--container-xs)"],
5755
6125
  ["max-w-sm", "var(--container-sm)"],
5756
6126
  ["max-w-md", "var(--container-md)"],
@@ -5781,22 +6151,23 @@ functionalUtility({
5781
6151
  description: "max-width utility (spacing, fraction, arbitrary, custom property, static supported)",
5782
6152
  category: "sizing"
5783
6153
  });
5784
- staticUtility("font-sans", [["font-family", "var(--font-family-sans)"]], { category: "typography" });
5785
- staticUtility("font-serif", [["font-family", "var(--font-family-serif)"]], { category: "typography" });
5786
- staticUtility("font-mono", [["font-family", "var(--font-family-mono)"]], { category: "typography" });
5787
- staticUtility("text-xs", [["font-size", "var(--text-xs)"], ["line-height", "var(--text-xs--line-height)"]], { category: "typography" });
5788
- staticUtility("text-sm", [["font-size", "var(--text-sm)"], ["line-height", "var(--text-sm--line-height)"]], { category: "typography" });
5789
- staticUtility("text-base", [["font-size", "var(--text-base)"], ["line-height", "var(--text-base--line-height)"]], { category: "typography" });
5790
- staticUtility("text-lg", [["font-size", "var(--text-lg)"], ["line-height", "var(--text-lg--line-height)"]], { category: "typography" });
5791
- staticUtility("text-xl", [["font-size", "var(--text-xl)"], ["line-height", "var(--text-xl--line-height)"]], { category: "typography" });
5792
- staticUtility("text-2xl", [["font-size", "var(--text-2xl)"], ["line-height", "var(--text-2xl--line-height)"]], { category: "typography" });
5793
- staticUtility("text-3xl", [["font-size", "var(--text-3xl)"], ["line-height", "var(--text-3xl--line-height)"]], { category: "typography" });
5794
- staticUtility("text-4xl", [["font-size", "var(--text-4xl)"], ["line-height", "var(--text-4xl--line-height)"]], { category: "typography" });
5795
- staticUtility("text-5xl", [["font-size", "var(--text-5xl)"], ["line-height", "var(--text-5xl--line-height)"]], { category: "typography" });
5796
- staticUtility("text-6xl", [["font-size", "var(--text-6xl)"], ["line-height", "var(--text-6xl--line-height)"]], { category: "typography" });
5797
- staticUtility("text-7xl", [["font-size", "var(--text-7xl)"], ["line-height", "var(--text-7xl--line-height)"]], { category: "typography" });
5798
- staticUtility("text-8xl", [["font-size", "var(--text-8xl)"], ["line-height", "var(--text-8xl--line-height)"]], { category: "typography" });
5799
- staticUtility("text-9xl", [["font-size", "var(--text-9xl)"], ["line-height", "var(--text-9xl--line-height)"]], { category: "typography" });
6154
+ const leadingProperty = () => atRoot([property("--baro-leading")]);
6155
+ staticUtility("font-sans", [["font-family", "var(--font-sans)"]], { category: "typography" });
6156
+ staticUtility("font-serif", [["font-family", "var(--font-serif)"]], { category: "typography" });
6157
+ staticUtility("font-mono", [["font-family", "var(--font-mono)"]], { category: "typography" });
6158
+ staticUtility("text-xs", [["font-size", "var(--text-xs)"], ["line-height", "var(--baro-leading, var(--text-xs--line-height))"]], { category: "typography" });
6159
+ staticUtility("text-sm", [["font-size", "var(--text-sm)"], ["line-height", "var(--baro-leading, var(--text-sm--line-height))"]], { category: "typography" });
6160
+ staticUtility("text-base", [["font-size", "var(--text-base)"], ["line-height", "var(--baro-leading, var(--text-base--line-height))"]], { category: "typography" });
6161
+ staticUtility("text-lg", [["font-size", "var(--text-lg)"], ["line-height", "var(--baro-leading, var(--text-lg--line-height))"]], { category: "typography" });
6162
+ staticUtility("text-xl", [["font-size", "var(--text-xl)"], ["line-height", "var(--baro-leading, var(--text-xl--line-height))"]], { category: "typography" });
6163
+ staticUtility("text-2xl", [["font-size", "var(--text-2xl)"], ["line-height", "var(--baro-leading, var(--text-2xl--line-height))"]], { category: "typography" });
6164
+ staticUtility("text-3xl", [["font-size", "var(--text-3xl)"], ["line-height", "var(--baro-leading, var(--text-3xl--line-height))"]], { category: "typography" });
6165
+ staticUtility("text-4xl", [["font-size", "var(--text-4xl)"], ["line-height", "var(--baro-leading, var(--text-4xl--line-height))"]], { category: "typography" });
6166
+ staticUtility("text-5xl", [["font-size", "var(--text-5xl)"], ["line-height", "var(--baro-leading, var(--text-5xl--line-height))"]], { category: "typography" });
6167
+ staticUtility("text-6xl", [["font-size", "var(--text-6xl)"], ["line-height", "var(--baro-leading, var(--text-6xl--line-height))"]], { category: "typography" });
6168
+ staticUtility("text-7xl", [["font-size", "var(--text-7xl)"], ["line-height", "var(--baro-leading, var(--text-7xl--line-height))"]], { category: "typography" });
6169
+ staticUtility("text-8xl", [["font-size", "var(--text-8xl)"], ["line-height", "var(--baro-leading, var(--text-8xl--line-height))"]], { category: "typography" });
6170
+ staticUtility("text-9xl", [["font-size", "var(--text-9xl)"], ["line-height", "var(--baro-leading, var(--text-9xl--line-height))"]], { category: "typography" });
5800
6171
  staticUtility("font-thin", [["font-weight", "var(--font-weight-thin)"]], { category: "typography" });
5801
6172
  staticUtility("font-extralight", [["font-weight", "var(--font-weight-extralight)"]], { category: "typography" });
5802
6173
  staticUtility("font-light", [["font-weight", "var(--font-weight-light)"]], { category: "typography" });
@@ -5842,12 +6213,12 @@ functionalUtility({
5842
6213
  description: "letter-spacing utility (theme, arbitrary, custom property supported)",
5843
6214
  category: "typography"
5844
6215
  });
5845
- staticUtility("leading-none", [["line-height", "var(--line-height-none)"]], { category: "typography" });
5846
- staticUtility("leading-tight", [["line-height", "var(--line-height-tight)"]], { category: "typography" });
5847
- staticUtility("leading-snug", [["line-height", "var(--line-height-snug)"]], { category: "typography" });
5848
- staticUtility("leading-normal", [["line-height", "var(--line-height-normal)"]], { category: "typography" });
5849
- staticUtility("leading-relaxed", [["line-height", "var(--line-height-relaxed)"]], { category: "typography" });
5850
- staticUtility("leading-loose", [["line-height", "var(--line-height-loose)"]], { category: "typography" });
6216
+ staticUtility("leading-none", [["--baro-leading", "var(--leading-none, 1)"], ["line-height", "var(--leading-none, 1)"], leadingProperty()], { category: "typography" });
6217
+ staticUtility("leading-tight", [["--baro-leading", "var(--leading-tight, 1.25)"], ["line-height", "var(--leading-tight, 1.25)"], leadingProperty()], { category: "typography" });
6218
+ staticUtility("leading-snug", [["--baro-leading", "var(--leading-snug, 1.375)"], ["line-height", "var(--leading-snug, 1.375)"], leadingProperty()], { category: "typography" });
6219
+ staticUtility("leading-normal", [["--baro-leading", "var(--leading-normal, 1.5)"], ["line-height", "var(--leading-normal, 1.5)"], leadingProperty()], { category: "typography" });
6220
+ staticUtility("leading-relaxed", [["--baro-leading", "var(--leading-relaxed, 1.625)"], ["line-height", "var(--leading-relaxed, 1.625)"], leadingProperty()], { category: "typography" });
6221
+ staticUtility("leading-loose", [["--baro-leading", "var(--leading-loose, 2)"], ["line-height", "var(--leading-loose, 2)"], leadingProperty()], { category: "typography" });
5851
6222
  functionalUtility({
5852
6223
  name: "leading",
5853
6224
  prop: "line-height",
@@ -5855,6 +6226,8 @@ functionalUtility({
5855
6226
  supportsArbitrary: true,
5856
6227
  supportsCustomProperty: true,
5857
6228
  handleBareValue: ({ value }) => parseNumber(value),
6229
+ handle: (value) => [decl("--baro-leading", value), decl("line-height", value), leadingProperty()],
6230
+ handleCustomProperty: (value) => [decl("--baro-leading", `var(${value})`), decl("line-height", `var(${value})`), leadingProperty()],
5858
6231
  description: "line-height utility (theme, number, arbitrary, custom property supported)",
5859
6232
  category: "typography"
5860
6233
  });
@@ -5864,6 +6237,17 @@ staticUtility("text-right", [["text-align", "right"]], { category: "typography"
5864
6237
  staticUtility("text-justify", [["text-align", "justify"]], { category: "typography" });
5865
6238
  staticUtility("text-start", [["text-align", "start"]], { category: "typography" });
5866
6239
  staticUtility("text-end", [["text-align", "end"]], { category: "typography" });
6240
+ const FONT_SIZE_HINTS = /* @__PURE__ */ new Set(["length", "size", "percentage", "absolute-size", "relative-size"]);
6241
+ const FONT_SIZE_KEYWORDS = /^(xx-small|x-small|small|medium|large|x-large|xx-large|xxx-large|larger|smaller)$/;
6242
+ const LENGTH_RE = /^-?(\d+\.?\d*|\.\d+)(px|r?em|r?lh|r?cap|r?ch|r?ex|r?ic|%|vh|vw|vmin|vmax|[sdl]v[hwib]|v[ib]|cq[whib]|cqmin|cqmax|pt|pc|in|cm|mm|q)$/i;
6243
+ function textArbitraryKind(raw) {
6244
+ const hint = /^([a-z-]+):(.+)$/.exec(raw);
6245
+ if (hint && (hint[1] === "color" || FONT_SIZE_HINTS.has(hint[1]))) {
6246
+ return { fontSize: hint[1] !== "color", value: hint[2] };
6247
+ }
6248
+ const fontSize2 = raw === "0" || LENGTH_RE.test(raw) || FONT_SIZE_KEYWORDS.test(raw) || /^(calc|min|max|clamp)\(/.test(raw);
6249
+ return { fontSize: fontSize2, value: raw };
6250
+ }
5867
6251
  staticUtility("text-inherit", [["color", "inherit"]], { category: "typography" });
5868
6252
  staticUtility("text-current", [["color", "currentColor"]], { category: "typography" });
5869
6253
  staticUtility("text-transparent", [["color", "transparent"]], { category: "typography" });
@@ -5877,27 +6261,14 @@ functionalUtility({
5877
6261
  supportsCustomProperty: true,
5878
6262
  supportsOpacity: true,
5879
6263
  handle: (value, ctx, token, extra) => {
5880
- if (extra?.realThemeValue) {
5881
- if (extra.opacity) {
5882
- return [
5883
- atRule("supports", `(color:color-mix(in lab, red, red))`, [
5884
- decl("color", `color-mix(in lab, ${value} ${extra.opacity}%, transparent)`)
5885
- ]),
5886
- decl("color", `color-mix(in lab, ${value} ${extra.opacity}%, transparent)`)
5887
- ];
5888
- }
5889
- return [decl("color", value)];
5890
- }
5891
- if (parseLength(value)) {
5892
- return [decl("font-size", value)];
5893
- }
5894
- return [decl("color", value)];
6264
+ if (extra?.realThemeValue) return themeColorDecls("color", value, extra);
6265
+ const kind = textArbitraryKind(value);
6266
+ return [decl(kind.fontSize ? "font-size" : "color", kind.value)];
5895
6267
  },
6268
+ // Tailwind 4: text-(--x) is a colour; text-(length:--x) is a font-size.
5896
6269
  handleCustomProperty: (value) => {
5897
- if (value.startsWith("color:")) {
5898
- return [decl("color", `var(${value.replace("color:", "")})`)];
5899
- }
5900
- return [decl("font-size", `var(${value})`)];
6270
+ const kind = textArbitraryKind(value);
6271
+ return [decl(kind.fontSize ? "font-size" : "color", `var(${kind.value})`)];
5901
6272
  },
5902
6273
  description: "text color utility (theme, arbitrary, custom property supported)",
5903
6274
  category: "typography"
@@ -5913,7 +6284,7 @@ functionalUtility({
5913
6284
  if (Array.isArray(themeValue)) {
5914
6285
  return [
5915
6286
  decl("font-size", themeValue[0]),
5916
- decl("line-height", themeValue[1])
6287
+ decl("line-height", `var(--baro-leading, ${themeValue[1]})`)
5917
6288
  ];
5918
6289
  } else {
5919
6290
  return [decl("font-size", themeValue)];
@@ -6027,17 +6398,7 @@ functionalUtility({
6027
6398
  supportsCustomProperty: true,
6028
6399
  supportsOpacity: true,
6029
6400
  handle: (value, ctx, token, extra) => {
6030
- if (extra?.realThemeValue) {
6031
- if (extra.opacity) {
6032
- return [
6033
- atRule("supports", `(color:color-mix(in lab, red, red))`, [
6034
- decl("text-decoration-color", `color-mix(in lab, ${value} ${extra.opacity}%, transparent)`)
6035
- ]),
6036
- decl("text-decoration-color", value)
6037
- ];
6038
- }
6039
- return [decl("text-decoration-color", value)];
6040
- }
6401
+ if (extra?.realThemeValue) return themeColorDecls("text-decoration-color", value, extra);
6041
6402
  return [decl("text-decoration-color", value)];
6042
6403
  },
6043
6404
  handleCustomProperty: (value) => [decl("text-decoration-color", `var(${value})`)],
@@ -6061,7 +6422,7 @@ functionalUtility({
6061
6422
  prop: "text-decoration-thickness",
6062
6423
  supportsArbitrary: true,
6063
6424
  supportsCustomProperty: true,
6064
- handleBareValue: ({ value }) => `${value}px`,
6425
+ handleBareValue: ({ value }) => parseNumber(value) ? `${value}px` : null,
6065
6426
  description: "text-decoration-thickness utility (arbitrary, custom property supported)",
6066
6427
  category: "typography"
6067
6428
  });
@@ -6076,7 +6437,7 @@ functionalUtility({
6076
6437
  prop: "text-underline-offset",
6077
6438
  supportsArbitrary: true,
6078
6439
  supportsCustomProperty: true,
6079
- handleBareValue: ({ value }) => `${value}px`,
6440
+ handleBareValue: ({ value }) => parseNumber(value) ? `${value}px` : null,
6080
6441
  description: "text-underline-offset utility (arbitrary, custom property supported)",
6081
6442
  category: "typography"
6082
6443
  });
@@ -6090,8 +6451,8 @@ functionalUtility({
6090
6451
  supportsNegative: true,
6091
6452
  supportsArbitrary: true,
6092
6453
  supportsCustomProperty: true,
6093
- handleBareValue: ({ value }) => `calc(var(--spacing) * ${value})`,
6094
- handleNegativeBareValue: ({ value }) => `calc(var(--spacing) * -${value})`,
6454
+ handleBareValue: ({ value }) => parseNumber(value) ? `calc(var(--spacing) * ${value})` : null,
6455
+ handleNegativeBareValue: ({ value }) => parseNumber(value) ? `calc(var(--spacing) * -${value})` : null,
6095
6456
  description: "text-indent utility (spacing, negative, arbitrary, custom property supported)",
6096
6457
  category: "typography"
6097
6458
  });
@@ -6114,14 +6475,14 @@ functionalUtility({
6114
6475
  staticUtility("hyphens-none", [["hyphens", "none"]], { category: "typography" });
6115
6476
  staticUtility("hyphens-manual", [["hyphens", "manual"]], { category: "typography" });
6116
6477
  staticUtility("hyphens-auto", [["hyphens", "auto"]], { category: "typography" });
6117
- staticUtility("content-none", [["content", "none"]], { category: "typography" });
6478
+ staticUtility("content-none", [["--baro-content", "none"], ["content", "none"]], { category: "typography" });
6118
6479
  functionalUtility({
6119
6480
  name: "content",
6120
6481
  prop: "content",
6121
6482
  supportsArbitrary: true,
6122
6483
  supportsCustomProperty: true,
6123
- handle: (value) => [decl("content", `"${value}"`)],
6124
- handleCustomProperty: (value) => [decl("content", `var(${value})`)],
6484
+ handle: (value) => [decl("--baro-content", `"${value}"`), decl("content", "var(--baro-content)")],
6485
+ handleCustomProperty: (value) => [decl("--baro-content", `var(${value})`), decl("content", "var(--baro-content)")],
6125
6486
  description: "content utility (arbitrary, custom property supported)",
6126
6487
  category: "typography"
6127
6488
  });
@@ -6131,7 +6492,8 @@ const gradientStopProperties = () => {
6131
6492
  property("--baro-gradient-from", "#0000", "<color>"),
6132
6493
  property("--baro-gradient-via", "#0000", "<color>"),
6133
6494
  property("--baro-gradient-to", "#0000", "<color>"),
6134
- property("--baro-gradient-stops", "transparent"),
6495
+ property("--baro-gradient-stops"),
6496
+ property("--baro-gradient-via-stops"),
6135
6497
  property("--baro-gradient-from-position", "0%", "<length-percentage>"),
6136
6498
  property("--baro-gradient-via-position", "50%", "<length-percentage>"),
6137
6499
  property("--baro-gradient-to-position", "100%", "<length-percentage>")
@@ -6189,18 +6551,17 @@ functionalUtility({
6189
6551
  description: "background-size utility (arbitrary, custom property supported)",
6190
6552
  category: "background"
6191
6553
  });
6192
- const positionValue = (position) => {
6193
- return [
6194
- decl("--baro-gradient-position", position),
6195
- styleRule("@supports (background-image: linear-gradient(in lab, red, red))", [
6196
- decl("--baro-gradient-position", `${position} in oklab`)
6197
- ]),
6198
- decl(
6199
- "background-image",
6200
- `linear-gradient(${position}, var(--baro-gradient-stops))`
6201
- )
6202
- ];
6203
- };
6554
+ const positionValue = (position) => [
6555
+ decl("--baro-gradient-position", position),
6556
+ atRule("supports", "(background-image: linear-gradient(in lab, red, red))", [
6557
+ decl("--baro-gradient-position", `${position} in oklab`)
6558
+ ]),
6559
+ decl("background-image", "linear-gradient(var(--baro-gradient-stops))")
6560
+ ];
6561
+ const legacyPositionValue = (position) => [
6562
+ decl("--baro-gradient-position", `${position} in oklab`),
6563
+ decl("background-image", "linear-gradient(var(--baro-gradient-stops))")
6564
+ ];
6204
6565
  [
6205
6566
  ["bg-linear-to-t", positionValue("to top")],
6206
6567
  ["bg-linear-to-tr", positionValue("to top right")],
@@ -6211,14 +6572,14 @@ const positionValue = (position) => {
6211
6572
  ["bg-linear-to-l", positionValue("to left")],
6212
6573
  ["bg-linear-to-tl", positionValue("to top left")],
6213
6574
  // fallback , legacy CSS compatibility
6214
- ["bg-gradient-to-t", positionValue("to top")],
6215
- ["bg-gradient-to-tr", positionValue("to top right")],
6216
- ["bg-gradient-to-r", positionValue("to right")],
6217
- ["bg-gradient-to-br", positionValue("to bottom right")],
6218
- ["bg-gradient-to-b", positionValue("to bottom")],
6219
- ["bg-gradient-to-bl", positionValue("to bottom left")],
6220
- ["bg-gradient-to-l", positionValue("to left")],
6221
- ["bg-gradient-to-tl", positionValue("to top left")]
6575
+ ["bg-gradient-to-t", legacyPositionValue("to top")],
6576
+ ["bg-gradient-to-tr", legacyPositionValue("to top right")],
6577
+ ["bg-gradient-to-r", legacyPositionValue("to right")],
6578
+ ["bg-gradient-to-br", legacyPositionValue("to bottom right")],
6579
+ ["bg-gradient-to-b", legacyPositionValue("to bottom")],
6580
+ ["bg-gradient-to-bl", legacyPositionValue("to bottom left")],
6581
+ ["bg-gradient-to-l", legacyPositionValue("to left")],
6582
+ ["bg-gradient-to-tl", legacyPositionValue("to top left")]
6222
6583
  ].forEach(([name, value]) => {
6223
6584
  staticUtility(name, value, { category: "background", priority: 1e3 });
6224
6585
  });
@@ -6229,12 +6590,7 @@ functionalUtility({
6229
6590
  supportsCustomProperty: true,
6230
6591
  handle: (value, context, token) => {
6231
6592
  if (parseNumber(value)) {
6232
- return [
6233
- decl(
6234
- "background-image",
6235
- `linear-gradient(${value}deg in oklab, var(--baro-gradient-stops))`
6236
- )
6237
- ];
6593
+ return positionValue(`${value}deg`);
6238
6594
  }
6239
6595
  if (token.arbitrary) {
6240
6596
  return [
@@ -6263,152 +6619,79 @@ functionalUtility({
6263
6619
  description: "linear-gradient background-image utility (angle, arbitrary, custom property supported)",
6264
6620
  category: "background"
6265
6621
  });
6266
- staticUtility("bg-radial", [
6267
- ["background-image", "radial-gradient(in oklab, var(--baro-gradient-stops))"]
6268
- ], { category: "background" });
6622
+ const gradientImage = (fn, position, fallback) => [
6623
+ decl("--baro-gradient-position", position),
6624
+ decl("background-image", `${fn}(var(--baro-gradient-stops${fallback ? `,${fallback}` : ""}))`)
6625
+ ];
6626
+ staticUtility("bg-radial", gradientImage("radial-gradient", "in oklab"), { category: "background" });
6269
6627
  functionalUtility({
6270
6628
  name: "bg-radial",
6271
6629
  prop: "background-image",
6272
6630
  supportsArbitrary: true,
6273
6631
  supportsCustomProperty: true,
6274
- handle: (value, context, token) => {
6275
- if (token.arbitrary) {
6276
- return [
6277
- decl(
6278
- "background-image",
6279
- `radial-gradient(var(--baro-gradient-stops, ${value}))`
6280
- )
6281
- ];
6282
- }
6283
- if (token.customProperty) {
6284
- return [
6285
- decl(
6286
- "background-image",
6287
- `radial-gradient(var(--baro-gradient-stops, var(${value})))`
6288
- )
6289
- ];
6290
- }
6632
+ handle: (value, _context, token) => {
6633
+ if (token.arbitrary) return gradientImage("radial-gradient", value, value);
6634
+ if (token.customProperty) return gradientImage("radial-gradient", `var(${value})`, `var(${value})`);
6291
6635
  return null;
6292
6636
  },
6293
- handleCustomProperty: (value) => [
6294
- decl(
6295
- "background-image",
6296
- `radial-gradient(var(--baro-gradient-stops, var(${value})))`
6297
- )
6298
- ],
6637
+ handleCustomProperty: (value) => gradientImage("radial-gradient", `var(${value})`, `var(${value})`),
6299
6638
  description: "radial-gradient background-image utility (arbitrary, custom property supported)",
6300
6639
  category: "background"
6301
6640
  });
6302
- staticUtility("bg-conic", [
6303
- [
6304
- "background-image",
6305
- "conic-gradient(from 0deg in oklab, var(--baro-gradient-stops))"
6306
- ]
6307
- ], { category: "background" });
6641
+ staticUtility("bg-conic", gradientImage("conic-gradient", "in oklab"), { category: "background" });
6308
6642
  functionalUtility({
6309
6643
  name: "bg-conic",
6310
6644
  prop: "background-image",
6311
6645
  supportsArbitrary: true,
6312
6646
  supportsCustomProperty: true,
6313
- handle: (value, context, token) => {
6314
- if (parseNumber(value)) {
6315
- return [
6316
- decl(
6317
- "background-image",
6318
- `conic-gradient(from ${value}deg in oklab, var(--baro-gradient-stops))`
6319
- )
6320
- ];
6321
- }
6322
- if (token.arbitrary) {
6323
- return [decl("background-image", `${value}`)];
6324
- }
6325
- if (token.customProperty) {
6326
- return [
6327
- decl(
6328
- "background-image",
6329
- `conic-gradient(var(--baro-gradient-stops, var(${value})))`
6330
- )
6331
- ];
6647
+ handle: (value, _context, token) => {
6648
+ if (!token.arbitrary && !token.customProperty && parseNumber(value)) {
6649
+ return gradientImage("conic-gradient", `from ${value}deg in oklab`);
6332
6650
  }
6651
+ if (token.arbitrary) return gradientImage("conic-gradient", value, value);
6652
+ if (token.customProperty) return gradientImage("conic-gradient", `var(${value})`, `var(${value})`);
6333
6653
  return null;
6334
6654
  },
6335
- handleCustomProperty: (value) => [decl("background-image", `var(${value})`)],
6655
+ handleCustomProperty: (value) => gradientImage("conic-gradient", `var(${value})`, `var(${value})`),
6336
6656
  description: "conic-gradient background-image utility (angle, arbitrary, custom property supported)",
6337
6657
  category: "background"
6338
6658
  });
6659
+ const G = "--baro-gradient";
6660
+ const stopsDecls = (stop, color) => {
6661
+ const colorDecls = typeof color === "string" ? [decl(`${G}-${stop}`, color)] : color;
6662
+ if (stop === "via") {
6663
+ return [
6664
+ gradientStopProperties(),
6665
+ ...colorDecls,
6666
+ decl(`${G}-via-stops`, `var(${G}-position), var(${G}-from) var(${G}-from-position), var(${G}-via) var(${G}-via-position), var(${G}-to) var(${G}-to-position)`),
6667
+ decl(`${G}-stops`, `var(${G}-via-stops)`)
6668
+ ];
6669
+ }
6670
+ return [
6671
+ gradientStopProperties(),
6672
+ ...colorDecls,
6673
+ decl(`${G}-stops`, `var(${G}-via-stops, var(${G}-position), var(${G}-from) var(${G}-from-position), var(${G}-to) var(${G}-to-position))`)
6674
+ ];
6675
+ };
6339
6676
  ["from", "via", "to"].forEach((stop) => {
6340
6677
  functionalUtility({
6341
6678
  name: stop,
6342
- themeKeys: ["colors"],
6343
- supportsArbitrary: true,
6344
- supportsCustomProperty: true,
6345
- supportsOpacity: true,
6346
- handle: (value, context, token, extra) => {
6347
- if (extra?.realThemeValue) {
6348
- if (stop === "from") {
6349
- let color = value;
6350
- if (extra?.opacity) {
6351
- color = `color-mix(in lab, ${value} ${extra.opacity}%, transparent)`;
6352
- }
6353
- return [
6354
- gradientStopProperties(),
6355
- decl(`--baro-gradient-from`, color),
6356
- // decl(`--baro-gradient-to`, "var(--baro-gradient-to, transparent)"),
6357
- decl(`--baro-gradient-stops`, "var(--baro-gradient-from),var(--baro-gradient-to)")
6358
- ];
6359
- }
6360
- if (stop === "via") {
6361
- let color = value;
6362
- if (extra?.opacity) {
6363
- color = `color-mix(in lab, ${value} ${extra.opacity}%, transparent)`;
6364
- }
6365
- return [
6366
- gradientStopProperties(),
6367
- decl(`--baro-gradient-to`, color),
6368
- decl(`--baro-gradient-stops`, `var(--baro-gradient-from), ${value} var(--baro-gradient-via-position), var(--baro-gradient-to)`)
6369
- // via 포함 stops
6370
- ];
6371
- }
6372
- if (stop === "to") {
6373
- let color = value;
6374
- if (extra?.opacity) {
6375
- color = `color-mix(in lab, ${value} ${extra.opacity}%, transparent)`;
6376
- }
6377
- return [
6378
- gradientStopProperties(),
6379
- decl(`--baro-gradient-to`, color)
6380
- ];
6381
- }
6679
+ themeKeys: ["colors"],
6680
+ supportsArbitrary: true,
6681
+ supportsCustomProperty: true,
6682
+ supportsOpacity: true,
6683
+ handle: (value, _context, _token, extra) => {
6684
+ if (extra?.realThemeValue) {
6685
+ return stopsDecls(stop, themeColorDecls(`${G}-${stop}`, value, extra));
6382
6686
  }
6383
6687
  if (parseLength(value)) {
6384
- return [decl(`--baro-gradient-${stop}-position`, value)];
6688
+ return [gradientStopProperties(), decl(`${G}-${stop}-position`, value)];
6385
6689
  }
6386
6690
  if (parseNumber(value)) {
6387
- return [decl(`--baro-gradient-${stop}-position`, `${value}%`)];
6691
+ return [gradientStopProperties(), decl(`${G}-${stop}-position`, `${value}%`)];
6388
6692
  }
6389
6693
  if (parseColor(value)) {
6390
- if (stop === "from") {
6391
- return [
6392
- gradientStopProperties(),
6393
- decl(`--baro-gradient-from`, value),
6394
- decl(`--baro-gradient-to`, "transparent"),
6395
- decl(`--baro-gradient-stops`, "var(--baro-gradient-from),var(--baro-gradient-to)")
6396
- ];
6397
- }
6398
- if (stop === "via") {
6399
- return [
6400
- gradientStopProperties(),
6401
- decl(`--baro-gradient-to`, value),
6402
- decl(`--baro-gradient-stops`, `var(--baro-gradient-from), ${value} var(--baro-gradient-via-position), var(--baro-gradient-to)`)
6403
- // via 포함 stops
6404
- ];
6405
- }
6406
- if (stop === "to") {
6407
- return [
6408
- gradientStopProperties(),
6409
- decl(`--baro-gradient-to`, value)
6410
- ];
6411
- }
6694
+ return stopsDecls(stop, value);
6412
6695
  }
6413
6696
  return null;
6414
6697
  },
@@ -6443,20 +6726,7 @@ functionalUtility({
6443
6726
  if (value.startsWith("length:")) {
6444
6727
  return [decl("background-size", value.replace("length:", ""))];
6445
6728
  }
6446
- if (extra?.realThemeValue) {
6447
- if (extra.opacity) {
6448
- return [
6449
- atRule("supports", `(color:color-mix(in lab, red, red))`, [
6450
- decl(
6451
- "background-color",
6452
- `color-mix(in lab, ${value} ${extra.opacity}%, transparent)`
6453
- )
6454
- ]),
6455
- decl("background-color", `color-mix(in lab, ${value} ${extra.opacity}%, transparent)`)
6456
- ];
6457
- }
6458
- return [decl("background-color", value)];
6459
- }
6729
+ if (extra?.realThemeValue) return themeColorDecls("background-color", value, extra);
6460
6730
  if (parseColor(value)) {
6461
6731
  const parsedColor = parseColor(value);
6462
6732
  if (value.startsWith("color:")) {
@@ -6469,18 +6739,20 @@ functionalUtility({
6469
6739
  }
6470
6740
  return null;
6471
6741
  },
6472
- handleCustomProperty: (value) => [decl("background-size", `var(${value})`)],
6742
+ handleCustomProperty: (value) => value.startsWith("length:") ? [decl("background-size", `var(${value.slice(7)})`)] : [decl("background-color", `var(${value})`)],
6473
6743
  description: "background-size utility (arbitrary, custom property supported)",
6474
6744
  category: "background"
6475
6745
  });
6476
6746
  staticUtility("rounded-none", [["border-radius", "0px"]], { category: "borders" });
6477
6747
  staticUtility("rounded-sm", [["border-radius", "var(--radius-sm)"]], { category: "borders" });
6478
- staticUtility("rounded", [["border-radius", "var(--radius)"]], { category: "borders" });
6748
+ staticUtility("rounded", [["border-radius", "0.25rem"]], { category: "borders" });
6479
6749
  staticUtility("rounded-md", [["border-radius", "var(--radius-md)"]], { category: "borders" });
6480
6750
  staticUtility("rounded-lg", [["border-radius", "var(--radius-lg)"]], { category: "borders" });
6481
6751
  staticUtility("rounded-xl", [["border-radius", "var(--radius-xl)"]], { category: "borders" });
6482
6752
  staticUtility("rounded-2xl", [["border-radius", "var(--radius-2xl)"]], { category: "borders" });
6483
6753
  staticUtility("rounded-3xl", [["border-radius", "var(--radius-3xl)"]], { category: "borders" });
6754
+ staticUtility("rounded-4xl", [["border-radius", "var(--radius-4xl)"]], { category: "borders" });
6755
+ staticUtility("rounded-xs", [["border-radius", "var(--radius-xs)"]], { category: "borders" });
6484
6756
  staticUtility("rounded-full", [["border-radius", "9999px"]], { category: "borders" });
6485
6757
  [
6486
6758
  ["rounded-t", ["border-top-left-radius", "border-top-right-radius"]],
@@ -6495,12 +6767,14 @@ staticUtility("rounded-full", [["border-radius", "9999px"]], { category: "border
6495
6767
  const propList = props;
6496
6768
  staticUtility(`${name}-none`, propList.map((prop) => [prop, "0px"]), { category: "borders" });
6497
6769
  staticUtility(`${name}-sm`, propList.map((prop) => [prop, "var(--radius-sm)"]), { category: "borders" });
6498
- staticUtility(`${name}`, propList.map((prop) => [prop, "var(--radius)"]), { category: "borders" });
6770
+ staticUtility(`${name}`, propList.map((prop) => [prop, "0.25rem"]), { category: "borders" });
6499
6771
  staticUtility(`${name}-md`, propList.map((prop) => [prop, "var(--radius-md)"]), { category: "borders" });
6500
6772
  staticUtility(`${name}-lg`, propList.map((prop) => [prop, "var(--radius-lg)"]), { category: "borders" });
6501
6773
  staticUtility(`${name}-xl`, propList.map((prop) => [prop, "var(--radius-xl)"]), { category: "borders" });
6502
6774
  staticUtility(`${name}-2xl`, propList.map((prop) => [prop, "var(--radius-2xl)"]), { category: "borders" });
6503
6775
  staticUtility(`${name}-3xl`, propList.map((prop) => [prop, "var(--radius-3xl)"]), { category: "borders" });
6776
+ staticUtility(`${name}-4xl`, propList.map((prop) => [prop, "var(--radius-4xl)"]), { category: "borders" });
6777
+ staticUtility(`${name}-xs`, propList.map((prop) => [prop, "var(--radius-xs)"]), { category: "borders" });
6504
6778
  staticUtility(`${name}-full`, propList.map((prop) => [prop, "9999px"]), { category: "borders" });
6505
6779
  functionalUtility({
6506
6780
  name,
@@ -6531,11 +6805,15 @@ functionalUtility({
6531
6805
  description: "border-radius utility (spacing, arbitrary, custom property support)",
6532
6806
  category: "borders"
6533
6807
  });
6534
- staticUtility("border-0", [["border-width", "0px"]], { category: "borders" });
6535
- staticUtility("border-2", [["border-width", "2px"]], { category: "borders" });
6536
- staticUtility("border-4", [["border-width", "4px"]], { category: "borders" });
6537
- staticUtility("border-8", [["border-width", "8px"]], { category: "borders" });
6538
- staticUtility("border", [["border-width", "1px"]], { category: "borders" });
6808
+ const borderStyleProperty = () => atRoot([property("--baro-border-style", "solid")]);
6809
+ const withBorderStyle = (props, width) => [
6810
+ borderStyleProperty(),
6811
+ ...props.map((prop) => decl(prop.replace("width", "style"), "var(--baro-border-style)")),
6812
+ ...props.map((prop) => decl(prop, width))
6813
+ ];
6814
+ [["border-0", "0px"], ["border-2", "2px"], ["border-4", "4px"], ["border-8", "8px"], ["border", "1px"]].forEach(([name, width]) => {
6815
+ staticUtility(name, [borderStyleProperty, ["border-style", "var(--baro-border-style)"], ["border-width", width]], { category: "borders" });
6816
+ });
6539
6817
  [
6540
6818
  ["border-x", ["border-left-width", "border-right-width"]],
6541
6819
  ["border-y", ["border-top-width", "border-bottom-width"]],
@@ -6545,11 +6823,16 @@ staticUtility("border", [["border-width", "1px"]], { category: "borders" });
6545
6823
  ["border-l", ["border-left-width"]]
6546
6824
  ].forEach(([name, props]) => {
6547
6825
  const propList = props;
6548
- staticUtility(`${name}-0`, propList.map((prop) => [prop, "0px"]));
6549
- staticUtility(`${name}-2`, propList.map((prop) => [prop, "2px"]));
6550
- staticUtility(`${name}-4`, propList.map((prop) => [prop, "4px"]));
6551
- staticUtility(`${name}-8`, propList.map((prop) => [prop, "8px"]));
6552
- staticUtility(`${name}`, propList.map((prop) => [prop, "1px"]));
6826
+ const styled = (width) => [
6827
+ borderStyleProperty,
6828
+ ...propList.map((prop) => [prop.replace("width", "style"), "var(--baro-border-style)"]),
6829
+ ...propList.map((prop) => [prop, width])
6830
+ ];
6831
+ staticUtility(`${name}-0`, styled("0px"));
6832
+ staticUtility(`${name}-2`, styled("2px"));
6833
+ staticUtility(`${name}-4`, styled("4px"));
6834
+ staticUtility(`${name}-8`, styled("8px"));
6835
+ staticUtility(`${name}`, styled("1px"));
6553
6836
  functionalUtility({
6554
6837
  name,
6555
6838
  themeKeys: ["borderWidth", "colors"],
@@ -6561,18 +6844,19 @@ staticUtility("border", [["border-width", "1px"]], { category: "borders" });
6561
6844
  }
6562
6845
  return null;
6563
6846
  },
6564
- handle: (value, ctx, token) => {
6847
+ handle: (value, ctx, token, extra) => {
6848
+ if (extra?.realThemeValue) return propList.flatMap((prop) => themeColorDecls(prop.replace("width", "color"), value, extra));
6565
6849
  if (parseColor(value)) {
6566
6850
  return propList.map((prop) => decl(prop.replace("width", "color"), value));
6567
6851
  }
6568
6852
  if (token.arbitrary) {
6569
- return propList.map((prop) => decl(prop, value));
6853
+ return withBorderStyle(propList, value);
6570
6854
  }
6571
6855
  return null;
6572
6856
  },
6573
6857
  handleCustomProperty: (value) => {
6574
6858
  if (value.startsWith("length:")) {
6575
- return propList.map((prop) => decl(prop, `var(${value.replace("length:", "")})`));
6859
+ return withBorderStyle(propList, `var(${value.replace("length:", "")})`);
6576
6860
  }
6577
6861
  return propList.map((prop) => decl(prop.replace("width", "color"), `var(${value})`));
6578
6862
  },
@@ -6583,12 +6867,35 @@ staticUtility("border", [["border-width", "1px"]], { category: "borders" });
6583
6867
  staticUtility("border-inherit", [["border-color", "inherit"]], { category: "borders" });
6584
6868
  staticUtility("border-current", [["border-color", "currentColor"]], { category: "borders" });
6585
6869
  staticUtility("border-transparent", [["border-color", "transparent"]], { category: "borders" });
6586
- staticUtility("border-solid", [["border-style", "solid"]], { category: "borders" });
6587
- staticUtility("border-dashed", [["border-style", "dashed"]], { category: "borders" });
6588
- staticUtility("border-dotted", [["border-style", "dotted"]], { category: "borders" });
6589
- staticUtility("border-double", [["border-style", "double"]], { category: "borders" });
6590
- staticUtility("border-hidden", [["border-style", "hidden"]], { category: "borders" });
6591
- staticUtility("border-none", [["border-style", "none"]], { category: "borders" });
6870
+ staticUtility("border-solid", [["--baro-border-style", "solid"], ["border-style", "solid"]], { category: "borders" });
6871
+ staticUtility("border-dashed", [["--baro-border-style", "dashed"], ["border-style", "dashed"]], { category: "borders" });
6872
+ staticUtility("border-dotted", [["--baro-border-style", "dotted"], ["border-style", "dotted"]], { category: "borders" });
6873
+ staticUtility("border-double", [["--baro-border-style", "double"], ["border-style", "double"]], { category: "borders" });
6874
+ staticUtility("border-hidden", [["--baro-border-style", "hidden"], ["border-style", "hidden"]], { category: "borders" });
6875
+ staticUtility("border-none", [["--baro-border-style", "none"], ["border-style", "none"]], { category: "borders" });
6876
+ const divideSides = { x: ["border-inline-start", "border-inline-end", "border-inline-style"], y: ["border-top", "border-bottom", "border-bottom-style", "border-top-style"] };
6877
+ Object.entries(divideSides).forEach(([axis, [start, end, ...styles]]) => {
6878
+ const rev = `--baro-divide-${axis}-reverse`;
6879
+ const divide = (width) => [
6880
+ borderStyleProperty(),
6881
+ rule(":where(& > :not(:last-child))", [
6882
+ decl(rev, "0"),
6883
+ ...styles.map((s) => decl(s, "var(--baro-border-style)")),
6884
+ decl(`${start}-width`, `calc(${width} * var(${rev}))`),
6885
+ decl(`${end}-width`, `calc(${width} * calc(1 - var(${rev})))`)
6886
+ ])
6887
+ ];
6888
+ staticUtility(`divide-${axis}`, divide("1px"), { category: "borders" });
6889
+ staticUtility(`divide-${axis}-reverse`, [rule(":where(& > :not(:last-child))", [decl(rev, "1")])], { category: "borders" });
6890
+ functionalUtility({
6891
+ name: `divide-${axis}`,
6892
+ supportsArbitrary: true,
6893
+ handleBareValue: ({ value }) => /^\d+$/.test(value) ? `${value}px` : null,
6894
+ handle: (value) => divide(value),
6895
+ description: `divide-${axis} width utility`,
6896
+ category: "borders"
6897
+ });
6898
+ });
6592
6899
  functionalUtility({
6593
6900
  name: "border",
6594
6901
  themeKeys: ["colors", "borderWidth"],
@@ -6596,25 +6903,15 @@ functionalUtility({
6596
6903
  supportsCustomProperty: true,
6597
6904
  supportsOpacity: true,
6598
6905
  handle: (value, ctx, token, extra) => {
6599
- if (extra?.realThemeValue) {
6600
- if (extra.opacity) {
6601
- return [
6602
- atRule("supports", `(color:color-mix(in lab, red, red))`, [
6603
- decl("border-color", `color-mix(in lab, ${value} ${extra.opacity}%, transparent)`)
6604
- ]),
6605
- decl("border-color", `color-mix(in lab, ${value} ${extra.opacity}%, transparent)`)
6606
- ];
6607
- }
6608
- return [decl("border-color", value)];
6609
- }
6906
+ if (extra?.realThemeValue) return themeColorDecls("border-color", value, extra);
6610
6907
  if (token.arbitrary) {
6611
6908
  if (parseLength(value)) {
6612
- return [decl("border-width", value)];
6909
+ return withBorderStyle(["border-width"], value);
6613
6910
  }
6614
6911
  return [decl("border-color", value)];
6615
6912
  }
6616
6913
  if (parseNumber(value)) {
6617
- return [decl("border-width", `${value}px`)];
6914
+ return withBorderStyle(["border-width"], `${value}px`);
6618
6915
  }
6619
6916
  if (parseColor(value)) {
6620
6917
  return [decl("border-color", value)];
@@ -6623,26 +6920,35 @@ functionalUtility({
6623
6920
  },
6624
6921
  handleCustomProperty: (value) => {
6625
6922
  if (value.startsWith("length:")) {
6626
- return [decl("border-width", `var(${value.replace("length:", "")})`)];
6923
+ return withBorderStyle(["border-width"], `var(${value.replace("length:", "")})`);
6627
6924
  }
6628
6925
  return [decl("border-color", `var(${value})`)];
6629
6926
  },
6630
6927
  description: "border-width utility (number, arbitrary, custom property support)",
6631
6928
  category: "borders"
6632
6929
  });
6633
- staticUtility("outline-0", [["outline-width", "0px"]], { category: "borders" });
6634
- staticUtility("outline-1", [["outline-width", "1px"]], { category: "borders" });
6635
- staticUtility("outline-2", [["outline-width", "2px"]], { category: "borders" });
6636
- staticUtility("outline-4", [["outline-width", "4px"]], { category: "borders" });
6637
- staticUtility("outline-8", [["outline-width", "8px"]], { category: "borders" });
6930
+ const outlineStyleProperty = () => atRoot([property("--baro-outline-style", "solid")]);
6931
+ const withOutlineStyle = (width) => [
6932
+ outlineStyleProperty(),
6933
+ decl("outline-style", "var(--baro-outline-style)"),
6934
+ decl("outline-width", width)
6935
+ ];
6936
+ [["outline-0", "0px"], ["outline-1", "1px"], ["outline-2", "2px"], ["outline-4", "4px"], ["outline-8", "8px"]].forEach(([name, width]) => {
6937
+ staticUtility(name, [outlineStyleProperty, ["outline-style", "var(--baro-outline-style)"], ["outline-width", width]], { category: "borders" });
6938
+ });
6638
6939
  staticUtility("outline-inherit", [["outline-color", "inherit"]], { category: "borders" });
6639
6940
  staticUtility("outline-current", [["outline-color", "currentColor"]], { category: "borders" });
6640
6941
  staticUtility("outline-transparent", [["outline-color", "transparent"]], { category: "borders" });
6641
- staticUtility("outline-none", [["outline", "2px solid transparent"], ["outline-offset", "2px"]], { category: "borders" });
6642
- staticUtility("outline", [["outline-style", "solid"]], { category: "borders" });
6643
- staticUtility("outline-dashed", [["outline-style", "dashed"]], { category: "borders" });
6644
- staticUtility("outline-dotted", [["outline-style", "dotted"]], { category: "borders" });
6645
- staticUtility("outline-double", [["outline-style", "double"]], { category: "borders" });
6942
+ staticUtility("outline-none", [["--baro-outline-style", "none"], ["outline-style", "none"]], { category: "borders" });
6943
+ staticUtility("outline-hidden", [
6944
+ ["--baro-outline-style", "none"],
6945
+ ["outline-style", "none"],
6946
+ atRule("media", "(forced-colors: active)", [decl("outline", "2px solid transparent"), decl("outline-offset", "2px")])
6947
+ ], { category: "borders" });
6948
+ staticUtility("outline", [outlineStyleProperty, ["outline-style", "var(--baro-outline-style)"], ["outline-width", "1px"]], { category: "borders" });
6949
+ ["solid", "dashed", "dotted", "double"].forEach((style) => {
6950
+ staticUtility(`outline-${style}`, [["--baro-outline-style", style], ["outline-style", style]], { category: "borders" });
6951
+ });
6646
6952
  staticUtility("outline-offset-0", [["outline-offset", "0px"]], { category: "borders" });
6647
6953
  staticUtility("outline-offset-1", [["outline-offset", "1px"]], { category: "borders" });
6648
6954
  staticUtility("outline-offset-2", [["outline-offset", "2px"]], { category: "borders" });
@@ -6667,16 +6973,18 @@ functionalUtility({
6667
6973
  themeKeys: ["colors", "borderWidth"],
6668
6974
  supportsArbitrary: true,
6669
6975
  supportsCustomProperty: true,
6670
- handle: (value, ctx, token) => {
6976
+ supportsOpacity: true,
6977
+ handle: (value, ctx, token, extra) => {
6978
+ if (extra?.realThemeValue) return themeColorDecls("outline-color", value, extra);
6671
6979
  if (parseColor(value)) {
6672
6980
  return [decl("outline-color", value)];
6673
6981
  }
6674
6982
  if (parseNumber(value)) {
6675
- return [decl("outline-width", `${value}px`)];
6983
+ return withOutlineStyle(`${value}px`);
6676
6984
  }
6677
6985
  if (token.arbitrary) {
6678
6986
  if (parseLength(value)) {
6679
- return [decl("outline-width", value)];
6987
+ return withOutlineStyle(value);
6680
6988
  }
6681
6989
  return [decl("outline-color", value)];
6682
6990
  }
@@ -6687,7 +6995,7 @@ functionalUtility({
6687
6995
  return [decl("outline-color", value.replace("color:", ""))];
6688
6996
  }
6689
6997
  if (value.startsWith("length:")) {
6690
- return [decl("outline-width", `var(${value.replace("length:", "")})`)];
6998
+ return withOutlineStyle(`var(${value.replace("length:", "")})`);
6691
6999
  }
6692
7000
  return [decl("outline-color", `var(${value})`)];
6693
7001
  },
@@ -6708,6 +7016,40 @@ functionalUtility({
6708
7016
  description: "outline-width utility (number, arbitrary, custom property support)",
6709
7017
  category: "borders"
6710
7018
  });
7019
+ const divideColor = (value) => [rule(":where(& > :not(:last-child))", [decl("border-color", value)])];
7020
+ staticUtility("divide-inherit", divideColor("inherit"), { category: "borders" });
7021
+ staticUtility("divide-current", divideColor("currentColor"), { category: "borders" });
7022
+ staticUtility("divide-transparent", divideColor("transparent"), { category: "borders" });
7023
+ functionalUtility({
7024
+ name: "divide",
7025
+ themeKeys: ["colors"],
7026
+ supportsArbitrary: true,
7027
+ supportsCustomProperty: true,
7028
+ supportsOpacity: true,
7029
+ handle: (value, _ctx, _token, extra) => {
7030
+ if (extra?.realThemeValue) {
7031
+ return [rule(":where(& > :not(:last-child))", themeColorDecls("border-color", value, extra))];
7032
+ }
7033
+ if (parseColor(value)) return divideColor(value);
7034
+ return null;
7035
+ },
7036
+ handleCustomProperty: (value) => divideColor(`var(${value})`),
7037
+ description: "divide-color utility (theme, alpha, arbitrary, custom property)",
7038
+ category: "borders"
7039
+ });
7040
+ const ROTATE_SKEW = "var(--baro-rotate-x,) var(--baro-rotate-y,) var(--baro-rotate-z,) var(--baro-skew-x,) var(--baro-skew-y,)";
7041
+ const rotateAxis = (axis, fn) => [decl(`--baro-rotate-${axis}`, fn), decl("transform", ROTATE_SKEW)];
7042
+ const skewAxis = (axis, fn) => [decl(`--baro-skew-${axis}`, fn), decl("transform", ROTATE_SKEW)];
7043
+ const scaleProperties = () => atRoot([
7044
+ property("--baro-scale-x", "1"),
7045
+ property("--baro-scale-y", "1"),
7046
+ property("--baro-scale-z", "1")
7047
+ ]);
7048
+ const scaleAxis = (axis, v) => [
7049
+ scaleProperties(),
7050
+ decl(`--baro-scale-${axis}`, v),
7051
+ decl("scale", axis === "z" ? "var(--baro-scale-x) var(--baro-scale-y) var(--baro-scale-z)" : "var(--baro-scale-x) var(--baro-scale-y)")
7052
+ ];
6711
7053
  staticUtility("transform-none", [["transform", "none"]], {
6712
7054
  category: "transform"
6713
7055
  });
@@ -6716,7 +7058,7 @@ staticUtility(
6716
7058
  [
6717
7059
  [
6718
7060
  "transform",
6719
- "translateZ(0) var(--baro-rotate-x) var(--baro-rotate-y) var(--baro-rotate-z) var(--baro-skew-x) var(--baro-skew-y)"
7061
+ `translateZ(0) ${ROTATE_SKEW}`
6720
7062
  ]
6721
7063
  ],
6722
7064
  { category: "transform" }
@@ -6724,7 +7066,7 @@ staticUtility(
6724
7066
  staticUtility("transform-cpu", [
6725
7067
  [
6726
7068
  "transform",
6727
- "var(--baro-rotate-x) var(--baro-rotate-y) var(--baro-rotate-z) var(--baro-skew-x) var(--baro-skew-y)"
7069
+ ROTATE_SKEW
6728
7070
  ]
6729
7071
  ]);
6730
7072
  staticUtility("transform-3d", [["transform-style", "preserve-3d"]], {
@@ -6853,13 +7195,11 @@ functionalUtility({
6853
7195
  if (parseNumber(value) || negative) {
6854
7196
  const deg = `${Math.abs(Number(value))}deg`;
6855
7197
  const sign = negative || String(value).startsWith("-") ? "-" : "";
6856
- return [decl("transform", `rotateX(${sign}${deg}) var(--baro-rotate-y)`)];
7198
+ return rotateAxis("x", `rotateX(${sign}${deg})`);
6857
7199
  }
6858
- return [decl("transform", `rotateX(${value}) var(--baro-rotate-y)`)];
7200
+ return rotateAxis("x", `rotateX(${value})`);
6859
7201
  },
6860
- handleCustomProperty: (value) => [
6861
- decl("transform", `rotateX(var(${value})) var(--baro-rotate-y)`)
6862
- ],
7202
+ handleCustomProperty: (value) => rotateAxis("x", `rotateX(var(${value}))`),
6863
7203
  description: "rotate-x utility (named, arbitrary, custom property supported)",
6864
7204
  category: "transform"
6865
7205
  });
@@ -6873,13 +7213,11 @@ functionalUtility({
6873
7213
  if (parseNumber(value) || negative) {
6874
7214
  const deg = `${Math.abs(Number(value))}deg`;
6875
7215
  const sign = negative || String(value).startsWith("-") ? "-" : "";
6876
- return [decl("transform", `var(--baro-rotate-x) rotateY(${sign}${deg})`)];
7216
+ return rotateAxis("y", `rotateY(${sign}${deg})`);
6877
7217
  }
6878
- return [decl("transform", `var(--baro-rotate-x) rotateY(${value})`)];
7218
+ return rotateAxis("y", `rotateY(${value})`);
6879
7219
  },
6880
- handleCustomProperty: (value) => [
6881
- decl("transform", `var(--baro-rotate-x) rotateY(var(${value}))`)
6882
- ],
7220
+ handleCustomProperty: (value) => rotateAxis("y", `rotateY(var(${value}))`),
6883
7221
  description: "rotate-y utility (named, arbitrary, custom property supported)",
6884
7222
  category: "transform"
6885
7223
  });
@@ -6893,26 +7231,11 @@ functionalUtility({
6893
7231
  if (parseNumber(value) || negative) {
6894
7232
  const deg = `${Math.abs(Number(value))}deg`;
6895
7233
  const sign = negative || String(value).startsWith("-") ? "-" : "";
6896
- return [
6897
- decl(
6898
- "transform",
6899
- `var(--baro-rotate-x) var(--baro-rotate-y) rotateZ(${sign}${deg})`
6900
- )
6901
- ];
7234
+ return rotateAxis("z", `rotateZ(${sign}${deg})`);
6902
7235
  }
6903
- return [
6904
- decl(
6905
- "transform",
6906
- `var(--baro-rotate-x) var(--baro-rotate-y) rotateZ(${value})`
6907
- )
6908
- ];
7236
+ return rotateAxis("z", `rotateZ(${value})`);
6909
7237
  },
6910
- handleCustomProperty: (value) => [
6911
- decl(
6912
- "transform",
6913
- `var(--baro-rotate-x) var(--baro-rotate-y) rotateZ(var(${value}))`
6914
- )
6915
- ],
7238
+ handleCustomProperty: (value) => rotateAxis("z", `rotateZ(var(${value}))`),
6916
7239
  description: "rotate-z utility (named, arbitrary, custom property supported)",
6917
7240
  category: "transform"
6918
7241
  });
@@ -6939,7 +7262,7 @@ functionalUtility({
6939
7262
  staticUtility("scale-none", [["scale", "none"]], { category: "transform" });
6940
7263
  staticUtility(
6941
7264
  "scale-3d",
6942
- [["scale", "var(--baro-scale-x) var(--baro-scale-y) var(--baro-scale-z)"]],
7265
+ [scaleProperties, ["scale", "var(--baro-scale-x) var(--baro-scale-y) var(--baro-scale-z)"]],
6943
7266
  { category: "transform" }
6944
7267
  );
6945
7268
  functionalUtility({
@@ -6950,18 +7273,16 @@ functionalUtility({
6950
7273
  supportsNegative: true,
6951
7274
  handle: (value, ctx, { negative, arbitrary }) => {
6952
7275
  if (arbitrary) {
6953
- return [decl("scale", `${value}`)];
7276
+ return scaleAxis("x", value);
6954
7277
  }
6955
7278
  if (parseNumber(value) || negative) {
6956
7279
  const pct = `${Math.abs(Number(value))}%`;
6957
7280
  const sign = negative || String(value).startsWith("-") ? "-" : "";
6958
- return [decl("scale", `calc(${pct} * ${sign}1) var(--baro-scale-y)`)];
7281
+ return scaleAxis("x", `calc(${pct} * ${sign}1)`);
6959
7282
  }
6960
- return [decl("scale", `${value} var(--baro-scale-y)`)];
7283
+ return scaleAxis("x", value);
6961
7284
  },
6962
- handleCustomProperty: (value) => [
6963
- decl("scale", `var(${value}) var(--baro-scale-y)`)
6964
- ],
7285
+ handleCustomProperty: (value) => scaleAxis("x", `var(${value})`),
6965
7286
  description: "scale-x utility (named, arbitrary, custom property supported)",
6966
7287
  category: "transform"
6967
7288
  });
@@ -6973,18 +7294,16 @@ functionalUtility({
6973
7294
  supportsNegative: true,
6974
7295
  handle: (value, ctx, { negative, arbitrary }) => {
6975
7296
  if (arbitrary) {
6976
- return [decl("scale", `var(--baro-scale-x) ${value}`)];
7297
+ return scaleAxis("y", value);
6977
7298
  }
6978
7299
  if (parseNumber(value) || negative) {
6979
7300
  const pct = `${Math.abs(Number(value))}%`;
6980
7301
  const sign = negative || String(value).startsWith("-") ? "-" : "";
6981
- return [decl("scale", `var(--baro-scale-x) calc(${pct} * ${sign}1)`)];
7302
+ return scaleAxis("y", `calc(${pct} * ${sign}1)`);
6982
7303
  }
6983
- return [decl("scale", `var(--baro-scale-x) ${value}`)];
7304
+ return scaleAxis("y", value);
6984
7305
  },
6985
- handleCustomProperty: (value) => [
6986
- decl("scale", `var(--baro-scale-x) var(${value})`)
6987
- ],
7306
+ handleCustomProperty: (value) => scaleAxis("y", `var(${value})`),
6988
7307
  description: "scale-y utility (named, arbitrary, custom property supported)",
6989
7308
  category: "transform"
6990
7309
  });
@@ -6996,25 +7315,16 @@ functionalUtility({
6996
7315
  supportsNegative: true,
6997
7316
  handle: (value, ctx, { negative, arbitrary }) => {
6998
7317
  if (arbitrary) {
6999
- return [
7000
- decl("scale", `var(--baro-scale-x) var(--baro-scale-y) ${value}`)
7001
- ];
7318
+ return scaleAxis("z", value);
7002
7319
  }
7003
7320
  if (parseNumber(value) || negative) {
7004
7321
  const pct = `${Math.abs(Number(value))}%`;
7005
7322
  const sign = negative || String(value).startsWith("-") ? "-" : "";
7006
- return [
7007
- decl(
7008
- "scale",
7009
- `var(--baro-scale-x) var(--baro-scale-y) calc(${pct} * ${sign}1)`
7010
- )
7011
- ];
7323
+ return scaleAxis("z", `calc(${pct} * ${sign}1)`);
7012
7324
  }
7013
- return [decl("scale", `var(--baro-scale-x) var(--baro-scale-y) ${value}`)];
7325
+ return scaleAxis("z", value);
7014
7326
  },
7015
- handleCustomProperty: (value) => [
7016
- decl("scale", `var(--baro-scale-x) var(--baro-scale-y) var(${value})`)
7017
- ],
7327
+ handleCustomProperty: (value) => scaleAxis("z", `var(${value})`),
7018
7328
  description: "scale-z utility (named, arbitrary, custom property supported)",
7019
7329
  category: "transform"
7020
7330
  });
@@ -7053,11 +7363,11 @@ functionalUtility({
7053
7363
  if (parseNumber(value) || negative) {
7054
7364
  const deg = `${Math.abs(Number(value))}deg`;
7055
7365
  const sign = negative || String(value).startsWith("-") ? "-" : "";
7056
- return [decl("transform", `skewX(${sign}${deg})`)];
7366
+ return skewAxis("x", `skewX(${sign}${deg})`);
7057
7367
  }
7058
- return [decl("transform", `skewX(${value})`)];
7368
+ return skewAxis("x", `skewX(${value})`);
7059
7369
  },
7060
- handleCustomProperty: (value) => [decl("transform", `skewX(var(${value}))`)],
7370
+ handleCustomProperty: (value) => skewAxis("x", `skewX(var(${value}))`),
7061
7371
  description: "skew-x utility (named, arbitrary, custom property supported)",
7062
7372
  category: "transform"
7063
7373
  });
@@ -7071,11 +7381,11 @@ functionalUtility({
7071
7381
  if (parseNumber(value) || negative) {
7072
7382
  const deg = `${Math.abs(Number(value))}deg`;
7073
7383
  const sign = negative || String(value).startsWith("-") ? "-" : "";
7074
- return [decl("transform", `skewY(${sign}${deg})`)];
7384
+ return skewAxis("y", `skewY(${sign}${deg})`);
7075
7385
  }
7076
- return [decl("transform", `skewY(${value})`)];
7386
+ return skewAxis("y", `skewY(${value})`);
7077
7387
  },
7078
- handleCustomProperty: (value) => [decl("transform", `skewY(var(${value}))`)],
7388
+ handleCustomProperty: (value) => skewAxis("y", `skewY(var(${value}))`),
7079
7389
  description: "skew-y utility (named, arbitrary, custom property supported)",
7080
7390
  category: "transform"
7081
7391
  });
@@ -7089,12 +7399,14 @@ functionalUtility({
7089
7399
  if (parseNumber(value) || negative) {
7090
7400
  const deg = `${Math.abs(Number(value))}deg`;
7091
7401
  const sign = negative || String(value).startsWith("-") ? "-" : "";
7092
- return [decl("transform", `skewX(${sign}${deg}) skewY(${sign}${deg})`)];
7402
+ return [decl("--baro-skew-x", `skewX(${sign}${deg})`), decl("--baro-skew-y", `skewY(${sign}${deg})`), decl("transform", ROTATE_SKEW)];
7093
7403
  }
7094
- return [decl("transform", `skewX(${value}) skewY(${value})`)];
7404
+ return [decl("--baro-skew-x", `skewX(${value})`), decl("--baro-skew-y", `skewY(${value})`), decl("transform", ROTATE_SKEW)];
7095
7405
  },
7096
7406
  handleCustomProperty: (value) => [
7097
- decl("transform", `skewX(var(${value})) skewY(var(${value}))`)
7407
+ decl("--baro-skew-x", `skewX(var(${value}))`),
7408
+ decl("--baro-skew-y", `skewY(var(${value}))`),
7409
+ decl("transform", ROTATE_SKEW)
7098
7410
  ],
7099
7411
  description: "skew utility (named, arbitrary, custom property supported)",
7100
7412
  category: "transform"
@@ -7139,6 +7451,22 @@ const translateProperties = () => atRoot([
7139
7451
  property("--baro-translate-y", "0"),
7140
7452
  property("--baro-translate-z", "0")
7141
7453
  ]);
7454
+ const translateAxis = (axis, v) => [
7455
+ translateProperties(),
7456
+ decl(`--baro-translate-${axis}`, v),
7457
+ decl(
7458
+ "translate",
7459
+ axis === "z" ? "var(--baro-translate-x) var(--baro-translate-y) var(--baro-translate-z)" : "var(--baro-translate-x) var(--baro-translate-y)"
7460
+ )
7461
+ ];
7462
+ const staticTranslateAxis = (axis, v) => [
7463
+ translateProperties,
7464
+ [`--baro-translate-${axis}`, v],
7465
+ [
7466
+ "translate",
7467
+ axis === "z" ? "var(--baro-translate-x) var(--baro-translate-y) var(--baro-translate-z)" : "var(--baro-translate-x) var(--baro-translate-y)"
7468
+ ]
7469
+ ];
7142
7470
  staticUtility("translate-none", [["translate", "none"]], {
7143
7471
  category: "transform"
7144
7472
  });
@@ -7170,52 +7498,52 @@ staticUtility(
7170
7498
  );
7171
7499
  staticUtility(
7172
7500
  "translate-x-px",
7173
- [["translate", "1px var(--baro-translate-y)"]],
7501
+ staticTranslateAxis("x", "1px"),
7174
7502
  { category: "transform" }
7175
7503
  );
7176
7504
  staticUtility(
7177
7505
  "-translate-x-px",
7178
- [["translate", "-1px var(--baro-translate-y)"]],
7506
+ staticTranslateAxis("x", "-1px"),
7179
7507
  { category: "transform" }
7180
7508
  );
7181
7509
  staticUtility(
7182
7510
  "translate-x-full",
7183
- [["translate", "100% var(--baro-translate-y)"]],
7511
+ staticTranslateAxis("x", "100%"),
7184
7512
  { category: "transform" }
7185
7513
  );
7186
7514
  staticUtility(
7187
7515
  "-translate-x-full",
7188
- [["translate", "-100% var(--baro-translate-y)"]],
7516
+ staticTranslateAxis("x", "-100%"),
7189
7517
  { category: "transform" }
7190
7518
  );
7191
7519
  staticUtility(
7192
7520
  "translate-y-px",
7193
- [["translate", "var(--baro-translate-x) 1px"]],
7521
+ staticTranslateAxis("y", "1px"),
7194
7522
  { category: "transform" }
7195
7523
  );
7196
7524
  staticUtility(
7197
7525
  "-translate-y-px",
7198
- [["translate", "var(--baro-translate-x) -1px"]],
7526
+ staticTranslateAxis("y", "-1px"),
7199
7527
  { category: "transform" }
7200
7528
  );
7201
7529
  staticUtility(
7202
7530
  "translate-y-full",
7203
- [["translate", "var(--baro-translate-x) 100%"]],
7531
+ staticTranslateAxis("y", "100%"),
7204
7532
  { category: "transform" }
7205
7533
  );
7206
7534
  staticUtility(
7207
7535
  "-translate-y-full",
7208
- [["translate", "var(--baro-translate-x) -100%"]],
7536
+ staticTranslateAxis("y", "-100%"),
7209
7537
  { category: "transform" }
7210
7538
  );
7211
7539
  staticUtility(
7212
7540
  "translate-z-px",
7213
- [["translate", "var(--baro-translate-x) var(--baro-translate-y) 1px"]],
7541
+ staticTranslateAxis("z", "1px"),
7214
7542
  { category: "transform" }
7215
7543
  );
7216
7544
  staticUtility(
7217
7545
  "-translate-z-px",
7218
- [["translate", "var(--baro-translate-x) var(--baro-translate-y) -1px"]],
7546
+ staticTranslateAxis("z", "-1px"),
7219
7547
  { category: "transform" }
7220
7548
  );
7221
7549
  functionalUtility({
@@ -7225,19 +7553,17 @@ functionalUtility({
7225
7553
  supportsArbitrary: true,
7226
7554
  supportsCustomProperty: true,
7227
7555
  handle: (value, ctx, { negative }) => {
7228
- if (parseFractionOrNumber(value)) {
7556
+ if (value.includes("/") && parseFractionOrNumber(value)) {
7229
7557
  const v = `calc(${value} * 100%)`;
7230
- return [decl("translate", `${v} var(--baro-translate-y)`)];
7558
+ return translateAxis("x", v);
7231
7559
  }
7232
7560
  if (parseNumber(value) || negative) {
7233
7561
  const v = `calc(var(--spacing) * ${value})`;
7234
- return [decl("translate", `${v} var(--baro-translate-y)`)];
7562
+ return translateAxis("x", v);
7235
7563
  }
7236
- return [decl("translate", `${value} var(--baro-translate-y)`)];
7564
+ return translateAxis("x", value);
7237
7565
  },
7238
- handleCustomProperty: (value) => [
7239
- decl("translate", `var(${value}) var(--baro-translate-y)`)
7240
- ],
7566
+ handleCustomProperty: (value) => translateAxis("x", `var(${value})`),
7241
7567
  description: "translate-x utility (spacing, fraction, arbitrary, custom property, negative)",
7242
7568
  category: "transform"
7243
7569
  });
@@ -7248,19 +7574,17 @@ functionalUtility({
7248
7574
  supportsArbitrary: true,
7249
7575
  supportsCustomProperty: true,
7250
7576
  handle: (value, ctx, { negative }) => {
7251
- if (parseFractionOrNumber(value)) {
7577
+ if (value.includes("/") && parseFractionOrNumber(value)) {
7252
7578
  const v = `calc(${value} * 100%)`;
7253
- return [decl("translate", `var(--baro-translate-x) ${v}`)];
7579
+ return translateAxis("y", v);
7254
7580
  }
7255
7581
  if (parseNumber(value) || negative) {
7256
7582
  const v = `calc(var(--spacing) * ${value})`;
7257
- return [decl("translate", `var(--baro-translate-x) ${v}`)];
7583
+ return translateAxis("y", v);
7258
7584
  }
7259
- return [decl("translate", `var(--baro-translate-x) ${value}`)];
7585
+ return translateAxis("y", value);
7260
7586
  },
7261
- handleCustomProperty: (value) => [
7262
- decl("translate", `var(--baro-translate-x) var(${value})`)
7263
- ],
7587
+ handleCustomProperty: (value) => translateAxis("y", `var(${value})`),
7264
7588
  description: "translate-y utility (spacing, fraction, arbitrary, custom property, negative)",
7265
7589
  category: "transform"
7266
7590
  });
@@ -7271,37 +7595,17 @@ functionalUtility({
7271
7595
  supportsArbitrary: true,
7272
7596
  supportsCustomProperty: true,
7273
7597
  handle: (value, ctx, { negative }) => {
7274
- if (parseFractionOrNumber(value)) {
7598
+ if (value.includes("/") && parseFractionOrNumber(value)) {
7275
7599
  const v = `calc(${value} * 100%)`;
7276
- return [
7277
- decl(
7278
- "translate",
7279
- `var(--baro-translate-x) var(--baro-translate-y) ${v}`
7280
- )
7281
- ];
7600
+ return translateAxis("z", v);
7282
7601
  }
7283
7602
  if (parseNumber(value) || negative) {
7284
7603
  const v = `calc(var(--spacing) * ${value})`;
7285
- return [
7286
- decl(
7287
- "translate",
7288
- `var(--baro-translate-x) var(--baro-translate-y) ${v}`
7289
- )
7290
- ];
7604
+ return translateAxis("z", v);
7291
7605
  }
7292
- return [
7293
- decl(
7294
- "translate",
7295
- `var(--baro-translate-x) var(--baro-translate-y) ${value}`
7296
- )
7297
- ];
7606
+ return translateAxis("z", value);
7298
7607
  },
7299
- handleCustomProperty: (value) => [
7300
- decl(
7301
- "translate",
7302
- `var(--baro-translate-x) var(--baro-translate-y) var(${value})`
7303
- )
7304
- ],
7608
+ handleCustomProperty: (value) => translateAxis("z", `var(${value})`),
7305
7609
  description: "translate-z utility (spacing, fraction, arbitrary, custom property, negative)",
7306
7610
  category: "transform"
7307
7611
  });
@@ -7312,7 +7616,7 @@ functionalUtility({
7312
7616
  supportsArbitrary: true,
7313
7617
  supportsCustomProperty: true,
7314
7618
  handle: (value, ctx, { negative }) => {
7315
- if (parseFractionOrNumber(value)) {
7619
+ if (value.includes("/") && parseFractionOrNumber(value)) {
7316
7620
  const v = `calc(${value} * 100%)`;
7317
7621
  return [decl("translate", `${v} ${v}`)];
7318
7622
  }
@@ -7378,7 +7682,11 @@ functionalUtility({
7378
7682
  });
7379
7683
  staticUtility("forced-color-adjust-auto", [["forced-color-adjust", "auto"]], { category: "accessibility" });
7380
7684
  staticUtility("forced-color-adjust-none", [["forced-color-adjust", "none"]], { category: "accessibility" });
7381
- staticModifier("hover", ["&:hover"], { order: 50, source: "pseudo" });
7685
+ staticModifier("hover", ["&:hover"], {
7686
+ order: 50,
7687
+ source: "pseudo",
7688
+ wrap: () => [atRule("media", "(hover: hover)", [])]
7689
+ });
7382
7690
  staticModifier("focus", ["&:focus"], { order: 50, source: "pseudo" });
7383
7691
  staticModifier("active", ["&:active"], { order: 50, source: "pseudo" });
7384
7692
  staticModifier("visited", ["&:visited"], { order: 50, source: "pseudo" });
@@ -7473,8 +7781,13 @@ staticModifier("rtl", ["&[dir=rtl]"], { order: 20, source: "attribute" });
7473
7781
  staticModifier("ltr", ["&[dir=ltr]"], { order: 20, source: "attribute" });
7474
7782
  staticModifier("inert", ["&[inert]"], { order: 40, source: "attribute" });
7475
7783
  staticModifier("open", ["&:is([open], :popover-open, :open)"], { order: 40, source: "attribute" });
7476
- staticModifier("before", ["&::before"], { source: "pseudo" });
7477
- staticModifier("after", ["&::after"], { source: "pseudo" });
7784
+ const withPseudoContent = (ast) => [
7785
+ atRoot([property("--baro-content", '""')]),
7786
+ ...ast,
7787
+ decl("content", "var(--baro-content)")
7788
+ ];
7789
+ staticModifier("before", ["&::before"], { source: "pseudo", astHandler: withPseudoContent });
7790
+ staticModifier("after", ["&::after"], { source: "pseudo", astHandler: withPseudoContent });
7478
7791
  staticModifier("placeholder", [
7479
7792
  "&::placeholder",
7480
7793
  "&::-webkit-input-placeholder",
@@ -7507,9 +7820,6 @@ function createContainerParams(type, value, name) {
7507
7820
  const condition = type === "min" ? "width >=" : "width <";
7508
7821
  return name ? `${name} (${condition} ${value})` : `(${condition} ${value})`;
7509
7822
  }
7510
- function getThemeSize(ctx, key) {
7511
- return ctx.theme("container." + key) || ctx.theme("breakpoint." + key);
7512
- }
7513
7823
  function createContainerRule(params, ast) {
7514
7824
  return {
7515
7825
  type: "at-rule",
@@ -7529,6 +7839,35 @@ function getDefaultBreakpoint(breakpoint) {
7529
7839
  };
7530
7840
  return defaults[breakpoint] || `(min-width: ${breakpoint})`;
7531
7841
  }
7842
+ function decodeArbitrarySelector(value) {
7843
+ return value.replace(/\\_|_/g, (m) => m === "_" ? " " : "_");
7844
+ }
7845
+ function attributeVariantSelector(variant) {
7846
+ const bracket = /^(data|aria)-\[([a-zA-Z0-9_-]+)(?:=([^\]]+))?\]$/.exec(variant);
7847
+ if (bracket) {
7848
+ const [, kind, key, raw] = bracket;
7849
+ if (raw === void 0) return `[${kind}-${key}]`;
7850
+ const value = /^(["']).*\1$/.test(raw) ? raw : `"${decodeArbitrarySelector(raw)}"`;
7851
+ return `[${kind}-${key}=${value}]`;
7852
+ }
7853
+ const bare = /^data-([a-zA-Z0-9_-]+)$/.exec(variant);
7854
+ return bare ? `[data-${bare[1]}]` : void 0;
7855
+ }
7856
+ function functionalArgument(value) {
7857
+ const v = decodeArbitrarySelector(value);
7858
+ return /^[>+~]/.test(v.trim()) || !hasTopLevelComma(v) ? v : `*:is(${v})`;
7859
+ }
7860
+ function hasTopLevelComma(value) {
7861
+ let depth = 0;
7862
+ for (let i = 0; i < value.length; i++) {
7863
+ const c = value[i];
7864
+ if (c === "\\") i++;
7865
+ else if (c === "(" || c === "[") depth++;
7866
+ else if (c === ")" || c === "]") depth--;
7867
+ else if (c === "," && depth === 0) return true;
7868
+ }
7869
+ return false;
7870
+ }
7532
7871
  functionalModifier(
7533
7872
  (mod, context) => {
7534
7873
  const breakpoints2 = context.theme("breakpoints") || context.config("theme.breakpoints") || {};
@@ -7559,7 +7898,7 @@ functionalModifier(
7559
7898
  const breakpoints2 = context.theme("breakpoints") || context.config("theme.breakpoints") || {};
7560
7899
  if (Object.keys(breakpoints2).includes(breakpoint)) {
7561
7900
  let mediaQuery = context.theme(`breakpoints.${breakpoint}`) || getDefaultBreakpoint(breakpoint);
7562
- if (/^\d+(px|em|rem)?$/.test(mediaQuery)) {
7901
+ if (/^\d*\.?\d+(px|em|rem)?$/.test(mediaQuery)) {
7563
7902
  mediaQuery = `(min-width: ${mediaQuery})`;
7564
7903
  }
7565
7904
  return [atRule("media", mediaQuery, [], "responsive")];
@@ -7578,6 +7917,8 @@ functionalModifier(
7578
7917
  if (value) {
7579
7918
  mediaQuery = `(width < ${value})`;
7580
7919
  }
7920
+ } else if (/^\d*\.?\d+(px|em|rem)?$/.test(mediaQuery)) {
7921
+ mediaQuery = `(width < ${mediaQuery})`;
7581
7922
  }
7582
7923
  return [atRule("media", mediaQuery, [], "responsive")];
7583
7924
  }
@@ -7646,132 +7987,137 @@ functionalModifier(
7646
7987
  return result;
7647
7988
  }
7648
7989
  );
7990
+ const SIZE_VARIANT = /^@(?:(min|max)-)?(\[[^\]]+\]|[a-zA-Z0-9.]+)(?:\/([a-zA-Z0-9_-]+))?$/;
7649
7991
  functionalModifier(
7650
- (mod) => /^@container\/([a-zA-Z0-9_-]+)$/.test(mod),
7651
- void 0,
7652
- (mod, context) => {
7653
- const containerMatch = /^@container\/([a-zA-Z0-9_-]+)$/.exec(mod.type);
7654
- if (containerMatch) {
7655
- const name = containerMatch[1];
7656
- const params = name;
7657
- return [createContainerRule(params, [])];
7658
- }
7659
- return [];
7660
- }
7661
- );
7662
- functionalModifier(
7663
- (mod) => /^@container\/([a-zA-Z0-9_-]+)\s+\(([^)]+)\)$/.test(mod),
7992
+ (mod) => SIZE_VARIANT.test(mod) && !/^@container(?:\/|$)/.test(mod),
7664
7993
  void 0,
7665
7994
  (mod, context) => {
7666
- const containerSizeMatch = /^@container\/([a-zA-Z0-9_-]+)\s+\(([^)]+)\)$/.exec(mod.type);
7667
- if (containerSizeMatch) {
7668
- const [, name, size] = containerSizeMatch;
7669
- const params = createContainerParams("min", size, name);
7670
- return [createContainerRule(params, [])];
7671
- }
7672
- return [];
7995
+ const m = SIZE_VARIANT.exec(mod.type);
7996
+ if (!m) return [];
7997
+ const [, type, size, name] = m;
7998
+ const value = size.startsWith("[") ? size.slice(1, -1).replace(/_/g, " ") : context.theme("container." + size);
7999
+ if (!value) return [];
8000
+ return [createContainerRule(createContainerParams(type === "max" ? "max" : "min", value, name), [])];
7673
8001
  }
7674
8002
  );
8003
+ const startsAtRule = (bracket) => /^[\s_]*@/.test(bracket);
7675
8004
  functionalModifier(
7676
- (mod) => /^@(sm|md|lg|xl|2xl)\/([a-zA-Z0-9_-]+)$/.test(mod),
7677
- void 0,
7678
- (mod, context) => {
7679
- const namedSizeMatch = /^@(sm|md|lg|xl|2xl)\/([a-zA-Z0-9_-]+)$/.exec(mod.type);
7680
- if (namedSizeMatch) {
7681
- const [, size, name] = namedSizeMatch;
7682
- const sizeValue = getThemeSize(context, size) || size;
7683
- const params = createContainerParams("min", sizeValue, name);
7684
- return [createContainerRule(params, [])];
7685
- }
7686
- return [];
7687
- }
8005
+ (mod) => /^has-\[.*\]$/.test(mod) && !startsAtRule(mod.slice(5)),
8006
+ ({ selector, mod }) => {
8007
+ const m = /^has-\[(.+)\]$/.exec(mod.type);
8008
+ return m ? {
8009
+ selector: `&:has(${functionalArgument(m[1])})`,
8010
+ flatten: false,
8011
+ wrappingType: "rule",
8012
+ source: "attribute"
8013
+ } : {
8014
+ selector,
8015
+ source: "attribute"
8016
+ };
8017
+ },
8018
+ void 0
7688
8019
  );
7689
8020
  functionalModifier(
7690
- (mod) => /^@(sm|md|lg|xl|2xl)$/.test(mod),
7691
- void 0,
7692
- (mod, context) => {
7693
- const themeSizeMatch = /^@(sm|md|lg|xl|2xl)$/.exec(mod.type);
7694
- if (themeSizeMatch) {
7695
- const size = themeSizeMatch[1];
7696
- const sizeValue = getThemeSize(context, size) || size;
7697
- const params = createContainerParams("min", sizeValue);
7698
- return [createContainerRule(params, [])];
7699
- }
7700
- return [];
7701
- }
8021
+ (mod) => /^has-(data|aria)-/.test(mod) && !!attributeVariantSelector(mod.slice(4)),
8022
+ ({ mod }) => ({
8023
+ selector: `&:has(*${attributeVariantSelector(mod.type.slice(4))})`,
8024
+ flatten: false,
8025
+ wrappingType: "rule",
8026
+ source: "attribute"
8027
+ }),
8028
+ void 0
7702
8029
  );
8030
+ function innerCompound(variant, ctx) {
8031
+ const attr = attributeVariantSelector(variant);
8032
+ if (attr) return { compound: attr };
8033
+ if (/^(has|in|not|group|peer)-|[^a-z0-9-]/.test(variant)) return void 0;
8034
+ const inner = getModifier(ctx).find((m) => m.match(variant, ctx));
8035
+ if (!inner?.modifySelector || inner.astHandler) return void 0;
8036
+ const out = inner.modifySelector({ selector: "&", fullClassName: "", mod: { type: variant }, context: ctx });
8037
+ const list = typeof out === "string" ? [{ selector: out }] : Array.isArray(out) ? out : [out];
8038
+ if (list.length !== 1) return void 0;
8039
+ const sel = list[0].selector;
8040
+ if (!/^&[:[]/.test(sel) || sel.slice(1).includes("&") || /[\s,>+~]/.test(sel.replace(/\([^()]*\)/g, ""))) return void 0;
8041
+ return { compound: sel.slice(1), inner };
8042
+ }
8043
+ function resolveHasIn(mod, ctx) {
8044
+ const m = /^(has|in)-(.+)$/.exec(mod);
8045
+ if (!m) return void 0;
8046
+ const [, kind, v] = m;
8047
+ if (kind === "in" && /^\[.+\]$/.test(v)) {
8048
+ if (startsAtRule(v.slice(1))) return void 0;
8049
+ const sel = decodeArbitrarySelector(v.slice(1, -1));
8050
+ return { kind, compound: sel.startsWith("&") ? sel.slice(1) : `:is(${sel})` };
8051
+ }
8052
+ if (kind === "has" && (v.startsWith("[") || /^(data|aria)-/.test(v))) return void 0;
8053
+ const r = innerCompound(v, ctx);
8054
+ return r && { kind, ...r };
8055
+ }
8056
+ const hasInSelector = ({ selector, mod, context }) => {
8057
+ const r = resolveHasIn(mod.type, context);
8058
+ if (!r) return { selector };
8059
+ return {
8060
+ selector: r.kind === "has" ? `&:has(*${r.compound})` : `:where(*${r.compound}) &`,
8061
+ flatten: false,
8062
+ wrappingType: "rule",
8063
+ source: "attribute"
8064
+ };
8065
+ };
7703
8066
  functionalModifier(
7704
- (mod) => /^@max-(sm|md|lg|xl|2xl)$/.test(mod),
7705
- void 0,
7706
- (mod, context) => {
7707
- const themeSizeMatch = /^@max-(sm|md|lg|xl|2xl)$/.exec(mod.type);
7708
- if (themeSizeMatch) {
7709
- const size = themeSizeMatch[1];
7710
- const sizeValue = getThemeSize(context, size) || size;
7711
- const params = createContainerParams("max", sizeValue);
7712
- return [createContainerRule(params, [])];
7713
- }
7714
- return [];
7715
- }
8067
+ (mod, ctx) => !!resolveHasIn(mod, ctx)?.inner?.wrap,
8068
+ hasInSelector,
8069
+ (mod, context) => resolveHasIn(mod.type, context).inner.wrap({ ...mod, type: mod.type.replace(/^(has|in)-/, "") }, context)
7716
8070
  );
7717
8071
  functionalModifier(
7718
- (mod) => /^@(min|max)-\[.*\]$/.test(mod),
7719
- void 0,
7720
- (mod, context) => {
7721
- const arbitraryMatch = /^@(min|max)-\[(.+)\]$/.exec(mod.type);
7722
- if (arbitraryMatch) {
7723
- const [, type, value] = arbitraryMatch;
7724
- const params = createContainerParams(type, value);
7725
- return [createContainerRule(params, [])];
7726
- }
7727
- return [];
7728
- }
8072
+ (mod, ctx) => {
8073
+ const r = resolveHasIn(mod, ctx);
8074
+ return !!r && !r.inner?.wrap;
8075
+ },
8076
+ hasInSelector
7729
8077
  );
8078
+ function resolveGroupHas(mod, ctx) {
8079
+ const m = /^(group|peer)-has-(.+?)(?:\/([a-zA-Z0-9_-]+))?$/.exec(mod);
8080
+ if (!m) return void 0;
8081
+ const kind = m[1];
8082
+ const v = m[2];
8083
+ const base = m[3] ? `.${kind}\\/${m[3]}` : `.${kind}`;
8084
+ if (/^\[.+\]$/.test(v)) {
8085
+ if (startsAtRule(v.slice(1))) return void 0;
8086
+ const sel = decodeArbitrarySelector(v.slice(1, -1));
8087
+ return { kind, base, v, arg: /^[>+~]/.test(sel.trim()) ? sel : `*:is(${sel})` };
8088
+ }
8089
+ const r = innerCompound(v, ctx);
8090
+ return r && { kind, base, v, arg: `*${r.compound}`, inner: r.inner };
8091
+ }
8092
+ const groupHasSelector = ({ selector, mod, context }) => {
8093
+ const r = resolveGroupHas(mod.type, context);
8094
+ if (!r) return { selector };
8095
+ const tail = r.kind === "group" ? " *" : " ~ *";
8096
+ return { selector: `&:is(:where(${r.base}):has(${r.arg})${tail})`, wrappingType: "rule", source: r.kind };
8097
+ };
7730
8098
  functionalModifier(
7731
- (mod) => /^@(min|max)-\[.*\]\/([a-zA-Z0-9_-]+)$/.test(mod),
7732
- void 0,
8099
+ (mod, ctx) => !!resolveGroupHas(mod, ctx)?.inner?.wrap,
8100
+ groupHasSelector,
7733
8101
  (mod, context) => {
7734
- const arbitraryNamedMatch = /^@(min|max)-\[(.+)\]\/([a-zA-Z0-9_-]+)$/.exec(mod.type);
7735
- if (arbitraryNamedMatch) {
7736
- const [, type, value, name] = arbitraryNamedMatch;
7737
- const params = createContainerParams(type, value, name);
7738
- return [createContainerRule(params, [])];
7739
- }
7740
- return [];
8102
+ const r = resolveGroupHas(mod.type, context);
8103
+ return r.inner.wrap({ ...mod, type: r.v }, context);
7741
8104
  }
7742
8105
  );
7743
8106
  functionalModifier(
7744
- (mod) => /^has-\[.*\]$/.test(mod),
7745
- ({ selector, mod }) => {
7746
- const m = /^has-\[(.+)\]$/.exec(mod.type);
7747
- if (m && m[1].startsWith(".")) {
7748
- return {
7749
- selector: `&:has(${m[1]})`,
7750
- flatten: false,
7751
- wrappingType: "rule",
7752
- source: "attribute"
7753
- };
7754
- }
7755
- return m ? {
7756
- selector: `&:has(${m[1]})`,
7757
- flatten: false,
7758
- wrappingType: "rule",
7759
- source: "attribute"
7760
- } : {
7761
- selector,
7762
- source: "attribute"
7763
- };
8107
+ (mod, ctx) => {
8108
+ const r = resolveGroupHas(mod, ctx);
8109
+ return !!r && !r.inner?.wrap;
7764
8110
  },
7765
- void 0
8111
+ groupHasSelector
7766
8112
  );
7767
8113
  functionalModifier(
7768
8114
  (mod) => /^not-\[.*\]$/.test(mod),
7769
8115
  ({ selector, mod }) => {
7770
8116
  const m = /^not-\[(.+)\]$/.exec(mod.type);
7771
8117
  if (m) {
7772
- if (m[1].startsWith(".")) {
8118
+ if (!/^[a-zA-Z0-9_-]+(=.+)?$/.test(m[1])) {
7773
8119
  return {
7774
- selector: `&:not(${m[1]})`,
8120
+ selector: `&:not(${functionalArgument(m[1])})`,
7775
8121
  flatten: false,
7776
8122
  wrappingType: "rule",
7777
8123
  source: "attribute"
@@ -7804,27 +8150,14 @@ functionalModifier(
7804
8150
  );
7805
8151
  functionalModifier(
7806
8152
  (mod) => mod === "*",
7807
- ({ selector, fullClassName, variantChain }) => {
7808
- const isSingle = !variantChain || variantChain.length === 1;
7809
- return {
7810
- selector: `:is(.${escapeClassName(fullClassName)} > *)`,
7811
- flatten: true,
7812
- wrappingType: isSingle ? "rule" : "style-rule",
7813
- source: "universal"
7814
- };
8153
+ () => {
8154
+ return { selector: ":is(& > *)", wrappingType: "rule", source: "universal" };
7815
8155
  },
7816
8156
  void 0
7817
8157
  );
7818
8158
  functionalModifier(
7819
8159
  (mod) => mod === "**",
7820
- ({ selector, fullClassName }) => {
7821
- return {
7822
- selector: `:is(.${escapeClassName(fullClassName)} *)`,
7823
- flatten: false,
7824
- wrappingType: "style-rule",
7825
- source: "universal"
7826
- };
7827
- },
8160
+ () => ({ selector: ":is(& *)", wrappingType: "rule", source: "universal" }),
7828
8161
  void 0
7829
8162
  );
7830
8163
  functionalModifier(
@@ -7832,17 +8165,14 @@ functionalModifier(
7832
8165
  ({ selector, mod }) => {
7833
8166
  const m = /^\[(.+)\]$/.exec(mod.type);
7834
8167
  if (!m) return { selector };
7835
- const inner = m[1].trim();
8168
+ const inner = decodeArbitrarySelector(m[1]).trim();
7836
8169
  if (/^[a-zA-Z0-9_-]+(=.+)?$/.test(inner)) {
7837
8170
  return { selector: `&[${inner}]`, wrappingType: "rule", source: "attribute" };
7838
8171
  }
7839
- if (inner === "&>*") {
7840
- return { selector: `${inner}`, wrappingType: "style-rule", source: "peer" };
7841
- }
7842
8172
  if (inner.startsWith("&")) {
7843
8173
  return { selector: `${inner}`, wrappingType: "rule", source: "pseudo" };
7844
8174
  }
7845
- return { selector: `${inner} &`.trim(), wrappingType: "rule", source: "base" };
8175
+ return { selector: `&:is(${inner})`, wrappingType: "rule", source: "base" };
7846
8176
  },
7847
8177
  void 0
7848
8178
  );
@@ -7886,7 +8216,7 @@ functionalModifier(
7886
8216
  };
7887
8217
  } else {
7888
8218
  return {
7889
- selector: `&:not(${inner})`,
8219
+ selector: `&:not(${functionalArgument(inner)})`,
7890
8220
  source: "attribute"
7891
8221
  };
7892
8222
  }
@@ -8037,29 +8367,56 @@ functionalModifier(
8037
8367
  return m ? [atRule("scope", m[1], [])] : [];
8038
8368
  }
8039
8369
  );
8370
+ const atRuleHas = (mod) => /^(group|peer)-has-\[/.test(mod) && startsAtRule(mod.slice(mod.indexOf("[") + 1));
8371
+ function splitGroupName(kind, variant) {
8372
+ const named = /^(.+)\/([a-zA-Z0-9_-]+)$/.exec(variant);
8373
+ return named ? [named[1], `.${kind}\\/${named[2]}`] : [variant, `.${kind}`];
8374
+ }
8375
+ functionalModifier(
8376
+ (mod) => /^(group|peer)-hover(\/[a-zA-Z0-9_-]+)?$/.test(mod),
8377
+ ({ mod }) => {
8378
+ const kind = mod.type.startsWith("group") ? "group" : "peer";
8379
+ const [, base] = splitGroupName(kind, mod.type.slice(kind.length + 1));
8380
+ const tail = kind === "group" ? " *" : " ~ *";
8381
+ return { selector: `&:is(:where(${base}):hover${tail})`, wrappingType: "rule", source: kind };
8382
+ },
8383
+ () => [atRule("media", "(hover: hover)", [])]
8384
+ );
8385
+ function negated(value) {
8386
+ const v = value.slice(4);
8387
+ return v.startsWith("[") && v.endsWith("]") ? `:not(*:is(${decodeArbitrarySelector(v.slice(1, -1))}))` : `:not(:${v})`;
8388
+ }
8040
8389
  functionalModifier(
8041
- (mod) => /^group-(.+)$/.test(mod),
8390
+ (mod) => /^group-(.+)$/.test(mod) && !atRuleHas(mod),
8042
8391
  ({ selector, mod }) => {
8043
- const m = /^group-(.+)$/.exec(mod.type);
8392
+ const raw = /^group-(.+)$/.exec(mod.type);
8393
+ const [variant, base] = splitGroupName("group", raw?.[1] ?? "");
8394
+ const m = raw ? [raw[0], variant] : null;
8395
+ const g = `:where(${base})`;
8396
+ const attr = m ? attributeVariantSelector(m[1]) : void 0;
8397
+ if (attr) return { selector: `&:is(${g}${attr} *)`, wrappingType: "rule", source: "group" };
8044
8398
  if (m?.[1].startsWith("[") && m?.[1].endsWith("]")) {
8045
8399
  const value = m?.[1].slice(1, -1).replace(/_/g, "");
8046
8400
  return {
8047
- selector: `&:is(:where(.group):is(${value}) *)`,
8401
+ selector: `&:is(${g}:is(${value}) *)`,
8048
8402
  wrappingType: "rule",
8049
8403
  source: "group"
8050
8404
  };
8051
8405
  }
8406
+ if (m?.[1]?.startsWith("not-")) {
8407
+ return { selector: `&:is(${g}${negated(m[1])} *)`, wrappingType: "rule", source: "group" };
8408
+ }
8052
8409
  if (m?.[1]?.startsWith("has-")) {
8053
8410
  const pattern = /^has-\[([a-zA-Z0-9_-]+)\]$/.exec(m?.[1]);
8054
8411
  if (pattern) {
8055
8412
  const value = pattern[1];
8056
8413
  return {
8057
- selector: `&:is(:where(.group):has(:is(${value})) *)`,
8414
+ selector: `&:is(${g}:has(:is(${value})) *)`,
8058
8415
  source: "group"
8059
8416
  };
8060
8417
  }
8061
8418
  return {
8062
- selector: `&:is(:where(.group):has(:is(${m?.[1].slice(4, -1)})) *)`,
8419
+ selector: `&:is(${g}:has(${functionalArgument(m[1].slice(5, -1))}) *)`,
8063
8420
  source: "group"
8064
8421
  };
8065
8422
  }
@@ -8069,19 +8426,19 @@ functionalModifier(
8069
8426
  const value = pattern[1];
8070
8427
  if (pattern[2]) {
8071
8428
  return {
8072
- selector: `&:is(:where(.group)[aria-${value}="${pattern[2]}"] *)`,
8429
+ selector: `&:is(${g}[aria-${value}="${pattern[2]}"] *)`,
8073
8430
  source: "group"
8074
8431
  };
8075
8432
  } else {
8076
8433
  return {
8077
- selector: `&:is(:where(.group)[aria-${value}] *)`,
8434
+ selector: `&:is(${g}[aria-${value}] *)`,
8078
8435
  source: "group"
8079
8436
  };
8080
8437
  }
8081
8438
  }
8082
8439
  }
8083
8440
  return m ? {
8084
- selector: `&:is(:where(.group):${m[1]} *)`,
8441
+ selector: `&:is(${g}:${m[1]} *)`,
8085
8442
  wrappingType: "rule",
8086
8443
  source: "group"
8087
8444
  } : {
@@ -8092,27 +8449,35 @@ functionalModifier(
8092
8449
  void 0
8093
8450
  );
8094
8451
  functionalModifier(
8095
- (mod) => /^peer-(.+)$/.test(mod),
8452
+ (mod) => /^peer-(.+)$/.test(mod) && !atRuleHas(mod),
8096
8453
  ({ selector, mod }) => {
8097
- const m = /^peer-(.+)$/.exec(mod.type);
8454
+ const raw = /^peer-(.+)$/.exec(mod.type);
8455
+ const [variant, base] = splitGroupName("peer", raw?.[1] ?? "");
8456
+ const m = raw ? [raw[0], variant] : null;
8457
+ const g = `:where(${base})`;
8458
+ const attr = m ? attributeVariantSelector(m[1]) : void 0;
8459
+ if (attr) return { selector: `&:is(${g}${attr} ~ *)`, wrappingType: "rule", source: "peer" };
8098
8460
  if (m?.[1].startsWith("[") && m?.[1].endsWith("]")) {
8099
8461
  const value2 = m?.[1].slice(1, -1).replace(/_/g, "");
8100
8462
  return {
8101
- selector: `&:is(:where(.peer):is(${value2})~*)`,
8463
+ selector: `&:is(${g}:is(${value2})~*)`,
8102
8464
  wrappingType: "rule",
8103
8465
  source: "peer"
8104
8466
  };
8105
8467
  }
8106
8468
  const value = m?.[1];
8469
+ if (value?.startsWith("has-[") && value.endsWith("]")) {
8470
+ return { selector: `&:is(${g}:has(${functionalArgument(value.slice(5, -1))}) ~ *)`, source: "peer" };
8471
+ }
8107
8472
  if (value?.startsWith("has-")) {
8108
8473
  return {
8109
- selector: `&:is(:where(.peer):has(:${value.slice(4)})~*)`,
8474
+ selector: `&:is(${g}:has(:${value.slice(4)})~*)`,
8110
8475
  source: "peer"
8111
8476
  };
8112
8477
  }
8113
8478
  if (value?.startsWith("not-")) {
8114
8479
  return {
8115
- selector: `&:is(:where(.peer):not(:${value.slice(4)})~*)`,
8480
+ selector: `&:is(${g}${negated(value)} ~ *)`,
8116
8481
  source: "peer"
8117
8482
  };
8118
8483
  }
@@ -8121,7 +8486,7 @@ functionalModifier(
8121
8486
  if (pattern) {
8122
8487
  const key = pattern[1];
8123
8488
  return {
8124
- selector: `&:is(:where(.peer)[aria-${key}]~*)`,
8489
+ selector: `&:is(${g}[aria-${key}]~*)`,
8125
8490
  source: "peer"
8126
8491
  };
8127
8492
  }
@@ -8131,19 +8496,19 @@ functionalModifier(
8131
8496
  const value2 = pattern[2];
8132
8497
  if (pattern[2]) {
8133
8498
  return {
8134
- selector: `&:is(:where(.peer)[aria-${key}="${value2}"]~*)`,
8499
+ selector: `&:is(${g}[aria-${key}="${value2}"]~*)`,
8135
8500
  source: "peer"
8136
8501
  };
8137
8502
  } else {
8138
8503
  return {
8139
- selector: `&:is(:where(.peer)[aria-${key}]~*)`,
8504
+ selector: `&:is(${g}[aria-${key}]~*)`,
8140
8505
  source: "peer"
8141
8506
  };
8142
8507
  }
8143
8508
  }
8144
8509
  }
8145
8510
  return m ? {
8146
- selector: `&:is(:where(.peer):${value}~*)`,
8511
+ selector: `&:is(${g}:${value}~*)`,
8147
8512
  source: "peer"
8148
8513
  } : {
8149
8514
  selector,
@@ -8194,8 +8559,53 @@ functionalModifier(
8194
8559
  },
8195
8560
  void 0
8196
8561
  );
8562
+ const LEADING_AT = /^\s*@(media|container)\s+([^{]*)\{/;
8563
+ const LATE_MEDIA = /prefers-color-scheme|\bprint\b|forced-colors|orientation/;
8564
+ const MIN_W = /(?:min-width\s*:\s*|width\s*>=?\s*)([\d.]+)(px|rem|em)?/;
8565
+ const MAX_W = /(?:max-width\s*:\s*|width\s*<=?\s*)([\d.]+)(px|rem|em)?/;
8566
+ function toPx(n, unit) {
8567
+ const v = parseFloat(n);
8568
+ return unit === "rem" || unit === "em" ? v * 16 : v;
8569
+ }
8570
+ function preludeKey(kind, prelude) {
8571
+ const container2 = kind === "container";
8572
+ const min = MIN_W.exec(prelude);
8573
+ if (min) return [container2 ? 4 : 2, toPx(min[1], min[2])];
8574
+ const max = MAX_W.exec(prelude);
8575
+ if (max) return [container2 ? 3 : 1, -toPx(max[1], max[2])];
8576
+ if (!container2 && LATE_MEDIA.test(prelude)) return [5, 0];
8577
+ return [0, 0];
8578
+ }
8579
+ function ruleSortKey(rule2) {
8580
+ const key = [];
8581
+ let rest = rule2;
8582
+ let m;
8583
+ while (m = LEADING_AT.exec(rest)) {
8584
+ const [g, v] = preludeKey(m[1], m[2]);
8585
+ key.push(g, v);
8586
+ rest = rest.slice(m[0].length);
8587
+ }
8588
+ return key;
8589
+ }
8590
+ function compareKeys(a, b) {
8591
+ const n = Math.min(a.length, b.length);
8592
+ for (let i = 0; i < n; i++) {
8593
+ if (a[i] !== b[i]) return a[i] - b[i];
8594
+ }
8595
+ return a.length - b.length;
8596
+ }
8597
+ function upperBound(keys, key) {
8598
+ let lo = 0;
8599
+ let hi = keys.length;
8600
+ while (lo < hi) {
8601
+ const mid = lo + hi >> 1;
8602
+ if (compareKeys(keys[mid], key) <= 0) lo = mid + 1;
8603
+ else hi = mid;
8604
+ }
8605
+ return lo;
8606
+ }
8197
8607
  class StylePartitionManager {
8198
- constructor(insertionPoint, maxRulesPerPartition = 50, styleIdPrefix = "barocss-style-partition-") {
8608
+ constructor(insertionPoint, maxRulesPerPartition = 50, styleIdPrefix = "barocss-style-partition-", getCategory = (cls) => parseClassName(cls).utility?.category) {
8199
8609
  this.partitions = [];
8200
8610
  this.categoryPartitions = /* @__PURE__ */ new Map();
8201
8611
  this.partitionCounter = 0;
@@ -8206,12 +8616,30 @@ class StylePartitionManager {
8206
8616
  this.insertionPoint = insertionPoint;
8207
8617
  this.maxRulesPerPartition = maxRulesPerPartition;
8208
8618
  this.styleIdPrefix = styleIdPrefix;
8619
+ this.getCategory = getCategory;
8209
8620
  this.initializeDefaultPartition();
8210
8621
  }
8622
+ /**
8623
+ * Insert `rule` at its Tailwind variant position within `partition` (#254):
8624
+ * one insertRule at a binary-searched index, no sheet rewrite.
8625
+ */
8626
+ insertSorted(partition, rule2, key) {
8627
+ const keys = partition.keys ??= [];
8628
+ const index = upperBound(keys, key);
8629
+ const sheet = partition.styleElement.sheet;
8630
+ if (sheet && sheet.cssRules.length === keys.length) {
8631
+ sheet.insertRule(this.escapeCssRule(rule2), index);
8632
+ partition.styles.splice(index, 0, rule2);
8633
+ } else {
8634
+ partition.styles.splice(index, 0, rule2);
8635
+ partition.styleElement.textContent = partition.styles.join("\n") + "\n";
8636
+ }
8637
+ keys.splice(index, 0, key);
8638
+ }
8211
8639
  initializeDefaultPartition() {
8212
8640
  this.createNewPartition();
8213
8641
  }
8214
- createNewCategoryPartition(category) {
8642
+ createNewCategoryPartition(category, atDocumentStart = false) {
8215
8643
  const newPartition = {
8216
8644
  id: this.styleIdPrefix + `-${category}`,
8217
8645
  styles: [],
@@ -8220,7 +8648,12 @@ class StylePartitionManager {
8220
8648
  newPartition.styleElement.id = newPartition.id;
8221
8649
  newPartition.styleElement.setAttribute("data-barocss", "partition");
8222
8650
  newPartition.styleElement.setAttribute("data-category", category);
8223
- this.insertionPoint.appendChild(newPartition.styleElement);
8651
+ const head = this.insertionPoint.ownerDocument?.head;
8652
+ if (atDocumentStart && head) {
8653
+ head.insertBefore(newPartition.styleElement, head.firstChild);
8654
+ } else {
8655
+ this.insertionPoint.appendChild(newPartition.styleElement);
8656
+ }
8224
8657
  this.categoryPartitions.set(category, newPartition);
8225
8658
  return newPartition;
8226
8659
  }
@@ -8258,6 +8691,9 @@ class StylePartitionManager {
8258
8691
  getCategoryPartition(category) {
8259
8692
  return this.categoryPartitions.get(category);
8260
8693
  }
8694
+ hasDetachedPartitions() {
8695
+ return [...this.partitions, ...this.categoryPartitions.values()].some((partition) => !partition.styleElement.isConnected);
8696
+ }
8261
8697
  /**
8262
8698
  * Escape CSS rule text
8263
8699
  * - Properly escape special characters
@@ -8271,20 +8707,21 @@ class StylePartitionManager {
8271
8707
  if (this.hasRule(rule2)) {
8272
8708
  return false;
8273
8709
  }
8274
- if (this.currentPartition.styles.length >= this.maxRulesPerPartition) {
8275
- this.createNewPartition();
8710
+ const key = ruleSortKey(rule2);
8711
+ let partitionIndex = this.partitions.findIndex((p) => {
8712
+ const keys = p.keys;
8713
+ return !!keys && keys.length > 0 && compareKeys(keys[keys.length - 1], key) > 0;
8714
+ });
8715
+ if (partitionIndex === -1) {
8716
+ if (this.currentPartition.styles.length >= this.maxRulesPerPartition) {
8717
+ this.createNewPartition();
8718
+ }
8719
+ partitionIndex = this.partitions.length - 1;
8276
8720
  }
8277
- const currentPartition = this.currentPartition;
8278
- const partitionIndex = this.partitions.length - 1;
8721
+ const partition = this.partitions[partitionIndex];
8279
8722
  try {
8280
- const sheet = currentPartition.styleElement.sheet;
8281
- if (sheet) {
8282
- sheet.insertRule(this.escapeCssRule(rule2), sheet.cssRules.length);
8283
- } else {
8284
- currentPartition.styleElement.textContent += rule2 + "\n";
8285
- }
8723
+ this.insertSorted(partition, rule2, key);
8286
8724
  this.setRuleCache(rule2, partitionIndex);
8287
- currentPartition.styles.push(rule2);
8288
8725
  return true;
8289
8726
  } catch (error) {
8290
8727
  console.warn(
@@ -8303,12 +8740,7 @@ class StylePartitionManager {
8303
8740
  categoryPartition = this.createNewCategoryPartition(category);
8304
8741
  }
8305
8742
  try {
8306
- const sheet = categoryPartition.styleElement.sheet;
8307
- if (sheet) {
8308
- sheet.insertRule(this.escapeCssRule(rule2), sheet.cssRules.length);
8309
- } else {
8310
- categoryPartition.styleElement.textContent += rule2 + "\n";
8311
- }
8743
+ this.insertSorted(categoryPartition, rule2, ruleSortKey(rule2));
8312
8744
  } catch (error) {
8313
8745
  console.warn(
8314
8746
  `[StylePartitionManager] Failed to insert rule in category: ${category} ${rule2}`,
@@ -8317,7 +8749,6 @@ class StylePartitionManager {
8317
8749
  return false;
8318
8750
  }
8319
8751
  this.setCategoryRuleCache(rule2, category);
8320
- categoryPartition.styles.push(rule2);
8321
8752
  return true;
8322
8753
  }
8323
8754
  addRootRules(rules) {
@@ -8347,8 +8778,7 @@ class StylePartitionManager {
8347
8778
  let success = 0;
8348
8779
  let failed = 0;
8349
8780
  for (const rule2 of rules) {
8350
- const parsedResult = parseResultCache.get(rule2.cls);
8351
- const category = parsedResult?.utility?.category;
8781
+ const category = this.getCategory(rule2.cls);
8352
8782
  if (category) {
8353
8783
  for (const css of rule2.cssList) {
8354
8784
  this.addCategoryRule(css, category);
@@ -8379,12 +8809,12 @@ class StylePartitionManager {
8379
8809
  }
8380
8810
  return null;
8381
8811
  }
8382
- updateRuleContent(category, ruleContent) {
8812
+ updateRuleContent(category, ruleContent, atDocumentStart = false) {
8383
8813
  const partition = this.getCategoryPartition(category);
8384
8814
  if (partition) {
8385
8815
  partition.styleElement.textContent = ruleContent;
8386
8816
  } else {
8387
- const newPartition = this.createNewCategoryPartition(category);
8817
+ const newPartition = this.createNewCategoryPartition(category, atDocumentStart);
8388
8818
  console.log(`[StylePartitionManager] Created new partition for category: ${category}`);
8389
8819
  newPartition.styleElement.textContent = ruleContent;
8390
8820
  }
@@ -8404,6 +8834,7 @@ class StylePartitionManager {
8404
8834
  }
8405
8835
  });
8406
8836
  this.partitions = [];
8837
+ this.categoryPartitions.clear();
8407
8838
  this.partitionCounter = 0;
8408
8839
  this.classToPartitionMap.clear();
8409
8840
  this.classToCategoryPartitionMap.clear();
@@ -8411,8 +8842,8 @@ class StylePartitionManager {
8411
8842
  }
8412
8843
  function normalizeClassName(className) {
8413
8844
  if (!className) return "";
8414
- if (className instanceof SVGAnimatedString) {
8415
- return className.baseVal.toString();
8845
+ if (typeof className === "object" && typeof className.baseVal === "string") {
8846
+ return className.baseVal;
8416
8847
  }
8417
8848
  return className.toString();
8418
8849
  }
@@ -8427,11 +8858,14 @@ class ChangeDetector {
8427
8858
  * @param incrementalParser - IncrementalParser instance for class processing
8428
8859
  * @param BrowserRuntime - Optional BrowserRuntime instance for CSS injection
8429
8860
  */
8430
- constructor(incrementalParser, BrowserRuntime2) {
8861
+ constructor(incrementalParser, BrowserRuntime2, getCategory = (cls) => parseClassName(cls).utility?.category) {
8431
8862
  this.observer = null;
8432
- this.processedElements = /* @__PURE__ */ new WeakSet();
8433
8863
  this.incrementalParser = incrementalParser;
8434
8864
  this.BrowserRuntime = BrowserRuntime2;
8865
+ this.getCategory = getCategory;
8866
+ }
8867
+ setParser(parser) {
8868
+ this.incrementalParser = parser;
8435
8869
  }
8436
8870
  /**
8437
8871
  * Starts observing DOM changes for new CSS classes
@@ -8459,7 +8893,7 @@ class ChangeDetector {
8459
8893
  this.observer = new MutationObserver((mutations) => {
8460
8894
  const newClasses = /* @__PURE__ */ new Set();
8461
8895
  mutations.forEach((mutation) => {
8462
- if (mutation.type === "attributes" && mutation.attributeName === "class") {
8896
+ if (mutation.type === "attributes" && mutation.attributeName === "class" && root.contains(mutation.target)) {
8463
8897
  const target = mutation.target;
8464
8898
  if (target.className) {
8465
8899
  const classes = normalizeClassNameList(target.className);
@@ -8472,9 +8906,10 @@ class ChangeDetector {
8472
8906
  }
8473
8907
  if (mutation.type === "childList") {
8474
8908
  mutation.addedNodes.forEach((node) => {
8475
- if (node instanceof HTMLElement) {
8476
- this.processElement(node, newClasses);
8477
- node.querySelectorAll("[class]").forEach((el) => {
8909
+ if (node.nodeType === Node.ELEMENT_NODE && root.contains(node)) {
8910
+ const element = node;
8911
+ this.processElement(element, newClasses);
8912
+ element.querySelectorAll("[class]").forEach((el) => {
8478
8913
  this.processElement(el, newClasses);
8479
8914
  });
8480
8915
  }
@@ -8485,6 +8920,8 @@ class ChangeDetector {
8485
8920
  const classesArray = Array.from(newClasses);
8486
8921
  const results = this.incrementalParser.processClasses(classesArray);
8487
8922
  this.BrowserRuntime?.applyParseResults(results);
8923
+ } else {
8924
+ this.BrowserRuntime?.applyParseResults([]);
8488
8925
  }
8489
8926
  });
8490
8927
  this.observer.observe(root, {
@@ -8525,11 +8962,13 @@ class ChangeDetector {
8525
8962
  if (existingClasses.size > 0) {
8526
8963
  const classes = Array.from(existingClasses);
8527
8964
  const results = this.incrementalParser.processClasses(classes);
8528
- const layoutResults = results.filter((result) => parseResultCache.get(result.cls)?.utility?.category === "layout");
8529
- const nonLayoutResults = results.filter((result) => parseResultCache.get(result.cls)?.utility?.category !== "layout");
8965
+ const layoutResults = results.filter((result) => this.getCategory(result.cls) === "layout");
8966
+ const nonLayoutResults = results.filter((result) => this.getCategory(result.cls) !== "layout");
8530
8967
  this.BrowserRuntime?.applyParseResults(layoutResults);
8531
8968
  options?.onReady?.();
8532
8969
  this.BrowserRuntime?.applyParseResults(nonLayoutResults);
8970
+ } else {
8971
+ options?.onReady?.();
8533
8972
  }
8534
8973
  }
8535
8974
  /**
@@ -8537,17 +8976,14 @@ class ChangeDetector {
8537
8976
  *
8538
8977
  * This method is called for each element discovered during DOM mutations.
8539
8978
  * It:
8540
- * - Checks if the element has already been processed
8541
8979
  * - Extracts all class names from the element's className
8542
8980
  * - Filters out already processed classes
8543
8981
  * - Adds new classes to the collection for batch processing
8544
- * - Marks the element as processed to avoid duplicates
8545
8982
  *
8546
8983
  * @param element - The HTML element to process
8547
8984
  * @param newClasses - Set to collect newly discovered class names
8548
8985
  */
8549
8986
  processElement(element, newClasses) {
8550
- if (this.processedElements.has(element)) return;
8551
8987
  if (element.className) {
8552
8988
  const classes = normalizeClassNameList(element.className);
8553
8989
  classes.forEach((cls) => {
@@ -8556,7 +8992,6 @@ class ChangeDetector {
8556
8992
  }
8557
8993
  });
8558
8994
  }
8559
- this.processedElements.add(element);
8560
8995
  }
8561
8996
  /**
8562
8997
  * Stops observing DOM changes and cleans up resources
@@ -8572,22 +9007,61 @@ class ChangeDetector {
8572
9007
  }
8573
9008
  }
8574
9009
  }
9010
+ function unescapeCssIdent(s) {
9011
+ return s.replace(/\\([0-9a-fA-F]{1,6})\s?|\\(.)/g, (_m, hex, ch) => hex ? String.fromCodePoint(parseInt(hex, 16)) : ch);
9012
+ }
9013
+ const LEADING_CLASS = /^\s*\.((?:\\[0-9a-fA-F]{1,6}\s?|\\.|[\w-]|[^\x00-\x7F])+)/;
9014
+ function splitTopLevel(sel) {
9015
+ const parts = [];
9016
+ let depth = 0, start = 0;
9017
+ for (let i = 0; i < sel.length; i++) {
9018
+ const c = sel[i];
9019
+ if (c === "\\") i++;
9020
+ else if (c === "(" || c === "[") depth++;
9021
+ else if (c === ")" || c === "]") depth--;
9022
+ else if (c === "," && depth === 0) {
9023
+ parts.push(sel.slice(start, i));
9024
+ start = i + 1;
9025
+ }
9026
+ }
9027
+ parts.push(sel.slice(start));
9028
+ return parts;
9029
+ }
9030
+ function collectLeadingClasses(rules, out = /* @__PURE__ */ new Set()) {
9031
+ for (const rule2 of Array.from(rules)) {
9032
+ const selectorText = rule2.selectorText;
9033
+ if (typeof selectorText === "string") {
9034
+ for (const part of splitTopLevel(selectorText)) {
9035
+ const m = LEADING_CLASS.exec(part);
9036
+ if (m) out.add(unescapeCssIdent(m[1]));
9037
+ }
9038
+ }
9039
+ const inner = rule2.cssRules;
9040
+ if (inner && inner.length) collectLeadingClasses(inner, out);
9041
+ }
9042
+ return out;
9043
+ }
9044
+ const LAYER_ORDER = "@layer theme, base, components, utilities;";
8575
9045
  class BrowserRuntime {
8576
9046
  constructor(options = {}) {
8577
9047
  this.cache = /* @__PURE__ */ new Map();
8578
9048
  this.rootCache = /* @__PURE__ */ new Set();
8579
9049
  this.isDestroyed = false;
9050
+ this.existing = null;
9051
+ this.existingSheetCount = -1;
9052
+ this.getCategory = (cls) => parseClassName(cls, this.context).utility?.category;
8580
9053
  const defaultConfig = {};
8581
9054
  this.options = {
8582
9055
  config: options.config || defaultConfig,
8583
9056
  styleId: options.styleId || "barocss-runtime",
8584
9057
  insertionPoint: options.insertionPoint || "head",
8585
- maxRulesPerPartition: options.maxRulesPerPartition || 50
9058
+ maxRulesPerPartition: options.maxRulesPerPartition || 50,
9059
+ skipExisting: options.skipExisting ?? false
8586
9060
  };
8587
9061
  this.context = createContext(this.options.config);
8588
9062
  this.incrementalParser = new IncrementalParser(this.context);
8589
- this.changeDetector = new ChangeDetector(this.incrementalParser, this);
8590
- this.stylePartitionManager = new StylePartitionManager(this.getInsertionPoint(), this.options.maxRulesPerPartition, `${this.options.styleId}-partition`);
9063
+ this.changeDetector = new ChangeDetector(this.incrementalParser, this, this.getCategory);
9064
+ this.stylePartitionManager = new StylePartitionManager(this.getInsertionPoint(), this.options.maxRulesPerPartition, `${this.options.styleId}-partition`, this.getCategory);
8591
9065
  this.init();
8592
9066
  }
8593
9067
  // Debugging and logging helpers
@@ -8604,9 +9078,17 @@ class BrowserRuntime {
8604
9078
  this.ensureCssVars();
8605
9079
  }
8606
9080
  injectPreflightCSS() {
8607
- if (this.options.config.preflight) {
8608
- const preflightCSS = this.context.getPreflightCSS(this.options.config.preflight);
8609
- this.stylePartitionManager.updateRuleContent("preflight", preflightCSS);
9081
+ const level = this.options.config.preflight ?? true;
9082
+ if (level) {
9083
+ const preflightCSS = this.context.getPreflightCSS(level);
9084
+ this.stylePartitionManager.updateRuleContent(
9085
+ "preflight",
9086
+ `${LAYER_ORDER}
9087
+ @layer base {
9088
+ ${preflightCSS}
9089
+ }`,
9090
+ true
9091
+ );
8610
9092
  }
8611
9093
  }
8612
9094
  ensureCssVars() {
@@ -8615,7 +9097,7 @@ class BrowserRuntime {
8615
9097
  this.stylePartitionManager.updateRuleContent("css-vars", cssVars);
8616
9098
  }
8617
9099
  getInsertionPoint() {
8618
- if (this.options.insertionPoint instanceof HTMLElement) {
9100
+ if (typeof this.options.insertionPoint !== "string") {
8619
9101
  return this.options.insertionPoint;
8620
9102
  }
8621
9103
  switch (this.options.insertionPoint) {
@@ -8653,11 +9135,24 @@ class BrowserRuntime {
8653
9135
  * Public method to apply parser results, update internal caches, and inject CSS
8654
9136
  */
8655
9137
  applyParseResults(results, _opts) {
9138
+ if (this.isDestroyed) return;
9139
+ if (this.getInsertionPoint().isConnected && this.stylePartitionManager.hasDetachedPartitions()) {
9140
+ const existingResults = Array.from(this.cache.values());
9141
+ this.reset();
9142
+ results = [...existingResults, ...results];
9143
+ results.forEach((result) => this.incrementalParser.markProcessed(result.cls));
9144
+ }
9145
+ if (this.options.skipExisting && results.length > 0 && typeof document !== "undefined") {
9146
+ const existing = this.getExistingClasses();
9147
+ results = results.filter((result) => !existing.has(result.cls));
9148
+ }
9149
+ if (results.length === 0) return;
8656
9150
  const cssRules = [];
8657
9151
  const rootCssRules = [];
8658
9152
  for (const result of results) {
8659
9153
  if (result.css && Array.isArray(result.cssList)) {
8660
9154
  cssRules.push(result);
9155
+ this.cache.set(result.cls, result);
8661
9156
  }
8662
9157
  if (result.rootCss && Array.isArray(result.rootCssList)) {
8663
9158
  for (const rootCss of result.rootCssList) {
@@ -8679,6 +9174,27 @@ class BrowserRuntime {
8679
9174
  rootCssCount: rootCssRules.length
8680
9175
  });
8681
9176
  }
9177
+ /** Class names defined by the page's own stylesheets (BaroCSS's sheets and cross-origin sheets excluded). */
9178
+ getExistingClasses() {
9179
+ const sheets = Array.from(document.styleSheets).filter((sheet) => {
9180
+ const owner = sheet.ownerNode;
9181
+ return !(owner && typeof owner.hasAttribute === "function" && (owner.hasAttribute("data-barocss") || (owner.id || "").startsWith(this.options.styleId)));
9182
+ });
9183
+ if (this.existing && sheets.length === this.existingSheetCount) return this.existing;
9184
+ const out = /* @__PURE__ */ new Set();
9185
+ for (const sheet of sheets) {
9186
+ let rules;
9187
+ try {
9188
+ rules = sheet.cssRules;
9189
+ } catch {
9190
+ continue;
9191
+ }
9192
+ collectLeadingClasses(rules, out);
9193
+ }
9194
+ this.existing = out;
9195
+ this.existingSheetCount = sheets.length;
9196
+ return out;
9197
+ }
8682
9198
  /**
8683
9199
  * MutationObserver instance method to automatically call addClass when class attributes change in DOM
8684
9200
  */
@@ -8697,7 +9213,7 @@ class BrowserRuntime {
8697
9213
  return css;
8698
9214
  }
8699
9215
  getAllCss() {
8700
- const all = Array.from(this.cache.values()).flatMap((result) => result.cssList).join("\n");
9216
+ const all = [...this.rootCache, ...Array.from(this.cache.values()).flatMap((result) => result.cssList)].join("\n");
8701
9217
  return all;
8702
9218
  }
8703
9219
  getClasses() {
@@ -8708,46 +9224,64 @@ class BrowserRuntime {
8708
9224
  * Get comprehensive cache statistics
8709
9225
  */
8710
9226
  getCacheStats() {
9227
+ const incremental = this.incrementalParser.getStats();
8711
9228
  return {
8712
9229
  runtime: {
8713
9230
  cachedClasses: this.cache.size,
8714
9231
  rootCacheSize: this.rootCache.size
8715
9232
  },
8716
- ast: astCache.getStats(),
8717
- incremental: this.incrementalParser.getStats()
9233
+ ast: incremental.cacheStats.ast,
9234
+ incremental
8718
9235
  };
8719
9236
  }
8720
9237
  /**
8721
9238
  * Clear all caches (useful for debugging or memory management)
8722
9239
  */
8723
9240
  clearCaches() {
9241
+ if (this.isDestroyed) return;
8724
9242
  this.cache.clear();
8725
9243
  this.rootCache.clear();
8726
- astCache.clear();
9244
+ clearAstCache(this.context);
8727
9245
  this.incrementalParser.clearProcessed();
8728
9246
  this.stylePartitionManager.cleanup();
9247
+ this.stylePartitionManager = new StylePartitionManager(this.getInsertionPoint(), this.options.maxRulesPerPartition, `${this.options.styleId}-partition`, this.getCategory);
9248
+ this.injectPreflightCSS();
9249
+ this.ensureCssVars();
8729
9250
  }
8730
9251
  reset() {
9252
+ if (this.isDestroyed) return;
8731
9253
  this.cache.clear();
8732
9254
  this.rootCache.clear();
9255
+ this.incrementalParser.clearProcessed();
8733
9256
  this.stylePartitionManager.cleanup();
9257
+ this.stylePartitionManager = new StylePartitionManager(this.getInsertionPoint(), this.options.maxRulesPerPartition, `${this.options.styleId}-partition`, this.getCategory);
9258
+ this.injectPreflightCSS();
9259
+ this.ensureCssVars();
8734
9260
  }
8735
9261
  updateConfig(newConfig) {
9262
+ if (this.isDestroyed) return;
9263
+ const existingClasses = Array.from(this.cache.keys());
8736
9264
  this.options.config = newConfig;
8737
9265
  this.context = createContext(newConfig);
8738
- const existingClasses = Array.from(this.cache.keys());
9266
+ this.incrementalParser = new IncrementalParser(this.context);
9267
+ this.changeDetector.setParser(this.incrementalParser);
8739
9268
  this.reset();
8740
9269
  if (existingClasses.length > 0) {
8741
9270
  this.addClass(existingClasses);
8742
9271
  }
8743
9272
  }
8744
9273
  removeClass(classes) {
8745
- const classList = this.normalizeClasses(classes);
8746
- for (const cls of classList) {
8747
- this.cache.delete(cls);
8748
- }
9274
+ if (this.isDestroyed) return;
9275
+ const classList = new Set(this.normalizeClasses(classes));
9276
+ const retainedResults = Array.from(this.cache.values()).filter((result) => !classList.has(result.cls));
9277
+ if (retainedResults.length === this.cache.size) return;
9278
+ this.reset();
9279
+ retainedResults.forEach((result) => this.incrementalParser.markProcessed(result.cls));
9280
+ this.applyParseResults(retainedResults);
8749
9281
  }
8750
9282
  destroy() {
9283
+ if (this.isDestroyed) return;
9284
+ this.changeDetector.disconnect();
8751
9285
  this.stylePartitionManager.cleanup();
8752
9286
  this.cache.clear();
8753
9287
  this.rootCache.clear();
@@ -8765,13 +9299,22 @@ class BrowserRuntime {
8765
9299
  }
8766
9300
  }
8767
9301
  let runtime = null;
8768
- function getRuntime(options) {
8769
- if (!runtime) {
9302
+ let runtimeConfig;
9303
+ function getRuntime(options = {}) {
9304
+ if (!runtime || runtime.getStats().isDestroyed) {
8770
9305
  runtime = new BrowserRuntime(options);
9306
+ runtimeConfig = options.config;
9307
+ } else if (options.config && options.config !== runtimeConfig) {
9308
+ runtime.updateConfig(options.config);
9309
+ runtimeConfig = options.config;
8771
9310
  }
8772
9311
  return runtime;
8773
9312
  }
8774
9313
  function baroBoot({ loadingClassName = "baro-boot", ...options } = {}) {
9314
+ if (!document.body) {
9315
+ document.addEventListener("DOMContentLoaded", () => baroBoot({ loadingClassName, ...options }), { once: true });
9316
+ return;
9317
+ }
8775
9318
  const startClassName = `${loadingClassName}-doing`;
8776
9319
  const endClassName = `${loadingClassName}-done`;
8777
9320
  try {
@@ -8782,18 +9325,87 @@ function baroBoot({ loadingClassName = "baro-boot", ...options } = {}) {
8782
9325
  document.body.classList.add(endClassName);
8783
9326
  } });
8784
9327
  } catch (error) {
9328
+ document.body?.classList.remove(startClassName);
8785
9329
  console.error("BaroCSS boot failed:", error);
8786
9330
  }
8787
9331
  }
8788
9332
  const baroStart = baroBoot;
9333
+ function collectJsonRenderClassNames(spec) {
9334
+ if (!spec || typeof spec !== "object" || Array.isArray(spec)) return [];
9335
+ const elements = spec.elements;
9336
+ if (!elements || typeof elements !== "object" || Array.isArray(elements)) return [];
9337
+ const classes = /* @__PURE__ */ new Set();
9338
+ for (const key of Object.keys(elements)) {
9339
+ const element = elements[key];
9340
+ if (!element || typeof element !== "object" || Array.isArray(element)) continue;
9341
+ const props = element.props;
9342
+ if (!props || typeof props !== "object" || Array.isArray(props)) continue;
9343
+ const className = props.className;
9344
+ if (typeof className !== "string") continue;
9345
+ for (const cls of className.split(/\s+/)) {
9346
+ if (cls) classes.add(cls);
9347
+ }
9348
+ }
9349
+ return Array.from(classes);
9350
+ }
9351
+ function preloadJsonRenderClasses(spec, runtime2) {
9352
+ const classes = collectJsonRenderClassNames(spec);
9353
+ if (classes.length > 0) runtime2.addClass(classes);
9354
+ }
9355
+ const SHADCN_COLOR_NAMES = [
9356
+ "background",
9357
+ "foreground",
9358
+ "card",
9359
+ "card-foreground",
9360
+ "popover",
9361
+ "popover-foreground",
9362
+ "primary",
9363
+ "primary-foreground",
9364
+ "secondary",
9365
+ "secondary-foreground",
9366
+ "muted",
9367
+ "muted-foreground",
9368
+ "accent",
9369
+ "accent-foreground",
9370
+ "destructive",
9371
+ "border",
9372
+ "input",
9373
+ "ring",
9374
+ "chart-1",
9375
+ "chart-2",
9376
+ "chart-3",
9377
+ "chart-4",
9378
+ "chart-5",
9379
+ "sidebar",
9380
+ "sidebar-foreground",
9381
+ "sidebar-primary",
9382
+ "sidebar-primary-foreground",
9383
+ "sidebar-accent",
9384
+ "sidebar-accent-foreground",
9385
+ "sidebar-border",
9386
+ "sidebar-ring"
9387
+ ];
9388
+ const shadcnTheme = {
9389
+ colors: Object.fromEntries(SHADCN_COLOR_NAMES.map((n) => [n, `var(--${n})`])),
9390
+ borderRadius: {
9391
+ sm: "calc(var(--radius) - 4px)",
9392
+ md: "calc(var(--radius) - 2px)",
9393
+ lg: "var(--radius)",
9394
+ xl: "calc(var(--radius) + 4px)"
9395
+ }
9396
+ };
8789
9397
  export {
8790
9398
  BrowserRuntime,
8791
9399
  ChangeDetector,
9400
+ LAYER_ORDER,
8792
9401
  StylePartitionManager,
8793
9402
  baroBoot,
8794
9403
  baroStart,
9404
+ collectJsonRenderClassNames,
8795
9405
  getRuntime,
8796
9406
  normalizeClassName,
8797
- normalizeClassNameList
9407
+ normalizeClassNameList,
9408
+ preloadJsonRenderClasses,
9409
+ shadcnTheme
8798
9410
  };
8799
9411
  //# sourceMappingURL=barocss.js.map