feat(insights): add a cited reference-range backbone and richer metric explainers

Introduce src/lib/reference-ranges.ts: a structured, citation-backed
per-metric reference-range backbone (band + source body + year) with a
deterministic four-state placement helper, read by the UI surfaces. Each
band traces to the medical-citations registry, which gains the supporting
sources (ACC/AHA 2017 and ESC 2024 blood pressure, StatPearls pulse
pressure and mean arterial pressure, ESC/ESH 2018 pulse-wave velocity,
FDA 2024 and StatPearls pulse oximetry, J Gen Intern Med 2019 temperature,
RCP NEWS2 and American Lung Association respiratory rate, visceral-fat
imaging literature, AHA 2024 resting heart rate, ESC/NASPE 1996 HRV,
Wilcox 2000, ACOG 651, Phillips 2017 and CDC 2024 sleep).

Blood pressure keeps ESH 2023 as the labelled default; ACC/AHA 2017 and
ESC 2024 appear only as displayed placement context. Enrich the metric
explainers with concise cited reference bands and a general-guidance
tooltip on every metric page: a darker-skin pulse-oximeter over-read
caveat, device-proxy honesty for readiness/recovery/strain/stress, an
HRV day-to-day-noise note, and a resting-heart-rate clarification. Fill
the empty registry normal ranges, reconcile the steps green floor to
8,000, and tighten the body-temperature band below the fever line. Add
free pulse-pressure and mean-arterial-pressure context on the blood-
pressure detail page, plus cycle-physiology and sleep-hygiene copy across
all six locales. Cycle thresholds carry a verification marker pending an
ACOG source check.
This commit is contained in:
Marc-André Bombeck committed 2026-06-18 20:17:04 +02:00
1 parent 1d83e10764
commit 9be30897fa
12 files changed
+985 -29

No files matched your search

+34 -1
View File
@@ -3,10 +3,16 @@
import { useEffect, useRef, type ReactNode } from "react";
import Link from "next/link";
import { usePathname } from "next/navigation";
import { ListOrdered } from "lucide-react";
import { Info, ListOrdered } from "lucide-react";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "@/components/ui/tooltip";
import { CoachLaunchButton } from "@/components/insights/coach-launch-button";
import { TargetAdjustButton } from "@/components/insights/target-adjust-button";
import { TargetAdjustProvider } from "@/lib/insights/target-adjust-context";
@@ -291,6 +297,33 @@ export function SubPageShell({
className="text-muted-foreground text-sm leading-relaxed"
>
{t(`insights.subPage.explainer.${explainerMetric}Body`)}
{/* v1.18.6 — a discreet general-guidance tooltip travels with
every metric definition. The reference bands in the body
above are population anchors, not medical advice; this
caption pins that framing without crowding the prose. */}
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<button
type="button"
data-slot="metric-reference-guidance"
className={cn(
"text-muted-foreground hover:text-foreground ml-1.5 inline-flex",
"align-middle focus-visible:ring-ring/50 rounded-full",
"focus-visible:ring-2 focus-visible:outline-none",
)}
aria-label={t(
"insights.subPage.explainer.referenceGuidance",
)}
>
<Info className="size-3.5" aria-hidden="true" />
</button>
</TooltipTrigger>
<TooltipContent className="max-w-xs text-pretty">
{t("insights.subPage.explainer.referenceGuidance")}
</TooltipContent>
</Tooltip>
</TooltipProvider>
</p>
) : null}
{description && !explainerMetric ? (