{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "metric-range-card",
  "title": "Metric Range Card",
  "description": "Range-based metric card for score bands, ticks, and highlighted target ranges.",
  "registryDependencies": [
    "@blocks/metric-utils",
    "@blocks/reporting-types",
    "@circle-ui/card",
    "@circle-ui/utils"
  ],
  "files": [
    {
      "path": "registry/berlin/blocks/reporting/metric-range-card.tsx",
      "content": "// Generated from packages/ui/src/components/reporting/metric-range-card.tsx\nimport * as React from \"react\";\n\nimport { Card, CardContent, CardHeader } from \"@/registry/berlin/circle-ui/card\";\nimport { cn } from \"@/registry/berlin/lib/utils\";\nimport { formatMetricValue, statusClasses } from \"@/registry/berlin/blocks/metric-utils\";\n\nimport type { MetricRangeCardProps } from \"@/registry/berlin/blocks/reporting-types\";\n\n// Registry source of truth for patient-results metric card pulls into circleOS.\nfunction clamp(value: number, min: number, max: number) {\n  return Math.min(Math.max(value, min), max);\n}\n\nfunction percentageForValue(value: number, min: number, max: number) {\n  if (min === max) return 0;\n  return ((clamp(value, min, max) - min) / (max - min)) * 100;\n}\n\nexport function MetricRangeCard({\n  title,\n  value,\n  unit,\n  status,\n  ticks,\n  min,\n  max,\n  pointerValue,\n  highlightStart,\n  highlightEnd,\n  eyebrow,\n  summary,\n  layout = \"compact\",\n  className,\n}: MetricRangeCardProps) {\n  const pointerOffset = percentageForValue(pointerValue, min, max);\n  const highlightLeft = percentageForValue(highlightStart ?? min, min, max);\n  const highlightRight = percentageForValue(highlightEnd ?? max, min, max);\n  const showHeroValue = layout === \"hero\";\n\n  return (\n    <Card\n      className={cn(\n        \"border-black/10 bg-white\",\n        showHeroValue ? \"rounded-[16px]\" : \"rounded-[12px]\",\n        className,\n      )}\n    >\n      <CardHeader\n        className={cn(showHeroValue ? \"gap-12 p-6\" : \"gap-10 p-4\", \"pb-0\")}\n      >\n        <div className=\"flex items-start justify-between gap-4\">\n          <div className=\"min-w-0 flex-1 space-y-1\">\n            {eyebrow ? (\n              <p className=\"text-[11px] font-medium uppercase tracking-[0.08em] text-muted-foreground\">\n                {eyebrow}\n              </p>\n            ) : null}\n            <p className=\"text-sm leading-6 tracking-[-0.01em] text-[#202020]\">\n              {title}\n            </p>\n            {summary ? (\n              <p className=\"text-sm leading-6 tracking-[-0.01em] text-muted-foreground\">\n                {summary}\n              </p>\n            ) : null}\n          </div>\n\n          {status ? (\n            <span\n              className={cn(\n                \"inline-flex shrink-0 items-center justify-center whitespace-nowrap rounded-full px-4 py-1.5 text-center text-xs font-medium leading-none\",\n                showHeroValue && \"px-5 py-2 text-[15px]\",\n                statusClasses(status.tone),\n              )}\n            >\n              {status.label}\n            </span>\n          ) : null}\n        </div>\n\n        <div className=\"flex items-baseline justify-center gap-1 text-center\">\n          <span className=\"text-[48px] font-medium leading-[48px] tracking-[-0.03em] text-[#222222]\">\n            {formatMetricValue(value)}\n          </span>\n          {unit ? (\n            <span className=\"text-[16px] leading-[16px] tracking-[-0.03em] text-[#222222]\">\n              {unit}\n            </span>\n          ) : null}\n        </div>\n      </CardHeader>\n\n      <CardContent className={cn(showHeroValue ? \"p-6 pt-0\" : \"p-4 pt-0\")}>\n        <div className=\"space-y-1\">\n          <div className=\"relative h-11\">\n            <div className=\"absolute inset-x-0 top-5 h-4 rounded-full bg-[#f0f3f7]\" />\n            <div\n              className=\"absolute top-5 h-4 rounded-full bg-[#b8d3ee]\"\n              style={{\n                left: `${Math.min(highlightLeft, highlightRight)}%`,\n                width: `${Math.abs(highlightRight - highlightLeft)}%`,\n              }}\n            />\n            <div\n              className=\"absolute top-0 -translate-x-1/2\"\n              style={{ left: `${pointerOffset}%` }}\n            >\n              <svg\n                aria-hidden=\"true\"\n                className=\"mx-auto block\"\n                viewBox=\"0 0 12 11\"\n                width=\"12\"\n                height=\"11\"\n              >\n                <path\n                  d=\"M1 1.5C1 0.671573 1.67157 0 2.5 0H9.5C10.3284 0 11 0.671573 11 1.5C11 1.79836 10.911 2.08994 10.7444 2.33744L6 11L1.25559 2.33744C1.08905 2.08994 1 1.79836 1 1.5Z\"\n                  fill=\"currentColor\"\n                />\n              </svg>\n              <div className=\"mx-auto -mt-px h-8 w-px bg-[#cdd5df]\" />\n            </div>\n          </div>\n\n          <div className=\"flex items-center justify-between gap-2 text-[12px] font-medium tracking-[0.005em] text-[#626262]\">\n            {ticks.map((tick) => (\n              <span key={tick}>{tick}</span>\n            ))}\n          </div>\n        </div>\n      </CardContent>\n    </Card>\n  );\n}\n",
      "type": "registry:ui",
      "target": "src/components/ui/reporting/metric-range-card.tsx"
    }
  ],
  "type": "registry:ui"
}