[
  {
    "id": "behavior-state-context",
    "type": "context",
    "selector": "#good .metric, #bad .metric",
    "required": [".state-label", ".as-of", ".refresh-at"],
    "pages": ["failed-refresh"],
    "designRules": ["DR-009"],
    "severity": "error",
    "reason": "The controlled failed-refresh state must disclose status, snapshot age, and the separate refresh attempt. Labels do not establish backend truth."
  },
  {
    "id": "behavior-distinct-service-labels",
    "type": "no-clip",
    "selector": "#good .service, #bad .service",
    "pages": ["long-labels"],
    "designRules": ["DR-015"],
    "severity": "error",
    "reason": "These service names differ only at the suffix; clipping hides the distinction and no full-text inspection control is supplied."
  },
  {
    "id": "behavior-lesson-priority",
    "type": "min-font-size",
    "selector": "#rule-heading",
    "min": 28,
    "pages": ["failed-refresh"],
    "viewports": ["desktop"],
    "designRules": ["DR-013"],
    "severity": "error",
    "reason": "The specific lesson outranks fixture navigation in this desktop teaching view."
  },
  {
    "id": "behavior-gallery-overhead",
    "type": "max-height",
    "selector": ".gallery-heading",
    "max": 64,
    "pages": ["failed-refresh"],
    "viewports": ["desktop"],
    "designRules": ["DR-008", "DR-013"],
    "severity": "error",
    "reason": "Gallery framing must not compete with the example task."
  },
  {
    "id": "behavior-state-proximity",
    "type": "relative-position",
    "selector": "#good .metric",
    "from": "[data-role=\"count\"]",
    "to": ".state-label",
    "relation": "left-of",
    "minGap": 0,
    "maxGap": 16,
    "tolerance": 1,
    "pages": ["failed-refresh"],
    "viewports": ["desktop"],
    "designRules": ["DR-006", "DR-009"],
    "severity": "error",
    "reason": "The retained value and its stale qualifier form one readable unit, not a number followed by corrective prose."
  },
  {
    "id": "behavior-snapshot-proximity",
    "type": "relative-position",
    "selector": "#good .metric",
    "from": ".metric-value",
    "to": ".as-of",
    "relation": "above",
    "minGap": 0,
    "maxGap": 12,
    "tolerance": 1,
    "pages": ["failed-refresh"],
    "viewports": ["desktop"],
    "designRules": ["DR-003", "DR-006", "DR-009"],
    "severity": "error",
    "reason": "Keep the data as-of time immediately below the qualified value."
  },
  {
    "id": "behavior-finite-card",
    "type": "max-height",
    "selector": ".behavior-pair .sample",
    "max": 256,
    "pages": ["failed-refresh"],
    "viewports": ["desktop"],
    "designRules": ["DR-007", "DR-008"],
    "severity": "error",
    "reason": "This finite desktop snapshot needs no reserved 20rem panel; shared rows provide alignment."
  },
  {
    "id": "behavior-sample-alignment",
    "type": "align",
    "selector": ".behavior-pair .sample",
    "edge": "top",
    "tolerance": 1,
    "pages": ["failed-refresh"],
    "viewports": ["desktop"],
    "designRules": ["DR-006"],
    "severity": "error",
    "reason": "The two sample surfaces start together without fixed-height explanation slots."
  },
  {
    "id": "behavior-readable-type",
    "type": "min-font-size",
    "selector": ".behavior-pair",
    "min": 14,
    "pages": ["failed-refresh"],
    "viewports": ["desktop"],
    "designRules": ["DR-007"],
    "severity": "error",
    "reason": "Do not meet the finite-card boundary by shrinking readable evidence."
  },
  {
    "id": "behavior-retry-target",
    "type": "min-size",
    "selector": "#good [data-role=\"retry\"]",
    "minWidth": 44,
    "minHeight": 44,
    "pages": ["failed-refresh"],
    "viewports": ["desktop"],
    "designRules": ["DR-007", "DR-014"],
    "severity": "error",
    "reason": "Preserve the local recovery action and its usable target."
  },
  {
    "id": "behavior-secondary-notes",
    "type": "max-height",
    "selector": ".review-notes",
    "max": 56,
    "pages": ["failed-refresh"],
    "viewports": ["desktop"],
    "designRules": ["DR-006", "DR-013"],
    "severity": "error",
    "reason": "In the initial teaching state, explanations and sources are a disclosure; metric context and retry stay visible."
  }
]
