domflax 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/README.md +66 -31
  2. package/dist/chunk-EYQXQQQH.js +336 -0
  3. package/dist/chunk-EYQXQQQH.js.map +1 -0
  4. package/dist/{chunk-DNHOGPYV.js → chunk-FPT4EJ6Q.js} +1100 -1551
  5. package/dist/chunk-FPT4EJ6Q.js.map +1 -0
  6. package/dist/chunk-JBM3MJRM.js +382 -0
  7. package/dist/chunk-JBM3MJRM.js.map +1 -0
  8. package/dist/{chunk-DWLB7FRR.js → chunk-TTJEXWAC.js} +322 -9
  9. package/dist/chunk-TTJEXWAC.js.map +1 -0
  10. package/dist/{chunk-6WVVF6AD.js → chunk-U5GOONKV.js} +5 -2
  11. package/dist/{chunk-6WVVF6AD.js.map → chunk-U5GOONKV.js.map} +1 -1
  12. package/dist/cli.cjs +3010 -2789
  13. package/dist/cli.cjs.map +1 -1
  14. package/dist/cli.js +268 -232
  15. package/dist/cli.js.map +1 -1
  16. package/dist/index.cjs +1684 -1649
  17. package/dist/index.cjs.map +1 -1
  18. package/dist/index.d.cts +255 -498
  19. package/dist/index.d.ts +255 -498
  20. package/dist/index.js +17 -37
  21. package/dist/{pattern-F5xBtIE-.d.cts → pattern-DotR_dHs.d.cts} +1 -1
  22. package/dist/pattern-kit.cjs +60 -1
  23. package/dist/pattern-kit.cjs.map +1 -1
  24. package/dist/pattern-kit.d.cts +2 -2
  25. package/dist/pattern-kit.d.ts +2 -2
  26. package/dist/pattern-kit.js +2 -2
  27. package/dist/{pattern-CV607P87.d.ts → pattern-urm5uuwj.d.ts} +1 -1
  28. package/dist/{resolve-ops-DIwEelH-.d.ts → resolve-ops-D8aQina5.d.cts} +20 -0
  29. package/dist/{resolve-ops-DIwEelH-.d.cts → resolve-ops-D8aQina5.d.ts} +20 -0
  30. package/dist/verify.d.cts +1 -1
  31. package/dist/verify.d.ts +1 -1
  32. package/dist/verify.js +1 -1
  33. package/dist/webpack-loader.cjs +1615 -1633
  34. package/dist/webpack-loader.cjs.map +1 -1
  35. package/dist/webpack-loader.d.cts +8 -2
  36. package/dist/webpack-loader.d.ts +8 -2
  37. package/dist/webpack-loader.js +8 -5
  38. package/dist/webpack-loader.js.map +1 -1
  39. package/dist/worker.cjs +5337 -0
  40. package/dist/worker.cjs.map +1 -0
  41. package/dist/worker.d.cts +2 -0
  42. package/dist/worker.d.ts +2 -0
  43. package/dist/worker.js +72 -0
  44. package/dist/worker.js.map +1 -0
  45. package/package.json +4 -2
  46. package/dist/chunk-DNHOGPYV.js.map +0 -1
  47. package/dist/chunk-DOQEBGWB.js +0 -188
  48. package/dist/chunk-DOQEBGWB.js.map +0 -1
  49. package/dist/chunk-DWLB7FRR.js.map +0 -1
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  init_esm_shims
3
- } from "./chunk-6WVVF6AD.js";
3
+ } from "./chunk-U5GOONKV.js";
4
4
 
5
5
  // ../core/src/builders.ts
6
6
  init_esm_shims();
@@ -61,6 +61,7 @@ function defaultMeta(safetyFloor = 0) {
61
61
  hasDynamicChildren: false,
62
62
  isComponent: false,
63
63
  hasDangerousHtml: false,
64
+ hasUnresolvedClasses: false,
64
65
  targetedByCombinator: false,
65
66
  targetedByStructuralPseudo: false,
66
67
  selectorDependents: 0,
@@ -72,6 +73,7 @@ function defaultMeta(safetyFloor = 0) {
72
73
  declaresCustomProperties: false,
73
74
  whitespaceSensitive: false,
74
75
  touched: false,
76
+ styleDirty: false,
75
77
  synthetic: false,
76
78
  safetyFloor
77
79
  };
@@ -286,6 +288,14 @@ function markTouched(state, id) {
286
288
  state.touched.add(id);
287
289
  }
288
290
  }
291
+ function markStyleDirty(state, id) {
292
+ const n = state.doc.nodes.get(id);
293
+ if (n) {
294
+ n.meta.touched = true;
295
+ n.meta.styleDirty = true;
296
+ state.touched.add(id);
297
+ }
298
+ }
289
299
  function removeSubtree(state, id) {
290
300
  const node = state.doc.nodes.get(id);
291
301
  if (!node) return;
@@ -578,7 +588,7 @@ function applyOne(state, op) {
578
588
  return [precond(op, op.target, "setClassList target is not an element")];
579
589
  }
580
590
  el.computed = cloneStyleMap(op.style);
581
- markTouched(state, op.target);
591
+ markStyleDirty(state, op.target);
582
592
  return [];
583
593
  }
584
594
  case "mergeStyle": {
@@ -601,7 +611,7 @@ function applyOne(state, op) {
601
611
  const src = doc.nodes.get(op.source);
602
612
  if (src) markTouched(state, op.source);
603
613
  }
604
- markTouched(state, op.target);
614
+ markStyleDirty(state, op.target);
605
615
  return [];
606
616
  }
607
617
  case "foldInheritedStyles":
@@ -652,7 +662,7 @@ function applyFold(state, op) {
652
662
  }
653
663
  if (folded) {
654
664
  into.computed = { blocks: nextBlocks };
655
- markTouched(state, intoId);
665
+ markStyleDirty(state, intoId);
656
666
  }
657
667
  }
658
668
  for (const d of issues) state.diagnostics.push(d);
@@ -990,8 +1000,123 @@ init_esm_shims();
990
1000
  var DISPLAY = "display";
991
1001
  var POSITION = "position";
992
1002
  var TRANSFORM = "transform";
1003
+ var ALIGN_ITEMS = "align-items";
1004
+ var JUSTIFY_CONTENT = "justify-content";
1005
+ var JUSTIFY_ITEMS = "justify-items";
1006
+ var PLACE_ITEMS = "place-items";
1007
+ var PLACE_SELF = "place-self";
993
1008
  var CONTEXT_SAFE_DISPLAYS = /* @__PURE__ */ new Set(["block", "contents", ""]);
994
1009
  var STATIC_POSITIONS = /* @__PURE__ */ new Set(["static", ""]);
1010
+ var CENTERING_DISPLAYS = /* @__PURE__ */ new Set(["flex", "grid"]);
1011
+ var GRID_PARENT_DISPLAYS = /* @__PURE__ */ new Set(["grid"]);
1012
+ var STRETCHY_ITEM_ALIGN = /* @__PURE__ */ new Set(["normal", "stretch"]);
1013
+ var PARENT_ITEMS_ALIGN_PROPS = [ALIGN_ITEMS, JUSTIFY_ITEMS, PLACE_ITEMS];
1014
+ function isBaseCondition(block) {
1015
+ const c = block.condition;
1016
+ return c.media === "" && c.states.length === 0 && c.pseudoElement === "";
1017
+ }
1018
+ function baseValue(sm, prop) {
1019
+ for (const block of sm.blocks.values()) {
1020
+ if (!isBaseCondition(block)) continue;
1021
+ const d = block.decls.get(prop);
1022
+ return d ? String(d.value) : null;
1023
+ }
1024
+ return null;
1025
+ }
1026
+ function parentIsFillingGrid(before, wrapper, norm) {
1027
+ if (wrapper.parent == null) return false;
1028
+ const p = before.nodes.get(wrapper.parent);
1029
+ if (!p || p.kind !== "element") return false;
1030
+ const pc = norm.normalizeStyleMap(p.computed);
1031
+ let baseIsGrid = false;
1032
+ for (const block of pc.blocks.values()) {
1033
+ const disp = block.decls.get(DISPLAY);
1034
+ if (disp) {
1035
+ if (!GRID_PARENT_DISPLAYS.has(String(disp.value))) return false;
1036
+ if (isBaseCondition(block)) baseIsGrid = true;
1037
+ }
1038
+ for (const prop of PARENT_ITEMS_ALIGN_PROPS) {
1039
+ const d = block.decls.get(prop);
1040
+ if (d && !STRETCHY_ITEM_ALIGN.has(String(d.value))) return false;
1041
+ }
1042
+ }
1043
+ return baseIsGrid;
1044
+ }
1045
+ function wrapperHasOnlyCenteringStyle(wrapperComputed, childComputed, norm) {
1046
+ for (const block of wrapperComputed.blocks.values()) {
1047
+ const base = isBaseCondition(block);
1048
+ const ck = conditionKey(block.condition);
1049
+ for (const [prop, decl] of block.decls) {
1050
+ const val = String(decl.value);
1051
+ if (prop === DISPLAY) {
1052
+ if (base && CENTERING_DISPLAYS.has(val)) continue;
1053
+ return false;
1054
+ }
1055
+ if (prop === ALIGN_ITEMS) {
1056
+ if (base && val === "center") continue;
1057
+ return false;
1058
+ }
1059
+ if (prop === JUSTIFY_CONTENT) {
1060
+ if (base && val === "center") continue;
1061
+ return false;
1062
+ }
1063
+ if (prop === POSITION) {
1064
+ if (STATIC_POSITIONS.has(val)) continue;
1065
+ return false;
1066
+ }
1067
+ if (prop === TRANSFORM) {
1068
+ if (val === "none") continue;
1069
+ return false;
1070
+ }
1071
+ if (isInherited2(decl, norm)) continue;
1072
+ if (childReproduces(childComputed, ck, prop, val)) continue;
1073
+ return false;
1074
+ }
1075
+ }
1076
+ return true;
1077
+ }
1078
+ function wrapperCentersSingleElement(before, wrapper) {
1079
+ let elements = 0;
1080
+ for (const cid of wrapper.children) {
1081
+ const n = before.nodes.get(cid);
1082
+ if (!n) continue;
1083
+ if (n.kind === "element") {
1084
+ elements += 1;
1085
+ continue;
1086
+ }
1087
+ if (n.kind === "comment") continue;
1088
+ if (n.kind === "text" && n.value.trim() === "") continue;
1089
+ return false;
1090
+ }
1091
+ return elements === 1;
1092
+ }
1093
+ function childHasSelfAlign(childBefore, norm) {
1094
+ if (!childBefore) return false;
1095
+ const sm = norm.normalizeStyleMap(childBefore);
1096
+ for (const block of sm.blocks.values()) {
1097
+ for (const prop of SELF_ALIGN_PROPS) {
1098
+ const d = block.decls.get(prop);
1099
+ if (d && !NEUTRAL_ALIGN.has(String(d.value))) return true;
1100
+ }
1101
+ }
1102
+ return false;
1103
+ }
1104
+ function childGainsPlaceSelfCenter(childAfter) {
1105
+ if (baseValue(childAfter, PLACE_SELF) === "center") return true;
1106
+ return baseValue(childAfter, "align-self") === "center" && baseValue(childAfter, "justify-self") === "center";
1107
+ }
1108
+ function isContextCompensatedCentering(before, wrapper, wrapperComputed, childBefore, childAfter, norm) {
1109
+ if (!childAfter) return false;
1110
+ if (!CENTERING_DISPLAYS.has(baseValue(wrapperComputed, DISPLAY) ?? "")) return false;
1111
+ if (baseValue(wrapperComputed, ALIGN_ITEMS) !== "center") return false;
1112
+ if (baseValue(wrapperComputed, JUSTIFY_CONTENT) !== "center") return false;
1113
+ const childAfterNorm = norm.normalizeStyleMap(childAfter);
1114
+ if (!childGainsPlaceSelfCenter(childAfterNorm)) return false;
1115
+ if (!wrapperHasOnlyCenteringStyle(wrapperComputed, childAfterNorm, norm)) return false;
1116
+ if (!wrapperCentersSingleElement(before, wrapper)) return false;
1117
+ if (childHasSelfAlign(childBefore, norm)) return false;
1118
+ return parentIsFillingGrid(before, wrapper, norm);
1119
+ }
995
1120
  var SELF_ALIGN_PROPS = [
996
1121
  "place-self",
997
1122
  "align-self",
@@ -1087,10 +1212,16 @@ function classifyFlattenOps(before, after, ops, norm) {
1087
1212
  if (!wrapper || wrapper.kind !== "element") {
1088
1213
  return { kind: "provably-safe", wrapperId: null, childId: null };
1089
1214
  }
1215
+ if (wrapper.meta.hasUnresolvedClasses) {
1216
+ return { kind: "needs-verification", wrapperId, childId: survivingChildOf(ops, wrapper, before) };
1217
+ }
1090
1218
  const childId = survivingChildOf(ops, wrapper, before);
1091
1219
  const wrapperComputed = norm.normalizeStyleMap(wrapper.computed);
1092
1220
  const childAfter = childId != null ? getElement(after, childId)?.computed ?? null : null;
1093
1221
  const childBefore = childId != null ? getElement(before, childId)?.computed ?? null : null;
1222
+ if (isContextCompensatedCentering(before, wrapper, wrapperComputed, childBefore, childAfter, norm)) {
1223
+ return { kind: "provably-safe", wrapperId, childId };
1224
+ }
1094
1225
  if (establishesChildContext(wrapperComputed)) {
1095
1226
  return { kind: "needs-verification", wrapperId, childId };
1096
1227
  }
@@ -1529,22 +1660,52 @@ function sameTokens(a, b) {
1529
1660
  for (let i = 0; i < a.length; i += 1) if (a[i] !== b[i]) return false;
1530
1661
  return true;
1531
1662
  }
1663
+ function residualStyle(computed2, covered, norm) {
1664
+ const cov = norm.normalizeStyleMap(covered);
1665
+ const blocks = /* @__PURE__ */ new Map();
1666
+ for (const [key, block] of norm.normalizeStyleMap(computed2).blocks) {
1667
+ const covBlock = cov.blocks.get(key);
1668
+ const decls = /* @__PURE__ */ new Map();
1669
+ for (const [prop, decl] of block.decls) {
1670
+ const covDecl = covBlock?.decls.get(prop);
1671
+ if (covDecl && covDecl.value === decl.value && covDecl.important === decl.important) continue;
1672
+ decls.set(prop, decl);
1673
+ }
1674
+ if (decls.size > 0) blocks.set(key, { condition: block.condition, decls });
1675
+ }
1676
+ return { blocks };
1677
+ }
1678
+ function joinedLength(tokens) {
1679
+ if (tokens.length === 0) return 0;
1680
+ let len = tokens.length - 1;
1681
+ for (const t of tokens) len += t.length;
1682
+ return len;
1683
+ }
1684
+ var COMPRESS_FLOOR = 1;
1532
1685
  function syncClassesFromComputed(doc, resolver, norm) {
1533
1686
  const sink = createSyntheticSink();
1687
+ const isDroppable = (t) => resolver.owns(t) && resolver.selectorUsage(t).droppable;
1534
1688
  for (const id of elementIds(doc)) {
1535
1689
  const el = getElement(doc, id);
1536
- if (!el || !el.meta.touched) continue;
1690
+ if (!el) continue;
1537
1691
  if (el.classes.opaque || el.classes.hasDynamic) continue;
1692
+ const compressOnly = !el.meta.styleDirty;
1693
+ if (compressOnly && el.meta.safetyFloor < COMPRESS_FLOOR) continue;
1538
1694
  const tokens = staticTokensOf(el.classes);
1695
+ if (tokens.length === 0) continue;
1696
+ const retained = tokens.filter((t) => !isDroppable(t));
1697
+ if (compressOnly && retained.length === tokens.length) continue;
1698
+ const covered = retained.length > 0 ? resolver.resolve({ classes: retained }).styles : null;
1699
+ const target = covered ? residualStyle(el.computed, covered, norm) : el.computed;
1539
1700
  const ctx = { normalizer: norm, sink };
1540
- const emitted = resolver.emit(el.computed, ctx).classes;
1701
+ const emitted = resolver.emit(target, ctx).classes;
1541
1702
  if (emitted.length === 0) continue;
1542
1703
  const emittedSet = new Set(emitted);
1543
1704
  const next = [];
1544
1705
  const seen = /* @__PURE__ */ new Set();
1545
1706
  for (const t of tokens) {
1546
1707
  if (seen.has(t)) continue;
1547
- const keep = emittedSet.has(t) || !resolver.selectorUsage(t).droppable;
1708
+ const keep = emittedSet.has(t) || !isDroppable(t);
1548
1709
  if (keep) {
1549
1710
  next.push(t);
1550
1711
  seen.add(t);
@@ -1556,10 +1717,99 @@ function syncClassesFromComputed(doc, resolver, norm) {
1556
1717
  seen.add(c);
1557
1718
  }
1558
1719
  if (sameTokens(next, tokens)) continue;
1720
+ if (compressOnly) {
1721
+ if (!norm.equals(resolver.resolve({ classes: next }).styles, el.computed)) continue;
1722
+ if (joinedLength(next) > joinedLength(tokens)) continue;
1723
+ }
1559
1724
  el.classes = staticClassList(el.classes, next);
1560
1725
  }
1561
1726
  }
1562
1727
 
1728
+ // ../core/src/compress-engine.ts
1729
+ init_esm_shims();
1730
+ var SEP = "";
1731
+ function tupleKey(condition, property, value, important) {
1732
+ return `${condition}${SEP}${property}${SEP}${value}${SEP}${important ? "1" : "0"}`;
1733
+ }
1734
+ function styleMapTuples(map, norm) {
1735
+ const out = [];
1736
+ const normalized = norm.normalizeStyleMap(map);
1737
+ for (const [ck, block] of normalized.blocks) {
1738
+ for (const [prop, decl] of block.decls) {
1739
+ out.push(tupleKey(String(ck), String(prop), String(decl.value), decl.important));
1740
+ }
1741
+ }
1742
+ return out;
1743
+ }
1744
+ var DEFAULT_MAX_UNIVERSE = 20;
1745
+ function minStringCover(universe, vocabulary, options = {}) {
1746
+ const uniq = [...new Set(universe)];
1747
+ if (uniq.length === 0) return [];
1748
+ const n = uniq.length;
1749
+ const max = options.maxUniverse ?? DEFAULT_MAX_UNIVERSE;
1750
+ if (n > max) return null;
1751
+ const bitOf = /* @__PURE__ */ new Map();
1752
+ uniq.forEach((t, i) => bitOf.set(t, i));
1753
+ const byMask = /* @__PURE__ */ new Map();
1754
+ for (const entry of vocabulary) {
1755
+ if (entry.tuples.length === 0) continue;
1756
+ let mask = 0;
1757
+ let ok = true;
1758
+ for (const t of entry.tuples) {
1759
+ const b = bitOf.get(t);
1760
+ if (b === void 0) {
1761
+ ok = false;
1762
+ break;
1763
+ }
1764
+ mask |= 1 << b;
1765
+ }
1766
+ if (!ok || mask === 0) continue;
1767
+ const cost = entry.token.length + 1;
1768
+ const prev = byMask.get(mask);
1769
+ if (!prev || cost < prev.cost || cost === prev.cost && entry.token < prev.token) {
1770
+ byMask.set(mask, { token: entry.token, mask, cost });
1771
+ }
1772
+ }
1773
+ const cands = [...byMask.values()];
1774
+ if (cands.length === 0) return null;
1775
+ const full = (1 << n) - 1;
1776
+ const byBit = Array.from({ length: n }, () => []);
1777
+ cands.forEach((c, ci) => {
1778
+ for (let b = 0; b < n; b += 1) if (c.mask & 1 << b) byBit[b].push(ci);
1779
+ });
1780
+ const size = full + 1;
1781
+ const dp = new Float64Array(size).fill(Infinity);
1782
+ const fromCand = new Int32Array(size).fill(-1);
1783
+ const fromMask = new Int32Array(size).fill(-1);
1784
+ dp[0] = 0;
1785
+ for (let mask = 0; mask < full; mask += 1) {
1786
+ const cur = dp[mask];
1787
+ if (!Number.isFinite(cur)) continue;
1788
+ let b = 0;
1789
+ while (b < n && mask & 1 << b) b += 1;
1790
+ for (const ci of byBit[b]) {
1791
+ const c = cands[ci];
1792
+ const nm = mask | c.mask;
1793
+ const cost = cur + c.cost;
1794
+ if (cost < dp[nm]) {
1795
+ dp[nm] = cost;
1796
+ fromCand[nm] = ci;
1797
+ fromMask[nm] = mask;
1798
+ }
1799
+ }
1800
+ }
1801
+ if (!Number.isFinite(dp[full])) return null;
1802
+ const chosen = [];
1803
+ let m = full;
1804
+ while (m !== 0) {
1805
+ const ci = fromCand[m];
1806
+ if (ci < 0) return null;
1807
+ chosen.push(cands[ci].token);
1808
+ m = fromMask[m];
1809
+ }
1810
+ return [...new Set(chosen)].sort();
1811
+ }
1812
+
1563
1813
  // ../core/src/index.ts
1564
1814
  init_esm_shims();
1565
1815
 
@@ -1648,6 +1898,18 @@ var BOX_SIDES = {
1648
1898
  padding: ["padding-top", "padding-right", "padding-bottom", "padding-left"],
1649
1899
  margin: ["margin-top", "margin-right", "margin-bottom", "margin-left"],
1650
1900
  inset: ["top", "right", "bottom", "left"],
1901
+ "scroll-margin": [
1902
+ "scroll-margin-top",
1903
+ "scroll-margin-right",
1904
+ "scroll-margin-bottom",
1905
+ "scroll-margin-left"
1906
+ ],
1907
+ "scroll-padding": [
1908
+ "scroll-padding-top",
1909
+ "scroll-padding-right",
1910
+ "scroll-padding-bottom",
1911
+ "scroll-padding-left"
1912
+ ],
1651
1913
  "border-width": [
1652
1914
  "border-top-width",
1653
1915
  "border-right-width",
@@ -1665,8 +1927,35 @@ var BOX_SIDES = {
1665
1927
  "border-right-color",
1666
1928
  "border-bottom-color",
1667
1929
  "border-left-color"
1930
+ ],
1931
+ // `border-radius` 1–4 value form maps to the four CORNERS (TL, TR, BR, BL) — the same positional
1932
+ // pattern boxFourSides implements. Only the slash-free form is expanded (see expandShorthand).
1933
+ "border-radius": [
1934
+ "border-top-left-radius",
1935
+ "border-top-right-radius",
1936
+ "border-bottom-right-radius",
1937
+ "border-bottom-left-radius"
1668
1938
  ]
1669
1939
  };
1940
+ var AXIS_PAIRS = {
1941
+ overflow: ["overflow-x", "overflow-y"],
1942
+ "overscroll-behavior": ["overscroll-behavior-x", "overscroll-behavior-y"],
1943
+ "place-items": ["align-items", "justify-items"],
1944
+ "place-content": ["align-content", "justify-content"],
1945
+ "place-self": ["align-self", "justify-self"]
1946
+ };
1947
+ var LOGICAL_PAIRS = {
1948
+ "padding-inline": ["padding-left", "padding-right"],
1949
+ "padding-block": ["padding-top", "padding-bottom"],
1950
+ "margin-inline": ["margin-left", "margin-right"],
1951
+ "margin-block": ["margin-top", "margin-bottom"],
1952
+ "inset-inline": ["left", "right"],
1953
+ "inset-block": ["top", "bottom"],
1954
+ "scroll-padding-inline": ["scroll-padding-left", "scroll-padding-right"],
1955
+ "scroll-padding-block": ["scroll-padding-top", "scroll-padding-bottom"],
1956
+ "scroll-margin-inline": ["scroll-margin-left", "scroll-margin-right"],
1957
+ "scroll-margin-block": ["scroll-margin-top", "scroll-margin-bottom"]
1958
+ };
1670
1959
  function splitTopLevel(value) {
1671
1960
  const out = [];
1672
1961
  let depth = 0;
@@ -1700,6 +1989,7 @@ function boxFourSides(values) {
1700
1989
  }
1701
1990
  }
1702
1991
  function expandShorthand(prop, value) {
1992
+ if (prop === "border-radius" && value.includes("/")) return [[prop, value]];
1703
1993
  const box = BOX_SIDES[prop];
1704
1994
  if (box) {
1705
1995
  const parts = splitTopLevel(value);
@@ -1709,6 +1999,19 @@ function expandShorthand(prop, value) {
1709
1999
  }
1710
2000
  return [[prop, value]];
1711
2001
  }
2002
+ const axis = AXIS_PAIRS[prop];
2003
+ if (axis) {
2004
+ const parts = splitTopLevel(value);
2005
+ if (parts.length === 1) return [[axis[0], parts[0]], [axis[1], parts[0]]];
2006
+ if (parts.length === 2) return [[axis[0], parts[0]], [axis[1], parts[1]]];
2007
+ return [[prop, value]];
2008
+ }
2009
+ const logical = LOGICAL_PAIRS[prop];
2010
+ if (logical) {
2011
+ const parts = splitTopLevel(value);
2012
+ if (parts.length === 1) return [[logical[0], parts[0]], [logical[1], parts[0]]];
2013
+ return [[prop, value]];
2014
+ }
1712
2015
  if (prop === "gap" || prop === "grid-gap") {
1713
2016
  const parts = splitTopLevel(value);
1714
2017
  if (parts.length === 1) {
@@ -1870,7 +2173,12 @@ var VISUAL_PROPERTIES = /* @__PURE__ */ new Set([
1870
2173
  "border-right-color",
1871
2174
  "border-bottom-color",
1872
2175
  "border-left-color",
1873
- "border-radius",
2176
+ // `border-radius` is expanded to its four corner longhands by the shared normalizer, so the
2177
+ // paint-establishing check must match those (a rounded wrapper still clips its background).
2178
+ "border-top-left-radius",
2179
+ "border-top-right-radius",
2180
+ "border-bottom-right-radius",
2181
+ "border-bottom-left-radius",
1874
2182
  "box-shadow",
1875
2183
  "outline",
1876
2184
  "outline-width",
@@ -1896,6 +2204,7 @@ var hasOwnVisualStyle = (node, ctx) => {
1896
2204
  const el = asElement(node);
1897
2205
  if (!el) return false;
1898
2206
  if (el.meta.hasOwnVisualStyle) return true;
2207
+ if (el.meta.hasUnresolvedClasses) return true;
1899
2208
  const computedMap = ctx.computedOf(el) ?? el.computed;
1900
2209
  const norm = normalizer.normalizeStyleMap(computedMap);
1901
2210
  for (const block of norm.blocks.values()) {
@@ -2186,6 +2495,10 @@ export {
2186
2495
  createSyntheticSink,
2187
2496
  createPipeline,
2188
2497
  syncClassesFromComputed,
2498
+ tupleKey,
2499
+ styleMapTuples,
2500
+ DEFAULT_MAX_UNIVERSE,
2501
+ minStringCover,
2189
2502
  createNormalizer,
2190
2503
  normalizer,
2191
2504
  isStyleSuperset,
@@ -2209,4 +2522,4 @@ export {
2209
2522
  definePattern,
2210
2523
  pattern
2211
2524
  };
2212
- //# sourceMappingURL=chunk-DWLB7FRR.js.map
2525
+ //# sourceMappingURL=chunk-TTJEXWAC.js.map