@drskillissue/ganko 0.3.0 → 0.3.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.
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@ import {
2
2
  RULES,
3
3
  RULES_BY_CATEGORY,
4
4
  getRule
5
- } from "./chunk-TNKZGWOR.js";
5
+ } from "./chunk-4W4KAPRH.js";
6
6
  import {
7
7
  ACCESSIBILITY_POLICIES,
8
8
  CSS_EXTENSIONS,
@@ -83,7 +83,7 @@ import {
83
83
  splitTopLevelWhitespace,
84
84
  splitWhitespaceTokens,
85
85
  toKebabCase
86
- } from "./chunk-2VRVUMIE.js";
86
+ } from "./chunk-WJGGSO5O.js";
87
87
  import "./chunk-EGRHWZRV.js";
88
88
 
89
89
  // src/runner.ts
@@ -300,24 +300,26 @@ function buildTailwindValidatorFromEval(utilities, variants, logger) {
300
300
  has(className) {
301
301
  if (staticValidator.has(className)) return true;
302
302
  const cached = batchCache.get(className);
303
- if (cached !== void 0) return cached;
303
+ if (cached !== void 0) return cached !== null;
304
304
  return false;
305
305
  },
306
- resolve() {
306
+ resolve(className) {
307
+ const cached = batchCache.get(className);
308
+ if (cached !== void 0) return cached;
307
309
  return null;
308
310
  },
309
311
  preloadBatch(classNames, results) {
310
312
  for (let i = 0; i < classNames.length; i++) {
311
313
  const name = classNames[i];
312
- const valid = results[i];
313
- if (name !== void 0 && valid !== void 0) {
314
- batchCache.set(name, valid);
314
+ const css = results[i];
315
+ if (name !== void 0 && css !== void 0) {
316
+ batchCache.set(name, css);
315
317
  }
316
318
  }
317
319
  if (logger?.isLevelEnabled(Level.Debug)) {
318
320
  let validCount = 0;
319
321
  for (let i = 0; i < results.length; i++) {
320
- if (results[i]) validCount++;
322
+ if (results[i] !== null) validCount++;
321
323
  }
322
324
  logger.debug(`tailwind: preloaded ${classNames.length} candidates (${validCount} valid)`);
323
325
  }
@@ -513,7 +515,7 @@ function getActivePolicy() {
513
515
  }
514
516
 
515
517
  // src/compilation/symbols/class-name.ts
516
- function createClassNameSymbol(name, selectors, filePaths) {
518
+ function createClassNameSymbol(name, selectors, filePaths, tailwindResolvedCSS) {
517
519
  return {
518
520
  symbolKind: "className",
519
521
  name,
@@ -522,7 +524,8 @@ function createClassNameSymbol(name, selectors, filePaths) {
522
524
  kind: "css",
523
525
  selectors,
524
526
  filePaths
525
- }
527
+ },
528
+ tailwindResolvedCSS: tailwindResolvedCSS ?? null
526
529
  };
527
530
  }
528
531
 
@@ -993,7 +996,7 @@ function pushToMapArray(map, key, value) {
993
996
  if (arr !== void 0) arr.push(value);
994
997
  else map.set(key, [value]);
995
998
  }
996
- function buildSymbolTable(trees, tailwindValidator) {
999
+ function buildSymbolTable(trees, tailwindValidator, solidClassTokens) {
997
1000
  const classNamesMap = /* @__PURE__ */ new Map();
998
1001
  const selectorsMap = /* @__PURE__ */ new Map();
999
1002
  const customPropertiesMap = /* @__PURE__ */ new Map();
@@ -1020,6 +1023,7 @@ function buildSymbolTable(trees, tailwindValidator) {
1020
1023
  const allSelectors = [];
1021
1024
  const allDeclarations = [];
1022
1025
  const allVariables = [];
1026
+ const referencedCustomPropertyNamesSet = /* @__PURE__ */ new Set();
1023
1027
  const allAtRules = [];
1024
1028
  const allKeyframeAtRules = [];
1025
1029
  const allFontFaceAtRules = [];
@@ -1130,6 +1134,11 @@ function buildSymbolTable(trees, tailwindValidator) {
1130
1134
  customPropertiesMap.set(entity.name, createCustomPropertySymbol(entity, filePath));
1131
1135
  }
1132
1136
  }
1137
+ const treeVariableRefs = tree.variableRefs;
1138
+ for (let i = 0; i < treeVariableRefs.length; i++) {
1139
+ const ref = treeVariableRefs[i];
1140
+ if (ref) referencedCustomPropertyNamesSet.add(ref.name);
1141
+ }
1133
1142
  const treeAtRules = tree.atRules;
1134
1143
  for (let i = 0; i < treeAtRules.length; i++) {
1135
1144
  const entity = treeAtRules[i];
@@ -1183,11 +1192,32 @@ function buildSymbolTable(trees, tailwindValidator) {
1183
1192
  if (!placeholdersByNameMap.has(ph.name)) placeholdersByNameMap.set(ph.name, ph);
1184
1193
  }
1185
1194
  }
1195
+ const twValidator = tailwindValidator ?? null;
1186
1196
  const classNameSymbols = /* @__PURE__ */ new Map();
1187
1197
  for (const [name, entry] of classNamesMap) {
1188
- classNameSymbols.set(name, createClassNameSymbol(name, entry.selectors, [...entry.filePaths]));
1198
+ const twCSS = twValidator !== null && twValidator.has(name) ? twValidator.resolve(name) : null;
1199
+ classNameSymbols.set(name, createClassNameSymbol(name, entry.selectors, [...entry.filePaths], twCSS));
1200
+ }
1201
+ if (twValidator !== null && solidClassTokens !== null && solidClassTokens !== void 0) {
1202
+ for (const name of solidClassTokens) {
1203
+ if (classNameSymbols.has(name)) continue;
1204
+ if (!twValidator.has(name)) continue;
1205
+ const resolvedCSS = twValidator.resolve(name);
1206
+ classNameSymbols.set(name, {
1207
+ symbolKind: "className",
1208
+ name,
1209
+ filePath: null,
1210
+ source: {
1211
+ kind: "tailwind",
1212
+ candidate: { raw: name, variants: [], utility: name, value: null, modifier: null, important: false, negative: false },
1213
+ resolvedCSS,
1214
+ declarations: [],
1215
+ diagnostics: []
1216
+ },
1217
+ tailwindResolvedCSS: resolvedCSS
1218
+ });
1219
+ }
1189
1220
  }
1190
- const twValidator = tailwindValidator ?? null;
1191
1221
  const knownKeyframeNames = /* @__PURE__ */ new Set();
1192
1222
  for (let i = 0; i < allKeyframeAtRules.length; i++) {
1193
1223
  const kf = allKeyframeAtRules[i];
@@ -1544,8 +1574,9 @@ function buildSymbolTable(trees, tailwindValidator) {
1544
1574
  unusedFunctions: unusedFunctionsArr,
1545
1575
  unusedPlaceholders: unusedPlaceholdersArr,
1546
1576
  tokenCategories: [...tokensByCategoryMap.keys()],
1577
+ referencedCustomPropertyNames: referencedCustomPropertyNamesSet,
1547
1578
  hasClassName(name) {
1548
- return classNameSymbols.has(name) || twValidator !== null && twValidator.has(name);
1579
+ return classNameSymbols.has(name);
1549
1580
  },
1550
1581
  getClassName(name) {
1551
1582
  return classNameSymbols.get(name) ?? null;
@@ -2684,7 +2715,7 @@ function buildElementNodes(solidTree, compilation) {
2684
2715
  const selectorDispatchKeys = buildSelectorDispatchKeys(attributes, classTokens);
2685
2716
  const inlineStyleValues = inlineStyleValuesByElementId.get(element.id) ?? EMPTY_INLINE_STYLE_VALUES;
2686
2717
  const textualContent = getTextualContentState(element, textContentMemo, compositionMetaByElementId);
2687
- const parentElementId = resolveComposedParentElementId(element, compositionMetaByElementId);
2718
+ const parentElementId = resolveComposedParentElementId(element, compositionMetaByElementId, solidTree.compoundComponentParents);
2688
2719
  records.push({
2689
2720
  element,
2690
2721
  key: `${solidTree.filePath}::${element.id}`,
@@ -2717,12 +2748,32 @@ function buildElementNodes(solidTree, compilation) {
2717
2748
  byType.set(record.tagName, (byType.get(record.tagName) ?? 0) + 1);
2718
2749
  }
2719
2750
  }
2751
+ const recordsByElementId = /* @__PURE__ */ new Map();
2752
+ for (let i = 0; i < records.length; i++) {
2753
+ const r = records[i];
2754
+ if (r) recordsByElementId.set(r.element.id, r);
2755
+ }
2756
+ const sorted = [];
2757
+ const visited = /* @__PURE__ */ new Set();
2758
+ function visitRecord(r) {
2759
+ if (visited.has(r.element.id)) return;
2760
+ visited.add(r.element.id);
2761
+ if (r.parentElementId !== null) {
2762
+ const parent = recordsByElementId.get(r.parentElementId);
2763
+ if (parent) visitRecord(parent);
2764
+ }
2765
+ sorted.push(r);
2766
+ }
2767
+ for (let i = 0; i < records.length; i++) {
2768
+ const r = records[i];
2769
+ if (r) visitRecord(r);
2770
+ }
2720
2771
  const elements = [];
2721
2772
  const nodeByElementId = /* @__PURE__ */ new Map();
2722
2773
  const lastChildByParentId = /* @__PURE__ */ new Map();
2723
2774
  const siblingTypeSeenByParentId = /* @__PURE__ */ new Map();
2724
- for (let i = 0; i < records.length; i++) {
2725
- const record = records[i];
2775
+ for (let i = 0; i < sorted.length; i++) {
2776
+ const record = sorted[i];
2726
2777
  if (!record) continue;
2727
2778
  const parentElementId = record.parentElementId;
2728
2779
  const parentNode = parentElementId === null ? null : nodeByElementId.get(parentElementId) ?? null;
@@ -2886,13 +2937,19 @@ function resolveEffectiveTag(element, hostDescriptor) {
2886
2937
  if (!element.isDomElement) return null;
2887
2938
  return element.tag;
2888
2939
  }
2889
- function resolveComposedParentElementId(element, compositionMetaByElementId) {
2940
+ function resolveComposedParentElementId(element, compositionMetaByElementId, compoundComponentParents) {
2890
2941
  let parent = element.parent;
2891
2942
  while (parent !== null) {
2892
2943
  const meta = compositionMetaByElementId.get(parent.id);
2893
2944
  if (meta && meta.participates) return parent.id;
2894
2945
  parent = parent.parent;
2895
2946
  }
2947
+ let scope = element.scope;
2948
+ while (scope !== null) {
2949
+ const compoundParent = compoundComponentParents.get(scope.id);
2950
+ if (compoundParent !== void 0) return compoundParent;
2951
+ scope = scope.parent;
2952
+ }
2896
2953
  return null;
2897
2954
  }
2898
2955
  function getTextualContentState(element, memo, compositionMetaByElementId, logger = noopLogger) {
@@ -4182,6 +4239,136 @@ function compareCascadePositions(posA, posB) {
4182
4239
  return posA.sourceOrder - posB.sourceOrder;
4183
4240
  }
4184
4241
 
4242
+ // src/compilation/analysis/layout-fact.ts
4243
+ var SCROLLABLE_VALUES = /* @__PURE__ */ new Set(["auto", "scroll"]);
4244
+ var NON_RESERVING_DIMENSION_KEYWORDS = /* @__PURE__ */ new Set(["auto", "none", "fit-content", "min-content", "max-content", "stretch", "inherit", "initial", "unset", "revert", "revert-layer"]);
4245
+ var BLOCK_LEVEL_DISPLAY_VALUES = /* @__PURE__ */ new Set(["block", "flex", "grid", "table", "list-item", "flow-root", "table-row", "table-cell", "table-caption", "table-row-group", "table-header-group", "table-footer-group", "table-column", "table-column-group"]);
4246
+ function computeReservedSpaceFact(snapshot) {
4247
+ const reasons = [];
4248
+ const hasHeight = hasDeclaredDimension(snapshot, "height");
4249
+ if (hasHeight) reasons.push("height");
4250
+ const hasBlockSize = hasDeclaredDimension(snapshot, "block-size");
4251
+ if (hasBlockSize) reasons.push("block-size");
4252
+ const hasMinHeight = hasDeclaredDimension(snapshot, "min-height");
4253
+ if (hasMinHeight) reasons.push("min-height");
4254
+ const hasMinBlockSize = hasDeclaredDimension(snapshot, "min-block-size");
4255
+ if (hasMinBlockSize) reasons.push("min-block-size");
4256
+ const hasContainIntrinsic = hasDeclaredDimension(snapshot, "contain-intrinsic-size");
4257
+ if (hasContainIntrinsic) reasons.push("contain-intrinsic-size");
4258
+ const hasAspectRatio = hasUsableAspectRatio(snapshot);
4259
+ if (hasAspectRatio) {
4260
+ if (hasDeclaredDimension(snapshot, "width")) reasons.push("aspect-ratio+width");
4261
+ if (hasDeclaredDimension(snapshot, "inline-size")) reasons.push("aspect-ratio+inline-size");
4262
+ if (hasDeclaredDimension(snapshot, "min-width")) reasons.push("aspect-ratio+min-width");
4263
+ if (hasMinBlockSize) reasons.push("aspect-ratio+min-block-size");
4264
+ if (hasMinHeight) reasons.push("aspect-ratio+min-height");
4265
+ }
4266
+ return {
4267
+ hasReservedSpace: reasons.length > 0,
4268
+ reasons,
4269
+ hasContainIntrinsicSize: hasContainIntrinsic,
4270
+ hasUsableAspectRatio: hasAspectRatio,
4271
+ hasDeclaredBlockDimension: hasHeight || hasBlockSize || hasMinHeight || hasMinBlockSize,
4272
+ hasDeclaredInlineDimension: hasDeclaredDimension(snapshot, "width") || hasDeclaredDimension(snapshot, "inline-size") || hasDeclaredDimension(snapshot, "min-width") || hasDeclaredDimension(snapshot, "flex-basis") || isBlockLevelDisplay(snapshot)
4273
+ };
4274
+ }
4275
+ function hasDeclaredDimension(snapshot, property) {
4276
+ const signal = snapshot.signals.get(property);
4277
+ if (!signal) return false;
4278
+ if (signal.kind === 0 /* Known */) {
4279
+ if (signal.px !== null) return signal.px > 0;
4280
+ if (signal.normalized.length === 0) return false;
4281
+ return !isNonReservingDimension(signal.normalized);
4282
+ }
4283
+ if (signal.kind === 1 /* Unknown */) {
4284
+ return signal.source !== null;
4285
+ }
4286
+ return false;
4287
+ }
4288
+ function isBlockLevelDisplay(snapshot) {
4289
+ const signal = snapshot.signals.get("display");
4290
+ if (!signal || signal.kind !== 0 /* Known */) return false;
4291
+ return BLOCK_LEVEL_DISPLAY_VALUES.has(signal.normalized);
4292
+ }
4293
+ function hasUsableAspectRatio(snapshot) {
4294
+ const signal = snapshot.signals.get("aspect-ratio");
4295
+ if (!signal) return false;
4296
+ if (signal.guard.kind === 1) return false;
4297
+ if (signal.kind === 1 /* Unknown */) return false;
4298
+ if (signal.kind !== 0 /* Known */) return false;
4299
+ if (signal.normalized.length === 0) return false;
4300
+ return signal.normalized !== "auto";
4301
+ }
4302
+ function isNonReservingDimension(value) {
4303
+ if (NON_RESERVING_DIMENSION_KEYWORDS.has(value)) return true;
4304
+ if (value.startsWith("fit-content(")) return true;
4305
+ return false;
4306
+ }
4307
+ function computeScrollContainerFact(snapshot) {
4308
+ const overflowSignal = snapshot.signals.get("overflow");
4309
+ const overflowYSignal = snapshot.signals.get("overflow-y");
4310
+ const overflow = overflowSignal && overflowSignal.kind === 0 /* Known */ ? overflowSignal.normalized : null;
4311
+ const overflowY = overflowYSignal && overflowYSignal.kind === 0 /* Known */ ? overflowYSignal.normalized : null;
4312
+ const shorthandAxis = parseOverflowShorthandAxis(overflow);
4313
+ const yFromLonghand = parseSingleAxisScroll(overflowY);
4314
+ const xScroll = shorthandAxis.x;
4315
+ const yScroll = yFromLonghand === null ? shorthandAxis.y : yFromLonghand;
4316
+ const hasConditionalScroll = overflowSignal?.guard.kind === 1 && (shorthandAxis.x || shorthandAxis.y) || overflowYSignal?.guard.kind === 1 && yFromLonghand === true;
4317
+ const hasUnconditionalScroll = overflowSignal?.guard.kind === 0 && (shorthandAxis.x || shorthandAxis.y) || overflowYSignal?.guard.kind === 0 && yFromLonghand === true;
4318
+ return {
4319
+ isScrollContainer: xScroll || yScroll,
4320
+ axis: toScrollAxis(xScroll, yScroll),
4321
+ overflow,
4322
+ overflowY,
4323
+ hasConditionalScroll,
4324
+ hasUnconditionalScroll
4325
+ };
4326
+ }
4327
+ var NO_SCROLL = Object.freeze({ x: false, y: false });
4328
+ var BOTH_SCROLL = Object.freeze({ x: true, y: true });
4329
+ function parseOverflowShorthandAxis(value) {
4330
+ if (value === null) return NO_SCROLL;
4331
+ const trimmed = value.trim();
4332
+ const spaceIdx = trimmed.indexOf(" ");
4333
+ if (spaceIdx === -1) {
4334
+ const scroll = SCROLLABLE_VALUES.has(trimmed);
4335
+ return scroll ? BOTH_SCROLL : NO_SCROLL;
4336
+ }
4337
+ const first = trimmed.slice(0, spaceIdx);
4338
+ const second = trimmed.slice(spaceIdx + 1).trimStart();
4339
+ return {
4340
+ x: SCROLLABLE_VALUES.has(first),
4341
+ y: SCROLLABLE_VALUES.has(second)
4342
+ };
4343
+ }
4344
+ function parseSingleAxisScroll(value) {
4345
+ if (value === null) return null;
4346
+ const trimmed = value.trim();
4347
+ const spaceIdx = trimmed.indexOf(" ");
4348
+ const first = spaceIdx === -1 ? trimmed : trimmed.slice(0, spaceIdx);
4349
+ return SCROLLABLE_VALUES.has(first);
4350
+ }
4351
+ function toScrollAxis(x, y) {
4352
+ if (x && y) return 3 /* Both */;
4353
+ if (x) return 1 /* X */;
4354
+ if (y) return 2 /* Y */;
4355
+ return 0 /* None */;
4356
+ }
4357
+ function computeFlowParticipationFact(snapshot) {
4358
+ const signal = snapshot.signals.get("position");
4359
+ if (!signal || signal.kind !== 0 /* Known */) {
4360
+ return { inFlow: true, position: null, hasConditionalOutOfFlow: false, hasUnconditionalOutOfFlow: false };
4361
+ }
4362
+ const position = signal.normalized;
4363
+ const outOfFlow = position === "absolute" || position === "fixed";
4364
+ return {
4365
+ inFlow: !outOfFlow,
4366
+ position,
4367
+ hasConditionalOutOfFlow: signal.guard.kind === 1 && outOfFlow,
4368
+ hasUnconditionalOutOfFlow: signal.guard.kind === 0 && outOfFlow
4369
+ };
4370
+ }
4371
+
4185
4372
  // src/compilation/binding/cascade-binder.ts
4186
4373
  var bindCacheBySymbolTable = /* @__PURE__ */ new WeakMap();
4187
4374
  function getOrBuildBindState(symbolTable) {
@@ -4643,8 +4830,6 @@ function matchesRequiredAttributes(required, actual) {
4643
4830
  if (constraint === void 0) continue;
4644
4831
  if (!actual.has(constraint.name)) return 1 /* NoMatch */;
4645
4832
  if (constraint.operator === "exists") {
4646
- const existsValue = actual.get(constraint.name);
4647
- if (existsValue === null) hasConditional = true;
4648
4833
  continue;
4649
4834
  }
4650
4835
  const actualValue = actual.get(constraint.name);
@@ -4854,10 +5039,9 @@ function augmentCascadeWithTailwindFromSymbolTable(cascade, element, symbolTable
4854
5039
  for (let i = 0; i < classTokens.length; i++) {
4855
5040
  const token = classTokens[i];
4856
5041
  if (token === void 0) continue;
4857
- const classSymbol = symbolTable.classNames.get(token);
4858
- if (!classSymbol) continue;
4859
- if (classSymbol.source.kind !== "tailwind") continue;
4860
- const resolvedCSS = classSymbol.source.resolvedCSS;
5042
+ const classSymbol = symbolTable.getClassName(token);
5043
+ if (classSymbol === null) continue;
5044
+ const resolvedCSS = classSymbol.tailwindResolvedCSS;
4861
5045
  if (resolvedCSS === null) continue;
4862
5046
  const declarations = parseTailwindCssDeclarations(resolvedCSS);
4863
5047
  for (let j = 0; j < declarations.length; j++) {
@@ -4873,126 +5057,21 @@ function augmentCascadeWithTailwindFromSymbolTable(cascade, element, symbolTable
4873
5057
  }
4874
5058
  }
4875
5059
  }
4876
- var SCROLLABLE_VALUES = /* @__PURE__ */ new Set(["auto", "scroll"]);
4877
- var OUT_OF_FLOW_POSITIONS = /* @__PURE__ */ new Set(["absolute", "fixed", "sticky"]);
4878
- function computeLayoutFact(factKind, elementId, declarations, allElements, getCascadeForElement) {
5060
+ function computeLayoutFact(factKind, elementId, snapshot, allElements, getSnapshotForElement) {
4879
5061
  switch (factKind) {
4880
5062
  case "reservedSpace":
4881
- return computeReservedSpaceFact(declarations);
5063
+ return computeReservedSpaceFact(snapshot);
4882
5064
  case "scrollContainer":
4883
- return computeScrollContainerFact(declarations);
5065
+ return computeScrollContainerFact(snapshot);
4884
5066
  case "flowParticipation":
4885
- return computeFlowParticipationFact(declarations);
5067
+ return computeFlowParticipationFact(snapshot);
4886
5068
  case "containingBlock":
4887
- return computeContainingBlockFact(elementId, allElements, getCascadeForElement);
5069
+ return computeContainingBlockFact(elementId, allElements, getSnapshotForElement);
4888
5070
  default:
4889
5071
  throw new Error(`Unknown layout fact kind: ${factKind}`);
4890
5072
  }
4891
5073
  }
4892
- function getCascadeValue(declarations, property) {
4893
- const decl = declarations.get(property);
4894
- if (!decl) return null;
4895
- return decl.value.trim().toLowerCase();
4896
- }
4897
- function computeReservedSpaceFact(declarations) {
4898
- const reasons = [];
4899
- const height = getCascadeValue(declarations, "height");
4900
- if (height !== null && height !== "auto" && height !== "fit-content" && height !== "min-content" && height !== "max-content") {
4901
- reasons.push("height");
4902
- }
4903
- const blockSize = getCascadeValue(declarations, "block-size");
4904
- if (blockSize !== null && blockSize !== "auto" && blockSize !== "fit-content" && blockSize !== "min-content" && blockSize !== "max-content") {
4905
- reasons.push("block-size");
4906
- }
4907
- const minHeight = getCascadeValue(declarations, "min-height");
4908
- if (minHeight !== null && minHeight !== "0" && minHeight !== "0px" && minHeight !== "auto") {
4909
- reasons.push("min-height");
4910
- }
4911
- const minBlockSize = getCascadeValue(declarations, "min-block-size");
4912
- if (minBlockSize !== null && minBlockSize !== "0" && minBlockSize !== "0px" && minBlockSize !== "auto") {
4913
- reasons.push("min-block-size");
4914
- }
4915
- const containIntrinsicSize = getCascadeValue(declarations, "contain-intrinsic-size");
4916
- const hasContainIntrinsicSize = containIntrinsicSize !== null;
4917
- if (hasContainIntrinsicSize) {
4918
- reasons.push("contain-intrinsic-size");
4919
- }
4920
- const aspectRatio = getCascadeValue(declarations, "aspect-ratio");
4921
- const hasUsableAspectRatio = aspectRatio !== null && aspectRatio !== "auto";
4922
- const width = getCascadeValue(declarations, "width");
4923
- const inlineSize = getCascadeValue(declarations, "inline-size");
4924
- const hasDeclaredInlineDimension = width !== null && width !== "auto" || inlineSize !== null && inlineSize !== "auto";
4925
- const hasDeclaredBlockDimension = height !== null && height !== "auto";
4926
- if (hasUsableAspectRatio && hasDeclaredInlineDimension) {
4927
- if (width !== null) reasons.push("aspect-ratio+width");
4928
- if (inlineSize !== null) reasons.push("aspect-ratio+inline-size");
4929
- }
4930
- return {
4931
- hasReservedSpace: reasons.length > 0,
4932
- reasons,
4933
- hasContainIntrinsicSize,
4934
- hasUsableAspectRatio,
4935
- hasDeclaredInlineDimension,
4936
- hasDeclaredBlockDimension
4937
- };
4938
- }
4939
- function computeScrollContainerFact(declarations) {
4940
- const overflow = getCascadeValue(declarations, "overflow");
4941
- const overflowY = getCascadeValue(declarations, "overflow-y");
4942
- let axis = 0;
4943
- let isScrollContainer = false;
4944
- let hasConditionalScroll = false;
4945
- let hasUnconditionalScroll = false;
4946
- if (overflow !== null && SCROLLABLE_VALUES.has(overflow)) {
4947
- isScrollContainer = true;
4948
- axis = 3;
4949
- const decl = declarations.get("overflow");
4950
- if (decl && decl.guardProvenance.kind === 1 /* Conditional */) {
4951
- hasConditionalScroll = true;
4952
- } else {
4953
- hasUnconditionalScroll = true;
4954
- }
4955
- }
4956
- if (overflowY !== null && SCROLLABLE_VALUES.has(overflowY)) {
4957
- isScrollContainer = true;
4958
- if (axis === 0) axis = 2;
4959
- const decl = declarations.get("overflow-y");
4960
- if (decl && decl.guardProvenance.kind === 1 /* Conditional */) {
4961
- hasConditionalScroll = true;
4962
- } else {
4963
- hasUnconditionalScroll = true;
4964
- }
4965
- }
4966
- return {
4967
- isScrollContainer,
4968
- axis,
4969
- overflow,
4970
- overflowY,
4971
- hasConditionalScroll,
4972
- hasUnconditionalScroll
4973
- };
4974
- }
4975
- function computeFlowParticipationFact(declarations) {
4976
- const position = getCascadeValue(declarations, "position");
4977
- const isOutOfFlow = position !== null && OUT_OF_FLOW_POSITIONS.has(position);
4978
- let hasConditionalOutOfFlow = false;
4979
- let hasUnconditionalOutOfFlow = false;
4980
- if (isOutOfFlow) {
4981
- const decl = declarations.get("position");
4982
- if (decl && decl.guardProvenance.kind === 1 /* Conditional */) {
4983
- hasConditionalOutOfFlow = true;
4984
- } else {
4985
- hasUnconditionalOutOfFlow = true;
4986
- }
4987
- }
4988
- return {
4989
- inFlow: !isOutOfFlow,
4990
- position,
4991
- hasConditionalOutOfFlow,
4992
- hasUnconditionalOutOfFlow
4993
- };
4994
- }
4995
- function computeContainingBlockFact(elementId, allElements, getCascadeForElement) {
5074
+ function computeContainingBlockFact(elementId, allElements, getSnapshotForElement) {
4996
5075
  let current = null;
4997
5076
  for (let i = 0; i < allElements.length; i++) {
4998
5077
  const el = allElements[i];
@@ -5006,10 +5085,11 @@ function computeContainingBlockFact(elementId, allElements, getCascadeForElement
5006
5085
  }
5007
5086
  let ancestor = current.parentElementNode;
5008
5087
  while (ancestor !== null) {
5009
- const ancestorCascade = getCascadeForElement(ancestor.elementId);
5010
- const pos = getCascadeValue(ancestorCascade, "position");
5088
+ const ancestorSnapshot = getSnapshotForElement(ancestor.elementId);
5089
+ const posSignal = ancestorSnapshot.signals.get("position");
5090
+ const pos = posSignal && posSignal.kind === 0 ? posSignal.normalized : null;
5011
5091
  if (pos !== null && pos !== "static") {
5012
- const reservedFact = computeReservedSpaceFact(ancestorCascade);
5092
+ const reservedFact = computeReservedSpaceFact(ancestorSnapshot);
5013
5093
  return {
5014
5094
  nearestPositionedAncestorKey: ancestor.key,
5015
5095
  nearestPositionedAncestorHasReservedSpace: reservedFact.hasReservedSpace
@@ -5068,59 +5148,6 @@ function buildScopedSelectorIndex(scopedCSSFiles, symbolTable) {
5068
5148
  };
5069
5149
  }
5070
5150
 
5071
- // src/compilation/analysis/layout-fact.ts
5072
- var SCROLLABLE_VALUES2 = /* @__PURE__ */ new Set(["auto", "scroll"]);
5073
- function computeScrollContainerFact2(snapshot) {
5074
- const overflowSignal = snapshot.signals.get("overflow");
5075
- const overflowYSignal = snapshot.signals.get("overflow-y");
5076
- const overflow = overflowSignal && overflowSignal.kind === 0 /* Known */ ? overflowSignal.normalized : null;
5077
- const overflowY = overflowYSignal && overflowYSignal.kind === 0 /* Known */ ? overflowYSignal.normalized : null;
5078
- const shorthandAxis = parseOverflowShorthandAxis(overflow);
5079
- const yFromLonghand = parseSingleAxisScroll(overflowY);
5080
- const xScroll = shorthandAxis.x;
5081
- const yScroll = yFromLonghand === null ? shorthandAxis.y : yFromLonghand;
5082
- const hasConditionalScroll = overflowSignal?.guard.kind === 1 && (shorthandAxis.x || shorthandAxis.y) || overflowYSignal?.guard.kind === 1 && yFromLonghand === true;
5083
- const hasUnconditionalScroll = overflowSignal?.guard.kind === 0 && (shorthandAxis.x || shorthandAxis.y) || overflowYSignal?.guard.kind === 0 && yFromLonghand === true;
5084
- return {
5085
- isScrollContainer: xScroll || yScroll,
5086
- axis: toScrollAxis(xScroll, yScroll),
5087
- overflow,
5088
- overflowY,
5089
- hasConditionalScroll,
5090
- hasUnconditionalScroll
5091
- };
5092
- }
5093
- var NO_SCROLL = Object.freeze({ x: false, y: false });
5094
- var BOTH_SCROLL = Object.freeze({ x: true, y: true });
5095
- function parseOverflowShorthandAxis(value) {
5096
- if (value === null) return NO_SCROLL;
5097
- const trimmed = value.trim();
5098
- const spaceIdx = trimmed.indexOf(" ");
5099
- if (spaceIdx === -1) {
5100
- const scroll = SCROLLABLE_VALUES2.has(trimmed);
5101
- return scroll ? BOTH_SCROLL : NO_SCROLL;
5102
- }
5103
- const first = trimmed.slice(0, spaceIdx);
5104
- const second = trimmed.slice(spaceIdx + 1).trimStart();
5105
- return {
5106
- x: SCROLLABLE_VALUES2.has(first),
5107
- y: SCROLLABLE_VALUES2.has(second)
5108
- };
5109
- }
5110
- function parseSingleAxisScroll(value) {
5111
- if (value === null) return null;
5112
- const trimmed = value.trim();
5113
- const spaceIdx = trimmed.indexOf(" ");
5114
- const first = spaceIdx === -1 ? trimmed : trimmed.slice(0, spaceIdx);
5115
- return SCROLLABLE_VALUES2.has(first);
5116
- }
5117
- function toScrollAxis(x, y) {
5118
- if (x && y) return 3 /* Both */;
5119
- if (x) return 1 /* X */;
5120
- if (y) return 2 /* Y */;
5121
- return 0 /* None */;
5122
- }
5123
-
5124
5151
  // src/compilation/analysis/alignment.ts
5125
5152
  var CONTROL_ELEMENT_TAGS2 = /* @__PURE__ */ new Set(["input", "select", "textarea", "button"]);
5126
5153
  var INTRINSIC_REPLACED_TAGS = /* @__PURE__ */ new Set(["img", "svg", "video", "canvas", "iframe", "object", "embed"]);
@@ -6545,13 +6572,13 @@ function buildConsistencyEvidence(input) {
6545
6572
  const lineHeight = normalizeDeviation(input.subjectLineHeightDeviation, input.cohortProfile.lineHeightDispersionPx, input.cohortProfile.medianLineHeightPx);
6546
6573
  const baselinesIrrelevant = input.context.baselineRelevance === "irrelevant";
6547
6574
  const blockAxisIsMainAxis = !input.context.crossAxisIsBlockAxis;
6548
- const suppressAll = blockAxisIsMainAxis;
6575
+ const suppressAll = blockAxisIsMainAxis || baselinesIrrelevant;
6549
6576
  const offset = suppressAll ? ZERO_STRENGTH : offsetRaw;
6550
6577
  const declaredOffset = suppressAll ? ZERO_STRENGTH : declaredOffsetRaw;
6551
- const baselineStrength = baselinesIrrelevant || suppressAll ? ZERO_STRENGTH : resolveBaselineStrength(input, lineHeight);
6552
- const contextStrength = baselinesIrrelevant || suppressAll ? ZERO_STRENGTH : resolveContextStrength(input, lineHeight);
6553
- const replacedStrength = baselinesIrrelevant || suppressAll ? ZERO_STRENGTH : resolveReplacedControlStrength(input, lineHeight);
6554
- const compositionResult = baselinesIrrelevant || suppressAll ? null : resolveContentCompositionStrength(input);
6578
+ const baselineStrength = suppressAll ? ZERO_STRENGTH : resolveBaselineStrength(input, lineHeight);
6579
+ const contextStrength = suppressAll ? ZERO_STRENGTH : resolveContextStrength(input, lineHeight);
6580
+ const replacedStrength = suppressAll ? ZERO_STRENGTH : resolveReplacedControlStrength(input, lineHeight);
6581
+ const compositionResult = suppressAll ? null : resolveContentCompositionStrength(input);
6555
6582
  const compositionStrength = compositionResult ? compositionResult.evidence : ZERO_STRENGTH;
6556
6583
  const contextCertaintyPenalty = resolveContextCertaintyPenalty(input);
6557
6584
  const provenance = input.cohortProvenance;
@@ -6848,7 +6875,7 @@ function formatPrimaryFix(findings) {
6848
6875
  }
6849
6876
 
6850
6877
  // src/compilation/analysis/cascade-analyzer.ts
6851
- var SCROLLABLE_VALUES3 = /* @__PURE__ */ new Set(["auto", "scroll"]);
6878
+ var SCROLLABLE_VALUES2 = /* @__PURE__ */ new Set(["auto", "scroll"]);
6852
6879
  function computeConditionalDelta(elements, cascadeByElementId, monitoredDeclarationsBySelectorId, symbolTable) {
6853
6880
  const deltaByElementId = /* @__PURE__ */ new Map();
6854
6881
  const elementsWithDeltaBySignal = /* @__PURE__ */ new Map();
@@ -7056,7 +7083,7 @@ function containsScrollToken(value) {
7056
7083
  for (let i = 0; i < tokens.length; i++) {
7057
7084
  const token = tokens[i];
7058
7085
  if (token === void 0) continue;
7059
- if (SCROLLABLE_VALUES3.has(token)) return true;
7086
+ if (SCROLLABLE_VALUES2.has(token)) return true;
7060
7087
  }
7061
7088
  return false;
7062
7089
  }
@@ -7503,14 +7530,14 @@ function createFileSemanticModel(solidTree, symbolTable, dependencyGraph, compil
7503
7530
  return out;
7504
7531
  },
7505
7532
  getLayoutFact(elementId, factKind) {
7506
- const cascade = this.getElementCascade(elementId);
7533
+ const snapshot = this.getSignalSnapshot(elementId);
7507
7534
  const allElements = this.getElementNodes();
7508
7535
  return computeLayoutFact(
7509
7536
  factKind,
7510
7537
  elementId,
7511
- cascade.declarations,
7538
+ snapshot,
7512
7539
  allElements,
7513
- (id) => this.getElementCascade(id).declarations
7540
+ (id) => this.getSignalSnapshot(id)
7514
7541
  );
7515
7542
  },
7516
7543
  // ── Tier 4-5: Signal + fact + alignment queries ────────────────────
@@ -7549,7 +7576,7 @@ function createFileSemanticModel(solidTree, symbolTable, dependencyGraph, compil
7549
7576
  if (!el) continue;
7550
7577
  const snapshot = snapshotIndex.get(el.elementId);
7551
7578
  if (!snapshot) continue;
7552
- const fact = computeScrollContainerFact2(snapshot);
7579
+ const fact = computeScrollContainerFact(snapshot);
7553
7580
  if (fact.isScrollContainer) out.push(el);
7554
7581
  }
7555
7582
  return out;
@@ -7614,7 +7641,26 @@ function makeCompilation(solidTrees, cssTrees, tailwindConfig, packageManifest,
7614
7641
  if (cachedSymbolTable === null) {
7615
7642
  const allCssTrees = [];
7616
7643
  for (const tree of cssTrees.values()) allCssTrees.push(tree);
7617
- cachedSymbolTable = buildSymbolTable(allCssTrees, tailwindConfig?.validator ?? null);
7644
+ let solidClassTokens = null;
7645
+ if (tailwindConfig?.validator !== null && tailwindConfig?.validator !== void 0) {
7646
+ const tokens = /* @__PURE__ */ new Set();
7647
+ for (const st of solidTrees.values()) {
7648
+ for (const [, idx] of st.staticClassTokensByElementId) {
7649
+ for (let i = 0; i < idx.tokens.length; i++) {
7650
+ const t = idx.tokens[i];
7651
+ if (t) tokens.add(t);
7652
+ }
7653
+ }
7654
+ for (const [, idx] of st.staticClassListKeysByElementId) {
7655
+ for (let i = 0; i < idx.keys.length; i++) {
7656
+ const t = idx.keys[i];
7657
+ if (t) tokens.add(t);
7658
+ }
7659
+ }
7660
+ }
7661
+ solidClassTokens = tokens;
7662
+ }
7663
+ cachedSymbolTable = buildSymbolTable(allCssTrees, tailwindConfig?.validator ?? null, solidClassTokens);
7618
7664
  }
7619
7665
  return cachedSymbolTable;
7620
7666
  },
@@ -8518,7 +8564,7 @@ function dispatchCompilationActions(actions, compilation, symbolTable, emit) {
8518
8564
  }
8519
8565
 
8520
8566
  // src/css/rules/animation/layout-animation-exempt.ts
8521
- var OUT_OF_FLOW_POSITIONS2 = /* @__PURE__ */ new Set(["fixed", "absolute"]);
8567
+ var OUT_OF_FLOW_POSITIONS = /* @__PURE__ */ new Set(["fixed", "absolute"]);
8522
8568
  var OVERFLOW_CONTAINMENT_VALUES = /* @__PURE__ */ new Set(["hidden", "clip"]);
8523
8569
  var IDENTITY_ATTRIBUTE_NAMES = /* @__PURE__ */ new Set(["data-component", "data-slot"]);
8524
8570
  function isLayoutAnimationExempt(declaration, layoutProperty) {
@@ -8548,7 +8594,7 @@ function hasOutOfFlowPosition(rule) {
8548
8594
  const decl = positionDecls[i];
8549
8595
  if (!decl) continue;
8550
8596
  const value = decl.value.trim().toLowerCase();
8551
- if (OUT_OF_FLOW_POSITIONS2.has(value)) return true;
8597
+ if (OUT_OF_FLOW_POSITIONS.has(value)) return true;
8552
8598
  }
8553
8599
  return false;
8554
8600
  }
@@ -9233,10 +9279,7 @@ var jsxStyleNoUnusedCustomProp = defineAnalysisRule({
9233
9279
  requirement: { tier: 1 /* CrossSyntax */ },
9234
9280
  register(registry) {
9235
9281
  registry.registerCrossSyntaxAction((solidTree, symbolTable, emit) => {
9236
- const usedVarNames = /* @__PURE__ */ new Set();
9237
- for (const [name] of symbolTable.customProperties) {
9238
- usedVarNames.add(name);
9239
- }
9282
+ const usedVarNames = symbolTable.referencedCustomPropertyNames;
9240
9283
  if (solidTree.jsxClassListAttributes.length > 0) return;
9241
9284
  let hasNonStaticClass = false;
9242
9285
  for (const [, idx] of solidTree.staticClassTokensByElementId) {
@@ -9274,7 +9317,7 @@ import ts9 from "typescript";
9274
9317
  var messages13 = {
9275
9318
  classListGeometryToggle: "classList toggles '{{className}}', and matching CSS changes layout-affecting '{{property}}', which can cause CLS."
9276
9319
  };
9277
- var OUT_OF_FLOW_POSITIONS3 = /* @__PURE__ */ new Set(["fixed", "absolute"]);
9320
+ var OUT_OF_FLOW_POSITIONS2 = /* @__PURE__ */ new Set(["fixed", "absolute"]);
9278
9321
  var jsxLayoutClasslistGeometryToggle = defineAnalysisRule({
9279
9322
  id: "jsx-layout-classlist-geometry-toggle",
9280
9323
  severity: "warn",
@@ -9327,7 +9370,7 @@ function classEstablishesOutOfFlow(className, symbolTable) {
9327
9370
  const decl = positionDecls[j];
9328
9371
  if (!decl) continue;
9329
9372
  const value = decl.value.trim().toLowerCase();
9330
- if (OUT_OF_FLOW_POSITIONS3.has(value)) return true;
9373
+ if (OUT_OF_FLOW_POSITIONS2.has(value)) return true;
9331
9374
  }
9332
9375
  }
9333
9376
  return false;
@@ -10196,7 +10239,7 @@ function normalizeStylePropertyKey(key) {
10196
10239
  if (key.includes("-")) return key.toLowerCase();
10197
10240
  return toKebabCase(key);
10198
10241
  }
10199
- function isExemptFromCLS(element, flowFact, property, _semanticModel) {
10242
+ function isExemptFromCLS(element, flowFact, property, semanticModel) {
10200
10243
  if (!flowFact.inFlow) return true;
10201
10244
  if (POSITIONED_OFFSET_PROPERTIES.has(property) && flowFact.position !== null && flowFact.position !== "static") {
10202
10245
  return true;
@@ -10204,8 +10247,17 @@ function isExemptFromCLS(element, flowFact, property, _semanticModel) {
10204
10247
  if (hasLayoutContainment(element) || element.parentElementNode !== null && hasLayoutContainment(element.parentElementNode)) {
10205
10248
  return true;
10206
10249
  }
10250
+ if (element.parentElementNode !== null && parentClipsOverflow(element.parentElementNode, semanticModel)) {
10251
+ return true;
10252
+ }
10207
10253
  return false;
10208
10254
  }
10255
+ var CLIPPING_OVERFLOW_VALUES = /* @__PURE__ */ new Set(["hidden", "clip"]);
10256
+ function parentClipsOverflow(parent, semanticModel) {
10257
+ const snapshot = semanticModel.getSignalSnapshot(parent.elementId);
10258
+ const signal = snapshot.signals.get("overflow");
10259
+ return signal !== void 0 && signal.kind === 0 /* Known */ && CLIPPING_OVERFLOW_VALUES.has(signal.normalized);
10260
+ }
10209
10261
  function hasLayoutContainment(node) {
10210
10262
  const contain = node.inlineStyleValues.get("contain");
10211
10263
  if (contain === void 0) return false;
@@ -10307,7 +10359,7 @@ var messages25 = {
10307
10359
  noReservedBlockSize: "Interactive element `<{{tag}}>` has no declared height (minimum `{{min}}px` required by policy `{{policy}}`). The element is content-sized and may not meet the touch-target threshold.",
10308
10360
  noReservedInlineSize: "Interactive element `<{{tag}}>` has no declared width (minimum `{{min}}px` required by policy `{{policy}}`). The element is content-sized and may not meet the touch-target threshold."
10309
10361
  };
10310
- var INTERACTIVE_HTML_TAGS2 = /* @__PURE__ */ new Set(["button", "a", "input", "select", "textarea", "label", "summary"]);
10362
+ var INTERACTIVE_HTML_TAGS2 = /* @__PURE__ */ new Set(["button", "a", "input", "select", "textarea", "summary"]);
10311
10363
  var INTERACTIVE_ARIA_ROLES2 = /* @__PURE__ */ new Set([
10312
10364
  "button",
10313
10365
  "link",
@@ -10468,9 +10520,12 @@ var jsxLayoutPolicyTouchTarget = defineAnalysisRule({
10468
10520
  }
10469
10521
  });
10470
10522
  function classifyInteractive(element, semanticModel) {
10523
+ if (element.attributes.has("hidden")) return null;
10471
10524
  const tag = element.tagName;
10472
10525
  if (tag !== null && INTERACTIVE_HTML_TAGS2.has(tag)) {
10526
+ if (tag === "input" && element.attributes.get("type") === "hidden") return null;
10473
10527
  if (tag === "input" || tag === "select" || tag === "textarea") return "input";
10528
+ if (tag === "a" && isInlineTextLink(element)) return null;
10474
10529
  return "button";
10475
10530
  }
10476
10531
  const roleAttr = getJSXAttributeEntity(semanticModel.solidTree, element.jsxEntity, "role");
@@ -10500,6 +10555,14 @@ function isVisuallyHidden(element, snapshot) {
10500
10555
  if (widthSignal && widthSignal.kind === 0 /* Known */ && widthSignal.px === 1 && heightSignal && heightSignal.kind === 0 /* Known */ && heightSignal.px === 1) return true;
10501
10556
  return false;
10502
10557
  }
10558
+ function isInlineTextLink(element) {
10559
+ const content = element.textualContent;
10560
+ if (content !== 0 /* Yes */ && content !== 3 /* DynamicText */) return false;
10561
+ const parent = element.parentElementNode;
10562
+ if (parent === null) return false;
10563
+ const parentContent = parent.textualContent;
10564
+ return parentContent === 0 /* Yes */ || parentContent === 3 /* DynamicText */ || parentContent === 2 /* Unknown */;
10565
+ }
10503
10566
  function checkDimension(snapshot, signal, min, element, semanticModel, emit, messageId, template, tag, policyName) {
10504
10567
  let px = readKnownPx2(snapshot, signal);
10505
10568
  if (px === null) {
@@ -10510,6 +10573,7 @@ function checkDimension(snapshot, signal, min, element, semanticModel, emit, mes
10510
10573
  }
10511
10574
  if (px === null) return;
10512
10575
  if (px >= min) return;
10576
+ if (px === 0 && (signal === "min-width" || signal === "min-height")) return;
10513
10577
  emit(createDiagnostic(
10514
10578
  element.solidFile,
10515
10579
  element.jsxEntity.node,
@@ -12628,10 +12692,8 @@ var cssPolicyTypography = defineAnalysisRule({
12628
12692
  var messages57 = {
12629
12693
  letterSpacingTooSmall: "Letter spacing `{{value}}` ({{resolved}}em) is below the minimum `{{min}}em` for policy `{{policy}}`.",
12630
12694
  wordSpacingTooSmall: "Word spacing `{{value}}` ({{resolved}}em) is below the minimum `{{min}}em` for policy `{{policy}}`.",
12631
- paragraphSpacingTooSmall: "Paragraph spacing `{{value}}` ({{resolved}}em) is below the minimum `{{min}}em` ({{minMultiplier}}\xD7 font-size) for policy `{{policy}}`.",
12632
- touchTargetTooSmall: "`{{property}}: {{value}}` ({{resolved}}px) is below the minimum `{{min}}px` for interactive elements in policy `{{policy}}`."
12695
+ paragraphSpacingTooSmall: "Paragraph spacing `{{value}}` ({{resolved}}em) is below the minimum `{{min}}em` ({{minMultiplier}}\xD7 font-size) for policy `{{policy}}`."
12633
12696
  };
12634
- var INTERACTIVE_SELECTORS = /button|input|select|textarea|\[role=/i;
12635
12697
  var cssPolicySpacing = defineAnalysisRule({
12636
12698
  id: "css-policy-spacing",
12637
12699
  severity: "warn",
@@ -12679,28 +12741,6 @@ var cssPolicySpacing = defineAnalysisRule({
12679
12741
  ));
12680
12742
  }
12681
12743
  }
12682
- for (const prop of ["height", "min-height"]) {
12683
- const decls = tree.declarationsByProperty.get(prop);
12684
- if (!decls) continue;
12685
- for (let i = 0; i < decls.length; i++) {
12686
- const d = decls[i];
12687
- if (!d) continue;
12688
- const rule = d.rule;
12689
- if (!rule) continue;
12690
- if (!INTERACTIVE_SELECTORS.test(rule.selectorText)) continue;
12691
- const px = parsePxValue(d.value);
12692
- if (px === null || px >= policy.minButtonHeight) continue;
12693
- emit(createCSSDiagnostic(
12694
- d.file.path,
12695
- d.startLine,
12696
- d.startColumn,
12697
- cssPolicySpacing.id,
12698
- "touchTargetTooSmall",
12699
- resolveMessage(messages57.touchTargetTooSmall, { property: prop, value: d.value.trim(), resolved: String(Math.round(px * 100) / 100), min: String(policy.minButtonHeight), policy: name }),
12700
- "warn"
12701
- ));
12702
- }
12703
- }
12704
12744
  for (const prop of ["margin-bottom", "margin-block-end"]) {
12705
12745
  const decls = tree.declarationsByProperty.get(prop);
12706
12746
  if (!decls) continue;