@homebound/truss 2.29.1 → 2.29.2

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.
@@ -257,20 +257,8 @@ function toVirtualCssSpecifier(source) {
257
257
  // src/plugin/transform-session.ts
258
258
  import { resolve as resolve2 } from "path";
259
259
 
260
- // src/plugin/emit-truss.ts
261
- import * as t4 from "@babel/types";
262
-
263
260
  // src/plugin/resolve-chain.ts
264
- import * as t3 from "@babel/types";
265
- import { pascalCase } from "change-case";
266
-
267
- // src/plugin/types.ts
268
- function isStyleSegment(seg) {
269
- return !seg.error && !seg.styleArrayArg && !seg.classNameArg && !seg.styleArg && !seg.typographyLookup;
270
- }
271
- function hasCondition(target) {
272
- return !!(target.mediaQuery || target.pseudoClass || target.pseudoElement || target.whenPseudo);
273
- }
261
+ import * as t10 from "@babel/types";
274
262
 
275
263
  // src/plugin/mapping-utils.ts
276
264
  import { readFileSync } from "fs";
@@ -308,131 +296,82 @@ function breakpointNameForMediaQuery(mapping, mediaQuery) {
308
296
  return getterName === void 0 ? null : getterName.replace(/^if/, "");
309
297
  }
310
298
 
311
- // src/plugin/when-relationships.ts
312
- var WHEN_RELATIONSHIPS = {
313
- ancestor: {
314
- short: "anc",
315
- priority: 10,
316
- /** I.e. `._mrk:hover .wh_anc_h_blue`. */
317
- selector(marker, target) {
318
- return `${marker} ${target()}`;
319
- }
320
- },
321
- descendant: {
322
- short: "desc",
323
- priority: 15,
324
- /** I.e. `.wh_desc_h_blue:has(._mrk:hover)`. */
325
- selector(marker, target) {
326
- return target(`:has(${marker})`);
327
- }
328
- },
329
- anySibling: {
330
- short: "anyS",
331
- priority: 20,
332
- /** I.e. `.wh_anyS_h_blue:has(~ ._mrk:hover), ._mrk:hover ~ .wh_anyS_h_blue`. */
333
- selector(marker, target) {
334
- return `${target(`:has(~ ${marker})`)}, ${marker} ~ ${target()}`;
335
- }
336
- },
337
- siblingBefore: {
338
- short: "sibB",
339
- priority: 30,
340
- /** I.e. `._mrk:hover ~ .wh_sibB_h_blue`. */
341
- selector(marker, target) {
342
- return `${marker} ~ ${target()}`;
343
- }
344
- },
345
- siblingAfter: {
346
- short: "sibA",
347
- priority: 40,
348
- /** I.e. `.wh_sibA_h_blue:has(~ ._mrk:hover)`. */
349
- selector(marker, target) {
350
- return target(`:has(~ ${marker})`);
351
- }
299
+ // src/plugin/chain-nodes.ts
300
+ var UnsupportedPatternError = class extends Error {
301
+ constructor(message) {
302
+ super(`[truss] Unsupported pattern: ${message}`);
303
+ this.name = "UnsupportedPatternError";
352
304
  }
353
305
  };
354
- function isWhenRelationship(value) {
355
- return Object.hasOwn(WHEN_RELATIONSHIPS, value);
356
- }
357
306
 
358
- // src/media-query.ts
359
- function invertMediaQuery(query) {
360
- const screenPrefix = "@media screen and ";
361
- if (query.startsWith(screenPrefix)) {
362
- const conditions = query.slice(screenPrefix.length).trim();
363
- const rangeMatch = conditions.match(/^\(min-width: (\d+)px\) and \(max-width: (\d+)px\)$/);
364
- if (rangeMatch) {
365
- const min = Number(rangeMatch[1]);
366
- const max = Number(rangeMatch[2]);
367
- return `@media screen and (max-width: ${min - 1}px), screen and (min-width: ${max + 1}px)`;
368
- }
369
- const minMatch = conditions.match(/^\(min-width: (\d+)px\)$/);
370
- if (minMatch) {
371
- return `@media screen and (max-width: ${Number(minMatch[1]) - 1}px)`;
372
- }
373
- const maxMatch = conditions.match(/^\(max-width: (\d+)px\)$/);
374
- if (maxMatch) {
375
- return `@media screen and (min-width: ${Number(maxMatch[1]) + 1}px)`;
376
- }
377
- }
378
- return query.replace("@media", "@media not");
307
+ // src/plugin/condition-context.ts
308
+ function emptyConditionContext() {
309
+ return {
310
+ mediaQuery: null,
311
+ pseudoClass: null,
312
+ pseudoElement: null,
313
+ whenPseudo: null
314
+ };
315
+ }
316
+ function cloneConditionContext(context) {
317
+ return { ...context };
318
+ }
319
+ function resetConditionContext(context) {
320
+ Object.assign(context, emptyConditionContext());
379
321
  }
380
322
 
381
- // src/pseudo-selectors.ts
382
- var TRUSS_PSEUDO_METHODS = {
383
- onHover: ":hover",
384
- onFocus: ":focus",
385
- onFocusVisible: ":focus-visible",
386
- onFocusWithin: ":focus-within",
387
- onActive: ":active",
388
- onDisabled: ":disabled",
389
- ifFirstOfType: ":first-of-type",
390
- ifLastOfType: ":last-of-type"
391
- };
392
- var PSEUDO_SELECTOR_PREFIXES = {
393
- ":hover": "h",
394
- ":focus": "f",
395
- ":focus-visible": "fv",
396
- ":focus-within": "fw",
397
- ":active": "a",
398
- ":disabled": "d",
399
- ":first-of-type": "fot",
400
- ":last-of-type": "lot",
401
- ":not": "n",
402
- ":is": "is",
403
- ":where": "where",
404
- ":has": "has"
405
- };
406
- function isTrussPseudoMethod(name) {
407
- return name in TRUSS_PSEUDO_METHODS;
323
+ // src/plugin/resolve-entry.ts
324
+ function requireEntry(mapping, abbr) {
325
+ const entry = mapping.abbreviations[abbr];
326
+ if (!entry) {
327
+ throw new UnsupportedPatternError(`Unknown abbreviation "${abbr}"`);
328
+ }
329
+ return entry;
408
330
  }
409
- function trussPseudoSelector(name) {
410
- return TRUSS_PSEUDO_METHODS[name];
331
+ function errorSegment(message) {
332
+ return { kind: "error", message };
411
333
  }
412
- function pseudoSelectorPrefix(pseudo) {
413
- const replaced = pseudo.trim().replace(/::?[a-zA-Z-]+/g, function pseudoMatchToPrefix(match) {
414
- return `_${pseudoIdentifierPrefix(match)}_`;
415
- });
416
- const cleaned = replaced.replace(/[^a-zA-Z0-9]/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "");
417
- return cleaned || "pseudo";
334
+ function staticSegment(abbr, defs, context, argResolved) {
335
+ return { kind: "static", abbr, defs, argResolved, condition: cloneConditionContext(context) };
418
336
  }
419
- function pseudoIdentifierPrefix(pseudo) {
420
- const normalized = normalizePseudoIdentifier(pseudo);
421
- const known = PSEUDO_SELECTOR_PREFIXES[normalized];
422
- if (known) {
423
- return known;
337
+ function resolveEntry(abbr, entry, mapping, context) {
338
+ switch (entry.kind) {
339
+ case "static": {
340
+ return [staticSegment(abbr, entry.defs, context)];
341
+ }
342
+ case "alias": {
343
+ const result = [];
344
+ for (const chainAbbr of entry.chain) {
345
+ const subEntry = mapping.abbreviations[chainAbbr];
346
+ if (!subEntry) {
347
+ throw new UnsupportedPatternError(`Alias "${abbr}" references unknown abbreviation "${chainAbbr}"`);
348
+ }
349
+ result.push(...resolveEntry(chainAbbr, subEntry, mapping, context));
350
+ }
351
+ return result;
352
+ }
353
+ case "variable":
354
+ case "delegate":
355
+ throw new UnsupportedPatternError(`Abbreviation "${abbr}" requires arguments \u2014 use ${abbr}() not .${abbr}`);
356
+ default:
357
+ throw new UnsupportedPatternError(`Unhandled entry kind for "${abbr}"`);
424
358
  }
425
- return normalized.replace(/^::?/, "").replace(/-/g, "_");
426
359
  }
427
- function normalizePseudoIdentifier(pseudo) {
428
- const prefixMatch = pseudo.match(/^::?/);
429
- const prefix = prefixMatch?.[0] ?? "";
430
- const name = pseudo.slice(prefix.length).replace(/[A-Z]/g, function upperToKebab(match) {
431
- return `-${match.toLowerCase()}`;
432
- });
433
- return `${prefix}${name}`;
360
+
361
+ // src/plugin/resolve-calls.ts
362
+ import * as t8 from "@babel/types";
363
+
364
+ // src/plugin/types.ts
365
+ function isCssSegment(seg) {
366
+ return seg.kind === "static" || seg.kind === "variable";
367
+ }
368
+ function hasCondition(condition) {
369
+ return !!(condition.mediaQuery || condition.pseudoClass || condition.pseudoElement || condition.whenPseudo);
434
370
  }
435
371
 
372
+ // src/plugin/resolve-literals.ts
373
+ import * as t3 from "@babel/types";
374
+
436
375
  // src/css-custom-property.ts
437
376
  function maybeCssVar(value) {
438
377
  if (typeof value !== "string") return value;
@@ -461,1509 +400,152 @@ function rootSpacingPreludeCss(incrementPx) {
461
400
  return `:root { ${SPACING_CUSTOM_PROPERTY}: ${incrementPx}px; }`;
462
401
  }
463
402
 
464
- // src/plugin/resolve-chain.ts
465
- function partSegments(part) {
466
- return part.type === "unconditional" ? part.segments : [...part.thenSegments, ...part.elseSegments];
403
+ // src/plugin/resolve-literals.ts
404
+ function tryEvaluatePropertyLiteral(node, mapping, incremented) {
405
+ const numeric = tryNumericLiteral(node);
406
+ if (numeric !== null) {
407
+ return incremented ? incrementCssValue(numeric) : String(numeric);
408
+ }
409
+ const raw = tryResolveValueLiteral(node, mapping);
410
+ return raw === null ? null : maybeCssVar(raw);
467
411
  }
468
- function chainSegments(chain) {
469
- return chain.parts.flatMap((part) => partSegments(part));
412
+ function isCustomPropertyLiteral(node, mapping) {
413
+ const raw = tryResolveValueLiteral(node, mapping);
414
+ return raw !== null && isCustomPropertyName(raw);
470
415
  }
471
- function resolveFullChain(ctx, chain) {
472
- const { mapping } = ctx;
473
- const initialContext = ctx.initialContext ?? emptyConditionContext();
474
- const parts = [];
475
- const nestedErrors = [];
476
- const markerScan = scanMarkerNodes(chain);
477
- const nodes = markerScan.chain;
478
- const markers = [...markerScan.markers];
479
- let i = 0;
480
- let currentNodes = [];
481
- const currentContext = cloneConditionContext(initialContext);
482
- let currentNodesStartContext = cloneConditionContext(initialContext);
483
- function flushCurrentNodes() {
484
- if (currentNodes.length === 0) {
485
- return;
486
- }
487
- parts.push({
488
- type: "unconditional",
489
- segments: resolveSegments({ ...ctx, initialContext: currentNodesStartContext }, currentNodes)
490
- });
491
- currentNodes = [];
492
- currentNodesStartContext = cloneConditionContext(currentContext);
416
+ function tryResolveValueLiteral(node, mapping) {
417
+ if (mapping) {
418
+ const token = tryResolveTokensMember(node, mapping);
419
+ if (token !== null) return token;
420
+ }
421
+ if (t3.isStringLiteral(node)) {
422
+ return node.value;
423
+ }
424
+ const numeric = tryNumericLiteral(node);
425
+ return numeric === null ? null : String(numeric);
426
+ }
427
+ function tryNumericLiteral(node) {
428
+ if (t3.isNumericLiteral(node)) {
429
+ return node.value;
430
+ }
431
+ if (t3.isUnaryExpression(node, { operator: "-" }) && t3.isNumericLiteral(node.argument)) {
432
+ return -node.argument.value;
433
+ }
434
+ return null;
435
+ }
436
+ function tryResolveTokensMember(node, mapping) {
437
+ if (!t3.isMemberExpression(node) || !t3.isIdentifier(node.object, { name: "Tokens" })) return null;
438
+ const memberName = memberPropertyName(node);
439
+ if (memberName === null) return null;
440
+ const tokenMap = mapping.tokens;
441
+ if (!tokenMap) {
442
+ throw new UnsupportedPatternError(`Tokens.* requires config.tokens`);
443
+ }
444
+ if (!(memberName in tokenMap)) {
445
+ throw new UnsupportedPatternError(`Unknown token "${memberName}" - add it to config.tokens`);
446
+ }
447
+ return tokenMap[memberName];
448
+ }
449
+ function singleArg(node, label) {
450
+ if (node.args.length !== 1) {
451
+ throw new UnsupportedPatternError(`${label}() expects exactly 1 argument, got ${node.args.length}`);
493
452
  }
494
- function pushCurrentNode(nodeToPush) {
495
- if (currentNodes.length === 0) {
496
- currentNodesStartContext = cloneConditionContext(currentContext);
453
+ const arg = node.args[0];
454
+ if (t3.isSpreadElement(arg)) {
455
+ throw new UnsupportedPatternError(`${label}() does not support spread arguments`);
456
+ }
457
+ return arg;
458
+ }
459
+ function plainObjectEntries(obj, label) {
460
+ return obj.properties.map((prop) => {
461
+ if (t3.isSpreadElement(prop)) {
462
+ throw new UnsupportedPatternError(`${label} does not support spread properties`);
497
463
  }
498
- currentNodes.push(nodeToPush);
499
- try {
500
- applyModifierNodeToConditionContext(currentContext, nodeToPush, mapping);
501
- } catch {
464
+ if (!t3.isObjectProperty(prop) || prop.computed) {
465
+ throw new UnsupportedPatternError(`${label} only supports plain object properties`);
466
+ }
467
+ const key = staticPropertyName(prop.key);
468
+ if (key === null) {
469
+ throw new UnsupportedPatternError(`${label} only supports identifier/string keys`);
502
470
  }
471
+ return { key, value: prop.value };
472
+ });
473
+ }
474
+ function numericLiteralValue(node, errorMessage) {
475
+ const numeric = tryNumericLiteral(node);
476
+ if (numeric === null) {
477
+ throw new UnsupportedPatternError(errorMessage);
503
478
  }
504
- while (i < nodes.length) {
505
- const node = nodes[i];
506
- const mediaQuery = mediaQueryOfNode(node, mapping);
507
- if (mediaQuery !== null) {
508
- const elseIndex = findElseIndex(nodes, i + 1);
509
- if (elseIndex === -1) {
510
- pushCurrentNode(makeMediaQueryNode(mediaQuery));
511
- i++;
512
- continue;
513
- }
514
- flushCurrentNodes();
515
- const branchContext = cloneConditionContext(currentContext);
516
- const branchEnd = findEndIndex(nodes, elseIndex + 1);
517
- const thenNodes = [makeMediaQueryNode(mediaQuery), ...nodes.slice(i + 1, elseIndex)];
518
- const elseNodes = [makeMediaQueryNode(invertMediaQuery(mediaQuery)), ...nodes.slice(elseIndex + 1, branchEnd)];
519
- parts.push({
520
- type: "unconditional",
521
- segments: [
522
- ...resolveSegments({ ...ctx, initialContext: branchContext }, thenNodes),
523
- ...resolveSegments({ ...ctx, initialContext: branchContext }, elseNodes)
524
- ]
525
- });
526
- if (branchEnd === nodes.length) {
527
- break;
528
- }
529
- resetConditionContext(currentContext);
530
- i = branchEnd + 1;
531
- continue;
532
- }
533
- if (isWhenObjectCall(node)) {
534
- flushCurrentNodes();
535
- const resolved = resolveWhenObjectSelectors(ctx, node, currentContext);
536
- parts.push(...resolved.parts);
537
- markers.push(...resolved.markers);
538
- nestedErrors.push(...resolved.errors);
539
- i++;
540
- continue;
541
- }
542
- if (node.type === "if") {
543
- flushCurrentNodes();
544
- const branchContext = cloneConditionContext(currentContext);
545
- const thenNodes = [];
546
- const elseNodes = [];
547
- i++;
548
- let inElse = false;
549
- while (i < nodes.length) {
550
- const branchNode = nodes[i];
551
- if (branchNode.type === "getter" && branchNode.name === "end") {
552
- resetConditionContext(currentContext);
553
- i++;
554
- break;
555
- }
556
- if (branchNode.type === "else") {
557
- inElse = true;
558
- i++;
559
- continue;
560
- }
561
- if (branchNode.type === "if") {
562
- break;
563
- }
564
- if (inElse) {
565
- elseNodes.push(branchNode);
566
- } else {
567
- thenNodes.push(branchNode);
568
- }
569
- i++;
570
- }
571
- parts.push({
572
- type: "conditional",
573
- conditionNode: node.conditionNode,
574
- thenSegments: resolveSegments({ ...ctx, initialContext: branchContext }, thenNodes),
575
- elseSegments: resolveSegments({ ...ctx, initialContext: branchContext }, elseNodes)
576
- });
577
- continue;
578
- }
579
- pushCurrentNode(node);
580
- i++;
581
- }
582
- flushCurrentNodes();
583
- const segmentErrors = parts.flatMap((part) => partSegments(part)).flatMap((seg) => seg.error ? [seg.error] : []);
584
- return { parts, markers, errors: [.../* @__PURE__ */ new Set([...markerScan.errors, ...nestedErrors, ...segmentErrors])] };
479
+ return numeric;
585
480
  }
586
- function resolveSegments(ctx, chain) {
587
- const { mapping } = ctx;
588
- const segments = [];
589
- const context = cloneConditionContext(ctx.initialContext ?? emptyConditionContext());
590
- for (const node of chain) {
591
- try {
592
- if (isWhenObjectCall(node)) {
593
- segments.push(...flattenWhenObjectParts(resolveWhenObjectSelectors(ctx, node, context)));
594
- continue;
595
- }
596
- if (applyModifierNodeToConditionContext(context, node, mapping)) {
597
- continue;
598
- }
599
- if (node.type === "getter") {
600
- segments.push(...resolveEntry(node.name, requireEntry(mapping, node.name), mapping, context));
601
- } else if (node.type === "call") {
602
- segments.push(...resolveCallNode(node, mapping, context));
603
- }
604
- } catch (err) {
605
- if (!(err instanceof UnsupportedPatternError)) throw err;
606
- segments.push(errorSegment(err.message));
607
- }
481
+ function stringLiteralValue(node, errorMessage) {
482
+ if (t3.isStringLiteral(node)) {
483
+ return node.value;
608
484
  }
609
- return segments;
610
- }
611
- function emptyConditionContext() {
612
- return {
613
- mediaQuery: null,
614
- pseudoClass: null,
615
- pseudoElement: null,
616
- whenPseudo: null
617
- };
618
- }
619
- function cloneConditionContext(context) {
620
- return { ...context };
621
- }
622
- function resetConditionContext(context) {
623
- Object.assign(context, emptyConditionContext());
485
+ if (t3.isTemplateLiteral(node) && node.expressions.length === 0 && node.quasis.length === 1) {
486
+ return node.quasis[0].value.cooked ?? "";
487
+ }
488
+ throw new UnsupportedPatternError(errorMessage);
624
489
  }
625
- function segmentWithConditionContext(segment, context) {
626
- return {
627
- ...segment,
628
- mediaQuery: context.mediaQuery,
629
- pseudoClass: context.pseudoClass,
630
- pseudoElement: context.pseudoElement,
631
- whenPseudo: context.whenPseudo
632
- };
490
+ function requireValueLiteral(node, errorMessage) {
491
+ const value = tryResolveValueLiteral(unwrapExpression(node));
492
+ if (value === null) {
493
+ throw new UnsupportedPatternError(errorMessage);
494
+ }
495
+ return value;
633
496
  }
634
- function applyModifierNodeToConditionContext(context, node, mapping) {
635
- if (node.type === "mediaQuery") {
636
- context.mediaQuery = node.mediaQuery;
637
- return true;
497
+
498
+ // src/plugin/resolve-setvar.ts
499
+ import * as t6 from "@babel/types";
500
+ import { pascalCase } from "change-case";
501
+
502
+ // src/plugin/container-query.ts
503
+ import * as t4 from "@babel/types";
504
+ function containerQueryFromCall(node) {
505
+ const arg = singleArg(node, "ifContainer");
506
+ if (!t4.isObjectExpression(arg)) {
507
+ throw new UnsupportedPatternError("ifContainer() expects an object literal argument");
638
508
  }
639
- if (node.type === "getter") {
640
- if (node.name === "end") {
641
- resetConditionContext(context);
642
- return true;
643
- }
644
- if (isTrussPseudoMethod(node.name)) {
645
- context.pseudoClass = trussPseudoSelector(node.name);
646
- return true;
647
- }
648
- const mediaQuery = breakpointMediaQuery(mapping, node.name);
649
- if (mediaQuery !== null) {
650
- context.mediaQuery = mediaQuery;
651
- return true;
509
+ const bounds = {};
510
+ for (const { key, value } of plainObjectEntries(arg, "ifContainer()")) {
511
+ if (!readContainerBound(bounds, key, value, "ifContainer().")) {
512
+ throw new UnsupportedPatternError(`ifContainer() does not support property "${key}"`);
652
513
  }
653
- return false;
654
- }
655
- if (node.type !== "call") {
656
- return false;
657
514
  }
658
- if (node.name === "ifContainer") {
659
- context.mediaQuery = containerQueryFromCall(node);
660
- return true;
515
+ if (bounds.lt === void 0 && bounds.gt === void 0) {
516
+ throw new UnsupportedPatternError('ifContainer() requires at least one of "lt" or "gt"');
661
517
  }
662
- if (node.name === "element") {
663
- const arg = node.args.length === 1 ? node.args[0] : null;
664
- if (!t3.isStringLiteral(arg)) {
665
- throw new UnsupportedPatternError(
666
- `element() requires exactly one string literal argument (e.g. "::placeholder")`
667
- );
668
- }
669
- context.pseudoElement = arg.value;
518
+ return containerQueryString(bounds);
519
+ }
520
+ function readContainerBound(bounds, key, value, label) {
521
+ if (key === "lt") {
522
+ bounds.lt = numericLiteralValue(value, `${label}lt must be a numeric literal`);
670
523
  return true;
671
524
  }
672
- if (node.name === "when") {
673
- if (isWhenObjectCall(node)) {
674
- return false;
675
- }
676
- const resolved = resolveWhenCall(node);
677
- if (resolved.kind === "selector") {
678
- context.pseudoClass = resolved.selector;
679
- } else {
680
- context.whenPseudo = resolved.condition;
681
- }
525
+ if (key === "gt") {
526
+ bounds.gt = numericLiteralValue(value, `${label}gt must be a numeric literal`);
682
527
  return true;
683
528
  }
684
- if (isTrussPseudoMethod(node.name)) {
685
- context.pseudoClass = trussPseudoSelector(node.name);
686
- if (node.args.length > 0) {
687
- throw new UnsupportedPatternError(
688
- `${node.name}() does not take arguments -- use when(marker, "ancestor", ":hover") for relationship selectors`
689
- );
690
- }
529
+ if (key === "name") {
530
+ bounds.name = stringLiteralValue(value, `${label}name must be a string literal`);
691
531
  return true;
692
532
  }
693
533
  return false;
694
534
  }
695
- function scanMarkerNodes(chain) {
696
- const filteredChain = [];
697
- const markers = [];
698
- const errors = [];
699
- for (const node of chain) {
700
- if (node.type === "getter" && node.name === "marker") {
701
- markers.push({ type: "marker" });
702
- continue;
703
- }
704
- if (node.type === "call" && node.name === "markerOf") {
705
- const arg = node.args.length === 1 ? node.args[0] : null;
706
- if (!arg || t3.isSpreadElement(arg)) {
707
- errors.push("[truss] Unsupported pattern: markerOf() requires exactly one argument (a marker variable)");
708
- } else {
709
- markers.push({ type: "marker", markerNode: arg });
710
- }
711
- continue;
712
- }
713
- filteredChain.push(node);
714
- }
715
- return { chain: filteredChain, markers, errors };
716
- }
717
- function mediaQueryOfNode(node, mapping) {
718
- if (node.type === "if" && t3.isStringLiteral(node.conditionNode)) {
719
- return node.conditionNode.value;
720
- }
721
- if (node.type === "getter") {
722
- return breakpointMediaQuery(mapping, node.name);
723
- }
724
- return null;
725
- }
726
- function findElseIndex(chain, start) {
727
- for (let i = start; i < chain.length; i++) {
728
- const node = chain[i];
729
- if (node.type === "if") {
730
- return -1;
731
- }
732
- if (node.type === "getter" && node.name === "end") {
733
- return -1;
734
- }
735
- if (node.type === "else") {
736
- return i;
737
- }
535
+ function containerQueryString(bounds) {
536
+ const parts = [];
537
+ if (bounds.gt !== void 0) {
538
+ parts.push(`(min-width: ${bounds.gt + 1}px)`);
738
539
  }
739
- return -1;
740
- }
741
- function findEndIndex(chain, start) {
742
- for (let i = start; i < chain.length; i++) {
743
- const node = chain[i];
744
- if (node.type === "getter" && node.name === "end") {
745
- return i;
746
- }
540
+ if (bounds.lt !== void 0) {
541
+ parts.push(`(max-width: ${bounds.lt}px)`);
747
542
  }
748
- return chain.length;
749
- }
750
- function makeMediaQueryNode(mediaQuery) {
751
- return { type: "mediaQuery", mediaQuery };
752
- }
753
- function isWhenObjectCall(node) {
754
- return node.type === "call" && node.name === "when" && node.args.length === 1 && t3.isObjectExpression(node.args[0]);
755
- }
756
- function resolveWhenObjectSelectors(ctx, node, initialContext) {
757
- if (!ctx.cssBindingName) {
758
- return {
759
- parts: [],
760
- markers: [],
761
- errors: [new UnsupportedPatternError(`when({ ... }) requires a resolvable Css binding`).message]
762
- };
763
- }
764
- const parts = [];
765
- const markers = [];
766
- const errors = [];
767
- for (const property of node.args[0].properties) {
768
- try {
769
- if (t3.isSpreadElement(property)) {
770
- throw new UnsupportedPatternError(`when({ ... }) does not support spread properties`);
771
- }
772
- if (!t3.isObjectProperty(property)) {
773
- throw new UnsupportedPatternError(`when({ ... }) only supports plain object properties`);
774
- }
775
- if (property.computed || !t3.isStringLiteral(property.key)) {
776
- throw new UnsupportedPatternError(`when({ ... }) selector keys must be string literals`);
777
- }
778
- const value = unwrapExpression(property.value);
779
- const innerChain = resolveWhenObjectValueChain(ctx, value);
780
- if (!innerChain) {
781
- throw new UnsupportedPatternError(`when({ ... }) values must be Css.*.$ expressions`);
782
- }
783
- const selectorContext = cloneConditionContext(initialContext);
784
- selectorContext.pseudoClass = property.key.value;
785
- const resolved = resolveFullChain({ ...ctx, initialContext: selectorContext }, innerChain);
786
- parts.push(...resolved.parts);
787
- markers.push(...resolved.markers);
788
- errors.push(...resolved.errors);
789
- } catch (err) {
790
- if (!(err instanceof UnsupportedPatternError)) throw err;
791
- errors.push(err.message);
792
- }
793
- }
794
- return { parts, markers, errors: [...new Set(errors)] };
795
- }
796
- function resolveWhenObjectValueChain(ctx, value) {
797
- const direct = ctx.cssBindingName ? extractDollarChain(value, ctx.cssBindingName) : null;
798
- return direct ?? ctx.resolveCssChainReference?.(value) ?? null;
799
- }
800
- function flattenWhenObjectParts(resolved) {
801
- const segments = [];
802
- for (const part of resolved.parts) {
803
- if (part.type !== "unconditional") {
804
- throw new UnsupportedPatternError(`when({ ... }) values cannot use if()/else in this context`);
805
- }
806
- segments.push(...part.segments);
807
- }
808
- for (const err of resolved.errors) {
809
- segments.push(errorSegment(err));
810
- }
811
- return segments;
812
- }
813
- function requireEntry(mapping, abbr) {
814
- const entry = mapping.abbreviations[abbr];
815
- if (!entry) {
816
- throw new UnsupportedPatternError(`Unknown abbreviation "${abbr}"`);
817
- }
818
- return entry;
819
- }
820
- function errorSegment(message) {
821
- return { abbr: "__error", defs: {}, error: message };
822
- }
823
- function resolveEntry(abbr, entry, mapping, context) {
824
- switch (entry.kind) {
825
- case "static": {
826
- return [segmentWithConditionContext({ abbr, defs: entry.defs }, context)];
827
- }
828
- case "alias": {
829
- const result = [];
830
- for (const chainAbbr of entry.chain) {
831
- const subEntry = mapping.abbreviations[chainAbbr];
832
- if (!subEntry) {
833
- throw new UnsupportedPatternError(`Alias "${abbr}" references unknown abbreviation "${chainAbbr}"`);
834
- }
835
- result.push(...resolveEntry(chainAbbr, subEntry, mapping, context));
836
- }
837
- return result;
838
- }
839
- case "variable":
840
- case "delegate":
841
- throw new UnsupportedPatternError(`Abbreviation "${abbr}" requires arguments \u2014 use ${abbr}() not .${abbr}`);
842
- default:
843
- throw new UnsupportedPatternError(`Unhandled entry kind for "${abbr}"`);
844
- }
845
- }
846
- function resolveCallNode(node, mapping, context) {
847
- switch (node.name) {
848
- case "with":
849
- return [resolveWithCall(node)];
850
- case "add":
851
- return resolveAddCall(node, mapping, context);
852
- case "className":
853
- return [resolveClassNameCall(node, context)];
854
- case "style":
855
- return [resolveStyleCall(node, context)];
856
- case "setVar":
857
- return resolveSetVarCall(node, mapping, context);
858
- case "typography":
859
- return resolveTypographyCall(node, mapping, context);
860
- }
861
- const entry = requireEntry(mapping, node.name);
862
- if (entry.kind === "variable") {
863
- return [resolveVariableCall(node.name, entry, node, mapping, context)];
864
- }
865
- if (entry.kind === "delegate") {
866
- return [resolveDelegateCall(node.name, entry, node, mapping, context)];
867
- }
868
- throw new UnsupportedPatternError(`Abbreviation "${node.name}" is ${entry.kind}, cannot be called as a function`);
869
- }
870
- function resolveVariableCall(abbr, entry, node, mapping, context) {
871
- const arg = singleArg(node, abbr);
872
- return resolveLiteralOrVariableSegment({
873
- abbr,
874
- props: entry.props,
875
- incremented: entry.incremented,
876
- extraDefs: entry.extraDefs,
877
- argAst: arg,
878
- literalValue: tryEvaluatePropertyLiteral(arg, mapping, entry.incremented),
879
- mapping,
880
- context
881
- });
882
- }
883
- function resolveDelegateCall(abbr, entry, node, mapping, context) {
884
- const targetEntry = mapping.abbreviations[entry.target];
885
- if (!targetEntry || targetEntry.kind !== "variable") {
886
- throw new UnsupportedPatternError(`Delegate "${abbr}" targets "${entry.target}" which is not a variable entry`);
887
- }
888
- const arg = singleArg(node, abbr);
889
- return resolveLiteralOrVariableSegment({
890
- abbr: entry.target,
891
- props: targetEntry.props,
892
- incremented: false,
893
- appendPx: true,
894
- extraDefs: targetEntry.extraDefs,
895
- argAst: arg,
896
- literalValue: t3.isNumericLiteral(arg) ? `${arg.value}px` : null,
897
- mapping,
898
- context
899
- });
900
- }
901
- function resolveLiteralOrVariableSegment(params) {
902
- const { abbr, props, incremented, appendPx, extraDefs, argAst, literalValue, mapping, context } = params;
903
- if (literalValue !== null && !isCustomPropertyLiteral(argAst, mapping)) {
904
- const defs = Object.fromEntries(props.map((prop) => [prop, literalValue]));
905
- return segmentWithConditionContext({ abbr, defs: { ...defs, ...extraDefs }, argResolved: literalValue }, context);
906
- }
907
- return segmentWithConditionContext(
908
- {
909
- abbr,
910
- defs: {},
911
- variableProps: props,
912
- incremented,
913
- appendPx,
914
- variableExtraDefs: extraDefs,
915
- argNode: literalValue === null ? argAst : void 0,
916
- argResolved: literalValue ?? void 0
917
- },
918
- context
919
- );
920
- }
921
- function resolveClassNameCall(node, context) {
922
- const arg = singleArg(node, "className");
923
- if (hasCondition(context)) {
924
- throw new UnsupportedPatternError(
925
- `className() cannot be used inside media query, pseudo-class, pseudo-element, or when() contexts`
926
- );
927
- }
928
- return { abbr: "className", defs: {}, classNameArg: arg };
929
- }
930
- function resolveStyleCall(node, context) {
931
- const arg = singleArg(node, "style");
932
- if (hasCondition(context)) {
933
- throw new UnsupportedPatternError(
934
- `style() cannot be used inside media query, pseudo-class, pseudo-element, or when() contexts`
935
- );
936
- }
937
- return { abbr: "style", defs: {}, styleArg: arg };
938
- }
939
- function resolveWithCall(node) {
940
- if (node.args.length !== 1) {
941
- throw new UnsupportedPatternError(`with() requires exactly 1 argument`);
942
- }
943
- const styleArg = node.args[0];
944
- if (t3.isSpreadElement(styleArg)) {
945
- throw new UnsupportedPatternError(`with() does not support spread arguments`);
946
- }
947
- const isAddCss = t3.isObjectExpression(styleArg) ? { isAddCss: true } : {};
948
- return { abbr: "__composed_css_prop", defs: {}, styleArrayArg: styleArg, ...isAddCss };
949
- }
950
- function resolveAddCall(node, mapping, context) {
951
- const usage = `add() requires 1 or 2 arguments (property name and value, or an object literal), got ${node.args.length}. Supported overloads are add({ prop: value }), add("propName", value), and with(cssProp)`;
952
- if (node.args.length === 1) {
953
- const styleArg = node.args[0];
954
- if (t3.isSpreadElement(styleArg)) {
955
- throw new UnsupportedPatternError(`add() does not support spread arguments`);
956
- }
957
- if (t3.isObjectExpression(styleArg)) {
958
- return resolveAddObjectLiteral(styleArg, mapping, context);
959
- }
960
- throw new UnsupportedPatternError(usage);
961
- }
962
- if (node.args.length !== 2) {
963
- throw new UnsupportedPatternError(usage);
964
- }
965
- const [propArg, valueArg] = node.args;
966
- if (!t3.isStringLiteral(propArg)) {
967
- throw new UnsupportedPatternError(`add() first argument must be a string literal property name`);
968
- }
969
- if (t3.isSpreadElement(valueArg)) {
970
- throw new UnsupportedPatternError(`add() does not support spread arguments`);
971
- }
972
- return [resolveAddDeclaration(propArg.value, valueArg, mapping, context)];
973
- }
974
- function resolveAddObjectLiteral(obj, mapping, context) {
975
- const segments = [];
976
- for (const property of obj.properties) {
977
- if (t3.isSpreadElement(property)) {
978
- throw new UnsupportedPatternError(`add({...}) does not support spread properties -- use with() instead`);
979
- }
980
- if (!t3.isObjectProperty(property) || property.computed) {
981
- throw new UnsupportedPatternError(`add({...}) only supports simple property keys`);
982
- }
983
- const propName = staticPropertyName(property.key);
984
- if (propName === null) {
985
- throw new UnsupportedPatternError(`add({...}) property keys must be identifiers or string literals`);
986
- }
987
- segments.push(resolveAddDeclaration(propName, property.value, mapping, context));
988
- }
989
- return segments;
990
- }
991
- function resolveAddDeclaration(propName, valueNode, mapping, context) {
992
- const literalValue = tryEvaluatePropertyLiteral(valueNode, mapping, false);
993
- const canonicalAbbr = literalValue !== null && !isCustomPropertyLiteral(valueNode, mapping) ? findCanonicalAbbreviation(mapping, propName, literalValue) : void 0;
994
- if (canonicalAbbr) {
995
- const entry = mapping.abbreviations[canonicalAbbr];
996
- return segmentWithConditionContext({ abbr: canonicalAbbr, defs: entry.defs }, context);
997
- }
998
- return resolveLiteralOrVariableSegment({
999
- abbr: propName,
1000
- props: [propName],
1001
- incremented: false,
1002
- argAst: valueNode,
1003
- literalValue,
1004
- mapping,
1005
- context
1006
- });
1007
- }
1008
- function resolveTypographyCall(node, mapping, context) {
1009
- const arg = singleArg(node, "typography");
1010
- if (t3.isStringLiteral(arg)) {
1011
- return resolveTypographyEntry(arg.value, mapping, context);
1012
- }
1013
- const typography = mapping.typography ?? [];
1014
- if (typography.length === 0) {
1015
- throw new UnsupportedPatternError(`typography() is unavailable because no typography abbreviations were generated`);
1016
- }
1017
- const suffix = typographyLookupKeySuffix(context, mapping);
1018
- const lookupKey = suffix ? `typography__${suffix}` : "typography";
1019
- const segmentsByName = {};
1020
- for (const name of typography) {
1021
- segmentsByName[name] = resolveTypographyEntry(name, mapping, context);
1022
- }
1023
- return [{ abbr: lookupKey, defs: {}, typographyLookup: { lookupKey, argNode: arg, segmentsByName } }];
1024
- }
1025
- function resolveTypographyEntry(name, mapping, context) {
1026
- if (!(mapping.typography ?? []).includes(name)) {
1027
- throw new UnsupportedPatternError(`Unknown typography abbreviation "${name}"`);
1028
- }
1029
- const entry = mapping.abbreviations[name];
1030
- if (!entry) {
1031
- throw new UnsupportedPatternError(`Unknown typography abbreviation "${name}"`);
1032
- }
1033
- const resolved = resolveEntry(name, entry, mapping, context);
1034
- for (const segment of resolved) {
1035
- if (segment.variableProps) {
1036
- throw new UnsupportedPatternError(`Typography abbreviation "${name}" cannot require runtime arguments`);
1037
- }
1038
- }
1039
- return resolved;
1040
- }
1041
- function typographyLookupKeySuffix(context, mapping) {
1042
- const parts = [];
1043
- if (context.pseudoElement) parts.push(context.pseudoElement.replace(/^::/, ""));
1044
- if (context.mediaQuery) {
1045
- const breakpoint = breakpointNameForMediaQuery(mapping, context.mediaQuery);
1046
- parts.push(breakpoint ? breakpoint.replace(/^./, (c) => c.toLowerCase()) : "mq");
1047
- }
1048
- if (context.pseudoClass) parts.push(context.pseudoClass.replace(/^:+/, "").replace(/-/g, "_"));
1049
- if (context.whenPseudo) parts.push(whenLookupKeyPart(context.whenPseudo));
1050
- return parts.join("_");
1051
- }
1052
- function whenLookupKeyPart(whenPseudo) {
1053
- const parts = ["when", whenPseudo.relationship, sanitizeClassNameToken(whenPseudo.pseudo) || "value"];
1054
- if (whenPseudo.markerNode) {
1055
- parts.push(whenPseudo.markerNode.name);
1056
- }
1057
- return parts.join("_");
1058
- }
1059
- function resolveWhenCall(node) {
1060
- if (node.args.length !== 1 && node.args.length !== 3) {
1061
- throw new UnsupportedPatternError(
1062
- `when() expects 1 or 3 arguments (selector) or (marker, relationship, pseudo), got ${node.args.length}`
1063
- );
1064
- }
1065
- if (node.args.length === 1) {
1066
- const selectorArg = node.args[0];
1067
- if (!t3.isStringLiteral(selectorArg)) {
1068
- throw new UnsupportedPatternError(`when() selector must be a string literal`);
1069
- }
1070
- return { kind: "selector", selector: selectorArg.value };
1071
- }
1072
- const [markerArg, relationshipArg, pseudoArg] = node.args;
1073
- const markerNode = resolveWhenMarker(markerArg);
1074
- if (!t3.isStringLiteral(relationshipArg)) {
1075
- throw new UnsupportedPatternError(`when() relationship argument must be a string literal`);
1076
- }
1077
- const relationship = relationshipArg.value;
1078
- if (!isWhenRelationship(relationship)) {
1079
- throw new UnsupportedPatternError(
1080
- `when() relationship must be one of: ${Object.keys(WHEN_RELATIONSHIPS).join(", ")} -- got "${relationship}"`
1081
- );
1082
- }
1083
- if (!t3.isStringLiteral(pseudoArg)) {
1084
- throw new UnsupportedPatternError(`when() pseudo selector (3rd argument) must be a string literal`);
1085
- }
1086
- return { kind: "relationship", condition: { pseudo: pseudoArg.value, markerNode, relationship } };
1087
- }
1088
- function resolveWhenMarker(node) {
1089
- if (isDefaultMarkerNode(node)) {
1090
- return void 0;
1091
- }
1092
- if (t3.isIdentifier(node)) {
1093
- return node;
1094
- }
1095
- throw new UnsupportedPatternError(`when() marker must be a marker variable or marker`);
1096
- }
1097
- function isDefaultMarkerNode(node) {
1098
- if (t3.isIdentifier(node) && (node.name === "marker" || node.name === "defaultMarker")) {
1099
- return true;
1100
- }
1101
- return t3.isCallExpression(node) && node.arguments.length === 0 && t3.isMemberExpression(node.callee) && !node.callee.computed && t3.isIdentifier(node.callee.property, { name: "defaultMarker" });
1102
- }
1103
- function tryEvaluatePropertyLiteral(node, mapping, incremented) {
1104
- const numeric = tryNumericLiteral(node);
1105
- if (numeric !== null) {
1106
- return incremented ? incrementCssValue(numeric) : String(numeric);
1107
- }
1108
- const raw = tryResolveValueLiteral(node, mapping);
1109
- return raw === null ? null : maybeCssVar(raw);
1110
- }
1111
- function isCustomPropertyLiteral(node, mapping) {
1112
- const raw = tryResolveValueLiteral(node, mapping);
1113
- return raw !== null && isCustomPropertyName(raw);
1114
- }
1115
- function tryResolveValueLiteral(node, mapping) {
1116
- if (mapping) {
1117
- const token = tryResolveTokensMember(node, mapping);
1118
- if (token !== null) return token;
1119
- }
1120
- if (t3.isStringLiteral(node)) {
1121
- return node.value;
1122
- }
1123
- const numeric = tryNumericLiteral(node);
1124
- return numeric === null ? null : String(numeric);
1125
- }
1126
- function tryNumericLiteral(node) {
1127
- if (t3.isNumericLiteral(node)) {
1128
- return node.value;
1129
- }
1130
- if (t3.isUnaryExpression(node, { operator: "-" }) && t3.isNumericLiteral(node.argument)) {
1131
- return -node.argument.value;
1132
- }
1133
- return null;
1134
- }
1135
- function tryResolveTokensMember(node, mapping) {
1136
- if (!t3.isMemberExpression(node) || !t3.isIdentifier(node.object, { name: "Tokens" })) return null;
1137
- const memberName = memberPropertyName(node);
1138
- if (memberName === null) return null;
1139
- const tokenMap = mapping.tokens;
1140
- if (!tokenMap) {
1141
- throw new UnsupportedPatternError(`Tokens.* requires config.tokens`);
1142
- }
1143
- if (!(memberName in tokenMap)) {
1144
- throw new UnsupportedPatternError(`Unknown token "${memberName}" - add it to config.tokens`);
1145
- }
1146
- return tokenMap[memberName];
1147
- }
1148
- function singleArg(node, label) {
1149
- if (node.args.length !== 1) {
1150
- throw new UnsupportedPatternError(`${label}() expects exactly 1 argument, got ${node.args.length}`);
1151
- }
1152
- const arg = node.args[0];
1153
- if (t3.isSpreadElement(arg)) {
1154
- throw new UnsupportedPatternError(`${label}() does not support spread arguments`);
1155
- }
1156
- return arg;
1157
- }
1158
- function plainObjectEntries(obj, label) {
1159
- return obj.properties.map((prop) => {
1160
- if (t3.isSpreadElement(prop)) {
1161
- throw new UnsupportedPatternError(`${label} does not support spread properties`);
1162
- }
1163
- if (!t3.isObjectProperty(prop) || prop.computed) {
1164
- throw new UnsupportedPatternError(`${label} only supports plain object properties`);
1165
- }
1166
- const key = staticPropertyName(prop.key);
1167
- if (key === null) {
1168
- throw new UnsupportedPatternError(`${label} only supports identifier/string keys`);
1169
- }
1170
- return { key, value: prop.value };
1171
- });
1172
- }
1173
- function numericLiteralValue(node, errorMessage) {
1174
- const numeric = tryNumericLiteral(node);
1175
- if (numeric === null) {
1176
- throw new UnsupportedPatternError(errorMessage);
1177
- }
1178
- return numeric;
1179
- }
1180
- function stringLiteralValue(node, errorMessage) {
1181
- if (t3.isStringLiteral(node)) {
1182
- return node.value;
1183
- }
1184
- if (t3.isTemplateLiteral(node) && node.expressions.length === 0 && node.quasis.length === 1) {
1185
- return node.quasis[0].value.cooked ?? "";
1186
- }
1187
- throw new UnsupportedPatternError(errorMessage);
1188
- }
1189
- function requireValueLiteral(node, errorMessage) {
1190
- const value = tryResolveValueLiteral(unwrapExpression(node));
1191
- if (value === null) {
1192
- throw new UnsupportedPatternError(errorMessage);
1193
- }
1194
- return value;
1195
- }
1196
- function containerQueryFromCall(node) {
1197
- const arg = singleArg(node, "ifContainer");
1198
- if (!t3.isObjectExpression(arg)) {
1199
- throw new UnsupportedPatternError("ifContainer() expects an object literal argument");
1200
- }
1201
- const bounds = {};
1202
- for (const { key, value } of plainObjectEntries(arg, "ifContainer()")) {
1203
- if (!readContainerBound(bounds, key, value, "ifContainer().")) {
1204
- throw new UnsupportedPatternError(`ifContainer() does not support property "${key}"`);
1205
- }
1206
- }
1207
- if (bounds.lt === void 0 && bounds.gt === void 0) {
1208
- throw new UnsupportedPatternError('ifContainer() requires at least one of "lt" or "gt"');
1209
- }
1210
- return containerQueryString(bounds);
1211
- }
1212
- function readContainerBound(bounds, key, value, label) {
1213
- if (key === "lt") {
1214
- bounds.lt = numericLiteralValue(value, `${label}lt must be a numeric literal`);
1215
- return true;
1216
- }
1217
- if (key === "gt") {
1218
- bounds.gt = numericLiteralValue(value, `${label}gt must be a numeric literal`);
1219
- return true;
1220
- }
1221
- if (key === "name") {
1222
- bounds.name = stringLiteralValue(value, `${label}name must be a string literal`);
1223
- return true;
1224
- }
1225
- return false;
1226
- }
1227
- function containerQueryString(bounds) {
1228
- const parts = [];
1229
- if (bounds.gt !== void 0) {
1230
- parts.push(`(min-width: ${bounds.gt + 1}px)`);
1231
- }
1232
- if (bounds.lt !== void 0) {
1233
- parts.push(`(max-width: ${bounds.lt}px)`);
1234
- }
1235
- const namePrefix = bounds.name ? `${bounds.name} ` : "";
1236
- return `@container ${namePrefix}${parts.join(" and ")}`;
1237
- }
1238
- function resolveSetVarCall(node, mapping, context) {
1239
- const arg = singleArg(node, "setVar");
1240
- if (!t3.isObjectExpression(arg)) {
1241
- throw new UnsupportedPatternError(`setVar() requires an object literal argument`);
1242
- }
1243
- const segments = [];
1244
- for (const prop of arg.properties) {
1245
- if (t3.isSpreadElement(prop)) {
1246
- throw new UnsupportedPatternError(`setVar() does not support spread properties`);
1247
- }
1248
- if (!t3.isObjectProperty(prop)) {
1249
- throw new UnsupportedPatternError(`setVar() only supports object properties`);
1250
- }
1251
- const cssVarName = resolveSetVarPropertyKey(prop, mapping);
1252
- const abbr = `__${sanitizeClassNameToken(cssVarName.replace(/^--/, ""))}`;
1253
- for (const leaf of expandSetVarValueToLeaves(prop.value, mapping, context)) {
1254
- segments.push(
1255
- segmentWithConditionContext(
1256
- { abbr, defs: { [cssVarName]: leaf.literal }, argResolved: leaf.literal },
1257
- leaf.context
1258
- )
1259
- );
1260
- }
1261
- }
1262
- return segments;
1263
- }
1264
- function resolveSetVarPropertyKey(prop, mapping) {
1265
- const key = prop.key;
1266
- if (!prop.computed) {
1267
- if (t3.isStringLiteral(key)) {
1268
- if (key.value.startsWith("--")) {
1269
- return key.value;
1270
- }
1271
- throw new UnsupportedPatternError(
1272
- `setVar() string keys must be CSS variables starting with "--" - got ${JSON.stringify(key.value)}`
1273
- );
1274
- }
1275
- if (t3.isIdentifier(key)) {
1276
- throw new UnsupportedPatternError(
1277
- `setVar() requires computed keys like [Tokens.Name] or string keys "--my-var", not bare property names`
1278
- );
1279
- }
1280
- throw new UnsupportedPatternError(`setVar() property keys must be string literals or [Tokens.*] members`);
1281
- }
1282
- if (!t3.isMemberExpression(key)) {
1283
- throw new UnsupportedPatternError(`setVar() computed keys must be Tokens.*-style members`);
1284
- }
1285
- const memberName = memberPropertyName(key);
1286
- if (memberName === null) {
1287
- throw new UnsupportedPatternError(
1288
- `setVar() [Tokens.name] keys must use a plain .member or ["string"] member access`
1289
- );
1290
- }
1291
- const tokenMap = mapping.tokens;
1292
- if (!tokenMap || !(memberName in tokenMap)) {
1293
- throw new UnsupportedPatternError(
1294
- tokenMap ? `Unknown token "${memberName}" - add it to config.tokens or use a "--" string literal key` : `setVar() [Tokens.*] requires config.tokens; use "--" string literal keys only`
1295
- );
1296
- }
1297
- return tokenMap[memberName];
1298
- }
1299
- function expandSetVarValueToLeaves(valueNode, mapping, baseContext) {
1300
- const unwrapped = unwrapExpression(valueNode);
1301
- const scalar = tryResolveValueLiteral(unwrapped);
1302
- if (scalar !== null) {
1303
- return [setVarLeaf(scalar, baseContext)];
1304
- }
1305
- if (!t3.isObjectExpression(unwrapped)) {
1306
- throw new UnsupportedPatternError(
1307
- `setVar() values must be string/number literals or a { default?, media?, container? } object`
1308
- );
1309
- }
1310
- let defaultLiteral;
1311
- let mediaObject;
1312
- let containerArray;
1313
- for (const { key, value } of plainObjectEntries(unwrapped, "setVar() responsive object")) {
1314
- if (key === "default") {
1315
- defaultLiteral = requireValueLiteral(value, `setVar().default must be a string or number literal`);
1316
- } else if (key === "media") {
1317
- if (!t3.isObjectExpression(value)) {
1318
- throw new UnsupportedPatternError(`setVar().media must be an object literal`);
1319
- }
1320
- mediaObject = value;
1321
- } else if (key === "container") {
1322
- if (!t3.isArrayExpression(value)) {
1323
- throw new UnsupportedPatternError(`setVar().container must be an array literal`);
1324
- }
1325
- containerArray = value;
1326
- } else {
1327
- throw new UnsupportedPatternError(`setVar() responsive object does not support property "${key}"`);
1328
- }
1329
- }
1330
- const leaves = [];
1331
- if (defaultLiteral !== void 0) {
1332
- leaves.push(setVarLeaf(defaultLiteral, baseContext));
1333
- }
1334
- if (mediaObject) {
1335
- leaves.push(...setVarMediaLeaves(mediaObject, mapping, baseContext));
1336
- }
1337
- if (containerArray) {
1338
- leaves.push(...setVarContainerLeaves(containerArray, baseContext));
1339
- }
1340
- if (leaves.length === 0) {
1341
- throw new UnsupportedPatternError(
1342
- `setVar() responsive object must include at least one of default, media entries, or container entries`
1343
- );
1344
- }
1345
- return leaves;
1346
- }
1347
- function setVarMediaLeaves(mediaObject, mapping, baseContext) {
1348
- return plainObjectEntries(mediaObject, "setVar().media").map(({ key: breakpointName, value }) => {
1349
- const mediaQuery = mapping.breakpoints?.[`if${pascalCase(breakpointName)}`] ?? null;
1350
- if (mediaQuery === null) {
1351
- throw new UnsupportedPatternError(
1352
- `Unknown breakpoint "${breakpointName}" in setVar().media - use a Breakpoint name from truss-config`
1353
- );
1354
- }
1355
- const literal = requireValueLiteral(value, `setVar().media[${breakpointName}] must be a string or number literal`);
1356
- return setVarLeaf(literal, baseContext, mediaQuery);
1357
- });
1358
- }
1359
- function setVarContainerLeaves(containerArray, baseContext) {
1360
- const leaves = [];
1361
- for (const element of containerArray.elements) {
1362
- if (element === null) {
1363
- continue;
1364
- }
1365
- if (!t3.isObjectExpression(element)) {
1366
- throw new UnsupportedPatternError(`setVar().container entries must be object literals`);
1367
- }
1368
- let rowValue;
1369
- const bounds = {};
1370
- for (const { key, value } of plainObjectEntries(element, "setVar().container row")) {
1371
- if (key === "value") {
1372
- rowValue = requireValueLiteral(value, `setVar().container row "value" must be a string or number literal`);
1373
- } else if (!readContainerBound(bounds, key, value, "setVar().container ")) {
1374
- throw new UnsupportedPatternError(`setVar().container row does not support property "${key}"`);
1375
- }
1376
- }
1377
- if (rowValue === void 0) {
1378
- throw new UnsupportedPatternError(`setVar().container row requires a "value" property`);
1379
- }
1380
- if (bounds.lt === void 0 && bounds.gt === void 0) {
1381
- throw new UnsupportedPatternError(`setVar().container row requires at least one of gt or lt`);
1382
- }
1383
- leaves.push(setVarLeaf(rowValue, baseContext, containerQueryString(bounds)));
1384
- }
1385
- return leaves;
1386
- }
1387
- function setVarLeaf(literal, baseContext, mediaQuery) {
1388
- const context = cloneConditionContext(baseContext);
1389
- if (mediaQuery !== void 0) {
1390
- context.mediaQuery = mediaQuery;
1391
- }
1392
- return { literal, context };
1393
- }
1394
- var UnsupportedPatternError = class extends Error {
1395
- constructor(message) {
1396
- super(`[truss] Unsupported pattern: ${message}`);
1397
- this.name = "UnsupportedPatternError";
1398
- }
1399
- };
1400
-
1401
- // src/plugin/property-priorities.ts
1402
- var longHandPhysical = /* @__PURE__ */ new Set();
1403
- var longHandLogical = /* @__PURE__ */ new Set();
1404
- var shorthandsOfLonghands = /* @__PURE__ */ new Set();
1405
- var shorthandsOfShorthands = /* @__PURE__ */ new Set();
1406
- longHandLogical.add("background-blend-mode");
1407
- longHandLogical.add("isolation");
1408
- longHandLogical.add("mix-blend-mode");
1409
- shorthandsOfShorthands.add("animation");
1410
- longHandLogical.add("animation-composition");
1411
- longHandLogical.add("animation-delay");
1412
- longHandLogical.add("animation-direction");
1413
- longHandLogical.add("animation-duration");
1414
- longHandLogical.add("animation-fill-mode");
1415
- longHandLogical.add("animation-iteration-count");
1416
- longHandLogical.add("animation-name");
1417
- longHandLogical.add("animation-play-state");
1418
- shorthandsOfLonghands.add("animation-range");
1419
- longHandLogical.add("animation-range-end");
1420
- longHandLogical.add("animation-range-start");
1421
- longHandLogical.add("animation-timing-function");
1422
- longHandLogical.add("animation-timeline");
1423
- shorthandsOfLonghands.add("scroll-timeline");
1424
- longHandLogical.add("scroll-timeline-axis");
1425
- longHandLogical.add("scroll-timeline-name");
1426
- longHandLogical.add("timeline-scope");
1427
- shorthandsOfLonghands.add("view-timeline");
1428
- longHandLogical.add("view-timeline-axis");
1429
- longHandLogical.add("view-timeline-inset");
1430
- longHandLogical.add("view-timeline-name");
1431
- shorthandsOfShorthands.add("background");
1432
- longHandLogical.add("background-attachment");
1433
- longHandLogical.add("background-clip");
1434
- longHandLogical.add("background-color");
1435
- longHandLogical.add("background-image");
1436
- longHandLogical.add("background-origin");
1437
- longHandLogical.add("background-repeat");
1438
- longHandLogical.add("background-size");
1439
- shorthandsOfLonghands.add("background-position");
1440
- longHandLogical.add("background-position-x");
1441
- longHandLogical.add("background-position-y");
1442
- shorthandsOfShorthands.add("border");
1443
- shorthandsOfLonghands.add("border-color");
1444
- shorthandsOfLonghands.add("border-style");
1445
- shorthandsOfLonghands.add("border-width");
1446
- shorthandsOfShorthands.add("border-block");
1447
- longHandLogical.add("border-block-color");
1448
- longHandLogical.add("border-block-stylex");
1449
- longHandLogical.add("border-block-width");
1450
- shorthandsOfLonghands.add("border-block-start");
1451
- shorthandsOfLonghands.add("border-top");
1452
- longHandLogical.add("border-block-start-color");
1453
- longHandPhysical.add("border-top-color");
1454
- longHandLogical.add("border-block-start-style");
1455
- longHandPhysical.add("border-top-style");
1456
- longHandLogical.add("border-block-start-width");
1457
- longHandPhysical.add("border-top-width");
1458
- shorthandsOfLonghands.add("border-block-end");
1459
- shorthandsOfLonghands.add("border-bottom");
1460
- longHandLogical.add("border-block-end-color");
1461
- longHandPhysical.add("border-bottom-color");
1462
- longHandLogical.add("border-block-end-style");
1463
- longHandPhysical.add("border-bottom-style");
1464
- longHandLogical.add("border-block-end-width");
1465
- longHandPhysical.add("border-bottom-width");
1466
- shorthandsOfShorthands.add("border-inline");
1467
- shorthandsOfLonghands.add("border-inline-color");
1468
- shorthandsOfLonghands.add("border-inline-style");
1469
- shorthandsOfLonghands.add("border-inline-width");
1470
- shorthandsOfLonghands.add("border-inline-start");
1471
- shorthandsOfLonghands.add("border-left");
1472
- longHandLogical.add("border-inline-start-color");
1473
- longHandPhysical.add("border-left-color");
1474
- longHandLogical.add("border-inline-start-style");
1475
- longHandPhysical.add("border-left-style");
1476
- longHandLogical.add("border-inline-start-width");
1477
- longHandPhysical.add("border-left-width");
1478
- shorthandsOfLonghands.add("border-inline-end");
1479
- shorthandsOfLonghands.add("border-right");
1480
- longHandLogical.add("border-inline-end-color");
1481
- longHandPhysical.add("border-right-color");
1482
- longHandLogical.add("border-inline-end-style");
1483
- longHandPhysical.add("border-right-style");
1484
- longHandLogical.add("border-inline-end-width");
1485
- longHandPhysical.add("border-right-width");
1486
- shorthandsOfLonghands.add("border-image");
1487
- longHandLogical.add("border-image-outset");
1488
- longHandLogical.add("border-image-repeat");
1489
- longHandLogical.add("border-image-slice");
1490
- longHandLogical.add("border-image-source");
1491
- longHandLogical.add("border-image-width");
1492
- shorthandsOfLonghands.add("border-radius");
1493
- longHandLogical.add("border-start-end-radius");
1494
- longHandLogical.add("border-start-start-radius");
1495
- longHandLogical.add("border-end-end-radius");
1496
- longHandLogical.add("border-end-start-radius");
1497
- longHandPhysical.add("border-top-left-radius");
1498
- longHandPhysical.add("border-top-right-radius");
1499
- longHandPhysical.add("border-bottom-left-radius");
1500
- longHandPhysical.add("border-bottom-right-radius");
1501
- shorthandsOfLonghands.add("corner-shape");
1502
- longHandLogical.add("corner-start-start-shape");
1503
- longHandLogical.add("corner-start-end-shape");
1504
- longHandLogical.add("corner-end-start-shape");
1505
- longHandLogical.add("corner-end-end-shape");
1506
- longHandPhysical.add("corner-top-left-shape");
1507
- longHandPhysical.add("corner-top-right-shape");
1508
- longHandPhysical.add("corner-bottom-left-shape");
1509
- longHandPhysical.add("corner-bottom-right-shape");
1510
- longHandLogical.add("box-shadow");
1511
- longHandLogical.add("accent-color");
1512
- longHandLogical.add("appearance");
1513
- longHandLogical.add("aspect-ratio");
1514
- shorthandsOfLonghands.add("caret");
1515
- longHandLogical.add("caret-color");
1516
- longHandLogical.add("caret-shape");
1517
- longHandLogical.add("cursor");
1518
- longHandLogical.add("ime-mode");
1519
- longHandLogical.add("input-security");
1520
- shorthandsOfLonghands.add("outline");
1521
- longHandLogical.add("outline-color");
1522
- longHandLogical.add("outline-offset");
1523
- longHandLogical.add("outline-style");
1524
- longHandLogical.add("outline-width");
1525
- longHandLogical.add("pointer-events");
1526
- longHandLogical.add("resize");
1527
- longHandLogical.add("text-overflow");
1528
- longHandLogical.add("user-select");
1529
- shorthandsOfLonghands.add("grid-gap");
1530
- shorthandsOfLonghands.add("gap");
1531
- longHandLogical.add("grid-row-gap");
1532
- longHandLogical.add("row-gap");
1533
- longHandLogical.add("grid-column-gap");
1534
- longHandLogical.add("column-gap");
1535
- shorthandsOfLonghands.add("place-content");
1536
- longHandLogical.add("align-content");
1537
- longHandLogical.add("justify-content");
1538
- shorthandsOfLonghands.add("place-items");
1539
- longHandLogical.add("align-items");
1540
- longHandLogical.add("justify-items");
1541
- shorthandsOfLonghands.add("place-self");
1542
- longHandLogical.add("align-self");
1543
- longHandLogical.add("justify-self");
1544
- longHandLogical.add("box-sizing");
1545
- longHandLogical.add("block-size");
1546
- longHandPhysical.add("height");
1547
- longHandLogical.add("inline-size");
1548
- longHandPhysical.add("width");
1549
- longHandLogical.add("max-block-size");
1550
- longHandPhysical.add("max-height");
1551
- longHandLogical.add("max-inline-size");
1552
- longHandPhysical.add("max-width");
1553
- longHandLogical.add("min-block-size");
1554
- longHandPhysical.add("min-height");
1555
- longHandLogical.add("min-inline-size");
1556
- longHandPhysical.add("min-width");
1557
- shorthandsOfShorthands.add("margin");
1558
- shorthandsOfLonghands.add("margin-block");
1559
- longHandLogical.add("margin-block-start");
1560
- longHandPhysical.add("margin-top");
1561
- longHandLogical.add("margin-block-end");
1562
- longHandPhysical.add("margin-bottom");
1563
- shorthandsOfLonghands.add("margin-inline");
1564
- longHandLogical.add("margin-inline-start");
1565
- longHandPhysical.add("margin-left");
1566
- longHandLogical.add("margin-inline-end");
1567
- longHandPhysical.add("margin-right");
1568
- longHandLogical.add("margin-trim");
1569
- shorthandsOfLonghands.add("overscroll-behavior");
1570
- longHandLogical.add("overscroll-behavior-block");
1571
- longHandPhysical.add("overscroll-behavior-y");
1572
- longHandLogical.add("overscroll-behavior-inline");
1573
- longHandPhysical.add("overscroll-behavior-x");
1574
- shorthandsOfShorthands.add("padding");
1575
- shorthandsOfLonghands.add("padding-block");
1576
- longHandLogical.add("padding-block-start");
1577
- longHandPhysical.add("padding-top");
1578
- longHandLogical.add("padding-block-end");
1579
- longHandPhysical.add("padding-bottom");
1580
- shorthandsOfLonghands.add("padding-inline");
1581
- longHandLogical.add("padding-inline-start");
1582
- longHandPhysical.add("padding-left");
1583
- longHandLogical.add("padding-inline-end");
1584
- longHandPhysical.add("padding-right");
1585
- longHandLogical.add("visibility");
1586
- longHandLogical.add("color");
1587
- longHandLogical.add("color-scheme");
1588
- longHandLogical.add("forced-color-adjust");
1589
- longHandLogical.add("opacity");
1590
- longHandLogical.add("print-color-adjust");
1591
- shorthandsOfLonghands.add("columns");
1592
- longHandLogical.add("column-count");
1593
- longHandLogical.add("column-width");
1594
- longHandLogical.add("column-fill");
1595
- longHandLogical.add("column-span");
1596
- shorthandsOfLonghands.add("column-rule");
1597
- longHandLogical.add("column-rule-color");
1598
- longHandLogical.add("column-rule-style");
1599
- longHandLogical.add("column-rule-width");
1600
- longHandLogical.add("contain");
1601
- shorthandsOfLonghands.add("contain-intrinsic-size");
1602
- longHandLogical.add("contain-intrinsic-block-size");
1603
- longHandLogical.add("contain-intrinsic-width");
1604
- longHandLogical.add("contain-intrinsic-height");
1605
- longHandLogical.add("contain-intrinsic-inline-size");
1606
- shorthandsOfLonghands.add("container");
1607
- longHandLogical.add("container-name");
1608
- longHandLogical.add("container-type");
1609
- longHandLogical.add("content-visibility");
1610
- longHandLogical.add("counter-increment");
1611
- longHandLogical.add("counter-reset");
1612
- longHandLogical.add("counter-set");
1613
- longHandLogical.add("display");
1614
- shorthandsOfLonghands.add("flex");
1615
- longHandLogical.add("flex-basis");
1616
- longHandLogical.add("flex-grow");
1617
- longHandLogical.add("flex-shrink");
1618
- shorthandsOfLonghands.add("flex-flow");
1619
- longHandLogical.add("flex-direction");
1620
- longHandLogical.add("flex-wrap");
1621
- longHandLogical.add("order");
1622
- shorthandsOfShorthands.add("font");
1623
- longHandLogical.add("font-family");
1624
- longHandLogical.add("font-size");
1625
- longHandLogical.add("font-stretch");
1626
- longHandLogical.add("font-style");
1627
- longHandLogical.add("font-weight");
1628
- longHandLogical.add("line-height");
1629
- shorthandsOfLonghands.add("font-variant");
1630
- longHandLogical.add("font-variant-alternates");
1631
- longHandLogical.add("font-variant-caps");
1632
- longHandLogical.add("font-variant-east-asian");
1633
- longHandLogical.add("font-variant-emoji");
1634
- longHandLogical.add("font-variant-ligatures");
1635
- longHandLogical.add("font-variant-numeric");
1636
- longHandLogical.add("font-variant-position");
1637
- longHandLogical.add("font-feature-settings");
1638
- longHandLogical.add("font-kerning");
1639
- longHandLogical.add("font-language-override");
1640
- longHandLogical.add("font-optical-sizing");
1641
- longHandLogical.add("font-palette");
1642
- longHandLogical.add("font-variation-settings");
1643
- longHandLogical.add("font-size-adjust");
1644
- longHandLogical.add("font-smooth");
1645
- longHandLogical.add("font-synthesis-position");
1646
- longHandLogical.add("font-synthesis-small-caps");
1647
- longHandLogical.add("font-synthesis-style");
1648
- longHandLogical.add("font-synthesis-weight");
1649
- longHandLogical.add("line-height-step");
1650
- longHandLogical.add("box-decoration-break");
1651
- longHandLogical.add("break-after");
1652
- longHandLogical.add("break-before");
1653
- longHandLogical.add("break-inside");
1654
- longHandLogical.add("orphans");
1655
- longHandLogical.add("widows");
1656
- longHandLogical.add("content");
1657
- longHandLogical.add("quotes");
1658
- shorthandsOfShorthands.add("grid");
1659
- longHandLogical.add("grid-auto-flow");
1660
- longHandLogical.add("grid-auto-rows");
1661
- longHandLogical.add("grid-auto-columns");
1662
- shorthandsOfShorthands.add("grid-template");
1663
- shorthandsOfLonghands.add("grid-template-areas");
1664
- longHandLogical.add("grid-template-columns");
1665
- longHandLogical.add("grid-template-rows");
1666
- shorthandsOfShorthands.add("grid-area");
1667
- shorthandsOfLonghands.add("grid-row");
1668
- longHandLogical.add("grid-row-start");
1669
- longHandLogical.add("grid-row-end");
1670
- shorthandsOfLonghands.add("grid-column");
1671
- longHandLogical.add("grid-column-start");
1672
- longHandLogical.add("grid-column-end");
1673
- longHandLogical.add("align-tracks");
1674
- longHandLogical.add("justify-tracks");
1675
- longHandLogical.add("masonry-auto-flow");
1676
- longHandLogical.add("image-orientation");
1677
- longHandLogical.add("image-rendering");
1678
- longHandLogical.add("image-resolution");
1679
- longHandLogical.add("object-fit");
1680
- longHandLogical.add("object-position");
1681
- longHandLogical.add("initial-letter");
1682
- longHandLogical.add("initial-letter-align");
1683
- shorthandsOfLonghands.add("list-style");
1684
- longHandLogical.add("list-style-image");
1685
- longHandLogical.add("list-style-position");
1686
- longHandLogical.add("list-style-type");
1687
- longHandLogical.add("clip");
1688
- longHandLogical.add("clip-path");
1689
- shorthandsOfLonghands.add("mask");
1690
- longHandLogical.add("mask-clip");
1691
- longHandLogical.add("mask-composite");
1692
- longHandLogical.add("mask-image");
1693
- longHandLogical.add("mask-mode");
1694
- longHandLogical.add("mask-origin");
1695
- longHandLogical.add("mask-position");
1696
- longHandLogical.add("mask-repeat");
1697
- longHandLogical.add("mask-size");
1698
- longHandLogical.add("mask-type");
1699
- shorthandsOfLonghands.add("mask-border");
1700
- longHandLogical.add("mask-border-mode");
1701
- longHandLogical.add("mask-border-outset");
1702
- longHandLogical.add("mask-border-repeat");
1703
- longHandLogical.add("mask-border-slice");
1704
- longHandLogical.add("mask-border-source");
1705
- longHandLogical.add("mask-border-width");
1706
- shorthandsOfShorthands.add("all");
1707
- longHandLogical.add("text-rendering");
1708
- shorthandsOfLonghands.add("offset");
1709
- longHandLogical.add("offset-anchor");
1710
- longHandLogical.add("offset-distance");
1711
- longHandLogical.add("offset-path");
1712
- longHandLogical.add("offset-position");
1713
- longHandLogical.add("offset-rotate");
1714
- longHandLogical.add("-webkit-box-orient");
1715
- longHandLogical.add("-webkit-line-clamp");
1716
- shorthandsOfLonghands.add("overflow");
1717
- longHandLogical.add("overflow-block");
1718
- longHandPhysical.add("overflow-y");
1719
- longHandLogical.add("overflow-inline");
1720
- longHandPhysical.add("overflow-x");
1721
- longHandLogical.add("overflow-clip-margin");
1722
- longHandLogical.add("scroll-gutter");
1723
- longHandLogical.add("scroll-behavior");
1724
- longHandLogical.add("page");
1725
- longHandLogical.add("page-break-after");
1726
- longHandLogical.add("page-break-before");
1727
- longHandLogical.add("page-break-inside");
1728
- shorthandsOfShorthands.add("inset");
1729
- shorthandsOfLonghands.add("inset-block");
1730
- longHandLogical.add("inset-block-start");
1731
- longHandPhysical.add("top");
1732
- longHandLogical.add("inset-block-end");
1733
- longHandPhysical.add("bottom");
1734
- shorthandsOfLonghands.add("inset-inline");
1735
- longHandLogical.add("inset-inline-start");
1736
- longHandPhysical.add("left");
1737
- longHandLogical.add("inset-inline-end");
1738
- longHandPhysical.add("right");
1739
- longHandLogical.add("clear");
1740
- longHandLogical.add("float");
1741
- longHandLogical.add("position");
1742
- longHandLogical.add("z-index");
1743
- longHandLogical.add("ruby-align");
1744
- longHandLogical.add("ruby-merge");
1745
- longHandLogical.add("ruby-position");
1746
- longHandLogical.add("overflow-anchor");
1747
- shorthandsOfShorthands.add("scroll-margin");
1748
- shorthandsOfLonghands.add("scroll-margin-block");
1749
- longHandLogical.add("scroll-margin-block-start");
1750
- longHandPhysical.add("scroll-margin-top");
1751
- longHandLogical.add("scroll-margin-block-end");
1752
- longHandPhysical.add("scroll-margin-bottom");
1753
- shorthandsOfLonghands.add("scroll-margin-inline");
1754
- longHandLogical.add("scroll-margin-inline-start");
1755
- longHandPhysical.add("scroll-margin-left");
1756
- longHandLogical.add("scroll-margin-inline-end");
1757
- longHandPhysical.add("scroll-margin-right");
1758
- shorthandsOfShorthands.add("scroll-padding");
1759
- shorthandsOfLonghands.add("scroll-padding-block");
1760
- longHandLogical.add("scroll-padding-block-start");
1761
- longHandPhysical.add("scroll-padding-top");
1762
- longHandLogical.add("scroll-padding-block-end");
1763
- longHandPhysical.add("scroll-padding-bottom");
1764
- shorthandsOfLonghands.add("scroll-padding-inline");
1765
- longHandLogical.add("scroll-padding-inline-start");
1766
- longHandPhysical.add("scroll-padding-left");
1767
- longHandLogical.add("scroll-padding-inline-end");
1768
- longHandPhysical.add("scroll-padding-right");
1769
- longHandLogical.add("scroll-snap-align");
1770
- longHandLogical.add("scroll-snap-stop");
1771
- shorthandsOfLonghands.add("scroll-snap-type");
1772
- longHandLogical.add("scrollbar-color");
1773
- longHandLogical.add("scrollbar-width");
1774
- longHandLogical.add("shape-image-threshold");
1775
- longHandLogical.add("shape-margin");
1776
- longHandLogical.add("shape-outside");
1777
- longHandLogical.add("azimuth");
1778
- longHandLogical.add("border-collapse");
1779
- longHandLogical.add("border-spacing");
1780
- longHandLogical.add("caption-side");
1781
- longHandLogical.add("empty-cells");
1782
- longHandLogical.add("table-layout");
1783
- longHandLogical.add("vertical-align");
1784
- shorthandsOfLonghands.add("text-decoration");
1785
- longHandLogical.add("text-decoration-color");
1786
- longHandLogical.add("text-decoration-line");
1787
- longHandLogical.add("text-decoration-skip");
1788
- longHandLogical.add("text-decoration-skip-ink");
1789
- longHandLogical.add("text-decoration-style");
1790
- longHandLogical.add("text-decoration-thickness");
1791
- shorthandsOfLonghands.add("text-emphasis");
1792
- longHandLogical.add("text-emphasis-color");
1793
- longHandLogical.add("text-emphasis-position");
1794
- longHandLogical.add("text-emphasis-style");
1795
- longHandLogical.add("text-shadow");
1796
- longHandLogical.add("text-underline-offset");
1797
- longHandLogical.add("text-underline-position");
1798
- longHandLogical.add("hanging-punctuation");
1799
- longHandLogical.add("hyphenate-character");
1800
- longHandLogical.add("hyphenate-limit-chars");
1801
- longHandLogical.add("hyphens");
1802
- longHandLogical.add("letter-spacing");
1803
- longHandLogical.add("line-break");
1804
- longHandLogical.add("overflow-wrap");
1805
- longHandLogical.add("paint-order");
1806
- longHandLogical.add("tab-size");
1807
- longHandLogical.add("text-align");
1808
- longHandLogical.add("text-align-last");
1809
- longHandLogical.add("text-indent");
1810
- longHandLogical.add("text-justify");
1811
- longHandLogical.add("text-size-adjust");
1812
- longHandLogical.add("text-transform");
1813
- longHandLogical.add("text-wrap");
1814
- longHandLogical.add("white-space");
1815
- longHandLogical.add("white-space-collapse");
1816
- longHandLogical.add("word-break");
1817
- longHandLogical.add("word-spacing");
1818
- longHandLogical.add("word-wrap");
1819
- longHandLogical.add("backface-visibility");
1820
- longHandLogical.add("perspective");
1821
- longHandLogical.add("perspective-origin");
1822
- longHandLogical.add("rotate");
1823
- longHandLogical.add("scale");
1824
- longHandLogical.add("transform");
1825
- longHandLogical.add("transform-box");
1826
- longHandLogical.add("transform-origin");
1827
- longHandLogical.add("transform-style");
1828
- longHandLogical.add("translate");
1829
- shorthandsOfLonghands.add("transition");
1830
- longHandLogical.add("transition-delay");
1831
- longHandLogical.add("transition-duration");
1832
- longHandLogical.add("transition-property");
1833
- longHandLogical.add("transition-timing-function");
1834
- longHandLogical.add("view-transition-name");
1835
- longHandLogical.add("will-change");
1836
- longHandLogical.add("direction");
1837
- longHandLogical.add("text-combine-upright");
1838
- longHandLogical.add("text-orientation");
1839
- longHandLogical.add("unicode-bidi");
1840
- longHandLogical.add("writing-mode");
1841
- longHandLogical.add("backdrop-filter");
1842
- longHandLogical.add("filter");
1843
- longHandLogical.add("math-depth");
1844
- longHandLogical.add("math-shift");
1845
- longHandLogical.add("math-style");
1846
- longHandLogical.add("touch-action");
1847
- var PSEUDO_CLASS_PRIORITIES = {
1848
- ":is": 40,
1849
- ":where": 40,
1850
- ":not": 40,
1851
- ":has": 45,
1852
- ":dir": 50,
1853
- ":lang": 51,
1854
- ":first-child": 52,
1855
- ":first-of-type": 53,
1856
- ":last-child": 54,
1857
- ":last-of-type": 55,
1858
- ":only-child": 56,
1859
- ":only-of-type": 57,
1860
- ":nth-child": 60,
1861
- ":nth-last-child": 61,
1862
- ":nth-of-type": 62,
1863
- ":nth-last-of-type": 63,
1864
- ":empty": 70,
1865
- ":link": 80,
1866
- ":any-link": 81,
1867
- ":local-link": 82,
1868
- ":target-within": 83,
1869
- ":target": 84,
1870
- ":visited": 85,
1871
- ":enabled": 91,
1872
- ":disabled": 92,
1873
- ":required": 93,
1874
- ":optional": 94,
1875
- ":read-only": 95,
1876
- ":read-write": 96,
1877
- ":placeholder-shown": 97,
1878
- ":in-range": 98,
1879
- ":out-of-range": 99,
1880
- ":default": 100,
1881
- ":checked": 101,
1882
- ":indeterminate": 101,
1883
- ":blank": 102,
1884
- ":valid": 103,
1885
- ":invalid": 104,
1886
- ":user-invalid": 105,
1887
- ":autofill": 110,
1888
- ":picture-in-picture": 120,
1889
- ":modal": 121,
1890
- ":fullscreen": 122,
1891
- ":paused": 123,
1892
- ":playing": 124,
1893
- ":current": 125,
1894
- ":past": 126,
1895
- ":future": 127,
1896
- ":hover": 130,
1897
- ":focus-within": 140,
1898
- ":focus": 150,
1899
- ":focus-visible": 160,
1900
- ":active": 170
1901
- };
1902
- var AT_RULE_PRIORITIES = {
1903
- "@supports": 30,
1904
- "@media": 200,
1905
- "@container": 300
1906
- };
1907
- var PSEUDO_ELEMENT_PRIORITY = 5e3;
1908
- function getPropertyPriority(property) {
1909
- if (shorthandsOfShorthands.has(property)) return 1e3;
1910
- if (shorthandsOfLonghands.has(property)) return 2e3;
1911
- if (longHandLogical.has(property)) return 3e3;
1912
- if (longHandPhysical.has(property)) return 4e3;
1913
- return 3e3;
1914
- }
1915
- function getPseudoClassPriority(pseudo) {
1916
- const leadingPseudo = pseudo.trim().match(/^::?[a-zA-Z-]+/)?.[0] ?? pseudo.split("(")[0];
1917
- const base = leadingPseudo.replace(/[A-Z]/g, (match) => {
1918
- return `-${match.toLowerCase()}`;
1919
- });
1920
- return PSEUDO_CLASS_PRIORITIES[base] ?? 40;
1921
- }
1922
- function getAtRulePriority(atRule) {
1923
- if (atRule.startsWith("--")) return 1;
1924
- if (atRule.startsWith("@supports")) return AT_RULE_PRIORITIES["@supports"];
1925
- if (atRule.startsWith("@media")) return AT_RULE_PRIORITIES["@media"];
1926
- if (atRule.startsWith("@container")) return AT_RULE_PRIORITIES["@container"];
1927
- return 0;
543
+ const namePrefix = bounds.name ? `${bounds.name} ` : "";
544
+ return `@container ${namePrefix}${parts.join(" and ")}`;
1928
545
  }
1929
546
 
1930
- // src/plugin/priority.ts
1931
- function computeRulePriority(rule) {
1932
- let priority = getPropertyPriority(rule.declarations[0].cssProperty);
1933
- if (rule.pseudoElement) {
1934
- priority += PSEUDO_ELEMENT_PRIORITY;
1935
- }
1936
- if (rule.pseudoClass) {
1937
- priority += getPseudoClassPriority(rule.pseudoClass);
1938
- }
1939
- if (rule.mediaQuery) {
1940
- priority += getAtRulePriority(rule.mediaQuery);
1941
- }
1942
- if (rule.whenSelector) {
1943
- const relBase = WHEN_RELATIONSHIPS[rule.whenSelector.relationship].priority;
1944
- const pseudoFraction = getPseudoClassPriority(rule.whenSelector.pseudo) / 100;
1945
- priority += relBase + pseudoFraction;
1946
- }
1947
- if (isVariableRule(rule)) {
1948
- priority += 0.5;
1949
- }
1950
- return priority;
1951
- }
1952
- function isVariableRule(rule) {
1953
- return rule.declarations.some((d) => d.cssVarName !== void 0);
1954
- }
1955
- function sortRulesByPriority(rules) {
1956
- const decorated = Array.from(rules, (rule) => {
1957
- return { rule, priority: computeRulePriority(rule) };
1958
- });
1959
- decorated.sort((a, b) => {
1960
- return a.priority - b.priority || compareClassNames(a.rule.className, b.rule.className);
1961
- });
1962
- return decorated;
1963
- }
1964
- function compareClassNames(a, b) {
1965
- return a < b ? -1 : a > b ? 1 : 0;
1966
- }
547
+ // src/plugin/style-entries.ts
548
+ import * as t5 from "@babel/types";
1967
549
 
1968
550
  // src/plugin/css-property-abbreviations.ts
1969
551
  var cssPropertyAbbreviations = {
@@ -2347,37 +929,1532 @@ var cssPropertyAbbreviations = {
2347
929
  // Bottom (positioned after "border*" to avoid scan confusion)
2348
930
  bottom: "bot"
2349
931
  };
2350
- var seen = /* @__PURE__ */ new Map();
2351
- for (const [prop, abbr] of Object.entries(cssPropertyAbbreviations)) {
2352
- const existing = seen.get(abbr);
2353
- if (existing) {
2354
- throw new Error(`CSS property abbreviation conflict: "${abbr}" is used by both "${existing}" and "${prop}"`);
932
+ var seen = /* @__PURE__ */ new Map();
933
+ for (const [prop, abbr] of Object.entries(cssPropertyAbbreviations)) {
934
+ const existing = seen.get(abbr);
935
+ if (existing) {
936
+ throw new Error(`CSS property abbreviation conflict: "${abbr}" is used by both "${existing}" and "${prop}"`);
937
+ }
938
+ seen.set(abbr, prop);
939
+ }
940
+
941
+ // src/plugin/when-relationships.ts
942
+ var WHEN_RELATIONSHIPS = {
943
+ ancestor: {
944
+ short: "anc",
945
+ priority: 10,
946
+ /** I.e. `._mrk:hover .wh_anc_h_blue`. */
947
+ selector(marker, target) {
948
+ return `${marker} ${target()}`;
949
+ }
950
+ },
951
+ descendant: {
952
+ short: "desc",
953
+ priority: 15,
954
+ /** I.e. `.wh_desc_h_blue:has(._mrk:hover)`. */
955
+ selector(marker, target) {
956
+ return target(`:has(${marker})`);
957
+ }
958
+ },
959
+ anySibling: {
960
+ short: "anyS",
961
+ priority: 20,
962
+ /** I.e. `.wh_anyS_h_blue:has(~ ._mrk:hover), ._mrk:hover ~ .wh_anyS_h_blue`. */
963
+ selector(marker, target) {
964
+ return `${target(`:has(~ ${marker})`)}, ${marker} ~ ${target()}`;
965
+ }
966
+ },
967
+ siblingBefore: {
968
+ short: "sibB",
969
+ priority: 30,
970
+ /** I.e. `._mrk:hover ~ .wh_sibB_h_blue`. */
971
+ selector(marker, target) {
972
+ return `${marker} ~ ${target()}`;
973
+ }
974
+ },
975
+ siblingAfter: {
976
+ short: "sibA",
977
+ priority: 40,
978
+ /** I.e. `.wh_sibA_h_blue:has(~ ._mrk:hover)`. */
979
+ selector(marker, target) {
980
+ return target(`:has(~ ${marker})`);
981
+ }
982
+ }
983
+ };
984
+ function isWhenRelationship(value) {
985
+ return Object.hasOwn(WHEN_RELATIONSHIPS, value);
986
+ }
987
+
988
+ // src/pseudo-selectors.ts
989
+ var TRUSS_PSEUDO_METHODS = {
990
+ onHover: ":hover",
991
+ onFocus: ":focus",
992
+ onFocusVisible: ":focus-visible",
993
+ onFocusWithin: ":focus-within",
994
+ onActive: ":active",
995
+ onDisabled: ":disabled",
996
+ ifFirstOfType: ":first-of-type",
997
+ ifLastOfType: ":last-of-type"
998
+ };
999
+ var PSEUDO_SELECTOR_PREFIXES = {
1000
+ ":hover": "h",
1001
+ ":focus": "f",
1002
+ ":focus-visible": "fv",
1003
+ ":focus-within": "fw",
1004
+ ":active": "a",
1005
+ ":disabled": "d",
1006
+ ":first-of-type": "fot",
1007
+ ":last-of-type": "lot",
1008
+ ":not": "n",
1009
+ ":is": "is",
1010
+ ":where": "where",
1011
+ ":has": "has"
1012
+ };
1013
+ function isTrussPseudoMethod(name) {
1014
+ return name in TRUSS_PSEUDO_METHODS;
1015
+ }
1016
+ function trussPseudoSelector(name) {
1017
+ return TRUSS_PSEUDO_METHODS[name];
1018
+ }
1019
+ function pseudoSelectorPrefix(pseudo) {
1020
+ const replaced = pseudo.trim().replace(/::?[a-zA-Z-]+/g, function pseudoMatchToPrefix(match) {
1021
+ return `_${pseudoIdentifierPrefix(match)}_`;
1022
+ });
1023
+ const cleaned = replaced.replace(/[^a-zA-Z0-9]/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "");
1024
+ return cleaned || "pseudo";
1025
+ }
1026
+ function pseudoIdentifierPrefix(pseudo) {
1027
+ const normalized = normalizePseudoIdentifier(pseudo);
1028
+ const known = PSEUDO_SELECTOR_PREFIXES[normalized];
1029
+ if (known) {
1030
+ return known;
1031
+ }
1032
+ return normalized.replace(/^::?/, "").replace(/-/g, "_");
1033
+ }
1034
+ function normalizePseudoIdentifier(pseudo) {
1035
+ const prefixMatch = pseudo.match(/^::?/);
1036
+ const prefix = prefixMatch?.[0] ?? "";
1037
+ const name = pseudo.slice(prefix.length).replace(/[A-Z]/g, function upperToKebab(match) {
1038
+ return `-${match.toLowerCase()}`;
1039
+ });
1040
+ return `${prefix}${name}`;
1041
+ }
1042
+
1043
+ // src/plugin/style-entries.ts
1044
+ var DEFAULT_MARKER_CLASS = "_mrk";
1045
+ function markerClassName(markerNode) {
1046
+ if (!markerNode) return DEFAULT_MARKER_CLASS;
1047
+ if (t5.isIdentifier(markerNode)) return `_${markerNode.name}_mrk`;
1048
+ return "_marker_mrk";
1049
+ }
1050
+ function styleEntriesForSegment(seg, mapping) {
1051
+ const prefix = segmentClassPrefix(seg.condition, mapping);
1052
+ const isConditional = prefix !== "";
1053
+ if (seg.kind === "variable") {
1054
+ return variableStyleEntries(seg, mapping, prefix, isConditional);
1055
+ }
1056
+ return staticStyleEntries(seg, mapping, prefix, isConditional, seg.defs);
1057
+ }
1058
+ function staticStyleEntries(seg, mapping, prefix, isConditional, defs, forceLonghandNames = false) {
1059
+ const isMultiProp = forceLonghandNames || Object.keys(defs).length > 1;
1060
+ return Object.entries(defs).map(([cssProp, value]) => {
1061
+ const cssValue = String(value);
1062
+ const baseName = computeStaticBaseName(seg, cssProp, cssValue, isMultiProp, mapping);
1063
+ return { cssProp, className: `${prefix}${baseName}`, isVariable: false, isConditional, cssValue };
1064
+ });
1065
+ }
1066
+ function variableStyleEntries(seg, mapping, prefix, isConditional) {
1067
+ const className = `${prefix}${seg.abbr}_var`;
1068
+ const entries = seg.props.map((cssProp) => {
1069
+ const varName = `--${prefix}${cssProp}`;
1070
+ return {
1071
+ cssProp,
1072
+ className,
1073
+ isVariable: true,
1074
+ isConditional,
1075
+ cssValue: `var(${varName})`,
1076
+ varName,
1077
+ argNode: seg.argNode,
1078
+ argResolved: seg.argResolved,
1079
+ incremented: seg.incremented,
1080
+ appendPx: seg.appendPx
1081
+ };
1082
+ });
1083
+ if (seg.extraDefs) {
1084
+ entries.push(...staticStyleEntries(seg, mapping, prefix, isConditional, seg.extraDefs, true));
1085
+ }
1086
+ return entries;
1087
+ }
1088
+ function computeStaticBaseName(seg, cssProp, cssValue, isMultiProp, mapping) {
1089
+ if (isMultiProp) {
1090
+ const canonical = findCanonicalAbbreviation(mapping, cssProp, cssValue);
1091
+ return canonical ?? `${getPropertyAbbreviation(cssProp)}_${classNameFragmentForResolvedValue(cssValue)}`;
1092
+ }
1093
+ if (seg.argResolved !== void 0) {
1094
+ return `${seg.abbr}_${classNameFragmentForResolvedValue(seg.argResolved)}`;
1095
+ }
1096
+ return seg.abbr;
1097
+ }
1098
+ function segmentClassPrefix(condition, mapping) {
1099
+ const parts = [];
1100
+ if (condition.pseudoElement) {
1101
+ parts.push(`${condition.pseudoElement.replace(/^::/, "")}_`);
1102
+ }
1103
+ if (condition.mediaQuery) {
1104
+ const breakpoint = breakpointNameForMediaQuery(mapping, condition.mediaQuery);
1105
+ parts.push(breakpoint ? `${breakpoint.toLowerCase()}_` : "mq_");
1106
+ }
1107
+ if (condition.pseudoClass) {
1108
+ parts.push(`${pseudoSelectorPrefix(condition.pseudoClass)}_`);
1109
+ }
1110
+ if (condition.whenPseudo) {
1111
+ parts.push(whenPrefix(condition.whenPseudo));
1112
+ }
1113
+ return parts.join("");
1114
+ }
1115
+ function whenPrefix(whenPseudo) {
1116
+ const rel = WHEN_RELATIONSHIPS[whenPseudo.relationship].short;
1117
+ const pseudoPrefix = pseudoSelectorPrefix(whenPseudo.pseudo);
1118
+ const markerPart = whenPseudo.markerNode ? `${whenPseudo.markerNode.name}_` : "";
1119
+ return `wh_${rel}_${pseudoPrefix}_${markerPart}`;
1120
+ }
1121
+ function camelToKebab(s) {
1122
+ return s.replace(/^(Webkit|Moz|Ms|O)/, (m) => `-${m.toLowerCase()}`).replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
1123
+ }
1124
+ function sanitizeClassNameToken(value) {
1125
+ return value.replace(/[^a-zA-Z0-9]/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "");
1126
+ }
1127
+ function cleanValueForClassName(value) {
1128
+ return sanitizeClassNameToken(value.startsWith("-") ? `neg${value.slice(1)}` : value);
1129
+ }
1130
+ function classNameFragmentForResolvedValue(value) {
1131
+ return cleanValueForClassName(tryParseIncrementCalcMultiplier(value) ?? value);
1132
+ }
1133
+ function getPropertyAbbreviation(cssProp) {
1134
+ return cssPropertyAbbreviations[cssProp] ?? cssProp;
1135
+ }
1136
+
1137
+ // src/plugin/resolve-setvar.ts
1138
+ function resolveSetVarCall(node, mapping, context) {
1139
+ const arg = singleArg(node, "setVar");
1140
+ if (!t6.isObjectExpression(arg)) {
1141
+ throw new UnsupportedPatternError(`setVar() requires an object literal argument`);
1142
+ }
1143
+ const segments = [];
1144
+ for (const prop of arg.properties) {
1145
+ if (t6.isSpreadElement(prop)) {
1146
+ throw new UnsupportedPatternError(`setVar() does not support spread properties`);
1147
+ }
1148
+ if (!t6.isObjectProperty(prop)) {
1149
+ throw new UnsupportedPatternError(`setVar() only supports object properties`);
1150
+ }
1151
+ const cssVarName = resolveSetVarPropertyKey(prop, mapping);
1152
+ const abbr = `__${sanitizeClassNameToken(cssVarName.replace(/^--/, ""))}`;
1153
+ for (const leaf of expandSetVarValueToLeaves(prop.value, mapping, context)) {
1154
+ segments.push(staticSegment(abbr, { [cssVarName]: leaf.literal }, leaf.context, leaf.literal));
1155
+ }
1156
+ }
1157
+ return segments;
1158
+ }
1159
+ function resolveSetVarPropertyKey(prop, mapping) {
1160
+ const key = prop.key;
1161
+ if (!prop.computed) {
1162
+ if (t6.isStringLiteral(key)) {
1163
+ if (key.value.startsWith("--")) {
1164
+ return key.value;
1165
+ }
1166
+ throw new UnsupportedPatternError(
1167
+ `setVar() string keys must be CSS variables starting with "--" - got ${JSON.stringify(key.value)}`
1168
+ );
1169
+ }
1170
+ if (t6.isIdentifier(key)) {
1171
+ throw new UnsupportedPatternError(
1172
+ `setVar() requires computed keys like [Tokens.Name] or string keys "--my-var", not bare property names`
1173
+ );
1174
+ }
1175
+ throw new UnsupportedPatternError(`setVar() property keys must be string literals or [Tokens.*] members`);
1176
+ }
1177
+ if (!t6.isMemberExpression(key)) {
1178
+ throw new UnsupportedPatternError(`setVar() computed keys must be Tokens.*-style members`);
1179
+ }
1180
+ const memberName = memberPropertyName(key);
1181
+ if (memberName === null) {
1182
+ throw new UnsupportedPatternError(
1183
+ `setVar() [Tokens.name] keys must use a plain .member or ["string"] member access`
1184
+ );
1185
+ }
1186
+ const tokenMap = mapping.tokens;
1187
+ if (!tokenMap || !(memberName in tokenMap)) {
1188
+ throw new UnsupportedPatternError(
1189
+ tokenMap ? `Unknown token "${memberName}" - add it to config.tokens or use a "--" string literal key` : `setVar() [Tokens.*] requires config.tokens; use "--" string literal keys only`
1190
+ );
1191
+ }
1192
+ return tokenMap[memberName];
1193
+ }
1194
+ function expandSetVarValueToLeaves(valueNode, mapping, baseContext) {
1195
+ const unwrapped = unwrapExpression(valueNode);
1196
+ const scalar = tryResolveValueLiteral(unwrapped);
1197
+ if (scalar !== null) {
1198
+ return [setVarLeaf(scalar, baseContext)];
1199
+ }
1200
+ if (!t6.isObjectExpression(unwrapped)) {
1201
+ throw new UnsupportedPatternError(
1202
+ `setVar() values must be string/number literals or a { default?, media?, container? } object`
1203
+ );
1204
+ }
1205
+ let defaultLiteral;
1206
+ let mediaObject;
1207
+ let containerArray;
1208
+ for (const { key, value } of plainObjectEntries(unwrapped, "setVar() responsive object")) {
1209
+ if (key === "default") {
1210
+ defaultLiteral = requireValueLiteral(value, `setVar().default must be a string or number literal`);
1211
+ } else if (key === "media") {
1212
+ if (!t6.isObjectExpression(value)) {
1213
+ throw new UnsupportedPatternError(`setVar().media must be an object literal`);
1214
+ }
1215
+ mediaObject = value;
1216
+ } else if (key === "container") {
1217
+ if (!t6.isArrayExpression(value)) {
1218
+ throw new UnsupportedPatternError(`setVar().container must be an array literal`);
1219
+ }
1220
+ containerArray = value;
1221
+ } else {
1222
+ throw new UnsupportedPatternError(`setVar() responsive object does not support property "${key}"`);
1223
+ }
1224
+ }
1225
+ const leaves = [];
1226
+ if (defaultLiteral !== void 0) {
1227
+ leaves.push(setVarLeaf(defaultLiteral, baseContext));
1228
+ }
1229
+ if (mediaObject) {
1230
+ leaves.push(...setVarMediaLeaves(mediaObject, mapping, baseContext));
1231
+ }
1232
+ if (containerArray) {
1233
+ leaves.push(...setVarContainerLeaves(containerArray, baseContext));
1234
+ }
1235
+ if (leaves.length === 0) {
1236
+ throw new UnsupportedPatternError(
1237
+ `setVar() responsive object must include at least one of default, media entries, or container entries`
1238
+ );
1239
+ }
1240
+ return leaves;
1241
+ }
1242
+ function setVarMediaLeaves(mediaObject, mapping, baseContext) {
1243
+ return plainObjectEntries(mediaObject, "setVar().media").map(({ key: breakpointName, value }) => {
1244
+ const mediaQuery = breakpointMediaQuery(mapping, `if${pascalCase(breakpointName)}`);
1245
+ if (mediaQuery === null) {
1246
+ throw new UnsupportedPatternError(
1247
+ `Unknown breakpoint "${breakpointName}" in setVar().media - use a Breakpoint name from truss-config`
1248
+ );
1249
+ }
1250
+ const literal = requireValueLiteral(value, `setVar().media[${breakpointName}] must be a string or number literal`);
1251
+ return setVarLeaf(literal, baseContext, mediaQuery);
1252
+ });
1253
+ }
1254
+ function setVarContainerLeaves(containerArray, baseContext) {
1255
+ const leaves = [];
1256
+ for (const element of containerArray.elements) {
1257
+ if (element === null) {
1258
+ continue;
1259
+ }
1260
+ if (!t6.isObjectExpression(element)) {
1261
+ throw new UnsupportedPatternError(`setVar().container entries must be object literals`);
1262
+ }
1263
+ let rowValue;
1264
+ const bounds = {};
1265
+ for (const { key, value } of plainObjectEntries(element, "setVar().container row")) {
1266
+ if (key === "value") {
1267
+ rowValue = requireValueLiteral(value, `setVar().container row "value" must be a string or number literal`);
1268
+ } else if (!readContainerBound(bounds, key, value, "setVar().container ")) {
1269
+ throw new UnsupportedPatternError(`setVar().container row does not support property "${key}"`);
1270
+ }
1271
+ }
1272
+ if (rowValue === void 0) {
1273
+ throw new UnsupportedPatternError(`setVar().container row requires a "value" property`);
1274
+ }
1275
+ if (bounds.lt === void 0 && bounds.gt === void 0) {
1276
+ throw new UnsupportedPatternError(`setVar().container row requires at least one of gt or lt`);
1277
+ }
1278
+ leaves.push(setVarLeaf(rowValue, baseContext, containerQueryString(bounds)));
1279
+ }
1280
+ return leaves;
1281
+ }
1282
+ function setVarLeaf(literal, baseContext, mediaQuery) {
1283
+ const context = cloneConditionContext(baseContext);
1284
+ if (mediaQuery !== void 0) {
1285
+ context.mediaQuery = mediaQuery;
1286
+ }
1287
+ return { literal, context };
1288
+ }
1289
+
1290
+ // src/plugin/resolve-typography.ts
1291
+ import * as t7 from "@babel/types";
1292
+ function resolveTypographyCall(node, mapping, context) {
1293
+ const arg = singleArg(node, "typography");
1294
+ if (t7.isStringLiteral(arg)) {
1295
+ return resolveTypographyEntry(arg.value, mapping, context);
1296
+ }
1297
+ const typography = mapping.typography ?? [];
1298
+ if (typography.length === 0) {
1299
+ throw new UnsupportedPatternError(`typography() is unavailable because no typography abbreviations were generated`);
1300
+ }
1301
+ const suffix = typographyLookupKeySuffix(context, mapping);
1302
+ const lookupKey = suffix ? `typography__${suffix}` : "typography";
1303
+ const segmentsByName = {};
1304
+ for (const name of typography) {
1305
+ segmentsByName[name] = resolveTypographyEntry(name, mapping, context);
1306
+ }
1307
+ return [{ kind: "typography", lookupKey, argNode: arg, segmentsByName }];
1308
+ }
1309
+ function resolveTypographyEntry(name, mapping, context) {
1310
+ if (!(mapping.typography ?? []).includes(name)) {
1311
+ throw new UnsupportedPatternError(`Unknown typography abbreviation "${name}"`);
1312
+ }
1313
+ const entry = mapping.abbreviations[name];
1314
+ if (!entry) {
1315
+ throw new UnsupportedPatternError(`Unknown typography abbreviation "${name}"`);
1316
+ }
1317
+ const resolved = resolveEntry(name, entry, mapping, context);
1318
+ for (const segment of resolved) {
1319
+ if (segment.kind === "variable") {
1320
+ throw new UnsupportedPatternError(`Typography abbreviation "${name}" cannot require runtime arguments`);
1321
+ }
1322
+ }
1323
+ return resolved;
1324
+ }
1325
+ function typographyLookupKeySuffix(context, mapping) {
1326
+ const parts = [];
1327
+ if (context.pseudoElement) parts.push(context.pseudoElement.replace(/^::/, ""));
1328
+ if (context.mediaQuery) {
1329
+ const breakpoint = breakpointNameForMediaQuery(mapping, context.mediaQuery);
1330
+ parts.push(breakpoint ? breakpoint.replace(/^./, (c) => c.toLowerCase()) : "mq");
1331
+ }
1332
+ if (context.pseudoClass) parts.push(context.pseudoClass.replace(/^:+/, "").replace(/-/g, "_"));
1333
+ if (context.whenPseudo) parts.push(whenLookupKeyPart(context.whenPseudo));
1334
+ return parts.join("_");
1335
+ }
1336
+ function whenLookupKeyPart(whenPseudo) {
1337
+ const parts = ["when", whenPseudo.relationship, sanitizeClassNameToken(whenPseudo.pseudo) || "value"];
1338
+ if (whenPseudo.markerNode) {
1339
+ parts.push(whenPseudo.markerNode.name);
1340
+ }
1341
+ return parts.join("_");
1342
+ }
1343
+
1344
+ // src/plugin/resolve-calls.ts
1345
+ function resolveCallNode(node, mapping, context) {
1346
+ switch (node.name) {
1347
+ case "with":
1348
+ return [resolveWithCall(node)];
1349
+ case "add":
1350
+ return resolveAddCall(node, mapping, context);
1351
+ case "className":
1352
+ return [resolveClassNameCall(node, context)];
1353
+ case "style":
1354
+ return [resolveStyleCall(node, context)];
1355
+ case "setVar":
1356
+ return resolveSetVarCall(node, mapping, context);
1357
+ case "typography":
1358
+ return resolveTypographyCall(node, mapping, context);
1359
+ }
1360
+ const entry = requireEntry(mapping, node.name);
1361
+ if (entry.kind === "variable") {
1362
+ return [resolveVariableCall(node.name, entry, node, mapping, context)];
1363
+ }
1364
+ if (entry.kind === "delegate") {
1365
+ return [resolveDelegateCall(node.name, entry, node, mapping, context)];
1366
+ }
1367
+ throw new UnsupportedPatternError(`Abbreviation "${node.name}" is ${entry.kind}, cannot be called as a function`);
1368
+ }
1369
+ function resolveVariableCall(abbr, entry, node, mapping, context) {
1370
+ const arg = singleArg(node, abbr);
1371
+ return resolveLiteralOrVariableSegment({
1372
+ abbr,
1373
+ props: entry.props,
1374
+ incremented: entry.incremented,
1375
+ extraDefs: entry.extraDefs,
1376
+ argAst: arg,
1377
+ literalValue: tryEvaluatePropertyLiteral(arg, mapping, entry.incremented),
1378
+ mapping,
1379
+ context
1380
+ });
1381
+ }
1382
+ function resolveDelegateCall(abbr, entry, node, mapping, context) {
1383
+ const targetEntry = mapping.abbreviations[entry.target];
1384
+ if (!targetEntry || targetEntry.kind !== "variable") {
1385
+ throw new UnsupportedPatternError(`Delegate "${abbr}" targets "${entry.target}" which is not a variable entry`);
1386
+ }
1387
+ const arg = singleArg(node, abbr);
1388
+ const pixels = tryNumericLiteral(arg);
1389
+ return resolveLiteralOrVariableSegment({
1390
+ abbr: entry.target,
1391
+ props: targetEntry.props,
1392
+ incremented: false,
1393
+ appendPx: true,
1394
+ extraDefs: targetEntry.extraDefs,
1395
+ argAst: arg,
1396
+ literalValue: pixels === null ? null : `${pixels}px`,
1397
+ mapping,
1398
+ context
1399
+ });
1400
+ }
1401
+ function resolveLiteralOrVariableSegment(params) {
1402
+ const { abbr, props, incremented, appendPx = false, extraDefs, argAst, literalValue, mapping, context } = params;
1403
+ if (literalValue !== null && !isCustomPropertyLiteral(argAst, mapping)) {
1404
+ const defs = Object.fromEntries(props.map((prop) => [prop, literalValue]));
1405
+ return staticSegment(abbr, { ...defs, ...extraDefs }, context, literalValue);
1406
+ }
1407
+ return {
1408
+ kind: "variable",
1409
+ abbr,
1410
+ props,
1411
+ incremented,
1412
+ appendPx,
1413
+ extraDefs,
1414
+ argNode: literalValue === null ? argAst : void 0,
1415
+ argResolved: literalValue ?? void 0,
1416
+ condition: cloneConditionContext(context)
1417
+ };
1418
+ }
1419
+ function resolveClassNameCall(node, context) {
1420
+ const arg = singleArg(node, "className");
1421
+ if (hasCondition(context)) {
1422
+ throw new UnsupportedPatternError(
1423
+ `className() cannot be used inside media query, pseudo-class, pseudo-element, or when() contexts`
1424
+ );
1425
+ }
1426
+ return { kind: "className", arg };
1427
+ }
1428
+ function resolveStyleCall(node, context) {
1429
+ const arg = singleArg(node, "style");
1430
+ if (hasCondition(context)) {
1431
+ throw new UnsupportedPatternError(
1432
+ `style() cannot be used inside media query, pseudo-class, pseudo-element, or when() contexts`
1433
+ );
1434
+ }
1435
+ return { kind: "inlineStyle", arg };
1436
+ }
1437
+ function resolveWithCall(node) {
1438
+ if (node.args.length !== 1) {
1439
+ throw new UnsupportedPatternError(`with() requires exactly 1 argument`);
1440
+ }
1441
+ const styleArg = node.args[0];
1442
+ if (t8.isSpreadElement(styleArg)) {
1443
+ throw new UnsupportedPatternError(`with() does not support spread arguments`);
1444
+ }
1445
+ return { kind: "composed", arg: styleArg, skipUndefined: t8.isObjectExpression(styleArg) };
1446
+ }
1447
+ function resolveAddCall(node, mapping, context) {
1448
+ const usage = `add() requires 1 or 2 arguments (property name and value, or an object literal), got ${node.args.length}. Supported overloads are add({ prop: value }), add("propName", value), and with(cssProp)`;
1449
+ if (node.args.length === 1) {
1450
+ const styleArg = node.args[0];
1451
+ if (t8.isSpreadElement(styleArg)) {
1452
+ throw new UnsupportedPatternError(`add() does not support spread arguments`);
1453
+ }
1454
+ if (t8.isObjectExpression(styleArg)) {
1455
+ return resolveAddObjectLiteral(styleArg, mapping, context);
1456
+ }
1457
+ throw new UnsupportedPatternError(usage);
1458
+ }
1459
+ if (node.args.length !== 2) {
1460
+ throw new UnsupportedPatternError(usage);
1461
+ }
1462
+ const [propArg, valueArg] = node.args;
1463
+ if (!t8.isStringLiteral(propArg)) {
1464
+ throw new UnsupportedPatternError(`add() first argument must be a string literal property name`);
1465
+ }
1466
+ if (t8.isSpreadElement(valueArg)) {
1467
+ throw new UnsupportedPatternError(`add() does not support spread arguments`);
1468
+ }
1469
+ return [resolveAddDeclaration(propArg.value, valueArg, mapping, context)];
1470
+ }
1471
+ function resolveAddObjectLiteral(obj, mapping, context) {
1472
+ const segments = [];
1473
+ for (const property of obj.properties) {
1474
+ if (t8.isSpreadElement(property)) {
1475
+ throw new UnsupportedPatternError(`add({...}) does not support spread properties -- use with() instead`);
1476
+ }
1477
+ if (!t8.isObjectProperty(property) || property.computed) {
1478
+ throw new UnsupportedPatternError(`add({...}) only supports simple property keys`);
1479
+ }
1480
+ const propName = staticPropertyName(property.key);
1481
+ if (propName === null) {
1482
+ throw new UnsupportedPatternError(`add({...}) property keys must be identifiers or string literals`);
1483
+ }
1484
+ segments.push(resolveAddDeclaration(propName, property.value, mapping, context));
1485
+ }
1486
+ return segments;
1487
+ }
1488
+ function resolveAddDeclaration(propName, valueNode, mapping, context) {
1489
+ const literalValue = tryEvaluatePropertyLiteral(valueNode, mapping, false);
1490
+ const canonicalAbbr = literalValue !== null && !isCustomPropertyLiteral(valueNode, mapping) ? findCanonicalAbbreviation(mapping, propName, literalValue) : void 0;
1491
+ if (canonicalAbbr) {
1492
+ const entry = mapping.abbreviations[canonicalAbbr];
1493
+ return staticSegment(canonicalAbbr, entry.defs, context);
1494
+ }
1495
+ return resolveLiteralOrVariableSegment({
1496
+ abbr: propName,
1497
+ props: [propName],
1498
+ incremented: false,
1499
+ argAst: valueNode,
1500
+ literalValue,
1501
+ mapping,
1502
+ context
1503
+ });
1504
+ }
1505
+
1506
+ // src/plugin/resolve-when.ts
1507
+ import * as t9 from "@babel/types";
1508
+ function resolveWhenCall(node) {
1509
+ if (node.args.length !== 1 && node.args.length !== 3) {
1510
+ throw new UnsupportedPatternError(
1511
+ `when() expects 1 or 3 arguments (selector) or (marker, relationship, pseudo), got ${node.args.length}`
1512
+ );
1513
+ }
1514
+ if (node.args.length === 1) {
1515
+ const selectorArg = node.args[0];
1516
+ if (!t9.isStringLiteral(selectorArg)) {
1517
+ throw new UnsupportedPatternError(`when() selector must be a string literal`);
1518
+ }
1519
+ return { kind: "selector", selector: selectorArg.value };
1520
+ }
1521
+ const [markerArg, relationshipArg, pseudoArg] = node.args;
1522
+ const markerNode = resolveWhenMarker(markerArg);
1523
+ if (!t9.isStringLiteral(relationshipArg)) {
1524
+ throw new UnsupportedPatternError(`when() relationship argument must be a string literal`);
1525
+ }
1526
+ const relationship = relationshipArg.value;
1527
+ if (!isWhenRelationship(relationship)) {
1528
+ throw new UnsupportedPatternError(
1529
+ `when() relationship must be one of: ${Object.keys(WHEN_RELATIONSHIPS).join(", ")} -- got "${relationship}"`
1530
+ );
1531
+ }
1532
+ if (!t9.isStringLiteral(pseudoArg)) {
1533
+ throw new UnsupportedPatternError(`when() pseudo selector (3rd argument) must be a string literal`);
1534
+ }
1535
+ return { kind: "relationship", condition: { pseudo: pseudoArg.value, markerNode, relationship } };
1536
+ }
1537
+ function resolveWhenMarker(node) {
1538
+ if (isDefaultMarkerNode(node)) {
1539
+ return void 0;
1540
+ }
1541
+ if (t9.isIdentifier(node)) {
1542
+ return node;
1543
+ }
1544
+ throw new UnsupportedPatternError(`when() marker must be a marker variable or marker`);
1545
+ }
1546
+ function isDefaultMarkerNode(node) {
1547
+ if (t9.isIdentifier(node) && (node.name === "marker" || node.name === "defaultMarker")) {
1548
+ return true;
1549
+ }
1550
+ return t9.isCallExpression(node) && node.arguments.length === 0 && t9.isMemberExpression(node.callee) && !node.callee.computed && t9.isIdentifier(node.callee.property, { name: "defaultMarker" });
1551
+ }
1552
+
1553
+ // src/media-query.ts
1554
+ function invertMediaQuery(query) {
1555
+ const screenPrefix = "@media screen and ";
1556
+ if (query.startsWith(screenPrefix)) {
1557
+ const conditions = query.slice(screenPrefix.length).trim();
1558
+ const rangeMatch = conditions.match(/^\(min-width: (\d+)px\) and \(max-width: (\d+)px\)$/);
1559
+ if (rangeMatch) {
1560
+ const min = Number(rangeMatch[1]);
1561
+ const max = Number(rangeMatch[2]);
1562
+ return `@media screen and (max-width: ${min - 1}px), screen and (min-width: ${max + 1}px)`;
1563
+ }
1564
+ const minMatch = conditions.match(/^\(min-width: (\d+)px\)$/);
1565
+ if (minMatch) {
1566
+ return `@media screen and (max-width: ${Number(minMatch[1]) - 1}px)`;
1567
+ }
1568
+ const maxMatch = conditions.match(/^\(max-width: (\d+)px\)$/);
1569
+ if (maxMatch) {
1570
+ return `@media screen and (min-width: ${Number(maxMatch[1]) + 1}px)`;
1571
+ }
1572
+ }
1573
+ return query.replace("@media", "@media not");
1574
+ }
1575
+
1576
+ // src/plugin/resolve-chain.ts
1577
+ function partSegments(part) {
1578
+ return part.type === "unconditional" ? part.segments : [...part.thenSegments, ...part.elseSegments];
1579
+ }
1580
+ function chainSegments(chain) {
1581
+ return chain.parts.flatMap((part) => partSegments(part));
1582
+ }
1583
+ function resolveFullChain(ctx, chain, initialContext = emptyConditionContext()) {
1584
+ const { mapping } = ctx;
1585
+ const markerScan = scanMarkerNodes(chain);
1586
+ const nodes = markerScan.chain;
1587
+ const markers = [...markerScan.markers];
1588
+ const errors = [...markerScan.errors];
1589
+ const parts = [];
1590
+ const context = cloneConditionContext(initialContext);
1591
+ let current = [];
1592
+ function closeCurrentPart() {
1593
+ if (current.length > 0) {
1594
+ parts.push({ type: "unconditional", segments: current });
1595
+ current = [];
1596
+ }
1597
+ }
1598
+ let i = 0;
1599
+ while (i < nodes.length) {
1600
+ const node = nodes[i];
1601
+ const mediaQuery = mediaQueryOfNode(node, mapping);
1602
+ if (mediaQuery !== null) {
1603
+ const elseIndex = findElseIndex(nodes, i + 1);
1604
+ if (elseIndex === -1) {
1605
+ context.mediaQuery = mediaQuery;
1606
+ i++;
1607
+ continue;
1608
+ }
1609
+ const branchEnd = findEndIndex(nodes, elseIndex + 1);
1610
+ const thenContext = cloneConditionContext(context);
1611
+ thenContext.mediaQuery = mediaQuery;
1612
+ const elseContext = cloneConditionContext(context);
1613
+ elseContext.mediaQuery = invertMediaQuery(mediaQuery);
1614
+ current.push(
1615
+ ...resolveSegments(ctx, nodes.slice(i + 1, elseIndex), thenContext),
1616
+ ...resolveSegments(ctx, nodes.slice(elseIndex + 1, branchEnd), elseContext)
1617
+ );
1618
+ if (branchEnd === nodes.length) {
1619
+ break;
1620
+ }
1621
+ resetConditionContext(context);
1622
+ i = branchEnd + 1;
1623
+ continue;
1624
+ }
1625
+ if (isWhenObjectCall(node)) {
1626
+ closeCurrentPart();
1627
+ const resolved = resolveWhenObjectSelectors(ctx, node, context);
1628
+ parts.push(...resolved.parts);
1629
+ markers.push(...resolved.markers);
1630
+ errors.push(...resolved.errors);
1631
+ i++;
1632
+ continue;
1633
+ }
1634
+ if (node.type === "if") {
1635
+ closeCurrentPart();
1636
+ const branchContext = cloneConditionContext(context);
1637
+ const thenNodes = [];
1638
+ const elseNodes = [];
1639
+ i++;
1640
+ let inElse = false;
1641
+ while (i < nodes.length) {
1642
+ const branchNode = nodes[i];
1643
+ if (branchNode.type === "getter" && branchNode.name === "end") {
1644
+ resetConditionContext(context);
1645
+ i++;
1646
+ break;
1647
+ }
1648
+ if (branchNode.type === "else") {
1649
+ inElse = true;
1650
+ i++;
1651
+ continue;
1652
+ }
1653
+ if (branchNode.type === "if") {
1654
+ break;
1655
+ }
1656
+ if (inElse) {
1657
+ elseNodes.push(branchNode);
1658
+ } else {
1659
+ thenNodes.push(branchNode);
1660
+ }
1661
+ i++;
1662
+ }
1663
+ parts.push({
1664
+ type: "conditional",
1665
+ conditionNode: node.conditionNode,
1666
+ thenSegments: resolveSegments(ctx, thenNodes, cloneConditionContext(branchContext)),
1667
+ elseSegments: resolveSegments(ctx, elseNodes, cloneConditionContext(branchContext))
1668
+ });
1669
+ continue;
1670
+ }
1671
+ current.push(...resolveNode(ctx, node, context));
1672
+ i++;
1673
+ }
1674
+ closeCurrentPart();
1675
+ const segmentErrors = parts.flatMap((part) => partSegments(part)).flatMap((seg) => seg.kind === "error" ? [seg.message] : []);
1676
+ return { parts, markers, errors: [.../* @__PURE__ */ new Set([...errors, ...segmentErrors])] };
1677
+ }
1678
+ function resolveSegments(ctx, nodes, context) {
1679
+ return nodes.flatMap((node) => resolveNode(ctx, node, context));
1680
+ }
1681
+ function resolveNode(ctx, node, context) {
1682
+ const { mapping } = ctx;
1683
+ try {
1684
+ if (isWhenObjectCall(node)) {
1685
+ return flattenWhenObjectParts(resolveWhenObjectSelectors(ctx, node, context));
1686
+ }
1687
+ if (applyModifierNodeToConditionContext(context, node, mapping)) {
1688
+ return [];
1689
+ }
1690
+ if (node.type === "getter") {
1691
+ return resolveEntry(node.name, requireEntry(mapping, node.name), mapping, context);
1692
+ }
1693
+ if (node.type === "call") {
1694
+ return resolveCallNode(node, mapping, context);
1695
+ }
1696
+ return [];
1697
+ } catch (err) {
1698
+ if (!(err instanceof UnsupportedPatternError)) throw err;
1699
+ return [errorSegment(err.message)];
1700
+ }
1701
+ }
1702
+ function applyModifierNodeToConditionContext(context, node, mapping) {
1703
+ if (node.type === "getter") {
1704
+ if (node.name === "end") {
1705
+ resetConditionContext(context);
1706
+ return true;
1707
+ }
1708
+ if (isTrussPseudoMethod(node.name)) {
1709
+ context.pseudoClass = trussPseudoSelector(node.name);
1710
+ return true;
1711
+ }
1712
+ const mediaQuery = breakpointMediaQuery(mapping, node.name);
1713
+ if (mediaQuery !== null) {
1714
+ context.mediaQuery = mediaQuery;
1715
+ return true;
1716
+ }
1717
+ return false;
1718
+ }
1719
+ if (node.type !== "call") {
1720
+ return false;
1721
+ }
1722
+ if (node.name === "ifContainer") {
1723
+ context.mediaQuery = containerQueryFromCall(node);
1724
+ return true;
1725
+ }
1726
+ if (node.name === "element") {
1727
+ const arg = node.args.length === 1 ? node.args[0] : null;
1728
+ if (!t10.isStringLiteral(arg)) {
1729
+ throw new UnsupportedPatternError(
1730
+ `element() requires exactly one string literal argument (e.g. "::placeholder")`
1731
+ );
1732
+ }
1733
+ context.pseudoElement = arg.value;
1734
+ return true;
1735
+ }
1736
+ if (node.name === "when") {
1737
+ if (isWhenObjectCall(node)) {
1738
+ return false;
1739
+ }
1740
+ const resolved = resolveWhenCall(node);
1741
+ if (resolved.kind === "selector") {
1742
+ context.pseudoClass = resolved.selector;
1743
+ } else {
1744
+ context.whenPseudo = resolved.condition;
1745
+ }
1746
+ return true;
1747
+ }
1748
+ if (isTrussPseudoMethod(node.name)) {
1749
+ context.pseudoClass = trussPseudoSelector(node.name);
1750
+ if (node.args.length > 0) {
1751
+ throw new UnsupportedPatternError(
1752
+ `${node.name}() does not take arguments -- use when(marker, "ancestor", ":hover") for relationship selectors`
1753
+ );
1754
+ }
1755
+ return true;
1756
+ }
1757
+ return false;
1758
+ }
1759
+ function scanMarkerNodes(chain) {
1760
+ const filteredChain = [];
1761
+ const markers = [];
1762
+ const errors = [];
1763
+ for (const node of chain) {
1764
+ if (node.type === "getter" && node.name === "marker") {
1765
+ markers.push({ type: "marker" });
1766
+ continue;
1767
+ }
1768
+ if (node.type === "call" && node.name === "markerOf") {
1769
+ const arg = node.args.length === 1 ? node.args[0] : null;
1770
+ if (!arg || t10.isSpreadElement(arg)) {
1771
+ errors.push("[truss] Unsupported pattern: markerOf() requires exactly one argument (a marker variable)");
1772
+ } else {
1773
+ markers.push({ type: "marker", markerNode: arg });
1774
+ }
1775
+ continue;
1776
+ }
1777
+ filteredChain.push(node);
1778
+ }
1779
+ return { chain: filteredChain, markers, errors };
1780
+ }
1781
+ function mediaQueryOfNode(node, mapping) {
1782
+ if (node.type === "if" && t10.isStringLiteral(node.conditionNode)) {
1783
+ return node.conditionNode.value;
1784
+ }
1785
+ if (node.type === "getter") {
1786
+ return breakpointMediaQuery(mapping, node.name);
1787
+ }
1788
+ return null;
1789
+ }
1790
+ function findElseIndex(chain, start) {
1791
+ for (let i = start; i < chain.length; i++) {
1792
+ const node = chain[i];
1793
+ if (node.type === "if") {
1794
+ return -1;
1795
+ }
1796
+ if (node.type === "getter" && node.name === "end") {
1797
+ return -1;
1798
+ }
1799
+ if (node.type === "else") {
1800
+ return i;
1801
+ }
1802
+ }
1803
+ return -1;
1804
+ }
1805
+ function findEndIndex(chain, start) {
1806
+ for (let i = start; i < chain.length; i++) {
1807
+ const node = chain[i];
1808
+ if (node.type === "getter" && node.name === "end") {
1809
+ return i;
1810
+ }
1811
+ }
1812
+ return chain.length;
1813
+ }
1814
+ function isWhenObjectCall(node) {
1815
+ return node.type === "call" && node.name === "when" && node.args.length === 1 && t10.isObjectExpression(node.args[0]);
1816
+ }
1817
+ function resolveWhenObjectSelectors(ctx, node, context) {
1818
+ if (!ctx.cssBindingName) {
1819
+ return {
1820
+ parts: [],
1821
+ markers: [],
1822
+ errors: [new UnsupportedPatternError(`when({ ... }) requires a resolvable Css binding`).message]
1823
+ };
1824
+ }
1825
+ const parts = [];
1826
+ const markers = [];
1827
+ const errors = [];
1828
+ for (const property of node.args[0].properties) {
1829
+ try {
1830
+ if (t10.isSpreadElement(property)) {
1831
+ throw new UnsupportedPatternError(`when({ ... }) does not support spread properties`);
1832
+ }
1833
+ if (!t10.isObjectProperty(property)) {
1834
+ throw new UnsupportedPatternError(`when({ ... }) only supports plain object properties`);
1835
+ }
1836
+ if (property.computed || !t10.isStringLiteral(property.key)) {
1837
+ throw new UnsupportedPatternError(`when({ ... }) selector keys must be string literals`);
1838
+ }
1839
+ const value = unwrapExpression(property.value);
1840
+ const innerChain = resolveWhenObjectValueChain(ctx, value);
1841
+ if (!innerChain) {
1842
+ throw new UnsupportedPatternError(`when({ ... }) values must be Css.*.$ expressions`);
1843
+ }
1844
+ const selectorContext = cloneConditionContext(context);
1845
+ selectorContext.pseudoClass = property.key.value;
1846
+ const resolved = resolveFullChain(ctx, innerChain, selectorContext);
1847
+ parts.push(...resolved.parts);
1848
+ markers.push(...resolved.markers);
1849
+ errors.push(...resolved.errors);
1850
+ } catch (err) {
1851
+ if (!(err instanceof UnsupportedPatternError)) throw err;
1852
+ errors.push(err.message);
1853
+ }
1854
+ }
1855
+ return { parts, markers, errors: [...new Set(errors)] };
1856
+ }
1857
+ function resolveWhenObjectValueChain(ctx, value) {
1858
+ const direct = ctx.cssBindingName ? extractDollarChain(value, ctx.cssBindingName) : null;
1859
+ return direct ?? ctx.resolveCssChainReference?.(value) ?? null;
1860
+ }
1861
+ function flattenWhenObjectParts(resolved) {
1862
+ const segments = [];
1863
+ for (const part of resolved.parts) {
1864
+ if (part.type !== "unconditional") {
1865
+ throw new UnsupportedPatternError(`when({ ... }) values cannot use if()/else in this context`);
1866
+ }
1867
+ segments.push(...part.segments);
1868
+ }
1869
+ for (const err of resolved.errors) {
1870
+ segments.push(errorSegment(err));
1871
+ }
1872
+ return segments;
1873
+ }
1874
+
1875
+ // src/plugin/property-priorities.ts
1876
+ var longHandPhysical = /* @__PURE__ */ new Set();
1877
+ var longHandLogical = /* @__PURE__ */ new Set();
1878
+ var shorthandsOfLonghands = /* @__PURE__ */ new Set();
1879
+ var shorthandsOfShorthands = /* @__PURE__ */ new Set();
1880
+ longHandLogical.add("background-blend-mode");
1881
+ longHandLogical.add("isolation");
1882
+ longHandLogical.add("mix-blend-mode");
1883
+ shorthandsOfShorthands.add("animation");
1884
+ longHandLogical.add("animation-composition");
1885
+ longHandLogical.add("animation-delay");
1886
+ longHandLogical.add("animation-direction");
1887
+ longHandLogical.add("animation-duration");
1888
+ longHandLogical.add("animation-fill-mode");
1889
+ longHandLogical.add("animation-iteration-count");
1890
+ longHandLogical.add("animation-name");
1891
+ longHandLogical.add("animation-play-state");
1892
+ shorthandsOfLonghands.add("animation-range");
1893
+ longHandLogical.add("animation-range-end");
1894
+ longHandLogical.add("animation-range-start");
1895
+ longHandLogical.add("animation-timing-function");
1896
+ longHandLogical.add("animation-timeline");
1897
+ shorthandsOfLonghands.add("scroll-timeline");
1898
+ longHandLogical.add("scroll-timeline-axis");
1899
+ longHandLogical.add("scroll-timeline-name");
1900
+ longHandLogical.add("timeline-scope");
1901
+ shorthandsOfLonghands.add("view-timeline");
1902
+ longHandLogical.add("view-timeline-axis");
1903
+ longHandLogical.add("view-timeline-inset");
1904
+ longHandLogical.add("view-timeline-name");
1905
+ shorthandsOfShorthands.add("background");
1906
+ longHandLogical.add("background-attachment");
1907
+ longHandLogical.add("background-clip");
1908
+ longHandLogical.add("background-color");
1909
+ longHandLogical.add("background-image");
1910
+ longHandLogical.add("background-origin");
1911
+ longHandLogical.add("background-repeat");
1912
+ longHandLogical.add("background-size");
1913
+ shorthandsOfLonghands.add("background-position");
1914
+ longHandLogical.add("background-position-x");
1915
+ longHandLogical.add("background-position-y");
1916
+ shorthandsOfShorthands.add("border");
1917
+ shorthandsOfLonghands.add("border-color");
1918
+ shorthandsOfLonghands.add("border-style");
1919
+ shorthandsOfLonghands.add("border-width");
1920
+ shorthandsOfShorthands.add("border-block");
1921
+ longHandLogical.add("border-block-color");
1922
+ longHandLogical.add("border-block-stylex");
1923
+ longHandLogical.add("border-block-width");
1924
+ shorthandsOfLonghands.add("border-block-start");
1925
+ shorthandsOfLonghands.add("border-top");
1926
+ longHandLogical.add("border-block-start-color");
1927
+ longHandPhysical.add("border-top-color");
1928
+ longHandLogical.add("border-block-start-style");
1929
+ longHandPhysical.add("border-top-style");
1930
+ longHandLogical.add("border-block-start-width");
1931
+ longHandPhysical.add("border-top-width");
1932
+ shorthandsOfLonghands.add("border-block-end");
1933
+ shorthandsOfLonghands.add("border-bottom");
1934
+ longHandLogical.add("border-block-end-color");
1935
+ longHandPhysical.add("border-bottom-color");
1936
+ longHandLogical.add("border-block-end-style");
1937
+ longHandPhysical.add("border-bottom-style");
1938
+ longHandLogical.add("border-block-end-width");
1939
+ longHandPhysical.add("border-bottom-width");
1940
+ shorthandsOfShorthands.add("border-inline");
1941
+ shorthandsOfLonghands.add("border-inline-color");
1942
+ shorthandsOfLonghands.add("border-inline-style");
1943
+ shorthandsOfLonghands.add("border-inline-width");
1944
+ shorthandsOfLonghands.add("border-inline-start");
1945
+ shorthandsOfLonghands.add("border-left");
1946
+ longHandLogical.add("border-inline-start-color");
1947
+ longHandPhysical.add("border-left-color");
1948
+ longHandLogical.add("border-inline-start-style");
1949
+ longHandPhysical.add("border-left-style");
1950
+ longHandLogical.add("border-inline-start-width");
1951
+ longHandPhysical.add("border-left-width");
1952
+ shorthandsOfLonghands.add("border-inline-end");
1953
+ shorthandsOfLonghands.add("border-right");
1954
+ longHandLogical.add("border-inline-end-color");
1955
+ longHandPhysical.add("border-right-color");
1956
+ longHandLogical.add("border-inline-end-style");
1957
+ longHandPhysical.add("border-right-style");
1958
+ longHandLogical.add("border-inline-end-width");
1959
+ longHandPhysical.add("border-right-width");
1960
+ shorthandsOfLonghands.add("border-image");
1961
+ longHandLogical.add("border-image-outset");
1962
+ longHandLogical.add("border-image-repeat");
1963
+ longHandLogical.add("border-image-slice");
1964
+ longHandLogical.add("border-image-source");
1965
+ longHandLogical.add("border-image-width");
1966
+ shorthandsOfLonghands.add("border-radius");
1967
+ longHandLogical.add("border-start-end-radius");
1968
+ longHandLogical.add("border-start-start-radius");
1969
+ longHandLogical.add("border-end-end-radius");
1970
+ longHandLogical.add("border-end-start-radius");
1971
+ longHandPhysical.add("border-top-left-radius");
1972
+ longHandPhysical.add("border-top-right-radius");
1973
+ longHandPhysical.add("border-bottom-left-radius");
1974
+ longHandPhysical.add("border-bottom-right-radius");
1975
+ shorthandsOfLonghands.add("corner-shape");
1976
+ longHandLogical.add("corner-start-start-shape");
1977
+ longHandLogical.add("corner-start-end-shape");
1978
+ longHandLogical.add("corner-end-start-shape");
1979
+ longHandLogical.add("corner-end-end-shape");
1980
+ longHandPhysical.add("corner-top-left-shape");
1981
+ longHandPhysical.add("corner-top-right-shape");
1982
+ longHandPhysical.add("corner-bottom-left-shape");
1983
+ longHandPhysical.add("corner-bottom-right-shape");
1984
+ longHandLogical.add("box-shadow");
1985
+ longHandLogical.add("accent-color");
1986
+ longHandLogical.add("appearance");
1987
+ longHandLogical.add("aspect-ratio");
1988
+ shorthandsOfLonghands.add("caret");
1989
+ longHandLogical.add("caret-color");
1990
+ longHandLogical.add("caret-shape");
1991
+ longHandLogical.add("cursor");
1992
+ longHandLogical.add("ime-mode");
1993
+ longHandLogical.add("input-security");
1994
+ shorthandsOfLonghands.add("outline");
1995
+ longHandLogical.add("outline-color");
1996
+ longHandLogical.add("outline-offset");
1997
+ longHandLogical.add("outline-style");
1998
+ longHandLogical.add("outline-width");
1999
+ longHandLogical.add("pointer-events");
2000
+ longHandLogical.add("resize");
2001
+ longHandLogical.add("text-overflow");
2002
+ longHandLogical.add("user-select");
2003
+ shorthandsOfLonghands.add("grid-gap");
2004
+ shorthandsOfLonghands.add("gap");
2005
+ longHandLogical.add("grid-row-gap");
2006
+ longHandLogical.add("row-gap");
2007
+ longHandLogical.add("grid-column-gap");
2008
+ longHandLogical.add("column-gap");
2009
+ shorthandsOfLonghands.add("place-content");
2010
+ longHandLogical.add("align-content");
2011
+ longHandLogical.add("justify-content");
2012
+ shorthandsOfLonghands.add("place-items");
2013
+ longHandLogical.add("align-items");
2014
+ longHandLogical.add("justify-items");
2015
+ shorthandsOfLonghands.add("place-self");
2016
+ longHandLogical.add("align-self");
2017
+ longHandLogical.add("justify-self");
2018
+ longHandLogical.add("box-sizing");
2019
+ longHandLogical.add("block-size");
2020
+ longHandPhysical.add("height");
2021
+ longHandLogical.add("inline-size");
2022
+ longHandPhysical.add("width");
2023
+ longHandLogical.add("max-block-size");
2024
+ longHandPhysical.add("max-height");
2025
+ longHandLogical.add("max-inline-size");
2026
+ longHandPhysical.add("max-width");
2027
+ longHandLogical.add("min-block-size");
2028
+ longHandPhysical.add("min-height");
2029
+ longHandLogical.add("min-inline-size");
2030
+ longHandPhysical.add("min-width");
2031
+ shorthandsOfShorthands.add("margin");
2032
+ shorthandsOfLonghands.add("margin-block");
2033
+ longHandLogical.add("margin-block-start");
2034
+ longHandPhysical.add("margin-top");
2035
+ longHandLogical.add("margin-block-end");
2036
+ longHandPhysical.add("margin-bottom");
2037
+ shorthandsOfLonghands.add("margin-inline");
2038
+ longHandLogical.add("margin-inline-start");
2039
+ longHandPhysical.add("margin-left");
2040
+ longHandLogical.add("margin-inline-end");
2041
+ longHandPhysical.add("margin-right");
2042
+ longHandLogical.add("margin-trim");
2043
+ shorthandsOfLonghands.add("overscroll-behavior");
2044
+ longHandLogical.add("overscroll-behavior-block");
2045
+ longHandPhysical.add("overscroll-behavior-y");
2046
+ longHandLogical.add("overscroll-behavior-inline");
2047
+ longHandPhysical.add("overscroll-behavior-x");
2048
+ shorthandsOfShorthands.add("padding");
2049
+ shorthandsOfLonghands.add("padding-block");
2050
+ longHandLogical.add("padding-block-start");
2051
+ longHandPhysical.add("padding-top");
2052
+ longHandLogical.add("padding-block-end");
2053
+ longHandPhysical.add("padding-bottom");
2054
+ shorthandsOfLonghands.add("padding-inline");
2055
+ longHandLogical.add("padding-inline-start");
2056
+ longHandPhysical.add("padding-left");
2057
+ longHandLogical.add("padding-inline-end");
2058
+ longHandPhysical.add("padding-right");
2059
+ longHandLogical.add("visibility");
2060
+ longHandLogical.add("color");
2061
+ longHandLogical.add("color-scheme");
2062
+ longHandLogical.add("forced-color-adjust");
2063
+ longHandLogical.add("opacity");
2064
+ longHandLogical.add("print-color-adjust");
2065
+ shorthandsOfLonghands.add("columns");
2066
+ longHandLogical.add("column-count");
2067
+ longHandLogical.add("column-width");
2068
+ longHandLogical.add("column-fill");
2069
+ longHandLogical.add("column-span");
2070
+ shorthandsOfLonghands.add("column-rule");
2071
+ longHandLogical.add("column-rule-color");
2072
+ longHandLogical.add("column-rule-style");
2073
+ longHandLogical.add("column-rule-width");
2074
+ longHandLogical.add("contain");
2075
+ shorthandsOfLonghands.add("contain-intrinsic-size");
2076
+ longHandLogical.add("contain-intrinsic-block-size");
2077
+ longHandLogical.add("contain-intrinsic-width");
2078
+ longHandLogical.add("contain-intrinsic-height");
2079
+ longHandLogical.add("contain-intrinsic-inline-size");
2080
+ shorthandsOfLonghands.add("container");
2081
+ longHandLogical.add("container-name");
2082
+ longHandLogical.add("container-type");
2083
+ longHandLogical.add("content-visibility");
2084
+ longHandLogical.add("counter-increment");
2085
+ longHandLogical.add("counter-reset");
2086
+ longHandLogical.add("counter-set");
2087
+ longHandLogical.add("display");
2088
+ shorthandsOfLonghands.add("flex");
2089
+ longHandLogical.add("flex-basis");
2090
+ longHandLogical.add("flex-grow");
2091
+ longHandLogical.add("flex-shrink");
2092
+ shorthandsOfLonghands.add("flex-flow");
2093
+ longHandLogical.add("flex-direction");
2094
+ longHandLogical.add("flex-wrap");
2095
+ longHandLogical.add("order");
2096
+ shorthandsOfShorthands.add("font");
2097
+ longHandLogical.add("font-family");
2098
+ longHandLogical.add("font-size");
2099
+ longHandLogical.add("font-stretch");
2100
+ longHandLogical.add("font-style");
2101
+ longHandLogical.add("font-weight");
2102
+ longHandLogical.add("line-height");
2103
+ shorthandsOfLonghands.add("font-variant");
2104
+ longHandLogical.add("font-variant-alternates");
2105
+ longHandLogical.add("font-variant-caps");
2106
+ longHandLogical.add("font-variant-east-asian");
2107
+ longHandLogical.add("font-variant-emoji");
2108
+ longHandLogical.add("font-variant-ligatures");
2109
+ longHandLogical.add("font-variant-numeric");
2110
+ longHandLogical.add("font-variant-position");
2111
+ longHandLogical.add("font-feature-settings");
2112
+ longHandLogical.add("font-kerning");
2113
+ longHandLogical.add("font-language-override");
2114
+ longHandLogical.add("font-optical-sizing");
2115
+ longHandLogical.add("font-palette");
2116
+ longHandLogical.add("font-variation-settings");
2117
+ longHandLogical.add("font-size-adjust");
2118
+ longHandLogical.add("font-smooth");
2119
+ longHandLogical.add("font-synthesis-position");
2120
+ longHandLogical.add("font-synthesis-small-caps");
2121
+ longHandLogical.add("font-synthesis-style");
2122
+ longHandLogical.add("font-synthesis-weight");
2123
+ longHandLogical.add("line-height-step");
2124
+ longHandLogical.add("box-decoration-break");
2125
+ longHandLogical.add("break-after");
2126
+ longHandLogical.add("break-before");
2127
+ longHandLogical.add("break-inside");
2128
+ longHandLogical.add("orphans");
2129
+ longHandLogical.add("widows");
2130
+ longHandLogical.add("content");
2131
+ longHandLogical.add("quotes");
2132
+ shorthandsOfShorthands.add("grid");
2133
+ longHandLogical.add("grid-auto-flow");
2134
+ longHandLogical.add("grid-auto-rows");
2135
+ longHandLogical.add("grid-auto-columns");
2136
+ shorthandsOfShorthands.add("grid-template");
2137
+ shorthandsOfLonghands.add("grid-template-areas");
2138
+ longHandLogical.add("grid-template-columns");
2139
+ longHandLogical.add("grid-template-rows");
2140
+ shorthandsOfShorthands.add("grid-area");
2141
+ shorthandsOfLonghands.add("grid-row");
2142
+ longHandLogical.add("grid-row-start");
2143
+ longHandLogical.add("grid-row-end");
2144
+ shorthandsOfLonghands.add("grid-column");
2145
+ longHandLogical.add("grid-column-start");
2146
+ longHandLogical.add("grid-column-end");
2147
+ longHandLogical.add("align-tracks");
2148
+ longHandLogical.add("justify-tracks");
2149
+ longHandLogical.add("masonry-auto-flow");
2150
+ longHandLogical.add("image-orientation");
2151
+ longHandLogical.add("image-rendering");
2152
+ longHandLogical.add("image-resolution");
2153
+ longHandLogical.add("object-fit");
2154
+ longHandLogical.add("object-position");
2155
+ longHandLogical.add("initial-letter");
2156
+ longHandLogical.add("initial-letter-align");
2157
+ shorthandsOfLonghands.add("list-style");
2158
+ longHandLogical.add("list-style-image");
2159
+ longHandLogical.add("list-style-position");
2160
+ longHandLogical.add("list-style-type");
2161
+ longHandLogical.add("clip");
2162
+ longHandLogical.add("clip-path");
2163
+ shorthandsOfLonghands.add("mask");
2164
+ longHandLogical.add("mask-clip");
2165
+ longHandLogical.add("mask-composite");
2166
+ longHandLogical.add("mask-image");
2167
+ longHandLogical.add("mask-mode");
2168
+ longHandLogical.add("mask-origin");
2169
+ longHandLogical.add("mask-position");
2170
+ longHandLogical.add("mask-repeat");
2171
+ longHandLogical.add("mask-size");
2172
+ longHandLogical.add("mask-type");
2173
+ shorthandsOfLonghands.add("mask-border");
2174
+ longHandLogical.add("mask-border-mode");
2175
+ longHandLogical.add("mask-border-outset");
2176
+ longHandLogical.add("mask-border-repeat");
2177
+ longHandLogical.add("mask-border-slice");
2178
+ longHandLogical.add("mask-border-source");
2179
+ longHandLogical.add("mask-border-width");
2180
+ shorthandsOfShorthands.add("all");
2181
+ longHandLogical.add("text-rendering");
2182
+ shorthandsOfLonghands.add("offset");
2183
+ longHandLogical.add("offset-anchor");
2184
+ longHandLogical.add("offset-distance");
2185
+ longHandLogical.add("offset-path");
2186
+ longHandLogical.add("offset-position");
2187
+ longHandLogical.add("offset-rotate");
2188
+ longHandLogical.add("-webkit-box-orient");
2189
+ longHandLogical.add("-webkit-line-clamp");
2190
+ shorthandsOfLonghands.add("overflow");
2191
+ longHandLogical.add("overflow-block");
2192
+ longHandPhysical.add("overflow-y");
2193
+ longHandLogical.add("overflow-inline");
2194
+ longHandPhysical.add("overflow-x");
2195
+ longHandLogical.add("overflow-clip-margin");
2196
+ longHandLogical.add("scroll-gutter");
2197
+ longHandLogical.add("scroll-behavior");
2198
+ longHandLogical.add("page");
2199
+ longHandLogical.add("page-break-after");
2200
+ longHandLogical.add("page-break-before");
2201
+ longHandLogical.add("page-break-inside");
2202
+ shorthandsOfShorthands.add("inset");
2203
+ shorthandsOfLonghands.add("inset-block");
2204
+ longHandLogical.add("inset-block-start");
2205
+ longHandPhysical.add("top");
2206
+ longHandLogical.add("inset-block-end");
2207
+ longHandPhysical.add("bottom");
2208
+ shorthandsOfLonghands.add("inset-inline");
2209
+ longHandLogical.add("inset-inline-start");
2210
+ longHandPhysical.add("left");
2211
+ longHandLogical.add("inset-inline-end");
2212
+ longHandPhysical.add("right");
2213
+ longHandLogical.add("clear");
2214
+ longHandLogical.add("float");
2215
+ longHandLogical.add("position");
2216
+ longHandLogical.add("z-index");
2217
+ longHandLogical.add("ruby-align");
2218
+ longHandLogical.add("ruby-merge");
2219
+ longHandLogical.add("ruby-position");
2220
+ longHandLogical.add("overflow-anchor");
2221
+ shorthandsOfShorthands.add("scroll-margin");
2222
+ shorthandsOfLonghands.add("scroll-margin-block");
2223
+ longHandLogical.add("scroll-margin-block-start");
2224
+ longHandPhysical.add("scroll-margin-top");
2225
+ longHandLogical.add("scroll-margin-block-end");
2226
+ longHandPhysical.add("scroll-margin-bottom");
2227
+ shorthandsOfLonghands.add("scroll-margin-inline");
2228
+ longHandLogical.add("scroll-margin-inline-start");
2229
+ longHandPhysical.add("scroll-margin-left");
2230
+ longHandLogical.add("scroll-margin-inline-end");
2231
+ longHandPhysical.add("scroll-margin-right");
2232
+ shorthandsOfShorthands.add("scroll-padding");
2233
+ shorthandsOfLonghands.add("scroll-padding-block");
2234
+ longHandLogical.add("scroll-padding-block-start");
2235
+ longHandPhysical.add("scroll-padding-top");
2236
+ longHandLogical.add("scroll-padding-block-end");
2237
+ longHandPhysical.add("scroll-padding-bottom");
2238
+ shorthandsOfLonghands.add("scroll-padding-inline");
2239
+ longHandLogical.add("scroll-padding-inline-start");
2240
+ longHandPhysical.add("scroll-padding-left");
2241
+ longHandLogical.add("scroll-padding-inline-end");
2242
+ longHandPhysical.add("scroll-padding-right");
2243
+ longHandLogical.add("scroll-snap-align");
2244
+ longHandLogical.add("scroll-snap-stop");
2245
+ shorthandsOfLonghands.add("scroll-snap-type");
2246
+ longHandLogical.add("scrollbar-color");
2247
+ longHandLogical.add("scrollbar-width");
2248
+ longHandLogical.add("shape-image-threshold");
2249
+ longHandLogical.add("shape-margin");
2250
+ longHandLogical.add("shape-outside");
2251
+ longHandLogical.add("azimuth");
2252
+ longHandLogical.add("border-collapse");
2253
+ longHandLogical.add("border-spacing");
2254
+ longHandLogical.add("caption-side");
2255
+ longHandLogical.add("empty-cells");
2256
+ longHandLogical.add("table-layout");
2257
+ longHandLogical.add("vertical-align");
2258
+ shorthandsOfLonghands.add("text-decoration");
2259
+ longHandLogical.add("text-decoration-color");
2260
+ longHandLogical.add("text-decoration-line");
2261
+ longHandLogical.add("text-decoration-skip");
2262
+ longHandLogical.add("text-decoration-skip-ink");
2263
+ longHandLogical.add("text-decoration-style");
2264
+ longHandLogical.add("text-decoration-thickness");
2265
+ shorthandsOfLonghands.add("text-emphasis");
2266
+ longHandLogical.add("text-emphasis-color");
2267
+ longHandLogical.add("text-emphasis-position");
2268
+ longHandLogical.add("text-emphasis-style");
2269
+ longHandLogical.add("text-shadow");
2270
+ longHandLogical.add("text-underline-offset");
2271
+ longHandLogical.add("text-underline-position");
2272
+ longHandLogical.add("hanging-punctuation");
2273
+ longHandLogical.add("hyphenate-character");
2274
+ longHandLogical.add("hyphenate-limit-chars");
2275
+ longHandLogical.add("hyphens");
2276
+ longHandLogical.add("letter-spacing");
2277
+ longHandLogical.add("line-break");
2278
+ longHandLogical.add("overflow-wrap");
2279
+ longHandLogical.add("paint-order");
2280
+ longHandLogical.add("tab-size");
2281
+ longHandLogical.add("text-align");
2282
+ longHandLogical.add("text-align-last");
2283
+ longHandLogical.add("text-indent");
2284
+ longHandLogical.add("text-justify");
2285
+ longHandLogical.add("text-size-adjust");
2286
+ longHandLogical.add("text-transform");
2287
+ longHandLogical.add("text-wrap");
2288
+ longHandLogical.add("white-space");
2289
+ longHandLogical.add("white-space-collapse");
2290
+ longHandLogical.add("word-break");
2291
+ longHandLogical.add("word-spacing");
2292
+ longHandLogical.add("word-wrap");
2293
+ longHandLogical.add("backface-visibility");
2294
+ longHandLogical.add("perspective");
2295
+ longHandLogical.add("perspective-origin");
2296
+ longHandLogical.add("rotate");
2297
+ longHandLogical.add("scale");
2298
+ longHandLogical.add("transform");
2299
+ longHandLogical.add("transform-box");
2300
+ longHandLogical.add("transform-origin");
2301
+ longHandLogical.add("transform-style");
2302
+ longHandLogical.add("translate");
2303
+ shorthandsOfLonghands.add("transition");
2304
+ longHandLogical.add("transition-delay");
2305
+ longHandLogical.add("transition-duration");
2306
+ longHandLogical.add("transition-property");
2307
+ longHandLogical.add("transition-timing-function");
2308
+ longHandLogical.add("view-transition-name");
2309
+ longHandLogical.add("will-change");
2310
+ longHandLogical.add("direction");
2311
+ longHandLogical.add("text-combine-upright");
2312
+ longHandLogical.add("text-orientation");
2313
+ longHandLogical.add("unicode-bidi");
2314
+ longHandLogical.add("writing-mode");
2315
+ longHandLogical.add("backdrop-filter");
2316
+ longHandLogical.add("filter");
2317
+ longHandLogical.add("math-depth");
2318
+ longHandLogical.add("math-shift");
2319
+ longHandLogical.add("math-style");
2320
+ longHandLogical.add("touch-action");
2321
+ var PSEUDO_CLASS_PRIORITIES = {
2322
+ ":is": 40,
2323
+ ":where": 40,
2324
+ ":not": 40,
2325
+ ":has": 45,
2326
+ ":dir": 50,
2327
+ ":lang": 51,
2328
+ ":first-child": 52,
2329
+ ":first-of-type": 53,
2330
+ ":last-child": 54,
2331
+ ":last-of-type": 55,
2332
+ ":only-child": 56,
2333
+ ":only-of-type": 57,
2334
+ ":nth-child": 60,
2335
+ ":nth-last-child": 61,
2336
+ ":nth-of-type": 62,
2337
+ ":nth-last-of-type": 63,
2338
+ ":empty": 70,
2339
+ ":link": 80,
2340
+ ":any-link": 81,
2341
+ ":local-link": 82,
2342
+ ":target-within": 83,
2343
+ ":target": 84,
2344
+ ":visited": 85,
2345
+ ":enabled": 91,
2346
+ ":disabled": 92,
2347
+ ":required": 93,
2348
+ ":optional": 94,
2349
+ ":read-only": 95,
2350
+ ":read-write": 96,
2351
+ ":placeholder-shown": 97,
2352
+ ":in-range": 98,
2353
+ ":out-of-range": 99,
2354
+ ":default": 100,
2355
+ ":checked": 101,
2356
+ ":indeterminate": 101,
2357
+ ":blank": 102,
2358
+ ":valid": 103,
2359
+ ":invalid": 104,
2360
+ ":user-invalid": 105,
2361
+ ":autofill": 110,
2362
+ ":picture-in-picture": 120,
2363
+ ":modal": 121,
2364
+ ":fullscreen": 122,
2365
+ ":paused": 123,
2366
+ ":playing": 124,
2367
+ ":current": 125,
2368
+ ":past": 126,
2369
+ ":future": 127,
2370
+ ":hover": 130,
2371
+ ":focus-within": 140,
2372
+ ":focus": 150,
2373
+ ":focus-visible": 160,
2374
+ ":active": 170
2375
+ };
2376
+ var AT_RULE_PRIORITIES = {
2377
+ "@supports": 30,
2378
+ "@media": 200,
2379
+ "@container": 300
2380
+ };
2381
+ var PSEUDO_ELEMENT_PRIORITY = 5e3;
2382
+ function getPropertyPriority(property) {
2383
+ if (shorthandsOfShorthands.has(property)) return 1e3;
2384
+ if (shorthandsOfLonghands.has(property)) return 2e3;
2385
+ if (longHandLogical.has(property)) return 3e3;
2386
+ if (longHandPhysical.has(property)) return 4e3;
2387
+ return 3e3;
2388
+ }
2389
+ function getPseudoClassPriority(pseudo) {
2390
+ const leadingPseudo = pseudo.trim().match(/^::?[a-zA-Z-]+/)?.[0] ?? pseudo.split("(")[0];
2391
+ const base = leadingPseudo.replace(/[A-Z]/g, (match) => {
2392
+ return `-${match.toLowerCase()}`;
2393
+ });
2394
+ return PSEUDO_CLASS_PRIORITIES[base] ?? 40;
2395
+ }
2396
+ function getAtRulePriority(atRule) {
2397
+ if (atRule.startsWith("--")) return 1;
2398
+ if (atRule.startsWith("@supports")) return AT_RULE_PRIORITIES["@supports"];
2399
+ if (atRule.startsWith("@media")) return AT_RULE_PRIORITIES["@media"];
2400
+ if (atRule.startsWith("@container")) return AT_RULE_PRIORITIES["@container"];
2401
+ return 0;
2402
+ }
2403
+
2404
+ // src/plugin/priority.ts
2405
+ function computeRulePriority(rule) {
2406
+ let priority = getPropertyPriority(rule.declarations[0].cssProperty);
2407
+ if (rule.pseudoElement) {
2408
+ priority += PSEUDO_ELEMENT_PRIORITY;
2409
+ }
2410
+ if (rule.pseudoClass) {
2411
+ priority += getPseudoClassPriority(rule.pseudoClass);
2412
+ }
2413
+ if (rule.mediaQuery) {
2414
+ priority += getAtRulePriority(rule.mediaQuery);
2415
+ }
2416
+ if (rule.whenSelector) {
2417
+ const relBase = WHEN_RELATIONSHIPS[rule.whenSelector.relationship].priority;
2418
+ const pseudoFraction = getPseudoClassPriority(rule.whenSelector.pseudo) / 100;
2419
+ priority += relBase + pseudoFraction;
2420
+ }
2421
+ if (isVariableRule(rule)) {
2422
+ priority += 0.5;
2355
2423
  }
2356
- seen.set(abbr, prop);
2424
+ return priority;
2357
2425
  }
2358
-
2359
- // src/plugin/emit-truss.ts
2360
- var DEFAULT_MARKER_CLASS = "_mrk";
2361
- function markerClassName(markerNode) {
2362
- if (!markerNode) return DEFAULT_MARKER_CLASS;
2363
- if (t4.isIdentifier(markerNode)) return `_${markerNode.name}_mrk`;
2364
- return "_marker_mrk";
2426
+ function isVariableRule(rule) {
2427
+ return rule.declarations.some((d) => d.cssVarName !== void 0);
2428
+ }
2429
+ function sortRulesByPriority(rules) {
2430
+ const decorated = Array.from(rules, (rule) => {
2431
+ return { rule, priority: computeRulePriority(rule) };
2432
+ });
2433
+ decorated.sort((a, b) => {
2434
+ return a.priority - b.priority || compareClassNames(a.rule.className, b.rule.className);
2435
+ });
2436
+ return decorated;
2365
2437
  }
2438
+ function compareClassNames(a, b) {
2439
+ return a < b ? -1 : a > b ? 1 : 0;
2440
+ }
2441
+
2442
+ // src/plugin/emit-css.ts
2366
2443
  function collectAtomicRules(chains, mapping) {
2367
2444
  const rules = /* @__PURE__ */ new Map();
2368
2445
  let needsMaybeInc = false;
2369
2446
  let needsMaybeCssVar = false;
2370
2447
  function collectSegment(seg) {
2371
- if (seg.typographyLookup) {
2372
- for (const segments of Object.values(seg.typographyLookup.segmentsByName)) {
2448
+ if (seg.kind === "typography") {
2449
+ for (const segments of Object.values(seg.segmentsByName)) {
2373
2450
  segments.forEach(collectSegment);
2374
2451
  }
2375
2452
  return;
2376
2453
  }
2377
- if (!isStyleSegment(seg)) return;
2378
- if (seg.incremented) needsMaybeInc = true;
2379
- if (seg.variableProps && seg.argResolved === void 0 && variableValueNeedsMaybeCssVar(seg)) {
2380
- needsMaybeCssVar = true;
2454
+ if (!isCssSegment(seg)) return;
2455
+ if (seg.kind === "variable") {
2456
+ if (seg.incremented) needsMaybeInc = true;
2457
+ if (seg.argResolved === void 0 && variableValueNeedsMaybeCssVar(seg)) needsMaybeCssVar = true;
2381
2458
  }
2382
2459
  collectSegmentRules(rules, seg, mapping);
2383
2460
  }
@@ -2387,6 +2464,7 @@ function collectAtomicRules(chains, mapping) {
2387
2464
  return { rules, needsMaybeInc, needsMaybeCssVar };
2388
2465
  }
2389
2466
  function collectSegmentRules(rules, seg, mapping) {
2467
+ const { condition } = seg;
2390
2468
  for (const entry of styleEntriesForSegment(seg, mapping)) {
2391
2469
  const declaration = {
2392
2470
  cssProperty: camelToKebab(entry.cssProp),
@@ -2398,10 +2476,10 @@ function collectSegmentRules(rules, seg, mapping) {
2398
2476
  rules.set(entry.className, {
2399
2477
  className: entry.className,
2400
2478
  declarations: [declaration],
2401
- pseudoClass: seg.pseudoClass ?? void 0,
2402
- mediaQuery: seg.mediaQuery ?? void 0,
2403
- pseudoElement: seg.pseudoElement ?? void 0,
2404
- whenSelector: seg.whenPseudo ? whenSelectorFor(seg.whenPseudo) : void 0
2479
+ pseudoClass: condition.pseudoClass ?? void 0,
2480
+ mediaQuery: condition.mediaQuery ?? void 0,
2481
+ pseudoElement: condition.pseudoElement ?? void 0,
2482
+ whenSelector: condition.whenPseudo ? whenSelectorFor(condition.whenPseudo) : void 0
2405
2483
  });
2406
2484
  continue;
2407
2485
  }
@@ -2420,92 +2498,6 @@ function whenSelectorFor(whenPseudo) {
2420
2498
  pseudo: whenPseudo.pseudo
2421
2499
  };
2422
2500
  }
2423
- function styleEntriesForSegment(seg, mapping) {
2424
- const prefix = segmentClassPrefix(seg, mapping);
2425
- const isConditional = prefix !== "";
2426
- if (seg.variableProps) {
2427
- return variableStyleEntries(seg, mapping, prefix, isConditional);
2428
- }
2429
- return staticStyleEntries(seg, mapping, prefix, isConditional, seg.defs);
2430
- }
2431
- function staticStyleEntries(seg, mapping, prefix, isConditional, defs, forceLonghandNames = false) {
2432
- const isMultiProp = forceLonghandNames || Object.keys(defs).length > 1;
2433
- return Object.entries(defs).map(([cssProp, value]) => {
2434
- const cssValue = String(value);
2435
- const baseName = computeStaticBaseName(seg, cssProp, cssValue, isMultiProp, mapping);
2436
- return { cssProp, className: `${prefix}${baseName}`, isVariable: false, isConditional, cssValue };
2437
- });
2438
- }
2439
- function variableStyleEntries(seg, mapping, prefix, isConditional) {
2440
- const className = `${prefix}${seg.abbr}_var`;
2441
- const entries = (seg.variableProps ?? []).map((cssProp) => {
2442
- const varName = `--${prefix}${cssProp}`;
2443
- return {
2444
- cssProp,
2445
- className,
2446
- isVariable: true,
2447
- isConditional,
2448
- cssValue: `var(${varName})`,
2449
- varName,
2450
- argNode: seg.argNode,
2451
- argResolved: seg.argResolved,
2452
- incremented: seg.incremented,
2453
- appendPx: seg.appendPx
2454
- };
2455
- });
2456
- if (seg.variableExtraDefs) {
2457
- entries.push(...staticStyleEntries(seg, mapping, prefix, isConditional, seg.variableExtraDefs, true));
2458
- }
2459
- return entries;
2460
- }
2461
- function computeStaticBaseName(seg, cssProp, cssValue, isMultiProp, mapping) {
2462
- if (isMultiProp) {
2463
- const canonical = findCanonicalAbbreviation(mapping, cssProp, cssValue);
2464
- return canonical ?? `${getPropertyAbbreviation(cssProp)}_${classNameFragmentForResolvedValue(cssValue)}`;
2465
- }
2466
- if (seg.argResolved !== void 0) {
2467
- return `${seg.abbr}_${classNameFragmentForResolvedValue(seg.argResolved)}`;
2468
- }
2469
- return seg.abbr;
2470
- }
2471
- function segmentClassPrefix(seg, mapping) {
2472
- const parts = [];
2473
- if (seg.pseudoElement) {
2474
- parts.push(`${seg.pseudoElement.replace(/^::/, "")}_`);
2475
- }
2476
- if (seg.mediaQuery) {
2477
- const breakpoint = breakpointNameForMediaQuery(mapping, seg.mediaQuery);
2478
- parts.push(breakpoint ? `${breakpoint.toLowerCase()}_` : "mq_");
2479
- }
2480
- if (seg.pseudoClass) {
2481
- parts.push(`${pseudoSelectorPrefix(seg.pseudoClass)}_`);
2482
- }
2483
- if (seg.whenPseudo) {
2484
- parts.push(whenPrefix(seg.whenPseudo));
2485
- }
2486
- return parts.join("");
2487
- }
2488
- function whenPrefix(whenPseudo) {
2489
- const rel = WHEN_RELATIONSHIPS[whenPseudo.relationship].short;
2490
- const pseudoPrefix = pseudoSelectorPrefix(whenPseudo.pseudo);
2491
- const markerPart = whenPseudo.markerNode ? `${whenPseudo.markerNode.name}_` : "";
2492
- return `wh_${rel}_${pseudoPrefix}_${markerPart}`;
2493
- }
2494
- function camelToKebab(s) {
2495
- return s.replace(/^(Webkit|Moz|Ms|O)/, (m) => `-${m.toLowerCase()}`).replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
2496
- }
2497
- function sanitizeClassNameToken(value) {
2498
- return value.replace(/[^a-zA-Z0-9]/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "");
2499
- }
2500
- function cleanValueForClassName(value) {
2501
- return sanitizeClassNameToken(value.startsWith("-") ? `neg${value.slice(1)}` : value);
2502
- }
2503
- function classNameFragmentForResolvedValue(value) {
2504
- return cleanValueForClassName(tryParseIncrementCalcMultiplier(value) ?? value);
2505
- }
2506
- function getPropertyAbbreviation(cssProp) {
2507
- return cssPropertyAbbreviations[cssProp] ?? cssProp;
2508
- }
2509
2501
  function generateCssText(rules) {
2510
2502
  const sorted = sortRulesByPriority(rules.values());
2511
2503
  const lines = [];
@@ -2538,95 +2530,12 @@ function buildTargetSelector(rule, duplicateClassName, extraPseudoClass = "") {
2538
2530
  const classSelector = duplicateClassName ? `.${rule.className}.${rule.className}` : `.${rule.className}`;
2539
2531
  return `${classSelector}${rule.pseudoClass ?? ""}${extraPseudoClass}${rule.pseudoElement ?? ""}`;
2540
2532
  }
2541
- function buildStyleHashProperties(segments, mapping, maybeIncHelperName, maybeCssVarHelperName) {
2542
- const propGroups = /* @__PURE__ */ new Map();
2543
- function pushEntry(entry) {
2544
- const entries = propGroups.get(entry.cssProp) ?? [];
2545
- const kept = entry.isConditional ? entries : entries.filter((existing) => existing.isConditional);
2546
- propGroups.set(entry.cssProp, [...kept, entry]);
2547
- }
2548
- for (const seg of segments) {
2549
- if (!isStyleSegment(seg)) continue;
2550
- for (const entry of styleEntriesForSegment(seg, mapping)) {
2551
- pushEntry(entry);
2552
- }
2553
- }
2554
- const properties = [];
2555
- for (const [cssProp, entries] of propGroups) {
2556
- const classNames = entries.map((e) => e.className).join(" ");
2557
- const variableEntries = entries.filter((e) => e.isVariable);
2558
- if (variableEntries.length === 0) {
2559
- properties.push(t4.objectProperty(toPropertyKey(cssProp), t4.stringLiteral(classNames)));
2560
- continue;
2561
- }
2562
- const varsProps = variableEntries.map((dyn) => {
2563
- return t4.objectProperty(
2564
- t4.stringLiteral(dyn.varName),
2565
- variableValueExpression(dyn, maybeIncHelperName, maybeCssVarHelperName)
2566
- );
2567
- });
2568
- const tuple = t4.arrayExpression([t4.stringLiteral(classNames), t4.objectExpression(varsProps)]);
2569
- properties.push(t4.objectProperty(toPropertyKey(cssProp), tuple));
2570
- }
2571
- return properties;
2572
- }
2573
- function variableValueExpression(dyn, maybeIncHelperName, maybeCssVarHelperName) {
2574
- if (dyn.argResolved !== void 0) {
2575
- return t4.stringLiteral(dyn.argResolved);
2576
- }
2577
- let valueExpr = dyn.argNode;
2578
- if (dyn.incremented) {
2579
- valueExpr = t4.callExpression(t4.identifier(maybeIncHelperName ?? "__maybeInc"), [valueExpr]);
2580
- } else if (dyn.appendPx) {
2581
- valueExpr = t4.templateLiteral(
2582
- [t4.templateElement({ raw: "", cooked: "" }, false), t4.templateElement({ raw: "px", cooked: "px" }, true)],
2583
- [valueExpr]
2584
- );
2585
- }
2586
- if (maybeCssVarHelperName && variableValueNeedsMaybeCssVar(dyn)) {
2587
- valueExpr = t4.callExpression(t4.identifier(maybeCssVarHelperName), [valueExpr]);
2588
- }
2589
- return valueExpr;
2590
- }
2591
- function buildMaybeIncDeclaration(helperName) {
2592
- const incParam = t4.identifier("inc");
2593
- const calcPrefix = `calc(var(${SPACING_CUSTOM_PROPERTY}) * `;
2594
- const body = t4.blockStatement([
2595
- t4.returnStatement(
2596
- t4.conditionalExpression(
2597
- t4.binaryExpression("===", t4.unaryExpression("typeof", incParam), t4.stringLiteral("string")),
2598
- incParam,
2599
- t4.templateLiteral(
2600
- [
2601
- t4.templateElement({ raw: calcPrefix, cooked: calcPrefix }, false),
2602
- t4.templateElement({ raw: ")", cooked: ")" }, true)
2603
- ],
2604
- [incParam]
2605
- )
2606
- )
2607
- )
2608
- ]);
2609
- return t4.variableDeclaration("const", [
2610
- t4.variableDeclarator(t4.identifier(helperName), t4.arrowFunctionExpression([incParam], body))
2611
- ]);
2612
- }
2613
- function buildRuntimeLookupDeclaration(lookupName, segmentsByName, mapping) {
2614
- const properties = Object.entries(segmentsByName).map(([name, segs]) => {
2615
- return t4.objectProperty(t4.identifier(name), t4.objectExpression(buildStyleHashProperties(segs, mapping)));
2616
- });
2617
- return t4.variableDeclaration("const", [
2618
- t4.variableDeclarator(t4.identifier(lookupName), t4.objectExpression(properties))
2619
- ]);
2620
- }
2621
- function toPropertyKey(key) {
2622
- return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key) ? t4.identifier(key) : t4.stringLiteral(key);
2623
- }
2624
2533
 
2625
2534
  // src/plugin/transform-css.ts
2626
- import * as t6 from "@babel/types";
2535
+ import * as t12 from "@babel/types";
2627
2536
 
2628
2537
  // src/plugin/css-ts-utils.ts
2629
- import * as t5 from "@babel/types";
2538
+ import * as t11 from "@babel/types";
2630
2539
  function collectStaticStringBindings(ast) {
2631
2540
  const bindings = /* @__PURE__ */ new Map();
2632
2541
  let changed = true;
@@ -2636,7 +2545,7 @@ function collectStaticStringBindings(ast) {
2636
2545
  const declaration = getTopLevelVariableDeclaration(node);
2637
2546
  if (!declaration) continue;
2638
2547
  for (const declarator of declaration.declarations) {
2639
- if (!t5.isIdentifier(declarator.id) || !declarator.init) continue;
2548
+ if (!t11.isIdentifier(declarator.id) || !declarator.init) continue;
2640
2549
  if (bindings.has(declarator.id.name)) continue;
2641
2550
  const value = resolveStaticString(declarator.init, bindings);
2642
2551
  if (value === null) continue;
@@ -2649,9 +2558,9 @@ function collectStaticStringBindings(ast) {
2649
2558
  }
2650
2559
  function resolveStaticString(node, bindings) {
2651
2560
  if (!node) return null;
2652
- if (t5.isExpression(node)) node = unwrapExpression(node);
2653
- if (t5.isStringLiteral(node)) return node.value;
2654
- if (t5.isTemplateLiteral(node)) {
2561
+ if (t11.isExpression(node)) node = unwrapExpression(node);
2562
+ if (t11.isStringLiteral(node)) return node.value;
2563
+ if (t11.isTemplateLiteral(node)) {
2655
2564
  let value = "";
2656
2565
  for (let i = 0; i < node.quasis.length; i++) {
2657
2566
  value += node.quasis[i].value.cooked ?? "";
@@ -2662,10 +2571,10 @@ function resolveStaticString(node, bindings) {
2662
2571
  }
2663
2572
  return value;
2664
2573
  }
2665
- if (t5.isIdentifier(node)) {
2574
+ if (t11.isIdentifier(node)) {
2666
2575
  return bindings.get(node.name) ?? null;
2667
2576
  }
2668
- if (t5.isBinaryExpression(node, { operator: "+" })) {
2577
+ if (t11.isBinaryExpression(node, { operator: "+" })) {
2669
2578
  const left = resolveStaticString(node.left, bindings);
2670
2579
  const right = resolveStaticString(node.right, bindings);
2671
2580
  if (left === null || right === null) return null;
@@ -2674,10 +2583,10 @@ function resolveStaticString(node, bindings) {
2674
2583
  return null;
2675
2584
  }
2676
2585
  function getTopLevelVariableDeclaration(node) {
2677
- if (t5.isVariableDeclaration(node)) {
2586
+ if (t11.isVariableDeclaration(node)) {
2678
2587
  return node;
2679
2588
  }
2680
- if (t5.isExportNamedDeclaration(node) && node.declaration && t5.isVariableDeclaration(node.declaration)) {
2589
+ if (t11.isExportNamedDeclaration(node) && node.declaration && t11.isVariableDeclaration(node.declaration)) {
2681
2590
  return node.declaration;
2682
2591
  }
2683
2592
  return null;
@@ -2695,11 +2604,11 @@ function transformCssTs(code, filename, mapping) {
2695
2604
  const rules = [];
2696
2605
  const stringBindings = collectStaticStringBindings(ast);
2697
2606
  for (const prop of cssExport.properties) {
2698
- if (t6.isSpreadElement(prop)) {
2607
+ if (t12.isSpreadElement(prop)) {
2699
2608
  rules.push(`/* [truss] unsupported: spread elements in css.ts export */`);
2700
2609
  continue;
2701
2610
  }
2702
- if (!t6.isObjectProperty(prop)) {
2611
+ if (!t12.isObjectProperty(prop)) {
2703
2612
  rules.push(`/* [truss] unsupported: non-property in css.ts export */`);
2704
2613
  continue;
2705
2614
  }
@@ -2714,7 +2623,7 @@ function transformCssTs(code, filename, mapping) {
2714
2623
  rules.push(formatRawCssRule(selector, rawCss));
2715
2624
  continue;
2716
2625
  }
2717
- if (!t6.isExpression(valueNode)) {
2626
+ if (!t12.isExpression(valueNode)) {
2718
2627
  rules.push(`/* [truss] unsupported: "${selector}" value is not an expression */`);
2719
2628
  continue;
2720
2629
  }
@@ -2733,28 +2642,28 @@ function transformCssTs(code, filename, mapping) {
2733
2642
  }
2734
2643
  function findNamedCssExportObject(ast) {
2735
2644
  for (const node of ast.program.body) {
2736
- if (!t6.isExportNamedDeclaration(node) || !node.declaration) continue;
2737
- if (!t6.isVariableDeclaration(node.declaration)) continue;
2645
+ if (!t12.isExportNamedDeclaration(node) || !node.declaration) continue;
2646
+ if (!t12.isVariableDeclaration(node.declaration)) continue;
2738
2647
  for (const declarator of node.declaration.declarations) {
2739
- if (!t6.isIdentifier(declarator.id, { name: "css" }) || !declarator.init) continue;
2648
+ if (!t12.isIdentifier(declarator.id, { name: "css" }) || !declarator.init) continue;
2740
2649
  const value = unwrapExpression(declarator.init);
2741
- if (t6.isObjectExpression(value)) return value;
2650
+ if (t12.isObjectExpression(value)) return value;
2742
2651
  }
2743
2652
  }
2744
2653
  return null;
2745
2654
  }
2746
2655
  function objectPropertyStringKey(prop, stringBindings) {
2747
- if (t6.isStringLiteral(prop.key)) return prop.key.value;
2748
- if (t6.isIdentifier(prop.key) && !prop.computed) return prop.key.name;
2656
+ if (t12.isStringLiteral(prop.key)) return prop.key.value;
2657
+ if (t12.isIdentifier(prop.key) && !prop.computed) return prop.key.name;
2749
2658
  if (prop.computed) return resolveStaticString(prop.key, stringBindings);
2750
2659
  return null;
2751
2660
  }
2752
2661
  function extractStaticStringValue(node, cssBindingName) {
2753
- if (t6.isStringLiteral(node)) return node.value;
2754
- if (t6.isTemplateLiteral(node) && node.expressions.length === 0 && node.quasis.length === 1) {
2662
+ if (t12.isStringLiteral(node)) return node.value;
2663
+ if (t12.isTemplateLiteral(node) && node.expressions.length === 0 && node.quasis.length === 1) {
2755
2664
  return node.quasis[0].value.cooked ?? node.quasis[0].value.raw;
2756
2665
  }
2757
- if (t6.isTaggedTemplateExpression(node) && t6.isMemberExpression(node.tag) && !node.tag.computed && t6.isIdentifier(node.tag.property, { name: "raw" }) && t6.isIdentifier(node.tag.object, { name: cssBindingName ?? "" }) && node.quasi.expressions.length === 0 && node.quasi.quasis.length === 1) {
2666
+ if (t12.isTaggedTemplateExpression(node) && t12.isMemberExpression(node.tag) && !node.tag.computed && t12.isIdentifier(node.tag.property, { name: "raw" }) && t12.isIdentifier(node.tag.object, { name: cssBindingName ?? "" }) && node.quasi.expressions.length === 0 && node.quasi.quasis.length === 1) {
2758
2667
  return node.quasi.quasis[0].value.cooked ?? node.quasi.quasis[0].value.raw;
2759
2668
  }
2760
2669
  return null;
@@ -2784,40 +2693,39 @@ function resolveCssExpression(node, cssBindingName, mapping, filename) {
2784
2693
  for (const part of resolved.parts) {
2785
2694
  if (part.type !== "unconditional") continue;
2786
2695
  for (const seg of part.segments) {
2787
- if (seg.error) {
2788
- return { error: seg.error };
2696
+ if (seg.kind === "error") {
2697
+ return { error: seg.message };
2789
2698
  }
2790
- if (seg.variableProps && !seg.argResolved) {
2699
+ if (seg.kind === "variable" && seg.argResolved === void 0) {
2791
2700
  return { error: `variable value with variable argument is not supported in .css.ts files` };
2792
2701
  }
2793
- if (seg.typographyLookup) {
2702
+ if (seg.kind === "typography") {
2794
2703
  return { error: `typography() with a runtime key is not supported in .css.ts files` };
2795
2704
  }
2796
- if (seg.styleArrayArg) {
2705
+ if (seg.kind === "composed") {
2797
2706
  return { error: `add(cssProp) is not supported in .css.ts files` };
2798
2707
  }
2799
- if (seg.styleArg) {
2708
+ if (seg.kind === "inlineStyle") {
2800
2709
  return { error: `style() is not supported in .css.ts files` };
2801
2710
  }
2802
- if (seg.mediaQuery) {
2711
+ if (seg.kind === "className") {
2712
+ return { error: `className() is not supported in .css.ts files` };
2713
+ }
2714
+ const { condition } = seg;
2715
+ if (condition.mediaQuery) {
2803
2716
  return { error: `media query modifiers (ifSm, ifMd, etc.) are not supported in .css.ts files` };
2804
2717
  }
2805
- if (seg.pseudoClass) {
2718
+ if (condition.pseudoClass) {
2806
2719
  return { error: `pseudo-class modifiers (onHover, onFocus, etc.) are not supported in .css.ts files` };
2807
2720
  }
2808
- if (seg.pseudoElement) {
2721
+ if (condition.pseudoElement) {
2809
2722
  return { error: `pseudo-element modifiers are not supported in .css.ts files` };
2810
2723
  }
2811
- if (seg.whenPseudo) {
2724
+ if (condition.whenPseudo) {
2812
2725
  return { error: `when() modifiers are not supported in .css.ts files` };
2813
2726
  }
2814
- if (seg.variableProps && seg.argResolved) {
2815
- for (const prop of seg.variableProps) {
2816
- declarations.push({ property: camelToKebab(prop), value: seg.argResolved });
2817
- }
2818
- continue;
2819
- }
2820
- for (const [prop, value] of Object.entries(seg.defs)) {
2727
+ const pairs = seg.kind === "variable" ? seg.props.map((prop) => [prop, seg.argResolved]) : Object.entries(seg.defs);
2728
+ for (const [prop, value] of pairs) {
2821
2729
  if (typeof value === "string" || typeof value === "number") {
2822
2730
  declarations.push({ property: camelToKebab(prop), value: String(value) });
2823
2731
  } else {
@@ -2847,11 +2755,100 @@ ${body}
2847
2755
  }
2848
2756
 
2849
2757
  // src/plugin/transform.ts
2850
- import * as t8 from "@babel/types";
2758
+ import * as t15 from "@babel/types";
2851
2759
  import { basename } from "path";
2852
2760
 
2761
+ // src/plugin/emit-style-hash.ts
2762
+ import * as t13 from "@babel/types";
2763
+ function buildStyleHashProperties(segments, mapping, maybeIncHelperName, maybeCssVarHelperName) {
2764
+ return styleHashProperties(collectStyleEntryGroups(segments, mapping), maybeIncHelperName, maybeCssVarHelperName);
2765
+ }
2766
+ function collectStyleEntryGroups(segments, mapping, seed) {
2767
+ const propGroups = /* @__PURE__ */ new Map();
2768
+ for (const seg of segments) {
2769
+ if (!isCssSegment(seg)) continue;
2770
+ for (const entry of styleEntriesForSegment(seg, mapping)) {
2771
+ const entries = propGroups.get(entry.cssProp) ?? seed?.get(entry.cssProp) ?? [];
2772
+ const kept = entry.isConditional ? entries : entries.filter((existing) => existing.isConditional);
2773
+ propGroups.set(entry.cssProp, [...kept, entry]);
2774
+ }
2775
+ }
2776
+ return propGroups;
2777
+ }
2778
+ function styleHashProperties(propGroups, maybeIncHelperName, maybeCssVarHelperName) {
2779
+ const properties = [];
2780
+ for (const [cssProp, entries] of propGroups) {
2781
+ const classNames = entries.map((e) => e.className).join(" ");
2782
+ const variableEntries = entries.filter((e) => e.isVariable);
2783
+ if (variableEntries.length === 0) {
2784
+ properties.push(t13.objectProperty(toPropertyKey(cssProp), t13.stringLiteral(classNames)));
2785
+ continue;
2786
+ }
2787
+ const varsProps = variableEntries.map((dyn) => {
2788
+ return t13.objectProperty(
2789
+ t13.stringLiteral(dyn.varName),
2790
+ variableValueExpression(dyn, maybeIncHelperName, maybeCssVarHelperName)
2791
+ );
2792
+ });
2793
+ const tuple = t13.arrayExpression([t13.stringLiteral(classNames), t13.objectExpression(varsProps)]);
2794
+ properties.push(t13.objectProperty(toPropertyKey(cssProp), tuple));
2795
+ }
2796
+ return properties;
2797
+ }
2798
+ function variableValueExpression(dyn, maybeIncHelperName, maybeCssVarHelperName) {
2799
+ if (dyn.argResolved !== void 0) {
2800
+ return t13.stringLiteral(dyn.argResolved);
2801
+ }
2802
+ let valueExpr = dyn.argNode;
2803
+ if (dyn.incremented) {
2804
+ valueExpr = t13.callExpression(t13.identifier(maybeIncHelperName ?? "__maybeInc"), [valueExpr]);
2805
+ } else if (dyn.appendPx) {
2806
+ valueExpr = t13.templateLiteral(
2807
+ [t13.templateElement({ raw: "", cooked: "" }, false), t13.templateElement({ raw: "px", cooked: "px" }, true)],
2808
+ [valueExpr]
2809
+ );
2810
+ }
2811
+ if (maybeCssVarHelperName && variableValueNeedsMaybeCssVar(dyn)) {
2812
+ valueExpr = t13.callExpression(t13.identifier(maybeCssVarHelperName), [valueExpr]);
2813
+ }
2814
+ return valueExpr;
2815
+ }
2816
+ function buildMaybeIncDeclaration(helperName) {
2817
+ const incParam = t13.identifier("inc");
2818
+ const calcPrefix = `calc(var(${SPACING_CUSTOM_PROPERTY}) * `;
2819
+ const body = t13.blockStatement([
2820
+ t13.returnStatement(
2821
+ t13.conditionalExpression(
2822
+ t13.binaryExpression("===", t13.unaryExpression("typeof", incParam), t13.stringLiteral("string")),
2823
+ incParam,
2824
+ t13.templateLiteral(
2825
+ [
2826
+ t13.templateElement({ raw: calcPrefix, cooked: calcPrefix }, false),
2827
+ t13.templateElement({ raw: ")", cooked: ")" }, true)
2828
+ ],
2829
+ [incParam]
2830
+ )
2831
+ )
2832
+ )
2833
+ ]);
2834
+ return t13.variableDeclaration("const", [
2835
+ t13.variableDeclarator(t13.identifier(helperName), t13.arrowFunctionExpression([incParam], body))
2836
+ ]);
2837
+ }
2838
+ function buildRuntimeLookupDeclaration(lookupName, segmentsByName, mapping) {
2839
+ const properties = Object.entries(segmentsByName).map(([name, segs]) => {
2840
+ return t13.objectProperty(t13.identifier(name), t13.objectExpression(buildStyleHashProperties(segs, mapping)));
2841
+ });
2842
+ return t13.variableDeclaration("const", [
2843
+ t13.variableDeclarator(t13.identifier(lookupName), t13.objectExpression(properties))
2844
+ ]);
2845
+ }
2846
+ function toPropertyKey(key) {
2847
+ return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key) ? t13.identifier(key) : t13.stringLiteral(key);
2848
+ }
2849
+
2853
2850
  // src/plugin/rewrite-sites.ts
2854
- import * as t7 from "@babel/types";
2851
+ import * as t14 from "@babel/types";
2855
2852
 
2856
2853
  // src/style-metadata.ts
2857
2854
  var TRUSS_MARKER_KEY = "__marker";
@@ -2867,7 +2864,7 @@ function rewriteExpressionSites(options) {
2867
2864
  if (cssAttrPath) {
2868
2865
  if (!options.debug && isFullyStaticStyleHash(styleHash) && !hasExistingAttribute(cssAttrPath, "className") && !hasExistingAttribute(cssAttrPath, "style")) {
2869
2866
  const classNames = extractStaticClassNames(styleHash);
2870
- cssAttrPath.replaceWith(t7.jsxAttribute(t7.jsxIdentifier("className"), t7.stringLiteral(classNames)));
2867
+ cssAttrPath.replaceWith(t14.jsxAttribute(t14.jsxIdentifier("className"), t14.stringLiteral(classNames)));
2871
2868
  } else {
2872
2869
  cssAttrPath.replaceWith(buildCssSpreadAttribute(cssAttrPath, styleHash, line, options));
2873
2870
  }
@@ -2883,249 +2880,185 @@ function getCssAttributePath(path) {
2883
2880
  if (!parentPath || !parentPath.isJSXExpressionContainer()) return null;
2884
2881
  const attrPath = parentPath.parentPath;
2885
2882
  if (!attrPath || !attrPath.isJSXAttribute()) return null;
2886
- if (!t7.isJSXIdentifier(attrPath.node.name, { name: "css" })) return null;
2883
+ if (!t14.isJSXIdentifier(attrPath.node.name, { name: "css" })) return null;
2887
2884
  return attrPath;
2888
2885
  }
2889
2886
  function buildStyleHashFromChain(chain, options) {
2890
2887
  const members = [];
2891
- const previousProperties = /* @__PURE__ */ new Map();
2888
+ const previousGroups = /* @__PURE__ */ new Map();
2892
2889
  const pendingUnconditionalSegments = [];
2893
2890
  function flushPendingUnconditionalSegments() {
2894
2891
  if (pendingUnconditionalSegments.length === 0) {
2895
2892
  return;
2896
2893
  }
2897
- const partMembers = buildStyleHashMembers(pendingUnconditionalSegments, options);
2898
- members.push(...partMembers);
2899
- for (const member of partMembers) {
2900
- if (t7.isObjectProperty(member)) {
2901
- previousProperties.set(propertyName(member.key), member);
2902
- }
2894
+ const built = buildStyleHashMembers(pendingUnconditionalSegments, options);
2895
+ members.push(...built.members);
2896
+ for (const [cssProp, entries] of built.groups) {
2897
+ previousGroups.set(cssProp, entries);
2903
2898
  }
2904
2899
  pendingUnconditionalSegments.length = 0;
2905
2900
  }
2901
+ function buildBranchMembers(segments) {
2902
+ const conditionalOnly = collectConditionalOnlyProps(segments);
2903
+ const seed = new Map([...previousGroups].filter(([cssProp]) => conditionalOnly.has(cssProp)));
2904
+ return buildStyleHashMembers(segments, options, seed).members;
2905
+ }
2906
2906
  if (chain.markers.length > 0) {
2907
2907
  const markerClasses = chain.markers.map((marker) => markerClassName(marker.markerNode));
2908
- members.push(t7.objectProperty(t7.identifier(TRUSS_MARKER_KEY), t7.stringLiteral(markerClasses.join(" "))));
2908
+ members.push(t14.objectProperty(t14.identifier(TRUSS_MARKER_KEY), t14.stringLiteral(markerClasses.join(" "))));
2909
2909
  }
2910
2910
  for (const part of chain.parts) {
2911
2911
  if (part.type === "unconditional") {
2912
2912
  pendingUnconditionalSegments.push(...part.segments);
2913
2913
  } else {
2914
2914
  flushPendingUnconditionalSegments();
2915
- const thenMembers = mergeConditionalBranchMembers(
2916
- buildStyleHashMembers(part.thenSegments, options),
2917
- previousProperties,
2918
- collectConditionalOnlyProps(part.thenSegments)
2919
- );
2920
- const elseMembers = mergeConditionalBranchMembers(
2921
- buildStyleHashMembers(part.elseSegments, options),
2922
- previousProperties,
2923
- collectConditionalOnlyProps(part.elseSegments)
2924
- );
2915
+ const thenMembers = buildBranchMembers(part.thenSegments);
2916
+ const elseMembers = buildBranchMembers(part.elseSegments);
2925
2917
  members.push(
2926
- t7.spreadElement(
2927
- t7.conditionalExpression(part.conditionNode, t7.objectExpression(thenMembers), t7.objectExpression(elseMembers))
2918
+ t14.spreadElement(
2919
+ t14.conditionalExpression(part.conditionNode, t14.objectExpression(thenMembers), t14.objectExpression(elseMembers))
2928
2920
  )
2929
2921
  );
2930
2922
  }
2931
2923
  }
2932
2924
  flushPendingUnconditionalSegments();
2933
- return t7.objectExpression(members);
2925
+ return t14.objectExpression(members);
2934
2926
  }
2935
- function buildStyleHashMembers(segments, options) {
2927
+ function buildStyleHashMembers(segments, options, seed) {
2936
2928
  const members = [];
2937
- const normalSegs = [];
2929
+ const groups = /* @__PURE__ */ new Map();
2930
+ const cssSegs = [];
2938
2931
  const classNameArgs = [];
2939
2932
  const styleKeyCounts = /* @__PURE__ */ new Map();
2940
- function flushNormal() {
2941
- if (normalSegs.length > 0) {
2942
- members.push(
2943
- ...buildStyleHashProperties(
2944
- normalSegs,
2945
- options.mapping,
2946
- options.maybeIncHelperName,
2947
- options.maybeCssVarHelperName
2948
- )
2949
- );
2950
- normalSegs.length = 0;
2933
+ function flushCssSegs() {
2934
+ if (cssSegs.length === 0) return;
2935
+ const batchGroups = collectStyleEntryGroups(cssSegs, options.mapping, seed);
2936
+ members.push(...styleHashProperties(batchGroups, options.maybeIncHelperName, options.maybeCssVarHelperName));
2937
+ for (const [cssProp, entries] of batchGroups) {
2938
+ groups.set(cssProp, entries);
2951
2939
  }
2940
+ cssSegs.length = 0;
2952
2941
  }
2953
2942
  for (const seg of segments) {
2954
- if (seg.error) continue;
2955
- if (seg.classNameArg) {
2956
- classNameArgs.push(t7.cloneNode(seg.classNameArg, true));
2957
- continue;
2958
- }
2959
- if (seg.styleArg) {
2960
- flushNormal();
2961
- members.push(buildMetadataMember(TRUSS_INLINE_STYLE_PREFIX, seg.styleArg, styleKeyCounts));
2962
- continue;
2963
- }
2964
- if (seg.styleArrayArg) {
2965
- flushNormal();
2966
- if (seg.isAddCss && t7.isObjectExpression(seg.styleArrayArg)) {
2967
- members.push(...buildAddCssObjectMembers(seg.styleArrayArg));
2968
- } else {
2969
- members.push(t7.spreadElement(seg.styleArrayArg));
2970
- }
2971
- continue;
2972
- }
2973
- if (seg.typographyLookup) {
2974
- flushNormal();
2975
- const lookupName = options.runtimeLookupNames.get(seg.typographyLookup.lookupKey);
2976
- if (lookupName) {
2977
- const lookupAccess = t7.memberExpression(t7.identifier(lookupName), seg.typographyLookup.argNode, true);
2978
- members.push(t7.spreadElement(t7.logicalExpression("??", lookupAccess, t7.objectExpression([]))));
2943
+ switch (seg.kind) {
2944
+ case "error":
2945
+ continue;
2946
+ case "className":
2947
+ classNameArgs.push(t14.cloneNode(seg.arg, true));
2948
+ continue;
2949
+ case "inlineStyle":
2950
+ flushCssSegs();
2951
+ members.push(buildMetadataMember(TRUSS_INLINE_STYLE_PREFIX, seg.arg, styleKeyCounts));
2952
+ continue;
2953
+ case "composed":
2954
+ flushCssSegs();
2955
+ if (seg.skipUndefined && t14.isObjectExpression(seg.arg)) {
2956
+ members.push(...buildAddCssObjectMembers(seg.arg));
2957
+ } else {
2958
+ members.push(t14.spreadElement(seg.arg));
2959
+ }
2960
+ continue;
2961
+ case "typography": {
2962
+ flushCssSegs();
2963
+ const lookupName = options.runtimeLookupNames.get(seg.lookupKey);
2964
+ if (lookupName) {
2965
+ const lookupAccess = t14.memberExpression(t14.identifier(lookupName), seg.argNode, true);
2966
+ members.push(t14.spreadElement(t14.logicalExpression("??", lookupAccess, t14.objectExpression([]))));
2967
+ }
2968
+ continue;
2979
2969
  }
2980
- continue;
2981
2970
  }
2982
2971
  if (options.debug) {
2983
- const isMultiProp = Object.keys(seg.defs).length > 1;
2984
- const hasExtraDefs = seg.variableExtraDefs && Object.keys(seg.variableExtraDefs).length > 0;
2972
+ const isMultiProp = seg.kind === "static" && Object.keys(seg.defs).length > 1;
2973
+ const hasExtraDefs = seg.kind === "variable" && !!seg.extraDefs && Object.keys(seg.extraDefs).length > 0;
2985
2974
  if (isMultiProp || hasExtraDefs) {
2986
- classNameArgs.push(t7.stringLiteral(seg.abbr));
2975
+ classNameArgs.push(t14.stringLiteral(seg.abbr));
2987
2976
  }
2988
2977
  }
2989
- normalSegs.push(seg);
2978
+ cssSegs.push(seg);
2990
2979
  }
2991
- flushNormal();
2980
+ flushCssSegs();
2992
2981
  if (classNameArgs.length > 0) {
2993
2982
  const classNameKeyCounts = /* @__PURE__ */ new Map();
2994
2983
  members.unshift(
2995
2984
  ...classNameArgs.map((arg) => buildMetadataMember(TRUSS_CUSTOM_CLASS_PREFIX, arg, classNameKeyCounts))
2996
2985
  );
2997
2986
  }
2998
- return members;
2987
+ return { members, groups };
2999
2988
  }
3000
2989
  function buildMetadataMember(prefix, arg, counts) {
3001
2990
  const baseKey = `${prefix}${sanitizeMetadataKey(arg)}`;
3002
2991
  const count = (counts.get(baseKey) ?? 0) + 1;
3003
2992
  counts.set(baseKey, count);
3004
2993
  const key = count === 1 ? baseKey : `${baseKey}_${count}`;
3005
- return t7.objectProperty(t7.identifier(key), t7.cloneNode(arg, true));
2994
+ return t14.objectProperty(t14.identifier(key), t14.cloneNode(arg, true));
3006
2995
  }
3007
2996
  function sanitizeMetadataKey(arg) {
3008
- const raw = t7.isStringLiteral(arg) ? arg.value : t7.isTemplateLiteral(arg) && arg.expressions.length === 0 && arg.quasis.length === 1 ? arg.quasis[0].value.cooked ?? "" : generate(arg).code;
2997
+ const raw = t14.isStringLiteral(arg) ? arg.value : t14.isTemplateLiteral(arg) && arg.expressions.length === 0 && arg.quasis.length === 1 ? arg.quasis[0].value.cooked ?? "" : generate(arg).code;
3009
2998
  const sanitized = raw.replace(/[^a-zA-Z0-9_$]/g, "_").replace(/_+/g, "_").replace(/^_+|_+$/g, "");
3010
2999
  return sanitized || "value";
3011
3000
  }
3012
3001
  function buildAddCssObjectMembers(styleObject) {
3013
3002
  const members = [];
3014
3003
  for (const property of styleObject.properties) {
3015
- if (t7.isSpreadElement(property)) {
3016
- members.push(t7.spreadElement(t7.cloneNode(property.argument, true)));
3004
+ if (t14.isSpreadElement(property)) {
3005
+ members.push(t14.spreadElement(t14.cloneNode(property.argument, true)));
3017
3006
  continue;
3018
3007
  }
3019
- if (!t7.isObjectProperty(property) || property.computed) {
3020
- members.push(t7.spreadElement(t7.objectExpression([t7.cloneNode(property, true)])));
3008
+ if (!t14.isObjectProperty(property) || property.computed) {
3009
+ members.push(t14.spreadElement(t14.objectExpression([t14.cloneNode(property, true)])));
3021
3010
  continue;
3022
3011
  }
3023
3012
  const value = property.value;
3024
- if (t7.isIdentifier(value) || t7.isMemberExpression(value) || t7.isOptionalMemberExpression(value)) {
3013
+ if (t14.isIdentifier(value) || t14.isMemberExpression(value) || t14.isOptionalMemberExpression(value)) {
3025
3014
  members.push(
3026
- t7.spreadElement(
3027
- t7.conditionalExpression(
3028
- t7.binaryExpression("===", t7.cloneNode(value, true), t7.identifier("undefined")),
3029
- t7.objectExpression([]),
3030
- t7.objectExpression([t7.objectProperty(clonePropertyKey(property.key), t7.cloneNode(value, true))])
3015
+ t14.spreadElement(
3016
+ t14.conditionalExpression(
3017
+ t14.binaryExpression("===", t14.cloneNode(value, true), t14.identifier("undefined")),
3018
+ t14.objectExpression([]),
3019
+ t14.objectExpression([t14.objectProperty(clonePropertyKey(property.key), t14.cloneNode(value, true))])
3031
3020
  )
3032
3021
  )
3033
3022
  );
3034
3023
  continue;
3035
3024
  }
3036
- members.push(t7.spreadElement(t7.objectExpression([t7.cloneNode(property, true)])));
3025
+ members.push(t14.spreadElement(t14.objectExpression([t14.cloneNode(property, true)])));
3037
3026
  }
3038
3027
  return members;
3039
3028
  }
3040
3029
  function collectConditionalOnlyProps(segments) {
3041
3030
  const conditionalOnly = /* @__PURE__ */ new Map();
3042
3031
  for (const seg of segments) {
3043
- if (!isStyleSegment(seg)) continue;
3044
- const segHasCondition = hasCondition(seg);
3045
- for (const prop of seg.variableProps ?? Object.keys(seg.defs)) {
3032
+ if (!isCssSegment(seg)) continue;
3033
+ const segHasCondition = hasCondition(seg.condition);
3034
+ const props = seg.kind === "variable" ? seg.props : Object.keys(seg.defs);
3035
+ for (const prop of props) {
3046
3036
  conditionalOnly.set(prop, (conditionalOnly.get(prop) ?? true) && segHasCondition);
3047
3037
  }
3048
3038
  }
3049
3039
  return new Set([...conditionalOnly].filter(([, isConditionalOnly]) => isConditionalOnly).map(([prop]) => prop));
3050
3040
  }
3051
- function mergeConditionalBranchMembers(members, previousProperties, conditionalOnlyProps) {
3052
- return members.map((member) => {
3053
- if (!t7.isObjectProperty(member)) {
3054
- return member;
3055
- }
3056
- const prop = propertyName(member.key);
3057
- const prior = previousProperties.get(prop);
3058
- if (!prior || !conditionalOnlyProps.has(prop)) {
3059
- return member;
3060
- }
3061
- return t7.objectProperty(
3062
- clonePropertyKey(member.key),
3063
- mergePropertyValues(prior.value, member.value)
3064
- );
3065
- });
3066
- }
3067
- function mergePropertyValues(previousValue, currentValue) {
3068
- if (t7.isStringLiteral(previousValue) && t7.isStringLiteral(currentValue)) {
3069
- return t7.stringLiteral(`${previousValue.value} ${currentValue.value}`);
3070
- }
3071
- if (t7.isStringLiteral(previousValue) && t7.isArrayExpression(currentValue)) {
3072
- return mergeTupleValue(currentValue, previousValue.value, true);
3073
- }
3074
- if (t7.isArrayExpression(previousValue) && t7.isStringLiteral(currentValue)) {
3075
- return mergeTupleValue(previousValue, currentValue.value, false);
3076
- }
3077
- if (t7.isArrayExpression(previousValue) && t7.isArrayExpression(currentValue)) {
3078
- const previousClassNames = tupleClassNames(previousValue);
3079
- return mergeTupleValue(currentValue, previousClassNames, true, arrayElementExpression(previousValue.elements[1]));
3080
- }
3081
- return t7.cloneNode(currentValue, true);
3082
- }
3083
- function mergeTupleValue(tuple, classNames, prependClassNames, previousVars) {
3084
- const currentClassNames = tupleClassNames(tuple);
3085
- const mergedClassNames = prependClassNames ? `${classNames} ${currentClassNames}` : `${currentClassNames} ${classNames}`;
3086
- const currentVars = arrayElementExpression(tuple.elements[1]);
3087
- const mergedVars = previousVars && currentVars ? mergeVarsObject(previousVars, currentVars) : currentVars ?? previousVars;
3088
- return t7.arrayExpression([
3089
- t7.stringLiteral(mergedClassNames),
3090
- mergedVars ? t7.cloneNode(mergedVars, true) : t7.objectExpression([])
3091
- ]);
3092
- }
3093
- function tupleClassNames(tuple) {
3094
- const classNames = tuple.elements[0];
3095
- return t7.isStringLiteral(classNames) ? classNames.value : "";
3096
- }
3097
- function arrayElementExpression(element) {
3098
- return element && !t7.isSpreadElement(element) ? element : null;
3099
- }
3100
- function mergeVarsObject(previousVars, currentVars) {
3101
- if (t7.isObjectExpression(previousVars) && t7.isObjectExpression(currentVars)) {
3102
- return t7.objectExpression(
3103
- [...previousVars.properties, ...currentVars.properties].map((property) => t7.cloneNode(property, true))
3104
- );
3105
- }
3106
- return t7.cloneNode(currentVars, true);
3107
- }
3108
3041
  function propertyName(key) {
3109
3042
  return staticPropertyName(key) ?? generate(key).code;
3110
3043
  }
3111
3044
  function clonePropertyKey(key) {
3112
- if (t7.isPrivateName(key)) {
3113
- return t7.identifier(key.id.name);
3045
+ if (t14.isPrivateName(key)) {
3046
+ return t14.identifier(key.id.name);
3114
3047
  }
3115
- return t7.cloneNode(key, true);
3048
+ return t14.cloneNode(key, true);
3116
3049
  }
3117
3050
  function injectDebugInfo(styleHash, line, options) {
3118
- if (!options.debug || line === null || !t7.isObjectExpression(styleHash)) return;
3051
+ if (!options.debug || line === null || !t14.isObjectExpression(styleHash)) return;
3119
3052
  const firstProp = styleHash.properties.find((p) => {
3120
- return t7.isObjectProperty(p) && !isMetadataKey(propertyName(p.key));
3053
+ return t14.isObjectProperty(p) && !isMetadataKey(propertyName(p.key));
3121
3054
  });
3122
3055
  if (!firstProp) return;
3123
- const debugExpr = t7.newExpression(t7.identifier(options.runtime.use("TrussDebugInfo")), [
3124
- t7.stringLiteral(`${options.filename}:${line}`)
3056
+ const debugExpr = t14.newExpression(t14.identifier(options.runtime.use("TrussDebugInfo")), [
3057
+ t14.stringLiteral(`${options.filename}:${line}`)
3125
3058
  ]);
3126
- if (t7.isStringLiteral(firstProp.value)) {
3127
- firstProp.value = t7.arrayExpression([firstProp.value, debugExpr]);
3128
- } else if (t7.isArrayExpression(firstProp.value)) {
3059
+ if (t14.isStringLiteral(firstProp.value)) {
3060
+ firstProp.value = t14.arrayExpression([firstProp.value, debugExpr]);
3061
+ } else if (t14.isArrayExpression(firstProp.value)) {
3129
3062
  firstProp.value.elements.push(debugExpr);
3130
3063
  }
3131
3064
  }
@@ -3137,12 +3070,12 @@ function buildCssSpreadAttribute(path, styleHash, line, options) {
3137
3070
  const existingStyleExpr = removeExistingAttribute(path, "style");
3138
3071
  injectDebugInfo(styleHash, line, options);
3139
3072
  if (!existingClassNameExpr && !existingStyleExpr) {
3140
- return t7.jsxSpreadAttribute(t7.callExpression(t7.identifier(options.runtime.use("trussProps")), [styleHash]));
3073
+ return t14.jsxSpreadAttribute(t14.callExpression(t14.identifier(options.runtime.use("trussProps")), [styleHash]));
3141
3074
  }
3142
- return t7.jsxSpreadAttribute(
3143
- t7.callExpression(t7.identifier(options.runtime.use("mergeProps")), [
3144
- existingClassNameExpr ?? t7.identifier("undefined"),
3145
- existingStyleExpr ?? t7.identifier("undefined"),
3075
+ return t14.jsxSpreadAttribute(
3076
+ t14.callExpression(t14.identifier(options.runtime.use("mergeProps")), [
3077
+ existingClassNameExpr ?? t14.identifier("undefined"),
3078
+ existingStyleExpr ?? t14.identifier("undefined"),
3146
3079
  styleHash
3147
3080
  ])
3148
3081
  );
@@ -3153,11 +3086,11 @@ function removeExistingAttribute(path, attrName) {
3153
3086
  const attrs = openingElement.node.attributes;
3154
3087
  for (let i = 0; i < attrs.length; i++) {
3155
3088
  const attr = attrs[i];
3156
- if (!t7.isJSXAttribute(attr) || !t7.isJSXIdentifier(attr.name, { name: attrName })) continue;
3089
+ if (!t14.isJSXAttribute(attr) || !t14.isJSXIdentifier(attr.name, { name: attrName })) continue;
3157
3090
  let expr = null;
3158
- if (t7.isStringLiteral(attr.value)) {
3091
+ if (t14.isStringLiteral(attr.value)) {
3159
3092
  expr = attr.value;
3160
- } else if (t7.isJSXExpressionContainer(attr.value) && t7.isExpression(attr.value.expression)) {
3093
+ } else if (t14.isJSXExpressionContainer(attr.value) && t14.isExpression(attr.value.expression)) {
3161
3094
  expr = attr.value.expression;
3162
3095
  }
3163
3096
  attrs.splice(i, 1);
@@ -3171,28 +3104,28 @@ function rewriteCssPropsAndCssAttributes(options) {
3171
3104
  CallExpression(path) {
3172
3105
  if (!options.cssBindingName || !isCssMethodCall(path.node, options.cssBindingName, "props")) return;
3173
3106
  const arg = path.node.arguments[0];
3174
- if (!arg || t7.isSpreadElement(arg) || !t7.isExpression(arg) || path.node.arguments.length !== 1) return;
3107
+ if (!arg || t14.isSpreadElement(arg) || !t14.isExpression(arg) || path.node.arguments.length !== 1) return;
3175
3108
  const classNameExpr = extractSiblingClassName(path);
3176
3109
  if (classNameExpr) {
3177
3110
  path.replaceWith(
3178
- t7.callExpression(t7.identifier(options.runtime.use("mergeProps")), [
3111
+ t14.callExpression(t14.identifier(options.runtime.use("mergeProps")), [
3179
3112
  classNameExpr,
3180
- t7.identifier("undefined"),
3113
+ t14.identifier("undefined"),
3181
3114
  arg
3182
3115
  ])
3183
3116
  );
3184
3117
  } else {
3185
- path.replaceWith(t7.callExpression(t7.identifier(options.runtime.use("trussProps")), [arg]));
3118
+ path.replaceWith(t14.callExpression(t14.identifier(options.runtime.use("trussProps")), [arg]));
3186
3119
  }
3187
3120
  },
3188
3121
  // -- Remaining css={expr} JSX attributes → {...trussProps(expr)} spreads --
3189
3122
  // I.e. css={someVariable}, css={{ ...a, ...b }}, css={cond ? a : b}
3190
3123
  JSXAttribute(path) {
3191
- if (!t7.isJSXIdentifier(path.node.name, { name: "css" })) return;
3124
+ if (!t14.isJSXIdentifier(path.node.name, { name: "css" })) return;
3192
3125
  if (isRuntimeStyleCssAttribute(path)) return;
3193
3126
  const value = path.node.value;
3194
- if (!t7.isJSXExpressionContainer(value)) return;
3195
- if (!t7.isExpression(value.expression)) return;
3127
+ if (!t14.isJSXExpressionContainer(value)) return;
3128
+ if (!t14.isExpression(value.expression)) return;
3196
3129
  path.replaceWith(buildCssSpreadAttribute(path, value.expression, path.node.loc?.start.line ?? null, options));
3197
3130
  }
3198
3131
  });
@@ -3205,9 +3138,9 @@ function extractSiblingClassName(callPath) {
3205
3138
  const properties = objectPath.node.properties;
3206
3139
  for (let i = 0; i < properties.length; i++) {
3207
3140
  const prop = properties[i];
3208
- if (!t7.isObjectProperty(prop)) continue;
3141
+ if (!t14.isObjectProperty(prop)) continue;
3209
3142
  if (staticPropertyName(prop.key) !== "className") continue;
3210
- if (!t7.isExpression(prop.value)) continue;
3143
+ if (!t14.isExpression(prop.value)) continue;
3211
3144
  const classNameExpr = prop.value;
3212
3145
  properties.splice(i, 1);
3213
3146
  return classNameExpr;
@@ -3217,15 +3150,15 @@ function extractSiblingClassName(callPath) {
3217
3150
  function isRuntimeStyleCssAttribute(path) {
3218
3151
  const openingElementPath = path.parentPath;
3219
3152
  if (!openingElementPath || !openingElementPath.isJSXOpeningElement()) return false;
3220
- return t7.isJSXIdentifier(openingElementPath.node.name, { name: "RuntimeStyle" });
3153
+ return t14.isJSXIdentifier(openingElementPath.node.name, { name: "RuntimeStyle" });
3221
3154
  }
3222
3155
  function isFullyStaticStyleHash(hash) {
3223
- return hash.properties.every((prop) => t7.isObjectProperty(prop) && t7.isStringLiteral(prop.value));
3156
+ return hash.properties.every((prop) => t14.isObjectProperty(prop) && t14.isStringLiteral(prop.value));
3224
3157
  }
3225
3158
  function extractStaticClassNames(hash) {
3226
3159
  const classNames = [];
3227
3160
  for (const prop of hash.properties) {
3228
- if (t7.isObjectProperty(prop) && t7.isStringLiteral(prop.value)) {
3161
+ if (t14.isObjectProperty(prop) && t14.isStringLiteral(prop.value)) {
3229
3162
  classNames.push(prop.value.value);
3230
3163
  }
3231
3164
  }
@@ -3235,7 +3168,7 @@ function hasExistingAttribute(path, attrName) {
3235
3168
  const openingElement = path.parentPath;
3236
3169
  if (!openingElement || !openingElement.isJSXOpeningElement()) return false;
3237
3170
  return openingElement.node.attributes.some((attr) => {
3238
- return t7.isJSXAttribute(attr) && t7.isJSXIdentifier(attr.name, { name: attrName });
3171
+ return t14.isJSXAttribute(attr) && t14.isJSXIdentifier(attr.name, { name: attrName });
3239
3172
  });
3240
3173
  }
3241
3174
 
@@ -3265,7 +3198,7 @@ function transformTruss(code, filename, mapping, options = {}) {
3265
3198
  return;
3266
3199
  }
3267
3200
  const parentPath = path.parentPath;
3268
- if (parentPath && parentPath.isMemberExpression() && t8.isIdentifier(parentPath.node.property, { name: "$" })) {
3201
+ if (parentPath && parentPath.isMemberExpression() && t15.isIdentifier(parentPath.node.property, { name: "$" })) {
3269
3202
  return;
3270
3203
  }
3271
3204
  const resolveCssChainReference2 = buildCssChainReferenceResolver(path, cssBindingName);
@@ -3284,7 +3217,7 @@ function transformTruss(code, filename, mapping, options = {}) {
3284
3217
  },
3285
3218
  // -- JSX css={...} attribute detection (so we don't bail when there are only css props) --
3286
3219
  JSXAttribute(path) {
3287
- if (!t8.isJSXIdentifier(path.node.name, { name: "css" })) return;
3220
+ if (!t15.isJSXIdentifier(path.node.name, { name: "css" })) return;
3288
3221
  hasBuildtimeJsxCssAttribute = true;
3289
3222
  }
3290
3223
  });
@@ -3337,16 +3270,16 @@ function transformTruss(code, filename, mapping, options = {}) {
3337
3270
  }
3338
3271
  if (options.injectCss && cssText.length > 0) {
3339
3272
  declarationsToInsert.push(
3340
- t8.expressionStatement(t8.callExpression(t8.identifier("__injectTrussCSS"), [t8.stringLiteral(cssText)]))
3273
+ t15.expressionStatement(t15.callExpression(t15.identifier("__injectTrussCSS"), [t15.stringLiteral(cssText)]))
3341
3274
  );
3342
3275
  }
3343
3276
  for (const { message, line } of errorMessages) {
3344
3277
  const location = line !== null ? `${filename}:${line}` : filename;
3345
3278
  const logMessage = `${message} (${location})`;
3346
3279
  declarationsToInsert.push(
3347
- t8.expressionStatement(
3348
- t8.callExpression(t8.memberExpression(t8.identifier("console"), t8.identifier("error")), [
3349
- t8.stringLiteral(logMessage)
3280
+ t15.expressionStatement(
3281
+ t15.callExpression(t15.memberExpression(t15.identifier("console"), t15.identifier("error")), [
3282
+ t15.stringLiteral(logMessage)
3350
3283
  ])
3351
3284
  )
3352
3285
  );
@@ -3387,7 +3320,7 @@ function isInsideWhenObjectValue(path, cssBindingName) {
3387
3320
  while (current) {
3388
3321
  if (current.isObjectExpression()) {
3389
3322
  const parent = current.parentPath;
3390
- if (parent?.isCallExpression() && parent.node.arguments[0] === current.node && t8.isMemberExpression(parent.node.callee) && !parent.node.callee.computed && t8.isIdentifier(parent.node.callee.property, { name: "when" }) && extractChain(parent.node.callee.object, cssBindingName)) {
3323
+ if (parent?.isCallExpression() && parent.node.arguments[0] === current.node && t15.isMemberExpression(parent.node.callee) && !parent.node.callee.computed && t15.isIdentifier(parent.node.callee.property, { name: "when" }) && extractChain(parent.node.callee.object, cssBindingName)) {
3391
3324
  return true;
3392
3325
  }
3393
3326
  }
@@ -3402,10 +3335,10 @@ function buildCssChainReferenceResolver(path, cssBindingName) {
3402
3335
  }
3403
3336
  function resolveCssChainReference(path, node, cssBindingName, seen2) {
3404
3337
  const value = unwrapExpression(node);
3405
- if (t8.isMemberExpression(value)) {
3338
+ if (t15.isMemberExpression(value)) {
3406
3339
  return extractDollarChain(value, cssBindingName);
3407
3340
  }
3408
- if (!t8.isIdentifier(value) || seen2.has(value.name)) {
3341
+ if (!t15.isIdentifier(value) || seen2.has(value.name)) {
3409
3342
  return null;
3410
3343
  }
3411
3344
  const binding = path.scope.getBinding(value.name);
@@ -3413,7 +3346,7 @@ function resolveCssChainReference(path, node, cssBindingName, seen2) {
3413
3346
  return null;
3414
3347
  }
3415
3348
  const init = binding.path.node.init;
3416
- if (!init || !t8.isExpression(init)) {
3349
+ if (!init || !t15.isExpression(init)) {
3417
3350
  return null;
3418
3351
  }
3419
3352
  seen2.add(value.name);
@@ -3422,8 +3355,8 @@ function resolveCssChainReference(path, node, cssBindingName, seen2) {
3422
3355
  function collectRuntimeLookups(chains) {
3423
3356
  const lookups = /* @__PURE__ */ new Map();
3424
3357
  for (const seg of chains.flatMap((chain) => chainSegments(chain))) {
3425
- if (seg.typographyLookup && !lookups.has(seg.typographyLookup.lookupKey)) {
3426
- lookups.set(seg.typographyLookup.lookupKey, seg.typographyLookup.segmentsByName);
3358
+ if (seg.kind === "typography" && !lookups.has(seg.lookupKey)) {
3359
+ lookups.set(seg.lookupKey, seg.segmentsByName);
3427
3360
  }
3428
3361
  }
3429
3362
  return lookups;