Clinic — Lab Results Viewer
A patient lab results viewer that groups analytes into collapsible CBC, lipid and metabolic panels. Every row pairs a value and unit with its reference interval, a colored Normal, High or Low status flag and a thin range bar whose marker shows exactly where the result sits within bounds. An out-of-range-only toggle filters live with a flagged count, per-panel badges stay truthful, and Download and Share fire calm confirmation toasts.
MCP
Codice
:root {
--teal: #129c93;
--teal-d: #0c7a73;
--teal-700: #0a655f;
--teal-50: #e7f5f3;
--coral: #ff7a66;
--coral-soft: #ffe6df;
--ink: #16322f;
--ink-2: #3a534f;
--muted: #6b827e;
--bg: #f1f7f6;
--white: #ffffff;
--line: rgba(16, 50, 47, 0.1);
--line-2: rgba(16, 50, 47, 0.18);
--ok: #2f9e6f;
--warn: #d98a2b;
--danger: #d4503e;
--font: "Inter", system-ui, -apple-system, sans-serif;
--r-sm: 8px;
--r-md: 14px;
--r-lg: 20px;
--shadow-1: 0 1px 2px rgba(16, 50, 47, 0.05), 0 4px 14px rgba(16, 50, 47, 0.06);
--shadow-2: 0 16px 40px rgba(12, 122, 115, 0.16);
}
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: var(--font);
background: var(--bg);
color: var(--ink);
-webkit-font-smoothing: antialiased;
line-height: 1.5;
}
button {
font: inherit;
}
:focus-visible {
outline: 2px solid var(--teal);
outline-offset: 2px;
border-radius: 6px;
}
/* ── Layout ── */
.labs {
max-width: 680px;
margin: 0 auto;
padding: 32px 20px 56px;
display: flex;
flex-direction: column;
gap: 16px;
}
/* ── Header ── */
.labs-head {
display: flex;
flex-direction: column;
gap: 18px;
margin-bottom: 4px;
}
.head-top {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 16px;
flex-wrap: wrap;
}
.eyebrow {
font-size: 0.74rem;
font-weight: 700;
letter-spacing: 0.07em;
text-transform: uppercase;
color: var(--teal-d);
}
.labs-head h1 {
font-size: 1.7rem;
font-weight: 800;
letter-spacing: -0.02em;
margin-top: 4px;
}
.collected {
font-size: 0.9rem;
color: var(--muted);
margin-top: 3px;
}
.collected strong {
color: var(--ink-2);
font-weight: 700;
}
.head-actions {
display: flex;
gap: 8px;
}
/* ── Buttons ── */
.btn {
border: none;
border-radius: 10px;
padding: 9px 15px;
font-weight: 600;
font-size: 0.85rem;
cursor: pointer;
display: inline-flex;
align-items: center;
gap: 7px;
transition: transform 0.12s, background 0.15s, border-color 0.15s, color 0.15s;
}
.btn:active {
transform: translateY(1px);
}
.btn .ico {
font-size: 0.95rem;
line-height: 1;
}
.btn.ghost {
background: var(--white);
border: 1px solid var(--line-2);
color: var(--ink-2);
}
.btn.ghost:hover {
background: var(--teal-50);
border-color: var(--teal);
color: var(--teal-d);
}
.btn.solid {
background: var(--teal-d);
color: #fff;
box-shadow: var(--shadow-1);
}
.btn.solid:hover {
background: var(--teal-700);
}
/* ── Filter bar ── */
.filterbar {
display: flex;
align-items: center;
gap: 14px;
flex-wrap: wrap;
background: var(--white);
border: 1px solid var(--line);
border-radius: var(--r-md);
padding: 12px 16px;
box-shadow: var(--shadow-1);
}
.switch {
display: inline-flex;
align-items: center;
gap: 10px;
cursor: pointer;
user-select: none;
}
.switch input {
position: absolute;
opacity: 0;
width: 0;
height: 0;
}
.track {
position: relative;
width: 40px;
height: 23px;
border-radius: 999px;
background: #cbdbd8;
transition: background 0.2s;
flex-shrink: 0;
}
.thumb {
position: absolute;
top: 2px;
left: 2px;
width: 19px;
height: 19px;
border-radius: 50%;
background: #fff;
box-shadow: 0 1px 3px rgba(16, 50, 47, 0.3);
transition: transform 0.2s;
}
.switch input:checked + .track {
background: var(--teal);
}
.switch input:checked + .track .thumb {
transform: translateX(17px);
}
.switch input:focus-visible + .track {
outline: 2px solid var(--teal);
outline-offset: 2px;
}
.switch-label {
font-size: 0.88rem;
font-weight: 600;
color: var(--ink-2);
}
.oor-count {
font-size: 0.78rem;
font-weight: 700;
color: var(--danger);
background: rgba(212, 80, 62, 0.12);
padding: 3px 10px;
border-radius: 999px;
}
.legend {
display: flex;
gap: 12px;
margin-left: auto;
}
.lg {
display: inline-flex;
align-items: center;
gap: 5px;
font-size: 0.75rem;
font-weight: 600;
color: var(--muted);
}
.dot {
width: 9px;
height: 9px;
border-radius: 50%;
display: inline-block;
}
.dot-ok {
background: var(--ok);
}
.dot-high {
background: var(--danger);
}
.dot-low {
background: var(--warn);
}
/* ── Empty state ── */
.empty {
background: var(--white);
border: 1px dashed var(--line-2);
border-radius: var(--r-md);
padding: 26px 22px;
text-align: center;
font-size: 0.92rem;
font-weight: 500;
color: var(--muted);
}
.empty[hidden] {
display: none;
}
/* ── Panel ── */
.panel {
background: var(--white);
border: 1px solid var(--line);
border-radius: var(--r-md);
box-shadow: var(--shadow-1);
overflow: hidden;
}
.panel.is-hidden {
display: none;
}
.panel-head {
width: 100%;
border: none;
background: transparent;
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
padding: 16px 18px;
cursor: pointer;
text-align: left;
transition: background 0.15s;
}
.panel-head:hover {
background: #f6fbfa;
}
.panel-title {
display: flex;
flex-direction: column;
gap: 1px;
}
.panel-name {
font-size: 1.04rem;
font-weight: 700;
letter-spacing: -0.01em;
color: var(--ink);
}
.panel-sub {
font-size: 0.78rem;
font-weight: 500;
color: var(--muted);
}
.panel-meta {
display: flex;
align-items: center;
gap: 12px;
}
.pill {
font-size: 0.72rem;
font-weight: 700;
padding: 4px 10px;
border-radius: 999px;
white-space: nowrap;
}
.pill-flag {
background: rgba(212, 80, 62, 0.12);
color: var(--danger);
}
.pill-flag.is-clear {
background: rgba(47, 158, 111, 0.14);
color: var(--ok);
}
.chev {
font-size: 1.2rem;
color: var(--muted);
line-height: 1;
transition: transform 0.2s;
}
.panel.is-open .chev {
transform: rotate(180deg);
}
.panel-body {
display: flex;
flex-direction: column;
}
.panel:not(.is-open) .panel-body {
display: none;
}
/* ── Analyte row ── */
.row {
display: grid;
grid-template-columns: 1fr auto;
grid-template-areas:
"main value"
"bar bar"
"ref ref";
column-gap: 16px;
row-gap: 8px;
padding: 14px 18px;
border-top: 1px solid var(--line);
transition: background 0.15s;
}
.row:hover {
background: #f8fcfb;
}
.row.is-hidden {
display: none;
}
.r-main {
grid-area: main;
display: flex;
align-items: center;
gap: 10px;
min-width: 0;
}
.r-name {
font-size: 0.95rem;
font-weight: 600;
color: var(--ink);
}
.r-flag {
font-size: 0.68rem;
font-weight: 800;
letter-spacing: 0.02em;
padding: 2px 8px;
border-radius: 999px;
text-transform: uppercase;
white-space: nowrap;
}
.flag-ok {
background: rgba(47, 158, 111, 0.14);
color: var(--ok);
}
.flag-high {
background: rgba(212, 80, 62, 0.14);
color: var(--danger);
}
.flag-low {
background: rgba(217, 138, 43, 0.16);
color: var(--warn);
}
.r-value {
grid-area: value;
text-align: right;
white-space: nowrap;
}
.r-value strong {
font-size: 1.15rem;
font-weight: 800;
letter-spacing: -0.01em;
color: var(--ink);
}
.r-value .unit {
font-size: 0.78rem;
font-weight: 600;
color: var(--muted);
margin-left: 4px;
}
.row[data-status="high"] .r-value strong {
color: var(--danger);
}
.row[data-status="low"] .r-value strong {
color: var(--warn);
}
/* ── Range bar ── */
.r-bar {
grid-area: bar;
position: relative;
height: 6px;
border-radius: 999px;
background: #e7eeec;
margin-top: 2px;
}
/* the in-range band */
.r-bar::before {
content: "";
position: absolute;
top: 0;
bottom: 0;
left: 18%;
right: 18%;
border-radius: 999px;
background: linear-gradient(90deg, var(--teal-50), #cdeae6);
}
/* the value marker */
.r-marker {
position: absolute;
top: 50%;
width: 13px;
height: 13px;
border-radius: 50%;
background: var(--ok);
border: 2.5px solid var(--white);
box-shadow: 0 1px 4px rgba(16, 50, 47, 0.28);
transform: translate(-50%, -50%);
transition: left 0.45s cubic-bezier(0.22, 1, 0.36, 1);
z-index: 2;
}
.row[data-status="high"] .r-marker {
background: var(--danger);
}
.row[data-status="low"] .r-marker {
background: var(--warn);
}
.r-ref {
grid-area: ref;
font-size: 0.76rem;
font-weight: 500;
color: var(--muted);
}
/* ── Footer ── */
.labs-foot {
margin-top: 6px;
padding: 4px 4px 0;
}
.labs-foot p {
font-size: 0.82rem;
color: var(--muted);
line-height: 1.55;
}
/* ── Toast ── */
.toast {
position: fixed;
left: 50%;
bottom: 26px;
transform: translateX(-50%);
background: var(--ink);
color: #fff;
padding: 13px 20px;
border-radius: 12px;
font-size: 0.9rem;
font-weight: 500;
box-shadow: var(--shadow-2);
z-index: 50;
max-width: 90vw;
}
.toast[hidden] {
display: none;
}
@media (max-width: 520px) {
.labs {
padding: 24px 14px 48px;
}
.head-top {
flex-direction: column;
}
.head-actions {
width: 100%;
}
.head-actions .btn {
flex: 1;
justify-content: center;
}
.legend {
margin-left: 0;
width: 100%;
}
.row {
grid-template-columns: 1fr;
grid-template-areas:
"main"
"value"
"bar"
"ref";
row-gap: 7px;
}
.r-value {
text-align: left;
}
}// ── Toast ──────────────────────────────────────────────────────────────────
const toast = document.getElementById("toast");
function showToast(msg) {
toast.textContent = msg;
toast.hidden = false;
clearTimeout(showToast._t);
showToast._t = setTimeout(() => (toast.hidden = true), 2600);
}
// ── Build the range bars ─────────────────────────────────────────────────────
// Each .r-bar has data-low / data-high (reference interval) and data-value.
// We map the value onto a padded scale so the in-range band (18%–82%, matching
// the ::before band in CSS) lines up with low..high, and out-of-range values
// land in the visible margins.
function buildBars() {
const PAD = 0.18; // matches CSS ::before inset
document.querySelectorAll(".r-bar").forEach((bar) => {
const low = parseFloat(bar.dataset.low);
const high = parseFloat(bar.dataset.high);
const value = parseFloat(bar.dataset.value);
const span = high - low || 1;
// position within the [low, high] band, clamped to a sensible margin
let t = (value - low) / span; // 0 at low, 1 at high
t = Math.max(-0.85, Math.min(1.85, t)); // allow drift into the margins
const pct = (PAD + t * (1 - 2 * PAD)) * 100;
const marker = document.createElement("span");
marker.className = "r-marker";
marker.style.left = Math.max(2, Math.min(98, pct)) + "%";
const status = bar.closest(".row").dataset.status;
marker.setAttribute(
"title",
`${value} (${status === "normal" ? "within" : status + ", outside"} reference range)`
);
bar.appendChild(marker);
});
}
// ── Per-panel flagged counts (derive from DOM so they stay truthful) ─────────
function refreshPanelCounts() {
document.querySelectorAll(".panel").forEach((panel) => {
const flagged = panel.querySelectorAll('.row[data-status="high"], .row[data-status="low"]').length;
const pill = panel.querySelector("[data-flagcount]");
if (!pill) return;
pill.textContent = flagged === 0 ? "All normal" : `${flagged} flagged`;
pill.classList.toggle("is-clear", flagged === 0);
});
}
// ── Global flagged count + filter ────────────────────────────────────────────
const oorToggle = document.getElementById("filter-oor");
const oorCount = document.getElementById("oor-count");
const emptyMsg = document.getElementById("empty");
function totalFlagged() {
return document.querySelectorAll('.row[data-status="high"], .row[data-status="low"]').length;
}
function applyFilter() {
const onlyOOR = oorToggle.checked;
let visiblePanels = 0;
document.querySelectorAll(".panel").forEach((panel) => {
let visibleRows = 0;
panel.querySelectorAll(".row").forEach((row) => {
const flagged = row.dataset.status !== "normal";
const show = !onlyOOR || flagged;
row.classList.toggle("is-hidden", !show);
if (show) visibleRows++;
});
// Hide a whole panel when filtering and none of its rows qualify.
const hidePanel = onlyOOR && visibleRows === 0;
panel.classList.toggle("is-hidden", hidePanel);
if (!hidePanel) visiblePanels++;
});
emptyMsg.hidden = !(onlyOOR && visiblePanels === 0);
}
function refreshCounts() {
const n = totalFlagged();
oorCount.textContent = n === 0 ? "All normal" : `${n} flagged`;
oorCount.style.background = n === 0 ? "rgba(47,158,111,0.14)" : "rgba(212,80,62,0.12)";
oorCount.style.color = n === 0 ? "var(--ok)" : "var(--danger)";
}
oorToggle.addEventListener("change", () => {
applyFilter();
showToast(
oorToggle.checked
? `Showing ${totalFlagged()} out-of-range result${totalFlagged() === 1 ? "" : "s"}.`
: "Showing all results."
);
});
// ── Collapsible panels ───────────────────────────────────────────────────────
document.querySelectorAll(".panel-head").forEach((head) => {
head.addEventListener("click", () => {
const panel = head.closest(".panel");
const open = panel.classList.toggle("is-open");
head.setAttribute("aria-expanded", String(open));
});
});
// ── Header actions ───────────────────────────────────────────────────────────
document.querySelector(".head-actions").addEventListener("click", (e) => {
const btn = e.target.closest("[data-action]");
if (!btn) return;
if (btn.dataset.action === "download") {
showToast("Preparing your lab report PDF — it will download shortly.");
} else if (btn.dataset.action === "share") {
showToast("Share link copied. It expires in 7 days for your privacy.");
}
});
// ── Init ─────────────────────────────────────────────────────────────────────
buildBars();
refreshPanelCounts();
refreshCounts();
applyFilter();<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap"
/>
<link rel="stylesheet" href="style.css" />
<title>Lab Results · Northpoint Clinic</title>
</head>
<body>
<main class="labs" id="labs">
<header class="labs-head">
<div class="head-top">
<div class="head-titles">
<p class="eyebrow">Northpoint Clinic · Laboratory</p>
<h1>Lab results</h1>
<p class="collected">
Results from <strong>Jun 4, 2026</strong> · Ordered by Dr. Lena Okafor
</p>
</div>
<div class="head-actions">
<button class="btn ghost" data-action="download" type="button">
<span class="ico" aria-hidden="true">↓</span> Download
</button>
<button class="btn solid" data-action="share" type="button">
<span class="ico" aria-hidden="true">↗</span> Share
</button>
</div>
</div>
<div class="filterbar">
<label class="switch">
<input type="checkbox" id="filter-oor" />
<span class="track" aria-hidden="true"><span class="thumb"></span></span>
<span class="switch-label">Out of range only</span>
</label>
<span class="oor-count" id="oor-count" aria-live="polite">3 flagged</span>
<div class="legend" aria-hidden="true">
<span class="lg"><i class="dot dot-ok"></i> Normal</span>
<span class="lg"><i class="dot dot-high"></i> High</span>
<span class="lg"><i class="dot dot-low"></i> Low</span>
</div>
</div>
</header>
<p class="empty" id="empty" hidden>
No out-of-range results. Every analyte falls within its reference interval.
</p>
<!-- ── Complete Blood Count ────────────────────────────────────────── -->
<section class="panel is-open" data-panel="cbc">
<button class="panel-head" type="button" aria-expanded="true" aria-controls="body-cbc">
<span class="panel-title">
<span class="panel-name">Complete Blood Count</span>
<span class="panel-sub">CBC with differential</span>
</span>
<span class="panel-meta">
<span class="pill pill-flag" data-flagcount>2 flagged</span>
<span class="chev" aria-hidden="true">⌄</span>
</span>
</button>
<div class="panel-body" id="body-cbc">
<div class="row" data-status="high" data-name="Hemoglobin">
<div class="r-main">
<span class="r-name">Hemoglobin</span>
<span class="r-flag flag-high">High</span>
</div>
<div class="r-value"><strong>17.4</strong><span class="unit">g/dL</span></div>
<div class="r-bar" data-low="13.5" data-high="17.5" data-value="17.4"></div>
<div class="r-ref">Ref 13.5–17.5 g/dL</div>
</div>
<div class="row" data-status="normal" data-name="Hematocrit">
<div class="r-main">
<span class="r-name">Hematocrit</span>
<span class="r-flag flag-ok">Normal</span>
</div>
<div class="r-value"><strong>46</strong><span class="unit">%</span></div>
<div class="r-bar" data-low="41" data-high="53" data-value="46"></div>
<div class="r-ref">Ref 41–53 %</div>
</div>
<div class="row" data-status="low" data-name="Platelets">
<div class="r-main">
<span class="r-name">Platelets</span>
<span class="r-flag flag-low">Low</span>
</div>
<div class="r-value"><strong>132</strong><span class="unit">×10³/µL</span></div>
<div class="r-bar" data-low="150" data-high="400" data-value="132"></div>
<div class="r-ref">Ref 150–400 ×10³/µL</div>
</div>
<div class="row" data-status="normal" data-name="White Blood Cells">
<div class="r-main">
<span class="r-name">White Blood Cells</span>
<span class="r-flag flag-ok">Normal</span>
</div>
<div class="r-value"><strong>6.8</strong><span class="unit">×10³/µL</span></div>
<div class="r-bar" data-low="4.0" data-high="11.0" data-value="6.8"></div>
<div class="r-ref">Ref 4.0–11.0 ×10³/µL</div>
</div>
</div>
</section>
<!-- ── Lipid Panel ─────────────────────────────────────────────────── -->
<section class="panel is-open" data-panel="lipid">
<button class="panel-head" type="button" aria-expanded="true" aria-controls="body-lipid">
<span class="panel-title">
<span class="panel-name">Lipid Panel</span>
<span class="panel-sub">Fasting · 12 hours</span>
</span>
<span class="panel-meta">
<span class="pill pill-flag" data-flagcount>1 flagged</span>
<span class="chev" aria-hidden="true">⌄</span>
</span>
</button>
<div class="panel-body" id="body-lipid">
<div class="row" data-status="high" data-name="LDL Cholesterol">
<div class="r-main">
<span class="r-name">LDL Cholesterol</span>
<span class="r-flag flag-high">High</span>
</div>
<div class="r-value"><strong>148</strong><span class="unit">mg/dL</span></div>
<div class="r-bar" data-low="0" data-high="100" data-value="148"></div>
<div class="r-ref">Ref < 100 mg/dL</div>
</div>
<div class="row" data-status="normal" data-name="HDL Cholesterol">
<div class="r-main">
<span class="r-name">HDL Cholesterol</span>
<span class="r-flag flag-ok">Normal</span>
</div>
<div class="r-value"><strong>54</strong><span class="unit">mg/dL</span></div>
<div class="r-bar" data-low="40" data-high="90" data-value="54"></div>
<div class="r-ref">Ref > 40 mg/dL</div>
</div>
<div class="row" data-status="normal" data-name="Triglycerides">
<div class="r-main">
<span class="r-name">Triglycerides</span>
<span class="r-flag flag-ok">Normal</span>
</div>
<div class="r-value"><strong>118</strong><span class="unit">mg/dL</span></div>
<div class="r-bar" data-low="0" data-high="150" data-value="118"></div>
<div class="r-ref">Ref < 150 mg/dL</div>
</div>
<div class="row" data-status="normal" data-name="Total Cholesterol">
<div class="r-main">
<span class="r-name">Total Cholesterol</span>
<span class="r-flag flag-ok">Normal</span>
</div>
<div class="r-value"><strong>192</strong><span class="unit">mg/dL</span></div>
<div class="r-bar" data-low="0" data-high="200" data-value="192"></div>
<div class="r-ref">Ref < 200 mg/dL</div>
</div>
</div>
</section>
<!-- ── Metabolic Panel ─────────────────────────────────────────────── -->
<section class="panel is-open" data-panel="metabolic">
<button class="panel-head" type="button" aria-expanded="true" aria-controls="body-metabolic">
<span class="panel-title">
<span class="panel-name">Metabolic Panel</span>
<span class="panel-sub">Basic metabolic · BMP</span>
</span>
<span class="panel-meta">
<span class="pill pill-flag" data-flagcount>0 flagged</span>
<span class="chev" aria-hidden="true">⌄</span>
</span>
</button>
<div class="panel-body" id="body-metabolic">
<div class="row" data-status="normal" data-name="Glucose">
<div class="r-main">
<span class="r-name">Glucose</span>
<span class="r-flag flag-ok">Normal</span>
</div>
<div class="r-value"><strong>92</strong><span class="unit">mg/dL</span></div>
<div class="r-bar" data-low="70" data-high="99" data-value="92"></div>
<div class="r-ref">Ref 70–99 mg/dL</div>
</div>
<div class="row" data-status="normal" data-name="Sodium">
<div class="r-main">
<span class="r-name">Sodium</span>
<span class="r-flag flag-ok">Normal</span>
</div>
<div class="r-value"><strong>139</strong><span class="unit">mmol/L</span></div>
<div class="r-bar" data-low="135" data-high="145" data-value="139"></div>
<div class="r-ref">Ref 135–145 mmol/L</div>
</div>
<div class="row" data-status="normal" data-name="Potassium">
<div class="r-main">
<span class="r-name">Potassium</span>
<span class="r-flag flag-ok">Normal</span>
</div>
<div class="r-value"><strong>4.2</strong><span class="unit">mmol/L</span></div>
<div class="r-bar" data-low="3.5" data-high="5.1" data-value="4.2"></div>
<div class="r-ref">Ref 3.5–5.1 mmol/L</div>
</div>
<div class="row" data-status="normal" data-name="Creatinine">
<div class="r-main">
<span class="r-name">Creatinine</span>
<span class="r-flag flag-ok">Normal</span>
</div>
<div class="r-value"><strong>0.9</strong><span class="unit">mg/dL</span></div>
<div class="r-bar" data-low="0.7" data-high="1.3" data-value="0.9"></div>
<div class="r-ref">Ref 0.7–1.3 mg/dL</div>
</div>
</div>
</section>
<footer class="labs-foot">
<p>
Questions about these results? Message your care team through the patient portal — a
clinician will respond within one business day.
</p>
</footer>
</main>
<div class="toast" id="toast" hidden role="status" aria-live="polite"></div>
<script src="script.js"></script>
</body>
</html>Lab Results Viewer
A calm, scannable way to read a blood panel. Results are grouped into collapsible sections — Complete Blood Count, Lipid Panel and Metabolic Panel — each headed by a flagged-count badge so a patient sees at a glance where attention is needed. The header reads Results from Jun 4, 2026 and names the ordering clinician, Dr. Lena Okafor of Northpoint Clinic.
Every analyte row carries its name, the measured value with units, the reference interval and a color-coded Normal / High / Low flag. Beneath each row a thin range bar plots the result against its in-range band, with the marker tinted teal when normal, coral when high and amber when low — so the distance from the boundary is visible, not just stated. High and low values also color their numbers to match.
An Out of range only switch filters the whole view in place, hiding in-range rows and any panel left empty, and updates a live flagged count; when nothing is out of range a reassuring empty state appears instead. Panels expand and collapse on click with a rotating chevron, and the Download and Share actions surface gentle confirmation toasts. Everything is vanilla JS, keyboard-usable and responsive down to small phones.
Illustrative UI only — not intended for real medical use.