/* ── OwnHealth.FIT — Shared Shell Stylesheet ─────────────────────────────────
   Provides: CSS variables, app shell layout, nav sidebar styles,
   and common utility classes used across all pages.
   ────────────────────────────────────────────────────────────────────────── */

/* ── CSS Custom Properties ── */
:root {
  /* Wave 2 — the display/serif face, as a token.
     Bound to a SYSTEM serif stack, deliberately NOT Playfair Display. The mockups
     (RT-4 categorical panel, SPEC-LAB-CC design pass) define --display locally as
     Playfair, but Playfair is loaded only by the marketing pages: the app shell
     cannot fetch it, because the runtime <link> to fonts.googleapis.com violated
     the CSP on every authed page and was removed (see onb1-wizard.js and
     server.js's note on the lapsed hero). A token promising a font the app can
     never load would resolve to the fallback anyway — so the fallback IS the
     token, and it says so. */
  --display: Georgia, "Times New Roman", serif;
  --bg: #0f1117;
  --surface: #1a1d27;
  --surface2: #22263a;
  --border: #2e3350;
  --accent: #4c5199;
  /* Per UAT — promote --accent-light to a global token. dashboard.html
     defined it locally (#6b74cc) but pages like protocol.html use it
     in gradients (e.g. .tod-progress-fill) and silently failed to
     render the second gradient stop because the var resolved to
     unset. Now lives at the root so every page that loads shell.css
     gets it for free. */
  --accent-light: #6b74cc;
  --green: #626f96;
  --teal: #10b981;
  --orange: #f97316;
  --red: #ef4444;
  --gold: #f59e0b;
  --purple: #7c3aed;
  /* SPEC-LAB-RT-3 §2.1 — the marker row's semantic band palette.
     --red and --danger BOTH STAY, and are deliberately not aliased (decided
     2026-08-15). An earlier note here called them near-duplicates and said one
     "should eventually go" — that was wrong on both counts. They are different
     colors (#ef4444 vs #F0616D here, #dc2626 vs #D64550 in light), at very
     different scale: ~350 consumers of --red across the app against ~37 of
     --danger. Aliasing either direction repaints one of those sets, so there is
     no zero-risk cleanup hiding here — only a choice nobody has needed to make.
     --red is the app's general-purpose error red; --danger is the value tuned
     for the navy marker-row surface (RT3-precheck.md §B). Keep both. */
  --danger: #F0616D;
  /* Dark mode only: here the optimal band genuinely IS --teal, so it aliases.
     Light mode does NOT — see the note at its definition below. */
  --band-optimal: var(--teal);
  --band-caution: var(--gold);
  --band-danger:  var(--danger);
  --band-neutral: #6E7290;
  --gauge-track:  rgba(255,255,255,0.06);
  --text: #e8eaf0;
  --text-muted: #8b91a8;
  --text-dim: #5c6180;
  --radius: 10px;
  --shadow: 0 4px 24px rgba(0,0,0,0.4);
  --nav-width: 220px;

  /* ── Session palette (workouts_today_tab_spec §10.5) ──────────────────────
     Dark-mode-only for v1. Consumed by the active-session takeover, the
     Today tab consistency header, FOCUS gradient text, and any future
     workout surfaces. Hex values tuned against rendered UI. */
  --session-bg: #0b0d12;                /* dark base */
  --session-surface: #17191f;           /* slightly lifted card */
  --session-surface-2: #1e212a;         /* inputs, chip bg */
  --session-divider: #2a2d37;           /* subtle line */

  --session-text: #f4f5f8;              /* primary copy on dark */
  --session-text-dim: #8f93a3;          /* secondary copy */
  --session-text-faint: #5a5e6e;        /* tertiary / icon-only */

  --session-set-complete: #7de5a5;      /* completed set badge (mint) */
  --session-set-pending: #1e212a;       /* pending set badge bg */

  --session-cta: #ff2b55;               /* Log Set / Start Workout */
  --session-cta-text: #ffffff;

  --session-focus-from: #f4d03f;        /* FOCUS gradient start (gold) */
  --session-focus-to:   #ff2b55;        /* FOCUS gradient end (pink) */

  --session-amber: #f0a500;             /* rest day 2d */
  --session-red:   #ef4444;             /* rest day 3d+, error */
  --session-mint:  #7de5a5;             /* worked-today affirmation */

  /* Aliases — names the active-session takeover uses internally, mapped
     onto the spec names above so one source of truth drives every surface. */
  --session-border:       var(--session-divider);
  --session-text-muted:   var(--session-text-dim);
  --session-accent:       var(--session-cta);
  --session-accent-soft:  rgba(255, 43, 85, 0.15);
  --session-success:      var(--session-mint);
  --session-warning:      var(--session-focus-from);

  /* ── SPEC-UAT-R1 §2 — restrained category palette ──────────────────────
     Used by the Plan-tab timeline + the Compounds-redesign surfaces.
     Desaturated, consistent saturation/lightness — reads as a clinical
     legend, not a loud rainbow. Dark mode uses lightened variants;
     :root.light below overrides with the spec's reference hex values.
     All consumers must reference via var(--cat-*) — never literal hex. */
  --cat-metabolic:    #6ba3a3;  /* teal-slate (lightened for dark mode) */
  --cat-recovery:     #c8a06d;  /* warm amber-brown */
  --cat-skin:         #c489a8;  /* muted rose */
  --cat-growth:       #8c8ed4;  /* indigo (brand-adjacent) */
  --cat-aging:        #9d97c0;  /* violet-slate */
  --cat-hormonal:     #b780ad;  /* plum */
  --cat-brain:        #7d9bc4;  /* slate blue */
  --cat-foundational: #8caa86;  /* sage */
  --cat-anabolic:     #c07a6a;  /* SPEC-ANB §5.1 — garnet/brick, anabolic type accent (dark) */

  /* ── SPEC-CMPD §B1 — Compounds-redesign shared tokens ──────────────
     Consumed by the member Compounds landing (protocol.html), the
     coach Compound Manager (compounds-coach.html), and the admin
     Compound Manager (compounds-admin.html). Mirrors the mockup
     palette in roadmap-spec/FEATURE_SPECS/Compound-Mock/. Brand /
     ink / line / status / surface tokens — additive; existing
     --accent / --text / --surface remain primary. */
  --cmpd-brand:     var(--accent);            /* #4c5199 dark / #4c5199 light */
  --cmpd-brand-50:  rgba(76,81,153,0.10);
  --cmpd-brand-100: rgba(76,81,153,0.18);
  --cmpd-brand-200: rgba(76,81,153,0.32);
  --cmpd-ok:        var(--teal);              /* status:active pill */
  --cmpd-ok-bg:     rgba(16,185,129,0.14);
  --cmpd-off:       var(--text-muted);
  --cmpd-off-bg:    var(--surface2);
  --cmpd-warn:      var(--gold);
  --cmpd-warn-bg:   rgba(245,158,11,0.14);
  --cmpd-gold:      #d9a93a;                  /* ⭐ Favorites chip + star */
}
:root.light {
  --bg: #f4f6fb;
  --surface: #ffffff;
  --surface2: #eef1f8;
  --border: #d4d9e8;
  --accent: #4c5199;
  --accent-light: #6b74cc;
  --green: #626f96;
  --teal: #059669;
  --orange: #ea6000;
  --red: #dc2626;
  --gold: #d97706;
  /* SPEC-LAB-RT-3 §2.1 — teal/gold darkened for legibility on white. This is the
     tokens earning their keep: the marker row is one component and flips entirely
     here. (The app themes with :root.light, NOT [data-theme] — the mockup's blocks
     are ported to the codebase's real mechanism; RT3-precheck §C.) */
  --danger: #D64550;
  /* DELIBERATELY NOT var(--teal). Dark mode aliases the two; light mode must not.
     --teal is #059669 here, which does not carry enough contrast on white for the
     optimal band — #1F97A6 is the value RT-3 landed after that check
     (RT3-precheck.md §C). Aliasing this to --teal would silently undo an
     accessibility decision across ~27 lab-band consumers, which is why it was
     reviewed in 2026-08 and left alone. Do not "tidy" it. */
  --band-optimal: #1F97A6;
  --band-caution: #B9871A;
  --band-danger:  var(--danger);
  --band-neutral: #8C8FA8;
  --gauge-track:  rgba(8,9,28,0.07);
  --text: #0f1117;
  --text-muted: #4b5578;
  --text-dim: #8b91a8;
  --shadow: 0 4px 24px rgba(0,0,0,0.1);

  /* SPEC-UAT-R1 §2 — restrained category palette, spec-reference hex
     for light mode. Dark-mode lightened variants live in :root. */
  --cat-metabolic:    #4f8a8a;
  --cat-recovery:     #b0814e;
  --cat-skin:         #b06487;
  --cat-growth:       #6a6cc0;
  --cat-aging:        #8079ad;
  --cat-hormonal:     #9c5f93;
  --cat-brain:        #5d7fb0;
  --cat-foundational: #6f9168;
  --cat-anabolic:     #a85a4f;  /* SPEC-ANB §5.1 — garnet/brick, anabolic type accent (light) */

  /* SPEC-CMPD §B1 — light-mode Compounds-redesign tokens.
     --cmpd-brand stays mapped to --accent so light + dark inherit
     correctly; ok/warn/off backgrounds tighten for white surfaces. */
  --cmpd-brand-50:  rgba(76,81,153,0.06);
  --cmpd-brand-100: rgba(76,81,153,0.12);
  --cmpd-brand-200: rgba(76,81,153,0.24);
  --cmpd-ok-bg:     rgba(5,150,105,0.10);
  --cmpd-warn-bg:   rgba(217,119,6,0.10);
  --cmpd-gold:      #c08a2c;
}

/* ── SPEC-CMPD §B1 — Compounds-redesign shared utility classes ─────
   Defined ONCE here so the member Compounds landing, the coach
   Compound Manager, and the admin Compound Manager all pull from
   the same source of truth. Mirrors the mockups in
   roadmap-spec/FEATURE_SPECS/Compound-Mock/. Pages opt-in by
   wrapping their landing markup in .cmpd-landing and consuming the
   utility classes below. Per-surface specializations stay in the
   page's own <style> block. */

.cmpd-landing { display: flex; flex-direction: column; gap: 12px; padding: 0; }

/* Hero banner — only shown on first visit (empty catalog).
   §B1.7 state machine: First visit = full gradient hero;
   Returning = no banner; Conditional nudge = slim ribbon below. */
.cmpd-hero {
  background: linear-gradient(135deg, var(--accent) 0%, var(--accent-light) 70%);
  border-radius: 16px;
  padding: 22px 24px;
  color: #fff;
  position: relative; overflow: hidden;
}
.cmpd-hero::after {
  content: ""; position: absolute; right: -50px; top: -50px;
  width: 220px; height: 220px; border-radius: 50%;
  background: rgba(255,255,255,0.08);
}
.cmpd-hero-kick {
  font-size: 0.72rem; font-weight: 700;
  letter-spacing: 0.1em; text-transform: uppercase;
  opacity: 0.85;
}
.cmpd-hero-title {
  font-size: 1.5rem; font-weight: 600; line-height: 1.25;
  margin-top: 6px; max-width: 460px;
}
.cmpd-hero-body {
  font-size: 0.92rem; line-height: 1.4;
  opacity: 0.88; margin-top: 8px; max-width: 480px;
}
.cmpd-hero-cta { margin-top: 18px; display: flex; gap: 10px; flex-wrap: wrap; }
.cmpd-hero-btn {
  background: #fff; color: var(--accent);
  border: 0; border-radius: 12px;
  padding: 10px 18px;
  font-family: inherit; font-size: 0.86rem; font-weight: 700;
  cursor: pointer;
}
.cmpd-hero-btn.line {
  background: rgba(255,255,255,0.16);
  color: #fff;
  border: 1.5px solid rgba(255,255,255,0.4);
}

/* Conditional ribbon — slim, dismissible, only when a condition
   is true (refills due, new compound pending review, etc.). */
.cmpd-ribbon {
  display: flex; align-items: center; gap: 12px;
  border-radius: 12px; padding: 11px 14px;
  font-size: 0.84rem; font-weight: 600; line-height: 1.35;
}
.cmpd-ribbon--alert { background: var(--cmpd-warn-bg); color: var(--text); border: 1px solid rgba(245,158,11,0.35); }
.cmpd-ribbon--info  { background: var(--cmpd-brand-50); color: var(--text); border: 1px solid var(--cmpd-brand-100); }
.cmpd-ribbon-ic { font-size: 1rem; flex: none; }
.cmpd-ribbon-msg { flex: 1; }
.cmpd-ribbon-msg small { display: block; font-weight: 500; opacity: 0.88; font-size: 0.78rem; }
.cmpd-ribbon-lnk { font-weight: 700; text-decoration: underline; cursor: pointer; color: inherit; background: 0; border: 0; font-family: inherit; padding: 0; }
.cmpd-ribbon-x { cursor: pointer; font-size: 1rem; opacity: 0.55; padding: 2px 4px; background: 0; border: 0; color: inherit; }
.cmpd-ribbon-x:hover { opacity: 1; }

/* Stat-card grid (4-up web, 2-up mobile). */
.cmpd-stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; }
@media (max-width: 600px) { .cmpd-stats { grid-template-columns: repeat(2, 1fr); } }
.cmpd-stat {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 11px; padding: 14px 16px;
  box-shadow: 0 1px 2px rgba(10,12,20,0.05);
}
.cmpd-stat-n  { font-size: 1.55rem; font-weight: 700; line-height: 1; color: var(--text); }
.cmpd-stat-l  { font-size: 0.74rem; color: var(--text-muted); margin-top: 5px; font-weight: 600; }
.cmpd-stat--ok    .cmpd-stat-n { color: var(--cmpd-ok); }
.cmpd-stat--warn  .cmpd-stat-n { color: var(--cmpd-warn); }
.cmpd-stat--brand .cmpd-stat-n { color: var(--cmpd-brand); }

/* Toolbar — row 1 = search + Add Compound, row 2 = filter chips.
   The Add button now shows at every breakpoint (the mobile-only
   in-list-head variant was retired 2026-06-02 — see the
   .cmpd-add-btn--mobile rule below). */
.cmpd-toolbar { display: flex; flex-direction: column; gap: 11px; }
/* Single row on wide screens: compact search + filter chips + Add (far right).
   Wraps gracefully on narrow widths. */
.cmpd-tb-row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.cmpd-search {
  flex: 1 1 240px; max-width: 360px; display: flex; align-items: center; gap: 9px;
  background: var(--surface2); border: 1px solid var(--border);
  border-radius: 12px; padding: 9px 13px;
}
.cmpd-tb-row .cmpd-add-btn--web { margin-left: auto; }
/* Add Compound hoisted to a compact top-right row above the stat panels; the
   negative top margin tucks it into the header↔panels gap so it costs little
   extra height. The view toggle now sits at the toolbar's far right. */
/* Add button tucks up tight beneath the page tabs and sits close to the stat cards
   (the landing owns the gap; a negative top margin claws back the container's top
   padding so the button doesn't float in dead space). */
/* SPEC-FTP-1 §4.2 — the row gained a second child (the compound-cap chip),
   so it needs a gap and a shared baseline. Inert while the chip is absent. */
.cmpd-topbar { display: flex; justify-content: flex-end; align-items: center; gap: 10px; margin: -16px 0 -2px; }
/* 2026-08-23 — the topbar holds only the FTP cap chip now (Add moved to the
   protocol page header); collapse entirely when the chip renders nothing. */
.cmpd-topbar:empty { display: none; }
.cmpd-tb-row .cmpd-viewtog { margin-left: auto; }
@media (max-width: 600px) { .cmpd-topbar { margin: -6px 0 -2px; } .cmpd-topbar .cmpd-add-btn { flex: 1 1 auto; } }
.cmpd-search input {
  border: 0; background: transparent; outline: 0;
  font-family: inherit; font-size: 0.9rem; color: var(--text);
  width: 100%;
}
.cmpd-filters { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.cmpd-chip {
  display: inline-flex; align-items: center; gap: 7px;
  border: 1.5px solid var(--border); background: var(--surface);
  padding: 6px 12px; border-radius: 30px;
  cursor: pointer;
  font-family: inherit; font-weight: 600; font-size: 0.82rem;
  color: var(--text-muted); transition: 0.15s;
}
.cmpd-chip:hover:not(.on) { border-color: var(--cmpd-brand-200); background: var(--cmpd-brand-50); color: var(--text); }
.cmpd-chip-ct {
  font-size: 0.7rem; font-weight: 700;
  color: var(--text-muted); background: var(--surface2);
  border-radius: 20px; padding: 1px 7px; min-width: 20px; text-align: center;
}
.cmpd-chip.on { border-color: var(--cmpd-brand); background: var(--cmpd-brand); color: #fff; }
.cmpd-chip.on .cmpd-chip-ct { background: rgba(255,255,255,0.22); color: #fff; }
.cmpd-chip--fav.on { border-color: var(--cmpd-gold); background: var(--cmpd-gold); color: #ffffff; }
.cmpd-chip--fav.on .cmpd-chip-ct { background: rgba(255,255,255,0.25); color: #fff; }

/* List-head (docked above the panels): empty left slot + view toggle
   right. The left slot used to carry a "X of Y compounds" count and
   a mobile-only + Add button; both were retired 2026-06-02 because
   the top stat panels cover counts more cleanly and the toolbar's
   + Add Compound button now shows at every breakpoint. */
.cmpd-list-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; padding: 4px 2px;
}
.cmpd-list-head-left { display: flex; align-items: center; gap: 10px; }
.cmpd-list-head-count { font-size: 0.78rem; color: var(--text-muted); font-weight: 600; }
/* SPEC-CMPD §B5 follow-up — primary Add button styled by the §B1
   utility (was previously only in protocol.html, so coach + admin
   surfaces showed an unstyled chip). Web/mobile visibility classes
   match the toolbar/list-head split: --web sits beside the search,
   --mobile docks into the list-head on narrow widths. */
.cmpd-add-btn {
  background: var(--accent); color: #fff;
  border: 0; border-radius: 12px;
  padding: 10px 16px;
  font-family: inherit; font-size: 0.84rem; font-weight: 700;
  cursor: pointer; white-space: nowrap;
  display: inline-flex; align-items: center; gap: 4px;
  transition: filter 0.15s;
}
.cmpd-add-btn:hover { filter: brightness(1.08); }
/* 2026-06-02 — the per-list-head `.cmpd-add-btn--mobile` button + the
   `.cmpd-list-head-count--web` result count were both retired (per
   user request: the top stat panels already convey counts more
   cleanly, and the top-row `+ Add Compound` button covers both
   mobile and desktop). The web Add button now shows at every
   breakpoint as the single Add affordance; the --mobile variant is
   kept as display:none defensively in case any stale markup still
   carries the class. */
.cmpd-add-btn--mobile { display: none; }
/* SPEC-CMPD §B5 follow-up — view-toggle now matches the Compound
   Library page's icon-only pattern (.view-toggle / .view-btn). SVG
   icons + accent border on hover/active for a unified look across
   every catalog surface. */
.cmpd-viewtog { display: inline-flex; gap: 4px; flex: none; }
.cmpd-viewtog button {
  background: var(--surface2); border: 1px solid var(--border);
  color: var(--text-dim); border-radius: 6px;
  padding: 6px 10px; cursor: pointer;
  font-family: inherit;
  display: inline-flex; align-items: center; justify-content: center;
  transition: all 0.15s;
}
.cmpd-viewtog button:hover,
.cmpd-viewtog button.on {
  background: var(--surface); color: var(--accent); border-color: var(--accent);
}
.cmpd-viewtog button svg { display: block; }

/* Group section header (category label + count). */
.cmpd-grp { margin-top: 4px; }
.cmpd-grp h3 {
  font-size: 0.78rem; font-weight: 700;
  letter-spacing: 0.03em; color: var(--text-muted);
  display: flex; align-items: center; gap: 9px; margin-bottom: 10px;
  text-transform: uppercase;
}
.cmpd-grp .cmpd-grp-dot {
  width: 9px; height: 9px; border-radius: 50%; flex: none;
}
/* SPEC-PVR §6.2 — time-of-day section icon (replaces the category dot). */
.cmpd-grp .cmpd-grp-ico, .cmpd-sec-hd .cmpd-sec-ico {
  display: inline-flex; align-items: center; flex: none;
  color: var(--accent); margin-right: 2px;
}
.cmpd-sec-hd .cmpd-sec-ico { vertical-align: -2px; }
.cmpd-grp .cmpd-grp-ct {
  color: var(--text-dim); font-weight: 600;
  text-transform: none; letter-spacing: 0; font-size: 0.78rem;
}

/* Panels view — responsive 3-up / 1-up card grid. */
.cmpd-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
@media (max-width: 800px) { .cmpd-grid { grid-template-columns: 1fr; } }

/* SPEC-PVR §6.3 — grouped-supplement cluster within a time-of-day section. */
.cmpd-cluster {
  margin-top: 11px; border: 1px solid var(--border); border-radius: 12px;
  padding: 11px 13px 13px; background: color-mix(in srgb, var(--accent) 4%, var(--surface));
}
.cmpd-cluster--list { padding: 8px 10px 6px; }
.cmpd-cluster-hd {
  font-size: 0.7rem; font-weight: 700; letter-spacing: 0.03em; text-transform: uppercase;
  color: var(--text-muted); display: flex; align-items: center; gap: 8px; margin-bottom: 9px;
}
.cmpd-cluster-ct { color: var(--text-dim); font-weight: 600; text-transform: none; letter-spacing: 0; }
/* SPEC-PVR §6.3 — dimmed Off / Inactive section. Kept at 0.7 (text stays above
   the AA contrast floor) and restored to full on hover/focus for legibility. */
.cmpd-off-sec { margin-top: 22px; opacity: 0.7; transition: opacity 0.2s; }
.cmpd-off-sec:hover, .cmpd-off-sec:focus-within { opacity: 1; }
/* Needs-setup section — enabled compounds still awaiting config. Actionable, so
   NOT dimmed like the paused/off section; the header icon carries the accent. */
.cmpd-needs-sec { margin-top: 22px; }
.cmpd-needs-sec > h3 .cmpd-grp-ico { color: var(--accent); }
.cmpd-card {
  background: var(--surface); border: 1px solid var(--border);
  border-left: 3px solid var(--cmpd-c, var(--cmpd-brand));
  border-radius: 11px; padding: 13px 15px;
  cursor: pointer; transition: 0.16s;
  display: block; width: 100%; text-align: left;
  font-family: inherit; color: var(--text);
}
.cmpd-card:hover {
  box-shadow: 0 1px 2px rgba(10,12,20,0.04), 0 8px 24px rgba(10,12,20,0.06);
  transform: translateY(-2px);
  border-color: var(--cmpd-brand-200);
}
.cmpd-card-top { display: flex; justify-content: space-between; align-items: flex-start; gap: 10px; }
/* SPEC-CMPD §B5 follow-up — compound-type icon docks LEFT of the
   name + kind label so the title row anchors to a consistent gutter
   across every surface. Same nav.js ICONS used in the rest of the
   app for consistency. */
.cmpd-card-icon {
  flex: none;
  width: 22px; height: 22px;
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--text-muted);
  margin-top: 2px;
}
.cmpd-card-icon svg { width: 18px; height: 18px; display: block; }
.cmpd-card-text { min-width: 0; flex: 1; }
.cmpd-card-nm  { font-weight: 700; font-size: 0.96rem; letter-spacing: -0.005em; color: var(--text); }
.cmpd-card-sub { font-size: 0.76rem; color: var(--text-muted); margin-top: 2px; }
.cmpd-card-meta {
  font-size: 0.8rem; color: var(--text); margin-top: 11px;
  padding-top: 10px; border-top: 1px dashed var(--border);
  font-weight: 600;
  display: flex; justify-content: space-between; align-items: center;
}
.cmpd-card-meta-mute { color: var(--text-dim); font-weight: 500; }

/* Status / favorite-star pills. */
.cmpd-pill {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 0.72rem; font-weight: 700;
  padding: 3px 9px; border-radius: 20px;
}
.cmpd-pill--ok  { color: var(--cmpd-ok);  background: var(--cmpd-ok-bg); }
.cmpd-pill--off { color: var(--cmpd-off); background: var(--cmpd-off-bg); }
.cmpd-pill-dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.cmpd-star {
  cursor: pointer; font-size: 0.94rem;
  color: var(--text-dim); flex: none;
  background: 0; border: 0; padding: 0;
  transition: 0.15s;
}
.cmpd-star.on { color: var(--cmpd-gold); }

/* List view — collapsible category sections, compact rows.
   SPEC-CMPD §B5 follow-up — removed `overflow: hidden` from the
   section wrapper. It was interacting badly with the grid-template-
   rows transition (the parent's overflow:hidden clipped the inner
   grid before it could size to its content), which left only the
   first row or two visible in large categories on the coach + admin
   surfaces. Rows are width:100% so they conform to the rounded
   border without needing the parent to clip. */
.cmpd-sec {
  border: 1px solid var(--border); border-radius: 11px;
  background: var(--surface);
  box-shadow: 0 1px 2px rgba(10,12,20,0.05);
  margin-bottom: 10px;
}
.cmpd-sec-hd {
  display: flex; align-items: center; gap: 11px;
  padding: 13px 16px; cursor: pointer; user-select: none;
  transition: 0.15s; background: 0; border: 0;
  width: 100%; text-align: left; font-family: inherit; color: var(--text);
}
.cmpd-sec-hd:hover { background: var(--surface2); }
.cmpd-sec-hd .bar { width: 4px; height: 20px; border-radius: 3px; background: var(--cmpd-c, var(--cmpd-brand)); }
.cmpd-sec-hd .ttl { font-weight: 700; font-size: 0.94rem; flex: 1; }
.cmpd-sec-hd .meta { font-size: 0.78rem; color: var(--text-muted); font-weight: 600; }
.cmpd-sec-hd .chev { color: var(--text-dim); transition: 0.25s; font-size: 0.78rem; }
.cmpd-sec.closed .chev { transform: rotate(-90deg); }
/* SPEC-CMPD §B5 follow-up (rev 2) — section body uses plain
   display:none for the closed state. Earlier attempts (max-height
   4000px, then grid-template-rows 0fr↔1fr) both fought with the
   parent's overflow:hidden and clipped rows in large categories.
   Dropping the open/close animation entirely makes the toggle
   visually instant but GUARANTEES every row renders. The bottom
   chevron rotation still telegraphs the state change.
   The first level child stays visible; .closed only collapses
   when the user clicks the header. */
.cmpd-sec-bd { display: block; }
.cmpd-sec.closed .cmpd-sec-bd { display: none; }
.cmpd-row {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 16px;
  border-top: 1px solid var(--border);
  cursor: pointer; transition: 0.14s;
  background: transparent; width: 100%; text-align: left;
  font-family: inherit; color: var(--text);
  border-left: 0; border-right: 0; border-bottom: 0;
}
.cmpd-row:hover { background: var(--cmpd-brand-50); }
/* Row-level icon at the left gutter. Same size + style as card icon. */
.cmpd-row-icon {
  flex: none;
  width: 22px; height: 22px;
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--text-muted);
}
.cmpd-row-icon svg { width: 18px; height: 18px; display: block; }
.cmpd-row .nm { font-weight: 600; font-size: 0.9rem; flex: 1; min-width: 0; color: var(--text); }
.cmpd-row .nm small { display: block; color: var(--text-muted); font-weight: 500; font-size: 0.78rem; }
.cmpd-row .gl { font-size: 0.78rem; color: var(--text); font-weight: 600; white-space: nowrap; }
.cmpd-row .chev { color: var(--text-dim); font-size: 0.94rem; }
/* SPEC-CMPD §B5 follow-up — star sits on the RIGHT of the row
   (mockup-correct). Override the default left-flow with order. */
.cmpd-row .cmpd-star { order: 99; margin-left: 4px; }
@media (max-width: 600px) { .cmpd-row .gl { display: none; } }

/* ── Reset ── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
body { background: var(--bg); color: var(--text); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; }
::-webkit-scrollbar { width: 5px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }

/* ── FAB safe-area utility ──────────────────────────────────────────
   2026-06-01 UAT — the AI chat FAB sits fixed bottom-right (52px
   button + 24px offset = 76px). Pages whose own action buttons live
   in the same corner can opt into `.has-bottom-fab-safearea` to
   reserve padding-bottom so the FAB doesn't cover them. Modals get
   the FAB auto-hidden (see nav.js), so this utility is mainly for
   non-modal pages with sticky bottom CTAs. */
.has-bottom-fab-safearea { padding-bottom: 88px; }
@media (max-width: 560px) {
  .has-bottom-fab-safearea { padding-bottom: 96px; }
}

/* ── App Shell Layout ── */
#app-shell { display: flex; height: 100vh; overflow: hidden; }
/* SPEC-DISC-2 R2c (owner, 2026-08-21) — the rail is a docked frame, not one
   long scroll. The logo header and the bottom cluster (Discover + profile) pin;
   only .nav-items scrolls between them. Before this the WHOLE rail scrolled
   (overflow-y here), so the logo scrolled away and the bottom cluster was just
   wherever the scroll happened to end — which is why Discover read as one more
   row in the list instead of a docked destination. */
#app-nav   { width: var(--nav-width); flex-shrink: 0; height: 100vh; background: var(--surface); border-right: 1px solid var(--border); display: flex; flex-direction: column; overflow: hidden; position: relative; z-index: 50; }
#app-content { flex: 1; min-width: 0; height: 100vh; display: flex; flex-direction: column; overflow-y: auto; }

/* Pages that need split-pane (overflow:hidden) content should add this class to #app-content */
#app-content.split-pane { overflow: hidden; }

/* ── Nav: Logo ── */
.nav-logo { display: flex; align-items: center; gap: 10px; padding: 16px 14px 12px; text-decoration: none; flex-shrink: 0; border-bottom: 1px solid var(--border); }
.nav-logo-icon { height: 34px; width: auto; display: block; flex-shrink: 0; }
.nav-logo-text { font-size: 1.05rem; font-weight: 700; color: var(--accent); letter-spacing: -0.5px; line-height: 1; white-space: nowrap; }
.nav-logo-health { font-weight: 400; color: var(--text-muted); }
.nav-logo-fit { font-size: 0.8rem; font-weight: 600; color: var(--accent); }

/* ── Nav: Admin View Toggle ── */
.nav-view-toggle { display: flex; gap: 4px; padding: 9px 10px; border-bottom: 1px solid var(--border); flex-shrink: 0; }
.nav-view-btn { flex: 1; background: var(--surface2); border: 1px solid var(--border); color: var(--text-muted); border-radius: 6px; padding: 5px 6px; font-size: 0.7rem; font-weight: 600; cursor: pointer; transition: all 0.15s; font-family: inherit; }
.nav-view-btn.active { background: rgba(76,81,153,0.12); border-color: rgba(76,81,153,0.4); color: var(--accent); }
.nav-view-btn:hover:not(.active) { border-color: var(--accent); color: var(--text); }

/* ── Nav: Items ── */
.nav-items { flex: 1; min-height: 0; overflow-y: auto; padding: 8px 8px 4px; display: flex; flex-direction: column; gap: 2px; }
.nav-items::-webkit-scrollbar { width: 6px; }
.nav-items::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }
.nav-items::-webkit-scrollbar-track { background: transparent; }
.nav-item { display: flex; align-items: center; gap: 10px; padding: 8px 10px; border-radius: 7px; font-size: 0.84rem; font-weight: 600; color: var(--text-muted); text-decoration: none; transition: all 0.15s; border: none; background: none; cursor: pointer; font-family: inherit; width: 100%; text-align: left; }
.nav-item:hover { background: var(--surface2); color: var(--text); }
.nav-item.active { background: rgba(76,81,153,0.12); color: var(--accent); }
.nav-item-icon { font-size: 0.95rem; line-height: 1; flex-shrink: 0; width: 18px; text-align: center; opacity: 0.85; }
/* Section headings in the left rail. The toggle button and the plain
   label share ONE typography rule so a collapsible section and a static
   one can never drift apart. Weight/colour were lifted from 700/--text-dim
   to 800/--text-muted (2026-09-27) so a heading reads as a heading rather
   than as faint chrome. */
.nav-section-label,
.nav-section-toggle { font-size: 0.66rem; text-transform: uppercase; letter-spacing: 1px; color: var(--text-muted); padding: 10px 10px 4px; font-weight: 800; flex-shrink: 0; }
.nav-divider { height: 1px; background: var(--border); margin: 5px 4px; flex-shrink: 0; }
/* SPEC_onboarding_wizard_and_home_routing_v1 §7 — More expander
   collapsed by default when focusModules is set. Non-focus
   modules live inside this <details> so they're one click away
   without cluttering the focused user's nav. */
.nav-more-group { margin: 4px 0; }
.nav-more-group > summary {
  list-style: none;
  cursor: pointer;
  user-select: none;
  display: flex; align-items: center; gap: 8px;
  padding: 8px 10px;
  border-radius: 8px;
  color: var(--text-muted);
  font-family: inherit; font-size: 0.85rem; font-weight: 600;
}
.nav-more-group > summary::-webkit-details-marker { display: none; }
.nav-more-group > summary:hover { background: var(--surface2); color: var(--text); }
.nav-more-group[open] > summary .nav-item-icon { transform: rotate(0deg); }
.nav-more-group > summary .nav-item-icon { transition: transform 0.15s; transform: rotate(-90deg); display: inline-block; }
.nav-more-group[open] > summary .nav-item-icon { transform: rotate(0deg); }

/* SPEC_tenant_member_storefront_v1 §4 — locked module nav rows.
   Tenant-members see ungranted modules at reduced opacity with a lock
   suffix; the click is intercepted by nav.js to surface a stubbed
   "feature not included" dialog (Phase E wires the purchase flow).
   Tier-derived users never see this state — the renderer emits the
   normal nav-item HTML for them. */
.nav-item--locked { opacity: 0.55; cursor: not-allowed; }
.nav-item--locked:hover { background: var(--surface2); color: var(--text-muted); opacity: 0.65; }
.nav-item--locked .nav-locked-suffix { margin-left: auto; font-size: 0.8rem; }

/* SPEC_feedback_infrastructure §6.2 — Beta Feedback nav trigger.
   Moved here from beta-feedback-fab.js (2026-05-12) so the nav can
   pre-render the button at slot-render time without waiting for the
   script's _injectStyles() to fire after the features fetch. Before
   the move, the slot was empty until features.betaFeedbackV1 resolved,
   then the button popped in and shifted the whole nav list down —
   user-reported as a "bouncing nav."

   Padding-top is intentionally smaller than padding-bottom: this
   section is the FIRST child of .nav-items, which already contributes
   8px of top padding (line 115). Symmetric 10px/10px padding stacked
   on that gave 18px above the button vs 10px below — visibly
   off-center. 2px + nav-items's 8px = 10px effective top space,
   matching the 10px below. */
.bfab-nav-section {
  border-bottom: 1px solid var(--border);
  padding: 2px 8px 10px; margin: 0 0 4px;
  flex-shrink: 0; display: flex; justify-content: center;
}
.bfab-nav-btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: 7px; padding: 9px 16px; border-radius: 999px;
  font-size: 0.84rem; font-weight: 600; color: #fff;
  background: var(--accent, #4c5199); border: none; cursor: pointer;
  font-family: inherit;
  box-shadow: 0 4px 14px rgba(76,81,153,0.35);
  transition: transform 0.15s, box-shadow 0.15s, filter 0.15s;
  white-space: nowrap;
}
.bfab-nav-btn:hover  { transform: translateY(-1px); box-shadow: 0 6px 18px rgba(76,81,153,0.45); filter: brightness(1.05); }
.bfab-nav-btn:active { transform: translateY(0);    box-shadow: 0 3px 10px rgba(76,81,153,0.35); }
.bfab-nav-btn.is-open { background: var(--accent, #4c5199); filter: brightness(1.08); box-shadow: 0 6px 18px rgba(76,81,153,0.5); }
.bfab-pulse {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--gold, #f59e0b);
  box-shadow: 0 0 0 0 rgba(245,158,11,0.7);
  animation: bfab-pulse 2.2s infinite; flex-shrink: 0;
}
@keyframes bfab-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(245,158,11,0.6); }
  70%  { box-shadow: 0 0 0 10px rgba(245,158,11,0); }
  100% { box-shadow: 0 0 0 0 rgba(245,158,11,0); }
}

/* Collapsible nav sections. Originally SPEC_Header_Standardization UAT
   (Admin · Management only); generalised 2026-09-27 so EVERY section
   header in the rail — Coach, Supply, Lab, Clinical, Insights, Admin —
   doubles as a disclosure control. Clicking a header collapses that
   section's rows, so an operator who lives in one area can shorten the
   others. State is persisted per-tab to sessionStorage and read back at
   render time so a collapsed group doesn't flash open. */
.nav-section-toggle {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px; width: 100%; cursor: pointer; user-select: none;
  background: none; border: none; font-family: inherit; text-align: left;
  border-radius: 7px;
}
.nav-section-toggle:hover { color: var(--text); background: var(--surface2); }
.nav-section-toggle .nav-section-chevron {
  display: inline-flex; align-items: center; flex-shrink: 0;
  transition: transform 0.18s ease;
  opacity: 0.7;
}
/* The group owns the same column layout as .nav-items so rows inside a
   section keep the 2px rhythm they'd have as direct children of the rail.
   (The old admin wrapper was a plain block, so its rows sat flush.) */
.nav-group, .nav-group-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
/* Chevron points down by default (group expanded). When collapsed
   the parent group gets .is-collapsed and the chevron rotates -90°
   so it points right, matching the standard disclosure pattern. */
.nav-group.is-collapsed .nav-section-toggle .nav-section-chevron {
  transform: rotate(-90deg);
}
.nav-group.is-collapsed .nav-group-body { display: none; }
/* The team-setup count on the Coach header — only while the section is folded, so the
   reminder is not lost; expanded, the tray itself carries it. */
.nav-sec-setup { display: none; }
.nav-group.is-collapsed .nav-sec-setup {
  display: inline-grid; place-items: center; min-width: 16px; height: 16px; padding: 0 4px;
  margin-left: 6px; border-radius: 5px; background: var(--accent); color: #fff;
  font-size: 0.62rem; font-weight: 800; letter-spacing: 0; vertical-align: 1px;
}

/* ── Nav: Dose badge ── */
.dose-badge { font-size: 0.68rem; color: var(--text-dim); font-weight: 600; margin-left: 6px; opacity: 0.8; }

/* ── Nav: Unread count badge (labs, messages) ── */
.nav-unread-badge {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 18px; height: 18px; padding: 0 6px;
  margin-left: auto;
  border-radius: 9px;
  background: var(--accent); color: #fff;
  font-size: 0.66rem; font-weight: 800; line-height: 1;
}
.nav-unread-badge[hidden] { display: none; }

/* ── Nav: Utility divider ── */
.utility-divider { height: 1px; background: var(--border); margin: 6px 12px; }

/* ── Research slide-in panel ── */
.research-panel-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.35); z-index: 300; opacity: 0; pointer-events: none; transition: opacity 0.25s ease; }
.research-panel-overlay.open { opacity: 1; pointer-events: all; }
.research-panel { position: fixed; top: 0; right: 0; bottom: 0; width: 420px; max-width: 100vw; background: var(--surface); border-left: 1px solid var(--border); z-index: 301; display: flex; flex-direction: column; transform: translateX(100%); transition: transform 0.25s ease-out; box-shadow: -4px 0 24px rgba(0,0,0,0.18); }
.research-panel.open { transform: translateX(0); }
.research-panel-head { display: flex; align-items: center; justify-content: space-between; padding: 16px 18px; border-bottom: 1px solid var(--border); flex-shrink: 0; }
.research-panel-title { font-size: 0.95rem; font-weight: 700; color: var(--text); }
.research-panel-close { background: none; border: none; cursor: pointer; color: var(--text-muted); font-size: 1.2rem; padding: 4px; line-height: 1; }
.research-panel-filters { display: flex; align-items: center; gap: 8px; padding: 10px 18px; border-bottom: 1px solid var(--border); flex-shrink: 0; flex-wrap: wrap; }
.research-panel-body { flex: 1; overflow-y: auto; padding: 14px 18px; }
.research-panel-footer { padding: 14px 18px; border-top: 1px solid var(--border); flex-shrink: 0; }
.research-panel-footer a { font-size: 0.85rem; color: var(--accent); font-weight: 600; text-decoration: none; }
.rp-unread-badge { display: inline-flex; align-items: center; background: var(--accent); color: #fff; border-radius: 10px; font-size: 0.65rem; font-weight: 700; padding: 1px 6px; margin-left: 6px; }

/* ── Nav: Bottom ── */
/* SPEC_Navigation_Reorganization §3 — .nav-bottom now hosts ONLY the
   profile dropdown cluster. The legacy footer icon strip (Peptide
   Calculator / Theme / Logout) and standalone .nav-user-block are
   gone. The cluster is positioned `relative` so its absolute-positioned
   menu (open state) anchors correctly to the bottom of the sidebar. */
.nav-bottom { padding: 10px 8px 12px; display: flex; flex-direction: column; gap: 0; flex-shrink: 0;
  border-top: 1px solid var(--border); background: var(--surface); }
.nav-bottom .nav-divider { margin: 0 4px 8px; }

/* SPEC_Navigation_Reorganization §"Coach My Team count badge" — distinct
   from .nav-unread-badge (which uses --accent for member-side counters);
   this one is destructive red so coaches can scan-and-find the engagement
   cohort instantly. Placed inside #nav-team-badge in the My Team nav row. */
.nav-count-badge {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 18px; height: 18px; padding: 0 6px;
  margin-left: auto;
  border-radius: 9px;
  background: #DC4545; color: #fff;
  font-size: 0.66rem; font-weight: 800; line-height: 1;
}
.nav-count-badge[hidden] { display: none; }
/* SPEC-CRL — the Correlations pending-count badge is informational, not an alert:
   a subtle light-purple (brand accent) pill instead of the alarming red. Scoped to
   this badge only — the "My Team" engagement badge stays red. */
#nav-crl-badge { background: rgba(124, 130, 204, 0.22); color: #b7bbec; font-weight: 700; }
:root.light #nav-crl-badge { background: #ECEBF9; color: #4c5199; }

/* 2026-05-16 — minimal notification dot for nav links where a numeric
   chip would force the label to wrap (e.g. "Compound Manager" — long
   label, narrow sidebar column). Renders as an 8px red dot anchored to
   the icon, absolutely positioned so it adds zero width to the row's
   flex layout. Pair with .nav-item (which is position:relative-friendly
   via its single absolute-positioned children). */
.nav-item { position: relative; }
.nav-dot-badge {
  position: absolute;
  top: 6px;
  left: 22px;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: #DC4545;
  border: 2px solid var(--surface);
  box-sizing: content-box;
  pointer-events: none;
}
.nav-dot-badge[hidden] { display: none; }

/* ── Profile dropdown (replaces footer icon strip + nav-user-block) ──
   SPEC_Navigation_Reorganization §3 — pill-shaped row at the bottom of
   the sidebar; click toggles a menu that opens UPWARD anchored to the
   pill's top edge. */
.profile-cluster { position: relative; padding: 0 4px; }

.profile-pill {
  display: flex; align-items: center; gap: 10px;
  width: 100%;
  padding: 8px 10px;
  border-radius: 10px;
  background: var(--surface2);
  /* Subtle accent outline at rest pulls the eye to the bottom-left
     account panel without competing with the active nav row. Hover +
     is-open both saturate to the full accent. */
  border: 1.5px solid rgba(76,81,153,0.45);
  color: var(--text);
  cursor: pointer;
  font-family: inherit;
  text-align: left;
  transition: border-color 0.15s, background 0.15s, box-shadow 0.15s;
}
.profile-pill:hover {
  background: var(--surface2);
  border-color: var(--accent);
  box-shadow: 0 0 0 1px rgba(76,81,153,0.35);
}
.profile-pill.is-open {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px rgba(76,81,153,0.35);
}
.profile-pill-avatar {
  flex-shrink: 0;
  width: 32px; height: 32px;
  border-radius: 50%;
  background: var(--accent);
  color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-size: 0.78rem; font-weight: 700; letter-spacing: 0.5px;
}
.profile-pill-text {
  flex: 1; min-width: 0;
  display: flex; flex-direction: column; gap: 1px;
}
.profile-pill-name {
  font-size: 0.85rem; font-weight: 700; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.profile-pill-role {
  font-size: 0.68rem; color: var(--text-dim);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.profile-pill-chevron {
  flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  transition: transform 150ms ease-out;
}
.profile-pill.is-open .profile-pill-chevron { transform: rotate(180deg); }

/* Menu panel — anchored to the pill's TOP edge so it opens upward. */
.profile-menu {
  position: absolute;
  bottom: calc(100% + 6px);
  left: 4px; right: 4px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: 0 -8px 28px rgba(0,0,0,0.32);
  padding: 6px;
  display: flex; flex-direction: column; gap: 1px;
  z-index: 20;
  animation: profile-menu-in 150ms ease-out;
}
@keyframes profile-menu-in {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(0); }
}
.profile-menu[hidden] { display: none; }
.profile-menu-item {
  display: flex; align-items: center; gap: 10px;
  width: 100%;
  padding: 9px 10px;
  border-radius: 8px;
  background: transparent;
  border: none;
  color: var(--text);
  font-size: 0.84rem; font-weight: 600;
  font-family: inherit;
  cursor: pointer;
  text-decoration: none;
  text-align: left;
}
.profile-menu-item:hover { background: var(--surface2); }
.profile-menu-icon {
  flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px;
}
.profile-menu-icon svg { width: 18px; height: 18px; }
.profile-menu-label { flex: 1; }
.profile-menu-value {
  font-size: 0.72rem; font-weight: 700; color: var(--text-dim);
  text-transform: uppercase; letter-spacing: 0.5px;
}
.profile-menu-divider { height: 1px; background: var(--border); margin: 4px 6px; }
.profile-menu-item-danger { color: var(--red); }
.profile-menu-item-danger:hover { background: rgba(239,68,68,0.08); }

/* ── SPEC-DISC-2 §2 P3/P4 — the Help & Support cluster is RETIRED ─────────
   `.hs-cluster`, `.hs-trigger`, `.hs-pop*`, `.hs-pr-*`, `.hs-ctx-*` and the
   `.hs-pop-foot` band neutraliser all went with the markup they styled. The
   slot they occupied in `.nav-bottom` is Discover's now; everything the popover
   carried lives in the profile menu below.

   The one rule that had to be RE-HOMED rather than deleted is the band
   neutraliser (audit R11). `.bfab-nav-section` paints as a bordered band by
   default — correct where it began life at the top of the rail, wrong in a menu.
   It was neutralised inside `.hs-pop-foot`; without the equivalent scoped to
   `.profile-menu` the demoted row would paint as exactly the band §34.4 removed.
   ────────────────────────────────────────────────────────────────────────── */

/* The demoted Help & support group inside the profile menu. */
.profile-menu-label-row {
  padding: 9px 14px 3px;
  font-size: 0.62rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--text-dim);
}
.profile-menu-search {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 2px 10px 6px;
  padding: 7px 10px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface2);
}
.profile-menu-search:focus-within { border-color: var(--accent); }
.profile-menu-search-ic { display: inline-flex; width: 14px; height: 14px; color: var(--text-dim); flex-shrink: 0; }
.profile-menu-search-ic svg { width: 14px; height: 14px; }
.profile-menu-search input {
  flex: 1;
  min-width: 0;
  border: 0;
  background: none;
  color: var(--text);
  font: inherit;
  /* Effective size is decided later in this file: the global iOS 16px input
     floor, then a precise-pointer override back down to 0.8rem. */
  font-size: 0.8rem;
  outline: none;
}
.profile-menu-search input::placeholder { color: var(--text-dim); }

/* R11 — the band neutraliser, re-homed. Same three declarations the
   `.hs-pop-foot` rule carried, scoped to the new parent. */
.profile-menu .bfab-nav-section { border: none; margin: 0; padding: 0; background: none; }
.profile-menu .bfab-nav-btn {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 9px 14px;
  border: 0;
  border-radius: 0;
  background: none;
  color: var(--text);
  font: inherit;
  font-size: 0.82rem;
  text-align: left;
  cursor: pointer;
}
.profile-menu .bfab-nav-btn:hover,
.profile-menu .bfab-nav-btn:active { background: none; }
/* Kill the global .bfab-nav-btn chrome inside the menu — its box-shadow and
   hover lift painted a raised card behind the pill (2026-08-23). The pill is
   the only visual affordance; the row itself stays flat and quiet. */
.profile-menu .bfab-nav-btn,
.profile-menu .bfab-nav-btn:hover,
.profile-menu .bfab-nav-btn:active { box-shadow: none; transform: none; filter: none; }
.profile-menu .bfab-pulse { flex-shrink: 0; }
/* GA cleanup (2026-08-23) — the feedback row renders one accent-tinted pill
   ("Send feedback"); the pulse dot and unstyled BETA suffix are gone. */
.bfab-feedback-pill {
  display: inline-flex;
  align-items: center;
  padding: 4px 14px;
  border-radius: 999px;
  background: var(--accent-dim, rgba(76, 81, 153, 0.12));
  border: 1px solid var(--accent-b, rgba(76, 81, 153, 0.3));
  color: var(--accent);
  font-size: 0.78rem;
  font-weight: 600;
  line-height: 1.4;
}
.profile-menu .bfab-nav-btn:hover .bfab-feedback-pill { filter: brightness(1.06); }

/* ── SPEC-DISC-2 R2 (owner pass, 2026-08-21) — the "On this page" pill is
   RETIRED with its rules. It duplicated on re-render and was redundant beside
   the info icon; the list it showed lives in the help drawer now
   (help-drawer.js: the smart-open list view and the footer's On-this-page
   tab). Nothing chrome-level replaces it — the info icon is the one entry. */

/* SPEC-DISC-2 R2c — the Discover row is a DOCKED destination, and it should
   look like one. An accent-tinted panel: enough presence that it does not blur
   into the scrolling list above, deliberately not the profile pill's bordered
   avatar-row shape below, so the two docked elements read as different kinds
   of control. It stays a .nav-item so hover/active/badge behaviour is inherited. */
.nav-bottom .nav-item.nav-discover {
  margin: 0 4px 8px;
  background: color-mix(in srgb, var(--accent) 9%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 26%, transparent);
  border-radius: 10px;
  font-weight: 700;
}
.nav-bottom .nav-item.nav-discover:hover {
  background: color-mix(in srgb, var(--accent) 15%, transparent);
}
.nav-bottom .nav-item.nav-discover.active {
  background: color-mix(in srgb, var(--accent) 20%, transparent);
  border-color: color-mix(in srgb, var(--accent) 45%, transparent);
}

/* ── Common Utility Styles ── */
.shell-btn { display: inline-flex; align-items: center; gap: 6px; background: var(--surface2); border: 1px solid var(--border); color: var(--text-muted); border-radius: 7px; padding: 7px 13px; font-size: 0.83rem; font-weight: 600; cursor: pointer; font-family: inherit; text-decoration: none; transition: all 0.2s; white-space: nowrap; }
.shell-btn:hover { border-color: var(--accent); color: var(--accent); }
.shell-btn.primary { background: var(--accent); color: #fff; border-color: var(--accent); }
.shell-btn.primary:hover { opacity: 0.88; }
.shell-btn.danger  { color: var(--red); }
.shell-btn.danger:hover { border-color: var(--red); background: rgba(239,68,68,0.08); }

/* ── Icon system variables ──────────────────────────────────────── */
:root {
  --icon-stroke:        #8b90b8;
  --icon-stroke-active: #7b82cc;
  --icon-stroke-teal:   #3d9e8c;
  --icon-stroke-red:    #c84c4c;
  --badge-peptide-bg:   rgba(76, 81, 153, 0.25);
  --badge-supplement-bg:rgba(61, 158, 140, 0.22);
  --badge-custom-bg:    rgba(200, 155, 60, 0.20);
}
:root.light {
  --icon-stroke:        #6b6f9a;
  --icon-stroke-active: #4c5199;
}
.nav-item .nav-item-icon { --icon-stroke: #8b90b8; display:inline-flex;align-items:center; }
.nav-item.active .nav-item-icon { --icon-stroke: #7b82cc; }
:root.light .nav-item .nav-item-icon { --icon-stroke: #6b6f9a; }
:root.light .nav-item.active .nav-item-icon { --icon-stroke: #4c5199; }
.nav-item svg { width:20px;height:20px;flex-shrink:0; }
.nav-util svg { width:18px;height:18px;flex-shrink:0; }
.compound-badge svg { width:28px;height:28px;flex-shrink:0; }
.compound-badge-sm svg { width:20px;height:20px;flex-shrink:0; }

/* ── Page scaffold helpers (for simple full-scroll pages) ── */
.page-wrap { max-width: 1200px; margin: 0 auto; padding: 28px 28px 64px; }
.page-heading { font-size: 1.4rem; font-weight: 700; margin-bottom: 4px; }
.page-subheading { font-size: 0.88rem; color: var(--text-muted); }

/* ── Full-bleed page layout (matches protocol.html pattern) ───────────────
   Opt-in alternative to .page-wrap. Content is flush to the left nav (no
   centered max-width), and the page header spans the full content width
   with its own bottom border — tab strip tucks into the same header band.
   Used by nutrition.html + workouts.html (Sprint 6 layout parity). */
.page-bleed { max-width: none; margin: 0; padding: 0; display: flex; flex-direction: column; min-height: 100%; }
.page-bleed-head { background: var(--surface); border-bottom: 1px solid var(--border); padding: 16px 24px 0; flex-shrink: 0; }
.page-bleed-title-row { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 12px; margin-bottom: 10px; }
.page-bleed-head .tab-strip { margin-bottom: 0; border-bottom: none; }
/* SPEC_Header_Standardization §3 — pages that use the legacy
   .page-tab-row variant (currently users.html) get the same
   border-collapse treatment when nested inside .page-bleed-head, so
   the tab row sits flush on the head's bottom border instead of
   stacking a second hairline below the tabs. */
.page-bleed-head .page-tab-row { margin-bottom: 0; border-bottom: none; }
.page-bleed-body { padding: 20px 24px 80px; flex: 1; }
@media (max-width: 640px) {
  .page-bleed-head { padding: 12px 14px 0; }
  .page-bleed-body { padding: 14px 14px 60px; }
}
/* ── Narrow-content opt-in ─────────────────────────────────────────────────
   Pages that apply `.page-narrow` on their <main class="page-bleed"> cap the
   header + body at ~960px so content doesn't spread edge-to-edge on wide
   displays. Anchored flush-LEFT (against the nav sidebar) to match the rest
   of the app — dashboard, protocol, progress all left-align their content. */
.page-narrow .page-bleed-title-row,
.page-narrow .page-bleed-head .tab-strip,
.page-narrow .page-bleed-body {
  max-width: 960px;
  margin-left: 0;
  margin-right: auto;
  width: 100%;
}

/* ─────────────────────────────────────────────────────────────────────────
   Shared page layout (promoted from progress.html + account.html).
   Adopted by nutrition.html / workouts.html (Sprint 1 of the nutrition +
   workouts overhaul). Use these classes on any new primary page so the
   header + tab strip + content cards all land in the same visual rhythm.
   ───────────────────────────────────────────────────────────────────────── */

.page-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 20px; flex-wrap: wrap; gap: 10px; }
.page-title { font-size: 1.4rem; font-weight: 800; color: var(--text); margin: 0; }
.page-subtitle { font-size: 0.88rem; color: var(--text-muted); margin-top: 2px; }
.page-header-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.page-header-actions .btn-secondary,
.page-header-actions .btn-primary { font-size: 0.82rem; padding: 7px 14px; }

/* Horizontal scrolling tab strip with pill-accent active state. */
.tab-strip { display: flex; gap: 2px; border-bottom: 1px solid var(--border); margin-bottom: 24px; overflow-x: auto; scrollbar-width: none; -ms-overflow-style: none; -webkit-overflow-scrolling: touch; }
.tab-strip::-webkit-scrollbar { display: none; }
.tab-btn { background: none; border: none; border-bottom: 3px solid transparent; padding: 10px 20px 11px; font-size: 0.88rem; font-weight: 600; color: var(--text-muted); cursor: pointer; font-family: inherit; transition: all 0.15s; margin-bottom: -1px; white-space: nowrap; flex-shrink: 0; border-radius: 6px 6px 0 0; }
.tab-btn:hover { color: var(--text); background: rgba(76,81,153,0.06); }
.tab-btn.active { color: #fff; background: var(--accent); border-bottom-color: var(--accent); border-radius: 8px 8px 0 0; }
.tab-btn .tab-badge { display: inline-block; background: var(--surface2); color: var(--text-muted); font-size: 0.68rem; font-weight: 700; padding: 1px 7px; border-radius: 10px; margin-left: 6px; border: 1px solid var(--border); }
.tab-btn.active .tab-badge { background: rgba(255,255,255,0.2); color: #fff; border-color: transparent; }
/* Keyboard focus ring — visible only via :focus-visible so mouse clicks
   don't show a persistent ring. A11y pass (Sprint 6). */
.tab-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.pill-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* ─── Sub-tab pill navigation ────────────────────────────────────────────── */
/* Used for sub-tab bars inside top-level tabs (e.g., Plan → My Plan /
   My Favorites / My Schedule). Promoted from the inline workouts.html
   rule so Nutrition and Protocol Plan panels can reuse the same
   visual language without duplicating CSS. */
.pill-row { display: flex; gap: 6px; margin-bottom: 14px; flex-wrap: wrap; }
.pill-btn { background: transparent; border: 1px solid var(--border); color: var(--text-muted); border-radius: 20px; padding: 6px 14px; font-family: inherit; font-size: 0.82rem; font-weight: 600; cursor: pointer; transition: background .15s, color .15s, border-color .15s; }
.pill-btn:hover:not(.active) { color: var(--text); border-color: var(--accent); }
.pill-btn.active { background: var(--accent); color: #fff; border-color: var(--accent); }
.btn-primary:focus-visible, .btn-secondary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Skeleton placeholder — subtle animated shimmer used while tab content is
   loading. Alternative to bare "Loading…" text. */
.skel-block { background: linear-gradient(90deg, var(--surface2) 25%, rgba(255,255,255,0.04) 37%, var(--surface2) 63%); background-size: 400% 100%; border-radius: 8px; animation: skelShimmer 1.4s infinite ease-in-out; }
@keyframes skelShimmer { 0% { background-position: 100% 50%; } 100% { background-position: 0% 50%; } }

/* 2026-05-14 — nav skeleton, painted by renderNavSkeleton() on cold
   loads (no cached user). Structural placeholder for the main site
   nav while /api/auth/me is in flight. Uses the same skelShimmer
   animation as .skel-block so it reads as part of the same loading
   visual language. The skeleton inherits #app-nav's flex column
   layout from its parent, so the items stack like the real nav.

   Faded opacity (0.5) makes it clear this isn't interactive yet,
   without going so transparent it feels like there's nothing there.
   The shimmer is what tells the user "this is loading", not the
   color alone. */
.nav-skeleton {
  display: flex; flex-direction: column;
  padding: 18px 14px;
  gap: 10px;
  opacity: 0.55;
}
.nav-skeleton .ns-logo {
  height: 28px; width: 130px;
  margin-bottom: 12px;
  background: linear-gradient(90deg, var(--surface2) 25%, rgba(255,255,255,0.04) 37%, var(--surface2) 63%);
  background-size: 400% 100%;
  border-radius: 6px;
  animation: skelShimmer 1.4s infinite ease-in-out;
}
.nav-skeleton .ns-item {
  display: flex; align-items: center; gap: 10px;
  padding: 4px 4px;
}
.nav-skeleton .ns-icon {
  width: 22px; height: 22px;
  flex-shrink: 0;
  background: linear-gradient(90deg, var(--surface2) 25%, rgba(255,255,255,0.04) 37%, var(--surface2) 63%);
  background-size: 400% 100%;
  border-radius: 6px;
  animation: skelShimmer 1.4s infinite ease-in-out;
}
.nav-skeleton .ns-label {
  height: 12px;
  /* width set inline per item so the skeleton looks like real labels
     of varying length rather than a uniform stripe pattern. */
  background: linear-gradient(90deg, var(--surface2) 25%, rgba(255,255,255,0.04) 37%, var(--surface2) 63%);
  background-size: 400% 100%;
  border-radius: 4px;
  animation: skelShimmer 1.4s infinite ease-in-out;
}
.nav-skeleton .ns-section-label {
  height: 8px; width: 56px;
  margin: 12px 4px 4px;
  background: linear-gradient(90deg, var(--surface2) 25%, rgba(255,255,255,0.04) 37%, var(--surface2) 63%);
  background-size: 400% 100%;
  border-radius: 3px;
  animation: skelShimmer 1.4s infinite ease-in-out;
  opacity: 0.7;
}

/* ── 2026-05-14 — shared loading state component ──────────────────────
   Used by any surface that needs to show "we're working on it" between
   parse-time and first-data-paint. Reads as friendlier than a blank
   pane or a misleading "No results found".

   Usage (one-liner):
     <div class="app-loading"><div class="app-loading-spinner"></div>
       <div class="app-loading-text">Loading compounds…</div></div>

   The grid-column:1/-1 hint lets it span a full responsive grid row
   when dropped into a card-grid container.

   Two-circle spinner — outer ring rotates, inner pulses — reads as
   "active and progressing" rather than the typical single-stroke
   spinner which can look stuck if a fetch genuinely hangs. */
.app-loading {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 14px;
  padding: 60px 20px;
  color: var(--text-dim, #6b7280);
  text-align: center;
  grid-column: 1 / -1;
}
.app-loading-spinner {
  position: relative;
  width: 42px; height: 42px;
}
.app-loading-spinner::before,
.app-loading-spinner::after {
  content: ''; position: absolute; inset: 0;
  border-radius: 50%;
}
.app-loading-spinner::before {
  border: 3px solid rgba(91, 63, 199, 0.18);
  border-top-color: var(--accent, #5b3fc7);
  animation: appLoadingSpin 0.9s linear infinite;
}
.app-loading-spinner::after {
  inset: 12px;
  background: var(--accent, #5b3fc7);
  opacity: 0.6;
  animation: appLoadingPulse 1.2s ease-in-out infinite;
}
.app-loading-text {
  font-size: 0.88rem; font-weight: 500;
  color: var(--text-muted, #9ca3af);
  letter-spacing: 0.01em;
}
.app-loading-sub {
  font-size: 0.74rem;
  color: var(--text-dim, #6b7280);
  margin-top: -6px;
}
@keyframes appLoadingSpin { to { transform: rotate(360deg); } }
@keyframes appLoadingPulse {
  0%, 100% { transform: scale(0.7); opacity: 0.35; }
  50%      { transform: scale(1.0); opacity: 0.75; }
}
/* Subtle entry — feels less abrupt when the component swaps in. */
.app-loading { animation: appLoadingFadeIn 0.2s ease-out; }
@keyframes appLoadingFadeIn { from { opacity: 0; } to { opacity: 1; } }

/* Screen-reader-only helper for labels we don't want visually rendered. */
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }

/* iOS Safari auto-zooms any <input> whose effective font-size is below 16px
   (platform default). Apply a 16px floor globally so users don't have to
   pinch-zoom out after focusing any search input. Per-page styles that need
   smaller visual density should shrink padding/height, never font-size. */
input[type="text"], input[type="search"], input[type="email"], input[type="password"],
input[type="number"], input[type="tel"], input[type="url"], input[type="date"],
input[type="time"], input[type="datetime-local"], input:not([type]), textarea, select {
  font-size: 16px;
}
/* The profile-menu help search is the one place the 16px floor visibly
   overflows its compact box. On precise-pointer devices (no auto-zoom to
   prevent) let it use the menu's own scale; touch devices keep the floor,
   where the shortened placeholder still fits. Same specificity as the floor
   above — this wins by order, and must stay AFTER it. */
@media (hover: hover) and (pointer: fine) {
  .profile-menu-search input { font-size: 0.8rem; }
}

/* Shared content card. Aliases .section so both names render the same — new
   code should prefer .card; existing .section usage on account.html + other
   pages stays valid. */
.card, .section { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); margin-bottom: 20px; }
.card-header, .section-header { padding: 16px 20px 14px; border-bottom: 1px solid var(--border); display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; flex-wrap: wrap; }
.card-title, .section-title { font-size: 0.82rem; font-weight: 700; text-transform: uppercase; letter-spacing: 1px; color: var(--text-dim); }
.card-sub, .section-sub { font-size: 0.76rem; color: var(--text-muted); margin-top: 4px; font-weight: 400; text-transform: none; letter-spacing: 0; }
.card-body, .section-body { padding: 20px; }
.card-body.flush, .section-body.flush { padding: 0; }
.card.subtle { background: var(--surface2); }

/* Empty state used inside any card or tab pane. */
.empty-state { padding: 36px 24px; text-align: center; color: var(--text-muted); }
.empty-state .empty-icon { font-size: 2.2rem; margin-bottom: 10px; opacity: 0.9; }
.empty-state h3 { margin: 0 0 6px; font-size: 1rem; font-weight: 700; color: var(--text); }
.empty-state p { margin: 0 auto 14px; font-size: 0.86rem; line-height: 1.55; max-width: 420px; }
.empty-state .btn-primary,
.empty-state .btn-integ { margin-top: 4px; }

/* Small placeholder for tabs whose full content lands in a later sprint —
   keeps the scaffold styled consistently while it's a stub. */
.sprint-stub { border: 1px dashed var(--border); border-radius: var(--radius); padding: 28px 24px; text-align: center; color: var(--text-dim); font-size: 0.86rem; background: transparent; }
.sprint-stub strong { color: var(--text-muted); font-weight: 700; }
.sprint-stub .stub-detail { display: block; margin-top: 6px; font-size: 0.78rem; color: var(--text-dim); }

/* Button helpers reused on new pages (accent/ghost). */
.btn-primary { background: var(--accent); color: #fff; border: none; border-radius: 8px; padding: 9px 16px; font-family: inherit; font-weight: 600; font-size: 0.86rem; cursor: pointer; transition: background 0.15s; display: inline-flex; align-items: center; gap: 6px; }
.btn-primary:hover { background: var(--accent-light, #6b74cc); }
.btn-primary:disabled { opacity: 0.5; cursor: default; }
.btn-secondary { background: transparent; color: var(--text-muted); border: 1px solid var(--border); border-radius: 8px; padding: 8px 14px; font-family: inherit; font-weight: 600; font-size: 0.84rem; cursor: pointer; transition: all 0.15s; display: inline-flex; align-items: center; gap: 6px; }
.btn-secondary:hover { border-color: var(--accent); color: var(--accent); }

/* ── Mobile header (hidden on desktop) ────────────────────────────────────── */
#mobile-header { display: none; }
#nav-backdrop  { display: none; }

/* ── Legacy hamburger / float-tab buttons (pre-mobile-nav artifacts) ──────── */
.hamburger-btn { display: none !important; }
#nav-float-tab  { display: none !important; }

/* ── Mobile breakpoint ─────────────────────────────────────────────────────── */
@media (max-width: 767px) {

  /* Fixed top bar — logo left, hamburger right */
  #mobile-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 16px;
    height: 54px;
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    position: fixed;
    top: 0; left: 0; right: 0;
    z-index: 110;
    flex-shrink: 0;
  }
  .mobile-logo {
    display: flex; align-items: center; gap: 9px;
    text-decoration: none;
  }
  .mobile-logo img { height: 36px; width: auto; }

  /* Hamburger button */
  #mobile-hamburger {
    background: none; border: none; cursor: pointer;
    padding: 8px 4px; display: flex; flex-direction: column;
    gap: 5px; width: 36px; align-items: center;
  }
  #mobile-hamburger span {
    display: block; width: 22px; height: 2px;
    background: var(--text-muted); border-radius: 2px;
    transition: transform 0.2s, opacity 0.2s;
  }
  /* Animate to × when open */
  #app-shell.nav-open #mobile-hamburger span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
  #app-shell.nav-open #mobile-hamburger span:nth-child(2) { opacity: 0; transform: scaleX(0); }
  #app-shell.nav-open #mobile-hamburger span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

  /* App shell stacks vertically; content gets top padding for the fixed header */
  #app-shell   { flex-direction: column; }
  #app-content { padding-top: 54px; width: 100%; height: 100vh; }

  /* Sidebar becomes a fixed slide-in overlay below the header */
  #app-nav {
    position: fixed;
    top: 54px; left: 0; bottom: 0;
    width: 260px;
    height: auto;
    transform: translateX(-100%);
    transition: transform 0.25s ease;
    z-index: 100;
    box-shadow: 4px 0 24px rgba(0,0,0,0.35);
    overflow-y: auto;
  }
  #app-shell.nav-open #app-nav { transform: translateX(0); }

  /* Semi-transparent backdrop behind open nav */
  #nav-backdrop {
    position: fixed;
    top: 54px; left: 0; right: 0; bottom: 0;
    background: rgba(0,0,0,0.5);
    z-index: 95;
    display: none;
  }
  #app-shell.nav-open #nav-backdrop { display: block; }

  /* Hide duplicate sidebar logo — mobile header already has it */
  #app-nav .nav-logo { display: none; }
  #app-nav .nav-items { padding-top: 12px; }
}

/* ── Page Navigation Bar — mobile-only context strip above page content ─── */
.page-nav-bar { display: none; }

@media (max-width: 767px) {
  .page-nav-bar {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 0 14px;
    height: 44px;
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    flex-shrink: 0;
    z-index: 87;
  }
  .page-nav-trigger {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    background: var(--surface2);
    border: 1px solid var(--border);
    color: var(--text-muted);
    border-radius: 7px;
    padding: 5px 11px;
    font-size: 0.8rem;
    font-weight: 600;
    cursor: pointer;
    font-family: inherit;
    white-space: nowrap;
    transition: all 0.15s;
    flex-shrink: 0;
  }
  .page-nav-trigger.open,
  .page-nav-trigger:hover {
    border-color: var(--accent);
    color: var(--accent);
    background: rgba(76,81,153,0.08);
  }
  .page-nav-trigger svg { flex-shrink: 0; }
  .page-nav-context {
    flex: 1;
    font-size: 0.8rem;
    color: var(--text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 0;
    text-align: right;
  }

  /* ── Flyout handle row — close button at top of each panel on mobile ── */
  .flyout-handle-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 11px 14px;
    border-bottom: 1px solid var(--border);
    flex-shrink: 0;
    background: var(--surface);
  }
  .flyout-handle-label {
    font-size: 0.82rem;
    font-weight: 700;
    color: var(--text-muted);
    letter-spacing: 0.01em;
  }
  .flyout-handle-close {
    background: none;
    border: 1px solid var(--border);
    color: var(--text-muted);
    border-radius: 7px;
    width: 28px; height: 28px;
    cursor: pointer;
    display: flex; align-items: center; justify-content: center;
    font-size: 0.85rem;
    transition: all 0.15s;
    line-height: 1;
  }
  .flyout-handle-close:hover { border-color: var(--accent); color: var(--text); }
}
@media (min-width: 768px) {
  .flyout-handle-row { display: none; }
}

/* ── AI Chat Button ───────────────────────────────────────────────────────── */
#ai-chat-btn {
  position: fixed; bottom: 24px; right: 24px; z-index: 1200;
  width: 52px; height: 52px; border-radius: 50%;
  background: var(--accent); color: #fff;
  border: none; cursor: pointer; box-shadow: 0 4px 16px rgba(76,81,153,0.45);
  display: flex; align-items: center; justify-content: center;
  transition: transform 0.15s, box-shadow 0.15s;
}
#ai-chat-btn:hover { transform: scale(1.1); box-shadow: 0 6px 20px rgba(76,81,153,0.6); }

/* ── AI Insights Page ─────────────────────────────────────────────────────── */
.ai-insights-section-card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 20px; margin-bottom: 14px;
}
.ai-insights-section-header {
  display: flex; align-items: center; gap: 10px; margin-bottom: 14px;
}
.ai-insights-observations {
  list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 8px;
}
.ai-insights-observations li {
  font-size: 0.88rem; color: var(--text-muted); line-height: 1.6;
  padding-left: 18px; position: relative;
}
.ai-insights-observations li::before { content: '•'; position: absolute; left: 0; color: var(--accent); font-weight: 700; }

.ai-insights-skeleton { background: var(--surface2); border-radius: 10px; height: 120px; animation: pulse 1.5s ease-in-out infinite; margin-bottom: 14px; }
.ai-insights-history-item {
  background: var(--surface); border: 1px solid var(--border); border-radius: 10px;
  padding: 14px 16px; cursor: pointer; transition: all 0.15s;
  display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px;
}
.ai-insights-history-item:hover { border-color: var(--accent); }
.ai-insights-history-item.active { border-color: var(--accent); background: rgba(76,81,153,0.06); }
.ai-insights-locked {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 40px 24px; text-align: center;
}

/* ── AI Disclaimer ────────────────────────────────────────────────────────── */
.ai-disclaimer {
  font-size: 0.76rem; color: var(--text-dim); font-style: italic;
  line-height: 1.6; padding: 14px 0 4px; border-top: 1px solid var(--border); margin-top: 14px;
}

/* ── AI Cost Monitoring — admin-ai.html ───────────────────────────────────── */

/* Budget warning banner */
.ai-budget-banner {
  position: fixed; top: 0; left: 0; right: 0; z-index: 2000;
  background: #f59e0b; color: #1c1917;
  padding: 10px 48px 10px 16px;
  font-size: 0.88rem; font-weight: 600; line-height: 1.5;
  display: flex; align-items: center; gap: 12px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.25);
}
.ai-budget-banner--red { background: #ef4444; color: #fff; }
.ai-budget-banner-text { flex: 1; }
.ai-budget-banner-link { color: inherit; font-weight: 700; text-decoration: underline; }
.ai-budget-banner-dismiss {
  position: absolute; right: 12px; top: 50%; transform: translateY(-50%);
  background: none; border: none; cursor: pointer; font-size: 1.2rem;
  color: inherit; opacity: 0.7; line-height: 1; padding: 2px 6px;
}
.ai-budget-banner-dismiss:hover { opacity: 1; }

/* Section card wrapper */
.ai-section {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 24px; margin-bottom: 20px;
}
.ai-section-title {
  font-size: 1rem; font-weight: 800; margin: 0 0 18px;
  color: var(--text); display: flex; align-items: center; gap: 8px;
}

/* CSS-only toggle switch */
.ai-toggle-row {
  display: flex; align-items: center; justify-content: space-between;
  padding: 10px 0; border-bottom: 1px solid var(--border);
}
.ai-toggle-row:last-child { border-bottom: none; }
.ai-toggle-label { font-size: 0.92rem; color: var(--text); font-weight: 500; }
.ai-toggle {
  position: relative; display: inline-block; width: 44px; height: 24px; flex-shrink: 0;
}
.ai-toggle input { opacity: 0; width: 0; height: 0; }
.ai-toggle-slider {
  position: absolute; cursor: pointer; inset: 0;
  background: var(--surface2); border: 1px solid var(--border);
  border-radius: 24px; transition: background 0.2s, border-color 0.2s;
}
.ai-toggle-slider::before {
  content: ''; position: absolute;
  width: 16px; height: 16px; border-radius: 50%;
  background: var(--text-muted); left: 3px; top: 3px;
  transition: transform 0.2s, background 0.2s;
}
.ai-toggle input:checked + .ai-toggle-slider { background: var(--accent); border-color: var(--accent); }
.ai-toggle input:checked + .ai-toggle-slider::before { transform: translateX(20px); background: #fff; }

/* Budget progress bar */
.ai-budget-bar-wrap { margin: 12px 0 6px; }
.ai-budget-bar {
  height: 12px; border-radius: 6px; background: var(--surface2);
  border: 1px solid var(--border); overflow: hidden;
}
.ai-budget-bar-fill {
  height: 100%; border-radius: 6px;
  background: #22c55e; transition: width 0.4s, background 0.4s;
}
.ai-budget-bar-fill--amber { background: #f59e0b; }
.ai-budget-bar-fill--red   { background: #ef4444; }
.ai-budget-bar-label { font-size: 0.82rem; color: var(--text-muted); margin-top: 5px; }

/* Usage scorecard */
.ai-period-toggle {
  display: inline-flex; border: 1px solid var(--border); border-radius: 8px;
  overflow: hidden; margin-bottom: 18px;
}
.ai-period-btn {
  padding: 7px 18px; font-size: 0.85rem; font-weight: 600; cursor: pointer;
  background: var(--surface2); border: none; color: var(--text-muted);
  font-family: inherit; transition: all 0.15s;
}
.ai-period-btn.active { background: var(--accent); color: #fff; }
.ai-scorecard {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px;
}
@media (max-width: 767px) { .ai-scorecard { grid-template-columns: repeat(2, 1fr); } }
.ai-metric-card {
  background: var(--surface2); border: 1px solid var(--border);
  border-radius: 10px; padding: 14px 16px;
}
.ai-metric-card-label { font-size: 0.74rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.8px; color: var(--text-dim); margin-bottom: 6px; }
.ai-metric-card-value { font-size: 1.4rem; font-weight: 800; color: var(--text); line-height: 1.1; }
.ai-metric-card-sub   { font-size: 0.76rem; color: var(--text-muted); margin-top: 3px; }

/* Usage table */
.ai-usage-table-wrap { overflow-x: auto; }
.ai-usage-table {
  width: 100%; border-collapse: collapse; font-size: 0.85rem;
}
.ai-usage-table th {
  text-align: left; padding: 8px 10px; font-size: 0.74rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.7px; color: var(--text-dim);
  border-bottom: 1px solid var(--border); white-space: nowrap; cursor: pointer;
  user-select: none;
}
.ai-usage-table th:hover { color: var(--accent); }
.ai-usage-table th.sort-asc::after  { content: ' ↑'; }
.ai-usage-table th.sort-desc::after { content: ' ↓'; }
.ai-usage-table td {
  padding: 9px 10px; border-bottom: 1px solid var(--border);
  vertical-align: middle; color: var(--text-muted);
}
.ai-usage-table tr:hover td { background: rgba(76,81,153,0.04); }
.ai-usage-table td:first-child { color: var(--text); font-weight: 500; }

/* Tier badge */
.ai-tier-badge {
  display: inline-block; font-size: 0.68rem; font-weight: 700;
  padding: 2px 7px; border-radius: 4px; text-transform: uppercase; letter-spacing: 0.5px;
}
.ai-tier-badge--free     { background: var(--surface2); color: var(--text-dim); border: 1px solid var(--border); }
.ai-tier-badge--optimize { background: rgba(76,81,153,0.15); color: #818cf8; border: 1px solid rgba(76,81,153,0.3); }
.ai-tier-badge--elite    { background: rgba(168,85,247,0.15); color: #c084fc; border: 1px solid rgba(168,85,247,0.3); }
.ai-tier-badge--admin    { background: rgba(239,68,68,0.12); color: #f87171; border: 1px solid rgba(239,68,68,0.25); }

/* Per-row sparkline */
.ai-sparkline { display: flex; align-items: flex-end; gap: 2px; height: 28px; }
.ai-sparkline-bar {
  flex: 1; min-height: 2px; border-radius: 2px 2px 0 0;
  background: var(--accent); opacity: 0.6;
}

/* Per-user override panel */
.ai-override-row td { padding: 0 !important; }
.ai-override-panel {
  padding: 16px 20px; background: var(--surface2); border-top: 1px solid var(--border);
}
.ai-override-panel h4 { font-size: 0.85rem; font-weight: 700; margin: 0 0 12px; color: var(--text); }
.ai-override-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 10px; margin-bottom: 12px;
}
.ai-override-field label { font-size: 0.76rem; color: var(--text-muted); display: block; margin-bottom: 4px; }
.ai-override-field input {
  width: 100%; padding: 6px 8px; background: var(--surface); border: 1px solid var(--border);
  border-radius: 6px; color: var(--text); font-size: 0.85rem; font-family: inherit;
}
.ai-override-field input:focus { outline: none; border-color: var(--accent); }
.ai-override-actions { display: flex; gap: 8px; flex-wrap: wrap; }

/* Config table */
.ai-config-table {
  width: 100%; border-collapse: collapse; font-size: 0.88rem; margin-bottom: 16px;
}
.ai-config-table th {
  text-align: left; padding: 6px 10px; font-size: 0.74rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.7px; color: var(--text-dim);
  border-bottom: 1px solid var(--border);
}
.ai-config-table th:not(:first-child) { text-align: center; }
.ai-config-table td { padding: 8px 10px; border-bottom: 1px solid var(--border); color: var(--text-muted); }
.ai-config-table td:first-child { color: var(--text); }
.ai-config-table input[type="number"] {
  width: 70px; padding: 5px 7px; text-align: center;
  background: var(--surface2); border: 1px solid var(--border);
  border-radius: 6px; color: var(--text); font-size: 0.85rem; font-family: inherit;
}
.ai-config-table input[type="number"]:focus { outline: none; border-color: var(--accent); }

/* Table filter row */
.ai-table-filters { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; margin-bottom: 12px; }
.ai-filter-pill {
  padding: 5px 14px; border-radius: 20px; font-size: 0.8rem; font-weight: 600;
  cursor: pointer; background: var(--surface2); border: 1px solid var(--border);
  color: var(--text-muted); transition: all 0.15s; font-family: inherit;
}
.ai-filter-pill.active { background: var(--accent); border-color: var(--accent); color: #fff; }
.ai-search-input {
  padding: 6px 12px; background: var(--surface2); border: 1px solid var(--border);
  border-radius: 8px; color: var(--text); font-size: 0.85rem; font-family: inherit;
  min-width: 180px;
}
.ai-search-input:focus { outline: none; border-color: var(--accent); }

/* Checkbox row */
.ai-checkbox-row { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.ai-checkbox-row label { font-size: 0.9rem; color: var(--text-muted); cursor: pointer; }
.ai-checkbox-row input[type="checkbox"] { accent-color: var(--accent); width: 15px; height: 15px; cursor: pointer; }

/* Validation warning */
.ai-validation-warn { color: #f59e0b; font-size: 0.8rem; margin-top: 4px; }

/* Buttons */
.ai-btn {
  padding: 9px 18px; border-radius: 8px; font-size: 0.88rem; font-weight: 700;
  cursor: pointer; font-family: inherit; border: none; transition: opacity 0.15s;
}
.ai-btn-primary { background: var(--accent); color: #fff; }
.ai-btn-primary:hover { opacity: 0.88; }
.ai-btn-secondary { background: var(--surface2); color: var(--text-muted); border: 1px solid var(--border); }
.ai-btn-secondary:hover { border-color: var(--accent); color: var(--accent); }
.ai-btn-danger { background: rgba(239,68,68,0.1); color: #ef4444; border: 1px solid rgba(239,68,68,0.25); }
.ai-btn-danger:hover { background: rgba(239,68,68,0.2); }
.ai-btn-sm { padding: 5px 12px; font-size: 0.8rem; }

.ai-last-changed { font-size: 0.78rem; color: var(--text-dim); margin-top: 12px; }
.ai-disclaimer-note { font-size: 0.76rem; color: var(--text-dim); font-style: italic; margin-top: 12px; }

/* ── Coaching Styles ──────────────────────────────────────────────────────── */

/* Member card grid */
.coaching-card-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
@media (max-width: 1024px) { .coaching-card-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 640px) { .coaching-card-grid { grid-template-columns: 1fr; } }

.coaching-card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 18px; display: flex;
  flex-direction: column; gap: 12px; position: relative; overflow: hidden;
  transition: border-color 0.15s;
}
.coaching-card:hover { border-color: var(--accent); }
.coaching-card.inactive { border-left: 3px solid #f59e0b; }
.coaching-card.dormant { border-left: 3px solid #ef4444; }

.coaching-card-header { display: flex; align-items: center; gap: 12px; }
.coaching-card-avatar {
  width: 44px; height: 44px; border-radius: 50%; flex-shrink: 0;
  background: var(--accent); color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-size: 1.1rem; font-weight: 800;
}
.coaching-card-name { font-size: 0.95rem; font-weight: 700; color: var(--text); }
.coaching-card-email { font-size: 0.78rem; color: var(--text-muted); margin-top: 2px; }
.coaching-card-goal {
  font-size: 0.82rem; color: var(--text-muted); overflow: hidden;
  white-space: nowrap; text-overflow: ellipsis; padding: 8px 10px;
  background: var(--surface2); border-radius: 6px; border: 1px solid var(--border);
}
.coaching-card-stats { display: flex; flex-direction: column; gap: 5px; }
.coaching-card-stat {
  display: flex; justify-content: space-between; align-items: center;
  font-size: 0.82rem;
}
.coaching-card-stat-label { color: var(--text-muted); }
.coaching-card-stat-value { font-weight: 600; color: var(--text); }
.coaching-dormant-badge {
  display: inline-flex; align-items: center; gap: 4px;
  background: rgba(239,68,68,0.1); color: #ef4444;
  border: 1px solid rgba(239,68,68,0.25); border-radius: 20px;
  padding: 2px 10px; font-size: 0.72rem; font-weight: 700;
}
.coaching-card-footer { margin-top: auto; padding-top: 8px; border-top: 1px solid var(--border); }
.coaching-card-footer .btn-view-member {
  width: 100%; padding: 9px; background: var(--surface2); border: 1px solid var(--border);
  border-radius: 8px; color: var(--text-muted); font-size: 0.88rem; font-weight: 600;
  cursor: pointer; font-family: inherit; transition: all 0.15s; text-align: center;
  text-decoration: none; display: block;
}
.coaching-card-footer .btn-view-member:hover { border-color: var(--accent); color: var(--accent); background: rgba(76,81,153,0.06); }

/* Summary strip */
.coaching-summary-strip {
  display: flex; gap: 20px; flex-wrap: wrap; align-items: center;
  padding: 12px 16px; background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); margin-bottom: 16px; font-size: 0.88rem; color: var(--text-muted);
}
.coaching-summary-strip span { font-weight: 600; color: var(--text); }

/* Sort/filter bar */
.coaching-filter-bar { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin-bottom: 16px; }
.coaching-sort-select {
  padding: 7px 12px; background: var(--surface2); border: 1px solid var(--border);
  border-radius: 8px; color: var(--text); font-size: 0.85rem; font-family: inherit; cursor: pointer;
}
.coaching-sort-select:focus { outline: none; border-color: var(--accent); }
.coaching-filter-pill {
  padding: 5px 14px; border-radius: 20px; font-size: 0.8rem; font-weight: 600;
  cursor: pointer; background: var(--surface2); border: 1px solid var(--border);
  color: var(--text-muted); transition: all 0.15s; font-family: inherit;
}
.coaching-filter-pill.active { background: var(--accent); border-color: var(--accent); color: #fff; }

/* ───────────────────────────────────────────────────────────────────────────
   Coach badge — uat-round-implementation-spec §1.2
   Replaces the prior pill-style "Coach Scheduled" / "🎯 COACH" / "Coach
   recommends:" labels with a compact circle + optional adjacent value pill.
   Used wherever something on a member surface is attributed to their coach.
   ─────────────────────────────────────────────────────────────────────────── */
.coach-badge {
  display: inline-flex; align-items: center; gap: 6px;
  vertical-align: middle;
  white-space: nowrap;
}
.coach-badge__circle {
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px;
  border-radius: 50%;
  background: var(--accent);
  color: #fff;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 0.62rem; font-weight: 700;
  line-height: 1;
  flex-shrink: 0;
  cursor: help;
}
.coach-badge__value {
  display: inline-block;
  background: rgba(76,81,153,0.12);
  color: var(--accent);
  font-size: 0.72rem; font-weight: 700;
  padding: 2px 8px;
  border-radius: 999px;
  line-height: 1.4;
}
.coach-badge--label .coach-badge__value {
  background: transparent;
  padding: 0;
  color: var(--accent);
}
:root.light .coach-badge__circle { background: var(--accent); color: #fff; }
:root.light .coach-badge__value  { background: rgba(76,81,153,0.10); color: var(--accent); }

/* ───────────────────────────────────────────────────────────────────────────
   Sub-page nav pattern — subnav-pattern-v2-spec (replaces UAT Round 1 §1.4)
   Three distinct visual vocabularies:
     · Tier 2 parent tabs   — flat .tab-strip / .tab-btn (filled-block active,
                              defined elsewhere in this file). Unchanged.
     · Tier 3 sub-tabs      — underlined .subnav-row / .subnav-tab with a
                              sliding 2px brand-purple bar (the "active bar"
                              is a single positioned element measured at
                              runtime by window.renderSubNav). Replaces the
                              Round-1 .pill-row + .pill-btn sub-nav style.
     · Tier 4 filter rows   — .segmented-control (existing, kept).
   The Round-1 .subpage-heading H2 is retired — the active sub-tab itself
   serves as the position indicator, so no separate heading is needed.
   ─────────────────────────────────────────────────────────────────────────── */
/* SPEC_Mobile_Header_And_Tab_Polish §4 — sub-tab row scrolls
   horizontally on narrow widths instead of wrapping. The previous
   flex-wrap pushed late tabs (e.g. "Plan" on My Account) onto a
   second line on phones; the new pattern keeps the row to a single
   line and lets touch-swipe / wheel scroll reveal tabs that overflow.
   Right-edge fade hints at off-screen content. */
.subnav-row {
  display: flex;
  flex-wrap: nowrap;
  gap: 24px;
  border-bottom: 0.5px solid var(--border);
  position: relative;
  margin-bottom: 16px;
  /* Horizontal scroll without a visible scrollbar. -webkit-overflow-
     scrolling preserves momentum on iOS. */
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;
  -ms-overflow-style: none;
  -webkit-overflow-scrolling: touch;
  /* Right-edge fade so users can tell more tabs are off-screen. The
     mask shortens the visible row by ~24px on the right; the .subnav-
     row.is-end class is added by renderSubNav when scrolled to the
     end (or when no overflow), at which point we drop the mask. */
  mask-image: linear-gradient(to right, black 0, black calc(100% - 24px), transparent 100%);
  -webkit-mask-image: linear-gradient(to right, black 0, black calc(100% - 24px), transparent 100%);
}
.subnav-row::-webkit-scrollbar { display: none; width: 0; height: 0; }
/* When the row isn't actually scrollable (or is fully scrolled to
   the end) renderSubNav adds .is-end so we drop the right fade. */
.subnav-row.is-end {
  mask-image: none;
  -webkit-mask-image: none;
}
.subnav-tab {
  background: none;
  border: none;
  padding: 10px 2px;
  font-family: inherit;
  font-size: 13px;
  font-weight: 400;
  color: var(--text-muted);
  cursor: pointer;
  position: relative;
  text-decoration: none;
  white-space: nowrap;
  /* Per §4 — keep each tab at its natural width when the row scrolls,
     otherwise flexbox would equally distribute / shrink them inside
     the overflow-x container. */
  flex-shrink: 0;
  transition: color 0.15s;
}
.subnav-tab:hover:not(.is-active) { color: var(--text); }
.subnav-tab.is-active {
  color: var(--accent);
  font-weight: 500;
}
/* Sliding underline bar — single absolutely-positioned element managed by
 * renderSubNav. Sits flush with the row's bottom border (overlaps the gray
 * baseline by 0.5px so the join reads cleanly). Width + transform animate
 * over 200 ms ease-out per spec §3.2. */
.subnav-active-bar {
  position: absolute;
  bottom: -0.5px;
  left: 0;
  height: 2px;
  background: var(--accent);
  transition: transform 200ms ease-out, width 200ms ease-out;
  pointer-events: none;
  border-radius: 1px;
}

.segmented-control {
  display: inline-flex;
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
  background: var(--surface);
}
.segmented-control button,
.segmented-control .segmented-control__btn {
  background: transparent;
  border: none;
  border-right: 1px solid var(--border);
  padding: 7px 14px;
  font-family: inherit;
  font-size: 0.82rem; font-weight: 500;
  color: var(--text-muted);
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
  white-space: nowrap;
}
.segmented-control button:last-child,
.segmented-control .segmented-control__btn:last-child {
  border-right: none;
}
.segmented-control button:hover:not(.active),
.segmented-control .segmented-control__btn:hover:not(.active) {
  background: rgba(76,81,153,0.04);
  color: var(--text);
}
.segmented-control button.active,
.segmented-control .segmented-control__btn.active {
  background: rgba(76,81,153,0.10);
  color: var(--accent);
  font-weight: 600;
}

/* Coach recommendation panel on protocol.html */
.coach-rec-panel {
  margin-top: 14px; padding: 14px; background: rgba(76,81,153,0.05);
  border: 1px solid rgba(76,81,153,0.2); border-radius: 10px;
}
.coach-rec-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-bottom: 10px; }
@media (max-width: 480px) { .coach-rec-cols { grid-template-columns: 1fr; } }
.coach-rec-label {
  font-size: 0.68rem; font-weight: 800; text-transform: uppercase; letter-spacing: 0.8px;
  color: var(--text-dim); margin-bottom: 6px;
}
.coach-rec-unconfigured {
  border: 1.5px dashed var(--border); border-radius: 8px; padding: 12px;
  color: var(--text-dim); font-size: 0.82rem; text-align: center; cursor: default;
}
.coach-note {
  font-size: 0.82rem; color: var(--text-muted); font-style: italic;
  background: var(--surface2); border-radius: 6px; padding: 8px 10px;
  margin-bottom: 10px;
}
.coach-rec-actions { display: flex; gap: 8px; }
.btn-use-coach-rec {
  padding: 7px 14px; background: rgba(76,81,153,0.1); border: 1px solid rgba(76,81,153,0.3);
  border-radius: 8px; color: var(--accent); font-size: 0.82rem; font-weight: 700;
  cursor: pointer; font-family: inherit; transition: all 0.15s;
}
.btn-use-coach-rec:hover { background: var(--accent); color: #fff; }

/* Metric cards row on coaching-member.html */
.coaching-metric-cards { display: grid; grid-template-columns: repeat(6, 1fr); gap: 10px; margin-bottom: 20px; }
@media (max-width: 1024px) { .coaching-metric-cards { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 640px) { .coaching-metric-cards { grid-template-columns: repeat(2, 1fr); } }
.coaching-metric-card {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
  padding: 14px 12px; text-align: center;
}
.coaching-metric-card .metric-value { font-size: 1.3rem; font-weight: 800; color: var(--text); }
.coaching-metric-card .metric-label { font-size: 0.72rem; color: var(--text-muted); margin-top: 3px; text-transform: uppercase; letter-spacing: 0.5px; }

/* Compliance heatmap */
.compliance-heatmap { display: flex; gap: 5px; margin-bottom: 20px; }
.compliance-dot {
  width: 28px; height: 28px; border-radius: 6px; border: 1px solid var(--border);
  display: flex; align-items: center; justify-content: center; font-size: 0.65rem;
  color: var(--text-dim); font-weight: 600;
}
.compliance-dot.filled { background: var(--accent); border-color: var(--accent); color: #fff; }

/* Compound card on coaching-member.html */
.compound-card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); margin-bottom: 12px; overflow: hidden;
}
.compound-card-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 16px; border-bottom: 1px solid var(--border);
  gap: 10px; flex-wrap: wrap;
}
.compound-card-title { font-size: 0.95rem; font-weight: 700; color: var(--text); }
.compound-card-badges { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
.compound-cat-badge {
  padding: 2px 8px; border-radius: 10px; font-size: 0.72rem; font-weight: 700;
  background: var(--surface2); color: var(--text-muted); border: 1px solid var(--border);
}
.compound-card-body { padding: 14px 16px; }
.compound-proto-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-bottom: 12px; }
@media (max-width: 600px) { .compound-proto-cols { grid-template-columns: 1fr; } }
.compound-proto-col-label {
  font-size: 0.68rem; font-weight: 800; text-transform: uppercase; letter-spacing: 0.8px;
  color: var(--text-dim); margin-bottom: 6px;
}
.compound-proto-value { font-size: 0.85rem; color: var(--text-muted); }
.compound-override-warning {
  background: rgba(245,158,11,0.08); border: 1px solid rgba(245,158,11,0.25);
  border-radius: 7px; padding: 8px 12px; font-size: 0.82rem; color: #f59e0b;
  margin-bottom: 10px;
}
.compound-card-footer {
  display: flex; gap: 8px; padding: 12px 16px;
  border-top: 1px solid var(--border); flex-wrap: wrap;
}

/* Edit coach rec side panel */
.coaching-edit-panel {
  position: fixed; top: 0; right: 0; width: 480px; max-width: 100vw;
  height: 100vh; background: var(--bg); border-left: 1px solid var(--border);
  box-shadow: -4px 0 24px rgba(0,0,0,0.18); z-index: 1100;
  transform: translateX(100%); transition: transform 0.25s ease;
  overflow-y: auto; display: flex; flex-direction: column;
}
.coaching-edit-panel.open { transform: translateX(0); }
.coaching-edit-panel-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 18px 20px; border-bottom: 1px solid var(--border); flex-shrink: 0;
}
.coaching-edit-panel-header h3 { font-size: 1rem; font-weight: 700; margin: 0; }
.coaching-edit-panel-body { padding: 20px; flex: 1; }
.coaching-edit-panel-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-bottom: 16px; }
@media (max-width: 540px) { .coaching-edit-panel-cols { grid-template-columns: 1fr; } }
.coaching-edit-col-label {
  font-size: 0.68rem; font-weight: 800; text-transform: uppercase; letter-spacing: 0.8px;
  color: var(--text-dim); margin-bottom: 8px;
}
.coaching-edit-readonly { font-size: 0.85rem; color: var(--text-muted); }
.coaching-edit-field { margin-bottom: 12px; }
.coaching-edit-field label { display: block; font-size: 0.78rem; font-weight: 600; color: var(--text-muted); margin-bottom: 5px; }
.coaching-edit-field input, .coaching-edit-field select, .coaching-edit-field textarea {
  width: 100%; padding: 8px 10px; background: var(--surface2); border: 1px solid var(--border);
  border-radius: 8px; color: var(--text); font-size: 0.88rem; font-family: inherit;
}
.coaching-edit-field input:focus, .coaching-edit-field select:focus, .coaching-edit-field textarea:focus {
  outline: none; border-color: var(--accent);
}
.coaching-edit-panel-footer {
  padding: 16px 20px; border-top: 1px solid var(--border);
  display: flex; gap: 8px; flex-wrap: wrap; flex-shrink: 0;
}
.coaching-panel-backdrop {
  position: fixed; inset: 0; background: rgba(0,0,0,0.4); z-index: 1099;
  display: none;
}
.coaching-panel-backdrop.open { display: block; }

/* ── Reference Library Expansion styles ──────────────────────────────────── */

/* Resource cards */
.resource-type-section { margin-bottom: 16px; }
.resource-type-header { font-size: 0.68rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.8px; color: var(--accent); margin-bottom: 8px; }
.resource-card { background: var(--surface2); border: 1px solid var(--border); border-radius: 8px; padding: 10px 12px; margin-bottom: 6px; }
.resource-card:last-child { margin-bottom: 0; }
.resource-card-title { font-size: 0.85rem; font-weight: 600; color: var(--accent); text-decoration: none; display: block; margin-bottom: 3px; }
.resource-card-title:hover { text-decoration: underline; }
.resource-card-source { font-size: 0.72rem; color: var(--text-dim); margin-bottom: 2px; }
.resource-card-notes { font-size: 0.78rem; color: var(--text-muted); line-height: 1.5; margin-top: 4px; }
.resource-admin-row { display: flex; gap: 8px; margin-top: 6px; }

/* Severity badges */
.contra-severity { display: inline-block; font-size: 0.65rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; padding: 2px 7px; border-radius: 10px; margin-right: 6px; flex-shrink: 0; }
.severity-avoid   { background: rgba(239,68,68,0.12);  color: #ef4444;  border: 1px solid rgba(239,68,68,0.3); }
.severity-caution { background: rgba(245,158,11,0.12); color: #f59e0b;  border: 1px solid rgba(245,158,11,0.3); }
.severity-monitor { background: rgba(59,130,246,0.12); color: #3b82f6;  border: 1px solid rgba(59,130,246,0.3); }

/* Contraindication items */
.contra-item { display: flex; align-items: flex-start; gap: 6px; padding: 6px 0; border-bottom: 1px solid var(--border); }
.contra-item:last-child { border-bottom: none; }
.contra-text { font-size: 0.84rem; color: var(--text); flex: 1; }
.contra-note { font-size: 0.74rem; color: var(--text-dim); margin-top: 2px; font-style: italic; }

/* Common stack items */
.stack-item { padding: 8px 10px; background: var(--surface2); border: 1px solid var(--border); border-radius: 7px; }
.stack-item-label { font-size: 0.74rem; color: var(--text-muted); }
.stack-item-notes { font-size: 0.72rem; color: var(--text-dim); }
.stack-popularity { font-size: 0.7rem; color: var(--text-dim); }

/* Compare tool */
.compare-table { display: flex; flex-direction: column; gap: 0; border: 1px solid var(--border); border-radius: 10px; overflow: hidden; background: var(--surface); }
.compare-header-row { display: flex; background: var(--surface2); border-bottom: 2px solid var(--border); }
.compare-row { display: flex; border-bottom: 1px solid var(--border); }
.compare-row:last-child { border-bottom: none; }
.compare-row-label { width: 140px; flex-shrink: 0; font-size: 0.7rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; color: var(--text-dim); padding: 10px 14px; display: flex; align-items: center; background: var(--surface2); border-right: 1px solid var(--border); }
.compare-column { flex: 1; padding: 10px 14px; font-size: 0.85rem; color: var(--text-muted); border-right: 1px solid var(--border); min-width: 0; }
.compare-column:last-child { border-right: none; }
.compare-col-name { font-size: 0.9rem; font-weight: 700; color: var(--accent); }
.compare-cell { line-height: 1.5; }

/* Research feed */
.research-feed-item { background: var(--surface); border: 1px solid var(--border); border-radius: 8px; padding: 14px 16px; margin-bottom: 10px; }
.research-feed-source { font-size: 0.7rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; color: var(--text-dim); margin-top: 4px; }
.research-feed-compound { font-size: 0.72rem; color: var(--accent); margin-top: 3px; }
.research-feed-date { font-size: 0.7rem; color: var(--text-dim); }

/* Integration cards (account.html) */
.integration-section-title { font-size: 0.72rem; font-weight: 700; text-transform: uppercase; letter-spacing: 1px; color: var(--text-dim); margin-bottom: 12px; margin-top: 8px; }
.integration-card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 16px 18px; margin-bottom: 12px; }
.integration-card.warning { border-color: rgba(245,158,11,0.5); }
.integration-card-header { display: flex; align-items: center; gap: 14px; }
.integration-logo { width: 36px; height: 36px; border-radius: 8px; background: var(--surface2); border: 1px solid var(--border); display: flex; align-items: center; justify-content: center; font-size: 1.2rem; flex-shrink: 0; overflow: hidden; }
.integration-logo img { width: 100%; height: 100%; object-fit: contain; }
.integration-info { flex: 1; min-width: 0; }
.integration-name { font-size: 0.92rem; font-weight: 700; color: var(--text); }
.integration-desc { font-size: 0.78rem; color: var(--text-dim); margin-top: 2px; }
.integration-status { display: flex; align-items: center; gap: 6px; font-size: 0.78rem; font-weight: 600; flex-shrink: 0; }
.status-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
.status-dot.green  { background: var(--green); }
.status-dot.amber  { background: #f59e0b; }
.status-dot.gray   { background: var(--text-dim); }
.integration-meta { font-size: 0.76rem; color: var(--text-dim); margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--border); }
.integration-actions { display: flex; gap: 8px; margin-top: 12px; flex-wrap: wrap; }
/* Reusable integration button — works inside .integration-actions, inside the
   settings panel's .isp-actions row, or standalone. Was previously nested
   under .integration-actions which meant buttons in the settings panel fell
   back to unstyled browser defaults. */
.btn-integ { padding: 8px 16px; border-radius: 8px; font-size: 0.82rem; font-weight: 600; cursor: pointer; border: 1px solid var(--border); background: var(--surface2); color: var(--text-muted); font-family: inherit; transition: all 0.15s; line-height: 1.2; display: inline-flex; align-items: center; gap: 6px; }
.btn-integ:hover { border-color: var(--accent); color: var(--accent); }
.btn-integ.primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.btn-integ.primary:hover { opacity: 0.88; }
.btn-integ.danger { border-color: rgba(239,68,68,0.4); color: var(--red); }
.btn-integ.danger:hover { background: rgba(239,68,68,0.08); }
.btn-integ.ghost { background: transparent; border-color: var(--border); color: var(--text-muted); }
.btn-integ.ghost:hover { border-color: var(--accent); color: var(--text); }
.btn-integ:disabled { opacity: 0.5; cursor: default; pointer-events: none; }
/* In the integration-actions row on the card header, keep the tighter padding
   so the Sync Now / Settings / Disconnect trio stays compact. */
.integration-actions .btn-integ { padding: 6px 14px; border-radius: 7px; font-size: 0.8rem; }

.integration-settings-panel { margin-top: 14px; padding: 16px; background: var(--surface2); border-radius: 10px; border: 1px solid var(--border); }
.integration-settings-panel .isp-title { font-size: 0.84rem; font-weight: 700; color: var(--text); margin-bottom: 3px; }
.integration-settings-panel .isp-subtitle { font-size: 0.76rem; color: var(--text-muted); margin-bottom: 14px; line-height: 1.5; }
.isp-metric-list { display: flex; flex-direction: column; gap: 8px; margin-bottom: 14px; }
.isp-metric-row { display: flex; align-items: center; gap: 10px; font-size: 0.84rem; color: var(--text); }
.isp-metric-row input[type=checkbox] { width: 16px; height: 16px; accent-color: var(--accent); cursor: pointer; }
.isp-metric-row.disabled { opacity: 0.4; pointer-events: none; }
.isp-label { font-size: 0.78rem; font-weight: 600; color: var(--text-muted); margin-bottom: 6px; margin-top: 10px; }

/* Bottom action row inside the settings panel: primary + secondary on the
   left, status text in the middle, Cancel anchored to the right. */
.isp-actions { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--border); display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.isp-actions .isp-status { font-size: 0.78rem; color: var(--text-muted); margin-left: 4px; }
.isp-actions .isp-spacer { flex: 1; }
@media (max-width: 500px) {
  .isp-actions { flex-direction: column; align-items: stretch; }
  .isp-actions .isp-spacer { display: none; }
  .isp-actions .btn-integ { width: 100%; justify-content: center; }
  .isp-actions .isp-status { text-align: center; margin: 4px 0; }
}

/* Inline retry link used in the integration meta row when push isn't active. */
.isp-retry-link { background: none; border: none; color: var(--accent); font-family: inherit; font-size: 0.74rem; font-weight: 600; cursor: pointer; padding: 0; margin-left: 6px; text-decoration: underline; text-underline-offset: 2px; }
.isp-retry-link:hover { color: var(--accent-light, #6b74cc); }
.isp-retry-link:disabled { opacity: 0.5; cursor: default; }
.coming-soon-badge { font-size: 0.7rem; font-weight: 700; padding: 2px 8px; border-radius: 10px; background: var(--surface2); color: var(--text-dim); border: 1px solid var(--border); white-space: nowrap; }
.connect-btn { padding: 8px 20px; border-radius: 8px; font-size: 0.84rem; font-weight: 700; cursor: pointer; border: 1px solid var(--accent); background: rgba(76,81,153,0.1); color: var(--accent); font-family: inherit; transition: all 0.15s; white-space: nowrap; }
.connect-btn:hover { background: var(--accent); color: #fff; }

/* Source badge on metric timeline */
.source-badge { display: inline-flex; align-items: center; font-size: 0.68rem; font-weight: 700; padding: 2px 7px; border-radius: 8px; letter-spacing: 0.3px; white-space: nowrap; }
.source-badge.withings { background: rgba(0,181,181,0.12); color: #00b5b5; border: 1px solid rgba(0,181,181,0.3); }
.source-badge.oura    { background: rgba(79,70,229,0.1); color: #818cf8; border: 1px solid rgba(79,70,229,0.3); }

/* Sync status bar on progress page */
.sync-status-bar { display: flex; align-items: center; gap: 10px; padding: 8px 14px; background: var(--surface); border: 1px solid var(--border); border-radius: 8px; margin-bottom: 16px; font-size: 0.78rem; }
.sync-status-bar.warning { border-color: rgba(245,158,11,0.4); background: rgba(245,158,11,0.05); }
.sync-status-bar .sync-icon { font-size: 1rem; }
.sync-status-bar .sync-text { flex: 1; color: var(--text-muted); }
.sync-status-bar .sync-now-btn { padding: 4px 12px; border-radius: 6px; font-size: 0.76rem; font-weight: 700; cursor: pointer; border: 1px solid rgba(76,81,153,0.4); background: rgba(76,81,153,0.08); color: var(--accent); font-family: inherit; transition: all 0.15s; }
.sync-status-bar .sync-now-btn:hover { background: rgba(76,81,153,0.18); }

/* Source filter in history tab */
.source-filter-strip { display: flex; gap: 4px; margin-bottom: 14px; }
.sf-btn { padding: 5px 13px; border-radius: 20px; font-size: 0.76rem; font-weight: 600; cursor: pointer; border: 1px solid var(--border); background: var(--surface); color: var(--text-muted); font-family: inherit; transition: all 0.15s; }
.sf-btn.active { border-color: var(--accent); background: rgba(76,81,153,0.1); color: var(--accent); }

/* Integration column in users.html */
.integ-icon { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; border-radius: 5px; font-size: 0.65rem; font-weight: 800; border: 1px solid; }
.integ-icon.withings-ok   { background: rgba(0,181,181,0.1); color: #00b5b5; border-color: rgba(0,181,181,0.3); }
.integ-icon.withings-warn { background: rgba(245,158,11,0.1); color: #f59e0b; border-color: rgba(245,158,11,0.35); }

/* Account tab strip */
.acct-tabs { display: flex; gap: 2px; border-bottom: 1px solid var(--border); margin-bottom: 24px; }
.acct-tab-btn { background: none; border: none; border-bottom: 2px solid transparent; padding: 8px 18px 10px; font-size: 0.88rem; font-weight: 600; color: var(--text-muted); cursor: pointer; font-family: inherit; transition: color 0.15s, border-color 0.15s; margin-bottom: -1px; position: relative; }
.acct-tab-btn:hover { color: var(--text); }
.acct-tab-btn.active { color: var(--accent); border-bottom-color: var(--accent); }
.acct-tab-badge { position: absolute; top: 6px; right: 4px; width: 7px; height: 7px; border-radius: 50%; background: var(--red); }
.acct-tab-content { display: none; }
.acct-tab-content.active { display: block; }

/* RSS queue admin styles */
.rss-queue-item { background: var(--surface); border: 1px solid var(--border); border-radius: 8px; padding: 14px 16px; margin-bottom: 8px; display: flex; align-items: flex-start; gap: 12px; }
.rss-queue-content { flex: 1; min-width: 0; }
.rss-queue-title { font-size: 0.88rem; font-weight: 600; color: var(--text); margin-bottom: 4px; }
.rss-queue-meta { font-size: 0.72rem; color: var(--text-dim); margin-bottom: 8px; }
.rss-queue-actions { display: flex; gap: 6px; flex-shrink: 0; flex-direction: column; }
.rss-approve-btn { background: rgba(16,185,129,0.1); border: 1px solid rgba(16,185,129,0.35); color: #10b981; border-radius: 6px; padding: 5px 12px; font-size: 0.78rem; font-weight: 600; cursor: pointer; font-family: inherit; transition: all 0.15s; white-space: nowrap; }
.rss-approve-btn:hover { background: #10b981; color: #fff; }
.rss-reject-btn { background: rgba(239,68,68,0.08); border: 1px solid rgba(239,68,68,0.25); color: var(--red); border-radius: 6px; padding: 5px 12px; font-size: 0.78rem; font-weight: 600; cursor: pointer; font-family: inherit; transition: all 0.15s; white-space: nowrap; }
.rss-reject-btn:hover { background: var(--red); color: #fff; }

/* ── Analytics Tab ───────────────────────────────────────────────────────────── */
.analytics-toolbar { display: flex; align-items: center; gap: 8px; margin-bottom: 18px; flex-wrap: wrap; }
.analytics-range-btns { display: flex; gap: 6px; }
.analytics-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.analytics-grid .achart-full { grid-column: 1 / -1; }
@media (max-width: 700px) { .analytics-grid { grid-template-columns: 1fr; } .analytics-grid .achart-full { grid-column: 1; } }
.achart-card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 16px; }
.achart-title { font-size: 0.72rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.8px; color: var(--text-dim); margin-bottom: 12px; }
.achart-canvas-wrap { position: relative; height: 220px; }
.achart-canvas-wrap canvas { width: 100% !important; height: 100% !important; }
.achart-empty { color: var(--text-dim); font-size: 0.85rem; padding: 24px 0; text-align: center; line-height: 1.6; }

/* ── Reports Tab ─────────────────────────────────────────────────────────────── */
.reports-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 16px; }
.generate-panel { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 20px; margin-bottom: 20px; }
.generate-panel-title { font-size: 0.95rem; font-weight: 700; margin-bottom: 14px; }
.include-checks { display: flex; flex-wrap: wrap; gap: 14px; font-size: 0.85rem; color: var(--text-muted); }
.include-checks label { display: flex; align-items: center; gap: 6px; cursor: pointer; }
.range-btn-group { display: flex; gap: 6px; flex-wrap: wrap; }
.report-card { display: flex; align-items: center; justify-content: space-between; gap: 12px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 14px 16px; margin-bottom: 8px; }
.report-card-info { min-width: 0; }
.report-card-title { font-size: 0.9rem; font-weight: 700; color: var(--text); margin-bottom: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.report-card-meta { font-size: 0.75rem; color: var(--text-dim); }
.report-card-actions { display: flex; gap: 6px; flex-shrink: 0; }
.report-empty { color: var(--text-dim); font-size: 0.85rem; padding: 40px 0; text-align: center; }

/* ── Report View (report-view.html) ──────────────────────────────────────────── */
.rv-page { max-width: 860px; margin: 0 auto; padding: 32px 20px; }
.rv-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 28px; padding-bottom: 18px; border-bottom: 1px solid var(--border); }
.rv-brand { font-size: 1.1rem; font-weight: 800; color: var(--accent); }
.rv-header-actions { display: flex; gap: 8px; }
.rv-title { font-size: 1.4rem; font-weight: 800; color: var(--text); margin-bottom: 4px; }
.rv-meta { font-size: 0.82rem; color: var(--text-dim); margin-bottom: 24px; }
.rv-section { margin-bottom: 28px; }
.rv-section-title { font-size: 0.72rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.8px; color: var(--text-dim); margin-bottom: 14px; }
.rv-stats-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 12px; margin-bottom: 20px; }
.rv-stat-card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 14px 16px; }
.rv-stat-label { font-size: 0.7rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.6px; color: var(--text-dim); margin-bottom: 4px; }
.rv-stat-value { font-size: 1.5rem; font-weight: 800; color: var(--text); }
.rv-stat-sub { font-size: 0.75rem; color: var(--text-muted); margin-top: 2px; }
.rv-canvas-wrap { position: relative; height: 260px; margin-bottom: 16px; }
.rv-canvas-wrap canvas { width: 100% !important; height: 100% !important; }
.rv-disclaimer { font-size: 0.75rem; color: var(--text-dim); border-top: 1px solid var(--border); padding-top: 16px; margin-top: 32px; }
.rv-shared-footer { text-align: center; padding: 24px; margin-top: 32px; border-top: 1px solid var(--border); font-size: 0.85rem; color: var(--text-muted); }

@media print {
  #rv-header-actions, .rv-header-actions, .no-print { display: none !important; }
  body { background: white !important; color: black !important; }
  .rv-page { padding: 0; }
  canvas { max-width: 100% !important; page-break-inside: avoid; }
  .rv-section { page-break-inside: avoid; }
  @page { margin: 0.8in; }
}

/* ── Body Composition Dashboard ─────────────────────────────────────────────── */
.bc-loading { padding: 40px; text-align: center; color: var(--text-muted); font-size: 0.88rem; }
.bc-empty { padding: 48px 20px; text-align: center; max-width: 400px; margin: 0 auto; }
.bc-empty-icon { font-size: 2.5rem; margin-bottom: 14px; }
.bc-empty-title { font-size: 1rem; font-weight: 700; margin-bottom: 8px; }
.bc-empty-sub { font-size: 0.84rem; color: var(--text-muted); line-height: 1.6; }

/* Date selector */
.bc-date-selector { display: flex; align-items: center; gap: 12px; padding: 16px 0 10px; }
.bc-date-center { flex: 1; text-align: center; }
.bc-date-select { background: var(--surface2); border: 1px solid var(--border); color: var(--text); border-radius: 8px; padding: 6px 12px; font-size: 0.88rem; font-family: inherit; cursor: pointer; }
.bc-date-sub { font-size: 0.72rem; color: var(--text-dim); margin-top: 3px; }
.bc-nav-btn { background: var(--surface2); border: 1px solid var(--border); color: var(--text-muted); border-radius: 7px; padding: 6px 14px; font-size: 0.8rem; cursor: pointer; font-family: inherit; transition: all 0.15s; white-space: nowrap; }
.bc-nav-btn:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); }
.bc-nav-btn:disabled { opacity: 0.35; cursor: default; }

/* Progress story strip */
.bc-story-strip { background: rgba(76,81,153,0.08); border: 1px solid rgba(76,81,153,0.2); border-radius: 10px; padding: 16px 18px; margin-bottom: 18px; }
.bc-story-title { font-size: 0.78rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; color: var(--accent); margin-bottom: 10px; }
.story-item { font-size: 0.85rem; padding: 4px 0; color: var(--text-muted); }
.story-item strong { color: var(--text); }
.story-item.story-good::before { content: '✓ '; color: var(--teal); }

/* Panel grid */
.bc-panels { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-bottom: 24px; }
@media (max-width: 640px) { .bc-panels { grid-template-columns: 1fr; } }
.bc-panel { background: var(--surface); border: 1px solid var(--border); border-radius: 12px; padding: 18px; }
.bc-panel-full { grid-column: 1 / -1; }
/* Side-by-side container: SMM panel + BCC chart — spans full grid width */
.bc-row-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; grid-column: 1 / -1; }
@media (max-width: 768px) { .bc-row-pair { grid-template-columns: 1fr; } }
.bc-panel-title { font-size: 0.68rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.1em; color: var(--text-dim); margin-bottom: 12px; }
.bc-2col { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; align-items: start; }
@media (max-width: 520px) { .bc-2col { grid-template-columns: 1fr; } }
.bc-stat-block { display: flex; flex-direction: column; gap: 4px; }
.bc-stat-label { font-size: 0.78rem; color: var(--text-muted); }
.bc-stat-value { font-size: 1.6rem; font-weight: 700; line-height: 1.1; }
.bc-stat-value.large { font-size: 2rem; }
.bc-stat-unit { font-size: 0.75rem; font-weight: 400; color: var(--text-muted); }
.bc-sub-row { font-size: 0.8rem; color: var(--text-muted); margin-top: 5px; }
.bc-pal { font-size: 0.82rem; color: var(--text-muted); margin-top: 10px; border-top: 1px solid var(--border); padding-top: 8px; }
.bc-trend { font-size: 0.78rem; }
.bc-trend.trend-up { color: var(--teal); }
.bc-trend.trend-down { color: var(--red); }

/* Range bar */
.bc-range-wrap { margin-top: 10px; }
.bc-zone-badge { display: inline-block; font-size: 0.65rem; font-weight: 700; padding: 2px 7px; border-radius: 10px; margin-bottom: 6px; letter-spacing: 0.04em; }
.bc-zone-ok   { background: rgba(16,185,129,0.12); color: #10b981; }
.bc-zone-warn { background: rgba(245,158,11,0.12); color: #f59e0b; }
.bc-zone-low  { background: rgba(96,165,250,0.12); color: #60a5fa; }
.bc-zone-high { background: rgba(239,68,68,0.12);  color: #ef4444; }
.bc-range-bar { position: relative; height: 6px; background: var(--surface2); border-radius: 3px; overflow: visible; margin: 6px 0 4px; }
.bc-range-fill { position: absolute; top: 0; bottom: 0; left: var(--nlo); width: calc(var(--nhi) - var(--nlo)); background: rgba(16,185,129,0.22); border-radius: 2px; }
.bc-range-dot { position: absolute; top: 50%; width: 10px; height: 10px; background: var(--accent); border-radius: 50%; transform: translate(-50%, -50%); box-shadow: 0 0 0 2px var(--surface); }
.bc-range-note { font-size: 0.7rem; color: var(--text-dim); }

/* Multi-zone bars — match seca PDF style: red/yellow/green segments + ticks
   at every cutoff with the value labeled below. Used for the main BC
   panels and (compact variant) for segmental cards. */
.bc-zonebar { position: relative; padding: 8px 0 22px; margin: 4px 0; }
.bc-zonebar-track { position: relative; height: 6px; border-radius: 3px; background: var(--surface2); overflow: hidden; }
.bc-zonebar-seg { position: absolute; top: 0; bottom: 0; }
.bc-zone-green  { background: #22c55e; }
.bc-zone-yellow { background: #eab308; }
.bc-zone-red    { background: #ef4444; }
.bc-zonebar-dot {
  position: absolute; top: 5px;
  width: 14px; height: 14px;
  background: var(--surface, #fff);
  border: 2.5px solid #1f2937;
  border-radius: 50%;
  transform: translateX(-50%);
  box-shadow: 0 1px 4px rgba(0,0,0,0.25);
  z-index: 2;
}
.bc-zonebar-ticks { position: absolute; left: 0; right: 0; top: 16px; height: 0; }
.bc-zonebar-tick { position: absolute; transform: translateX(-50%); }
.bc-zonebar-tick-line { width: 1px; height: 4px; background: var(--text-dim); margin: 0 auto; }
.bc-zonebar-tick-label { font-size: 0.62rem; color: var(--text-dim); margin-top: 1px; white-space: nowrap; line-height: 1; }
/* Compact variant for the smaller segmental cards */
.seg-zonebar { padding: 6px 0 18px; margin-top: 8px; }
.seg-zonebar .bc-zonebar-track { height: 4px; }
.seg-zonebar .bc-zonebar-dot { width: 11px; height: 11px; top: 3px; border-width: 2px; }
.seg-zonebar .bc-zonebar-ticks { top: 12px; }
.seg-zonebar .bc-zonebar-tick-label { font-size: 0.58rem; }

/* SMM-over-Age percentile chart panel — matches seca SingleView layout:
   value + percentile readout up top, then the SVG chart, then a footnote
   pointing at the data source. */
.smm-over-age-panel .smm-percentile-row {
  display: flex; align-items: baseline; gap: 24px; flex-wrap: wrap;
  margin-top: 4px;
}
.smm-value-block { display: flex; align-items: baseline; gap: 2px; }
.smm-percentile-block {
  display: flex; align-items: baseline; gap: 4px;
  padding-left: 24px;
  border-left: 1px solid var(--border);
}
.smm-pct-num { font-size: 1.4rem; font-weight: 700; color: var(--text); line-height: 1; }
.smm-pct-label { font-size: 0.85rem; color: var(--text-dim); font-weight: 500; }
.smm-chart-wrap { margin: 14px 0 6px; width: 100%; }
.smm-chart-svg { display: block; width: 100%; height: auto; max-height: 280px; }
.smm-chart-note { font-size: 0.65rem; color: var(--text-dim); line-height: 1.4; margin-top: 8px; font-style: italic; }
.smm-chart-note a { color: var(--accent); text-decoration: underline; }

/* Segment grid */
.bc-seg-grid { display: grid; grid-template-columns: 1fr auto 1fr; grid-template-rows: auto auto auto; gap: 12px 20px; align-items: start; }
.bc-seg-arm-left  { grid-column: 1; grid-row: 1; }
.bc-seg-torso     { grid-column: 2; grid-row: 1 / 3; text-align: center; }
.bc-seg-arm-right { grid-column: 3; grid-row: 1; }
.bc-seg-leg-left  { grid-column: 1; grid-row: 3; }
.bc-seg-spacer    { grid-column: 2; grid-row: 3; }
.bc-seg-leg-right { grid-column: 3; grid-row: 3; }
.bc-seg-name { font-size: 0.73rem; color: var(--text-dim); margin-bottom: 3px; font-weight: 600; }
.bc-seg-val { font-size: 0.9rem; font-weight: 600; }
.seg-ind { font-size: 0.75rem; margin-left: 4px; }
.seg-above { color: #10b981; }
.seg-below { color: #ef4444; }
.seg-ok    { color: #f59e0b; }
@media (max-width: 520px) { .bc-seg-grid { grid-template-columns: 1fr 1fr; } .bc-seg-torso { grid-column: 1 / 3; } }

/* Body Comp 2-column grid */
.body-comp-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; grid-column: 1 / -1; align-items: stretch; }
.body-comp-left, .body-comp-right { display: flex; flex-direction: column; gap: 12px; }
.body-comp-left .bc-panel, .body-comp-right .bc-panel { flex: 1; }
@media (max-width: 768px) { .body-comp-grid { grid-template-columns: 1fr; } }

/* Segmental Muscle Mass 5-card grid */
.smm-grid-row1 { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 10px; }
.smm-grid-row2 { display: flex; justify-content: center; margin-bottom: 10px; }
.smm-grid-row2 .seg-card { width: 50%; }
.smm-grid-row3 { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 10px; }
.smm-total { font-size: 12px; color: var(--text-muted); padding-top: 10px; border-top: 0.5px solid var(--border); }

/* Segment cards */
.seg-card { background: var(--surface2); border: 0.5px solid var(--border); border-radius: var(--radius); padding: 8px 10px; }
.seg-card-label { font-size: 10px; color: var(--text-muted); margin-bottom: 2px; }
.seg-card-value { font-size: 15px; font-weight: 500; color: var(--text); }
.seg-card-unit { font-size: 11px; font-weight: 400; color: var(--text-dim); }
.seg-status-badge { display: inline-block; font-size: 9px; font-weight: 500; padding: 1px 6px; border-radius: 8px; margin-top: 3px; }
.seg-status-badge.high   { background: var(--badge-supplement-bg); color: var(--teal); }
.seg-status-badge.normal { background: var(--surface2); color: var(--accent); }
.seg-status-badge.low    { background: rgba(220,38,38,0.1); color: var(--red); }
.seg-rangebar { height: 4px; background: var(--border); border-radius: 2px; margin-top: 6px; position: relative; overflow: visible; }
.seg-rangebar-fill { height: 100%; border-radius: 2px; background: var(--teal); }
.seg-rangebar-dot { position: absolute; width: 8px; height: 8px; background: var(--accent); border-radius: 50%; top: -2px; transform: translateX(-50%); }

/* Quadrant chart */
.bc-quad-wrap { display: flex; flex-direction: column; gap: 0; margin: 12px 0 8px; }
.bc-quad-inner { display: flex; align-items: stretch; gap: 8px; }
.bc-quad-yaxis { writing-mode: vertical-rl; transform: rotate(180deg); font-size: 0.68rem; color: var(--text-dim); align-self: center; white-space: nowrap; padding-bottom: 20px; }
.bc-quad-chart { position: relative; flex: 1; height: 260px; display: grid; grid-template-columns: 1fr 1fr; grid-template-rows: 1fr 1fr; border: 1px solid var(--border); border-radius: 8px; overflow: hidden; }
.bc-quad-q { border: 1px solid var(--border); position: relative; overflow: hidden; }
.bc-quad-q1 { border-radius: 8px 0 0 0; background: rgba(239,68,68,0.05); }
.bc-quad-q2 { border-radius: 0 8px 0 0; background: rgba(245,158,11,0.04); }
.bc-quad-q3 { border-radius: 0 0 0 8px; background: rgba(16,185,129,0.04); }
.bc-quad-q4 { border-radius: 0 0 8px 0; background: rgba(76,81,153,0.07); }
.bc-quad-label { font-size: 0.58rem; font-weight: 600; color: var(--text-dim); line-height: 1.4; text-transform: uppercase; letter-spacing: 0.3px; position: absolute; }
/* Label: inner corner (away from silhouette icon) */
.bc-quad-q1 .bc-quad-label { bottom: 7px; right: 6px; text-align: right; }
.bc-quad-q2 .bc-quad-label { bottom: 7px; left: 9px; }
.bc-quad-q3 .bc-quad-label { top: 7px; left: 9px; }
.bc-quad-q4 .bc-quad-label { top: 7px; left: 9px; }
/* Icon: outer corner of each quadrant */
.bc-quad-icon { width: 30px; height: 44px; color: var(--text-dim); opacity: 0.2; position: absolute; }
.bc-quad-q1 .bc-quad-icon { top: 6px; left: 6px; }
.bc-quad-q2 .bc-quad-icon { top: 6px; right: 6px; }
.bc-quad-q3 .bc-quad-icon { bottom: 6px; left: 6px; }
.bc-quad-q4 .bc-quad-icon { bottom: 6px; right: 6px; }
.bc-quad-diag { position: absolute; inset: 0; width: 100%; height: 100%; color: var(--border); pointer-events: none; z-index: 1; opacity: 0.6; }
.bc-quad-xaxis { font-size: 0.68rem; color: var(--text-dim); text-align: center; padding-top: 4px; padding-left: 28px; white-space: nowrap; }
.quad-dot { position: absolute; width: 10px; height: 10px; background: var(--text-dim); border-radius: 50%; transform: translate(-50%, -50%); opacity: 0.45; cursor: default; z-index: 2; }
.quad-dot-latest { background: var(--accent); width: 14px; height: 14px; opacity: 1; box-shadow: 0 0 0 3px rgba(76,81,153,0.25); z-index: 3; }
.bc-quad-legend { font-size: 0.7rem; color: var(--text-dim); display: flex; gap: 10px; flex-wrap: wrap; margin-top: 6px; }
.bc-ql-dot { display: inline-block; width: 8px; height: 8px; background: var(--text-dim); border-radius: 50%; opacity: 0.5; vertical-align: middle; }
.bc-ql-latest { background: var(--accent); opacity: 1; }

/* TRU Body Score */
.bc-tru-row { display: flex; gap: 20px; align-items: flex-start; }
.bc-tru-badge { border-radius: 12px; padding: 18px 24px; text-align: center; min-width: 110px; }
.tru-gold { background: rgba(200,155,60,0.15); border: 2px solid rgba(200,155,60,0.4); }
.tru-verygood { background: rgba(76,81,153,0.12); border: 2px solid rgba(76,81,153,0.3); }
.tru-good { background: rgba(16,185,129,0.08); border: 2px solid rgba(16,185,129,0.2); }
.bc-tru-num { font-size: 2.2rem; font-weight: 800; line-height: 1; }
.bc-tru-pts { font-size: 0.62rem; text-transform: uppercase; letter-spacing: 0.1em; color: var(--text-muted); margin: 3px 0; }
.bc-tru-tier { font-size: 0.72rem; font-weight: 700; letter-spacing: 0.06em; color: var(--gold); }
.tru-verygood .bc-tru-tier { color: var(--accent); }
.tru-good .bc-tru-tier { color: var(--teal); }
.bc-tru-details { flex: 1; }
.bc-tru-history { display: flex; align-items: flex-end; gap: 8px; height: 60px; margin-top: 12px; }
.bc-tru-bar-wrap { display: flex; flex-direction: column; align-items: center; gap: 4px; flex: 1; height: 100%; }
.bc-tru-bar { width: 100%; max-width: 28px; background: var(--accent); border-radius: 3px 3px 0 0; opacity: 0.7; }
.bc-tru-bar-lbl { font-size: 0.65rem; color: var(--text-dim); }

/* Comparison table */
.bc-compare-wrap { margin-top: 8px; }
.bc-compare-title { font-size: 0.78rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-dim); margin-bottom: 10px; }
.bc-compare-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.bc-compare-table { width: 100%; border-collapse: collapse; font-size: 0.8rem; }
.bc-compare-table th { background: var(--surface2); color: var(--text-muted); font-weight: 600; font-size: 0.72rem; padding: 8px 12px; text-align: left; white-space: nowrap; border-bottom: 1px solid var(--border); }
.bc-compare-table td { padding: 7px 12px; border-bottom: 1px solid var(--border); color: var(--text-muted); white-space: nowrap; }
.bc-td-label { color: var(--text); font-weight: 500; }
.bc-td-null { color: var(--text-dim); }
.bc-td-good { color: #10b981; font-weight: 600; }
.bc-td-bad  { color: #ef4444; }
/* §7 Scan History delta indicator pattern — small arrow + delta under each
   comparison cell, direction-sensitive coloring per metric. */
.bc-td-delta { font-size: 0.72rem; font-weight: 700; margin-top: 2px; font-variant-numeric: tabular-nums; letter-spacing: 0.3px; }
.bc-td-delta-good    { color: #10b981; }
.bc-td-delta-bad     { color: #ef4444; }
.bc-td-delta-neutral { color: var(--text-dim); font-weight: 500; }

/* ── Bottom Sheet (XC-02) — reusable mobile overlay component ────────────────
   Usage: add .bs-overlay to backdrop, .bs-sheet to panel, .bs-handle to drag
   handle element at top of sheet. Toggle .open on .bs-overlay to show/hide.
   Desktop-only styles are in page CSS; this only provides the mobile pattern.
   ────────────────────────────────────────────────────────────────────────── */
@media (max-width: 768px) {
  .bs-overlay {
    position: fixed; inset: 0; z-index: 600;
    background: rgba(0,0,0,0.55);
    display: flex; align-items: flex-end;
    opacity: 0; pointer-events: none;
    transition: opacity 0.25s;
  }
  .bs-overlay.open { opacity: 1; pointer-events: auto; }
  .bs-sheet {
    width: 100%; max-height: 67vh;
    background: var(--surface); border-radius: 16px 16px 0 0;
    display: flex; flex-direction: column;
    transform: translateY(100%);
    transition: transform 0.3s cubic-bezier(0.32, 0.72, 0, 1);
    overflow: hidden;
  }
  .bs-overlay.open .bs-sheet { transform: translateY(0); }
  .bs-handle {
    width: 40px; height: 4px; border-radius: 2px;
    background: var(--border); margin: 10px auto 6px;
    flex-shrink: 0; cursor: grab;
  }
  .bs-scroll {
    flex: 1; overflow-y: auto; -webkit-overflow-scrolling: touch;
  }
}


/* ─────────────────────────────────────────────────────────────────
   SPEC_HELP_TUTORIAL_EXPANSION §5.2 — inline help icon primitive.
   Lives in shell.css so any page using shell.css gets it without
   having to wait for help-drawer.js style injection. The drawer
   itself is fully namespaced under .hd-* and self-injects its own
   styles when first opened.
   ───────────────────────────────────────────────────────────────── */
button.help-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: transparent;
  border: 1px solid currentColor;
  color: currentColor;
  opacity: 0.5;
  font-size: 10px;
  font-weight: 500;
  cursor: pointer;
  margin-left: 4px;
  vertical-align: middle;
  transition: opacity 120ms;
  padding: 0;
  line-height: 1;
  font-family: inherit;
  font-style: italic;
  letter-spacing: 0;
}
button.help-icon:hover { opacity: 1; }
button.help-icon:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
button.help-icon.help-icon-md { width: 18px; height: 18px; font-size: 12px; }

/* SPEC_button_feedback — global busy-state styling applied by
   window.withButtonBusy. The helper toggles .is-busy + disabled + an
   aria-busy attr; this rule gives a uniform visual cue across every
   page (lower opacity, wait-cursor, suppressed hover-bg) so the user
   always knows their click registered while the network call is in
   flight. Per-page button styles can still override colors etc. — this
   is intentionally subtle so it composes with primary / danger / ghost
   button variants. */
button.is-busy,
button.is-busy:hover,
button.is-busy:focus,
button[aria-busy="true"] {
  opacity: 0.7;
  cursor: wait !important;
  pointer-events: none; /* defense-in-depth — disabled is the primary guard */
  /* SPEC-UAT-R1 §12 — on mobile, a button that swaps to the busy
     label ("Saving…", "Generating…", etc.) was visibly clipped /
     "cut in half" because the helper replaces innerHTML and the
     button's intrinsic height then collapses around a single line
     of text without a baseline anchor. Enforcing inline-flex +
     center alignment + a minimum tap-height keeps the visual
     stable across every consumer (Log meal, Save changes, Generate
     analysis, etc.). nowrap prevents the busy label from wrapping
     into a second line that would re-trigger the clip. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-height: 36px;
  line-height: 1.2;
}

/* 2026-05-14 — shared compound type filter (ctf) chip strip.
   Used on every surface that filters a compound list:
   compounds-admin, compounds-coach, library, protocol's Compound
   page. Multi-select: each chip toggles independently. Empty
   selection = show all.

   Layout: full-width chips stacked vertically so they align with
   the sibling controls in narrow sidebars (Favorites Only button,
   Search input). Each chip's content (icon + label + count) is
   distributed: icon+label left-justified, count right-justified.
   This reads as a clean checklist instead of a busy chip cloud. */
.ctf-strip {
  display: flex; flex-direction: column; gap: 6px;
  padding: 6px 10px 4px;
}
/* Inline variant. The column layout above is built for a page sidebar; in a
   dialog header the strip has to run horizontally. Both the save-from-member
   modal and My Library's compound picker need it, so the override lives here
   once rather than being re-declared per surface. Every sidebar caller depends
   on the column, so this is a wrapper class and never the default. */
.ctf-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 0 0 11px; }
.ctf-row .ctf-strip { margin: 0; padding: 0; flex-direction: row; flex-wrap: wrap; }
.ctf-row .ctf-chip { width: auto; padding: 5px 11px; }
.ctf-row .ctf-chip .ctf-count { margin-left: 4px; }
.ctf-chip {
  display: flex; align-items: center; gap: 6px;
  width: 100%;
  padding: 6px 12px;
  background: var(--surface, #fff);
  border: 1px solid var(--border, #d1d5db);
  border-radius: 999px;
  font-size: 0.78rem; font-weight: 600;
  color: var(--text-muted, #6b7280);
  cursor: pointer;
  transition: all 0.15s ease;
  font-family: inherit;
  white-space: nowrap;
  text-align: left;
  box-sizing: border-box;
}
/* Count badge slides to the far right via auto margin — no extra
   wrapper element needed in renderChips. */
.ctf-chip .ctf-count { margin-left: auto; }
.ctf-chip:hover {
  border-color: var(--accent, #5b3fc7);
  color: var(--text, #111);
}
.ctf-chip-active {
  background: rgba(91, 63, 199, 0.10);
  border-color: var(--accent, #5b3fc7);
  color: var(--accent, #5b3fc7);
}
.ctf-chip-active:hover { background: rgba(91, 63, 199, 0.16); }
.ctf-count {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 22px; padding: 0 7px;
  background: rgba(127, 127, 127, 0.12);
  border-radius: 10px;
  font-size: 0.68rem;
}
.ctf-chip-active .ctf-count {
  background: rgba(91, 63, 199, 0.20);
  color: var(--accent, #5b3fc7);
}

/* ─── SPEC-PTR §6.1 — Pull-to-refresh indicator ────────────────────────
   Vanilla, no-deps gesture layer for the standalone PWA. The DOM
   (#oh-ptr + #oh-ptr-live) is injected by pull-to-refresh.js on init —
   do not add markup to per-page templates. Indicator starts hidden
   above the viewport (translateY(-46px)) and tucks under the mobile
   sticky header (z-index 110 → indicator at 109). All colors resolve
   to existing shell.css tokens; light + dark mode are inherited
   automatically. */
#oh-ptr {
  position: fixed; left: 0; right: 0; top: 0;
  display: flex; justify-content: center;
  transform: translateY(-46px); opacity: 0;
  z-index: 109;                              /* SPEC-PTR §6.1 / audit §5 */
  pointer-events: none;
  will-change: transform, opacity;
  /* SPEC-PTR §7 — respect safe-area inset so the indicator sits below
     the iOS notch on standalone-mode launches. */
  padding-top: env(safe-area-inset-top, 0);
}
#oh-ptr .oh-ptr-puck {
  width: 46px; height: 46px; border-radius: 50%; margin-top: 10px;
  background: var(--surface2);               /* "surface-raised" → --surface2 (audit §3) */
  border: 1px solid var(--border);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.45);
  display: flex; align-items: center; justify-content: center;
}
#oh-ptr .oh-ptr-ring { display: block; }
/* SPEC-PTR §6.1 — refreshing state spins the ring. The JS toggles the
   `is-refreshing` class while the refresh promise is in flight. */
#oh-ptr.is-refreshing .oh-ptr-ring {
  animation: oh-ptr-spin 0.8s linear infinite;
}
@keyframes oh-ptr-spin {
  to { transform: rotate(360deg); }
}
/* SPEC-PTR §8 — accessibility: reduced-motion swaps the spin for a
   static fill (the JS also stops the per-frame rotation update). */
@media (prefers-reduced-motion: reduce) {
  #oh-ptr.is-refreshing .oh-ptr-ring {
    animation: none;
  }
}
/* Visually-hidden polite-live region used by the script for screen
   reader announcements ("Refreshing", "Content updated"). Same pattern
   the rest of the app already uses (e.g. modal close announcements). */
#oh-ptr-live {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
}

/* SPEC-PTR §6.2 + audit §2 — `#app-content` is the inner scroll
   container. `overscroll-behavior-y: contain` prevents the iOS rubber-
   band bounce so our custom gesture has the only paint at the top
   edge. Doesn't affect nested scrollers (modals/drawers) which are
   their own overflow contexts. */
#app-content {
  overscroll-behavior-y: contain;
}

/* ── SPEC-USE §5 — Concept A duration control (shared schedule-editor.js) ──
   Used by the member protocol fly-out + the coach schedule modal. Tokens
   only; dark mode inherits. */
.se-duration { display: flex; flex-direction: column; gap: 14px; }
.se-field-label { font-size: 0.95rem; font-weight: 700; color: var(--text); }
.se-startwrap { display: flex; align-items: center; gap: 10px; background: var(--surface2); border: 1px solid var(--border); border-radius: 12px; padding: 10px 14px; color: var(--text-dim); }
/* RELATIVE mode (coach library) — a template window has no start DATE; its
   position is set by the durations of the windows above it. Everything else in
   this control is the member's control, unchanged. */
.se-relstart { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  background: var(--surface2); border: 1px solid var(--border); border-radius: 12px; padding: 10px 14px; }
.se-relweek { font-family: ui-monospace, 'JetBrains Mono', monospace; font-size: 0.95rem;
  color: var(--accent-light, var(--accent)); }
.se-relnote { font-size: 0.76rem; color: var(--text-dim); }
.se-start-input { flex: 1; border: none; background: none; color: var(--text); font-family: ui-monospace, Menlo, monospace; font-size: 1.05rem; padding: 0; }
.se-start-input:focus { outline: none; }
.se-modeswitch { display: grid; grid-template-columns: 1fr 1fr; gap: 4px; background: var(--surface2); border-radius: 12px; padding: 5px; }
.se-mode { display: flex; align-items: center; justify-content: center; gap: 8px; border: none; background: none; color: var(--text-muted); font-family: inherit; font-size: 0.95rem; font-weight: 700; padding: 11px 8px; border-radius: 9px; cursor: pointer; }
.se-mode .se-mode-ico { font-size: 1rem; line-height: 1; }
.se-mode.active { background: var(--surface); color: var(--accent); box-shadow: 0 1px 3px rgba(0,0,0,0.08); }
.se-length-body { display: flex; flex-direction: column; gap: 14px; }
/* Respect the hidden attribute (set in Continuous mode) — the display:flex
   above otherwise overrides the UA [hidden] rule, leaving the Weeks/Days
   stepper visible when there's no end date. */
.se-length-body[hidden] { display: none; }
.se-stepper { display: flex; align-items: center; gap: 12px; background: var(--surface2); border-radius: 12px; padding: 10px 14px; }
.se-step { width: 40px; height: 40px; border-radius: 10px; border: none; background: var(--surface); color: var(--accent); font-size: 1.3rem; font-weight: 700; cursor: pointer; box-shadow: 0 1px 3px rgba(0,0,0,0.08); }
.se-step-val { font-size: 1.2rem; font-weight: 800; color: var(--text); min-width: 28px; text-align: center; }
.se-unit-toggle { margin-left: auto; display: inline-flex; background: var(--surface); border-radius: 9px; padding: 3px; }
.se-unit { border: none; background: none; color: var(--text-muted); font-family: inherit; font-size: 0.85rem; font-weight: 700; padding: 6px 12px; border-radius: 7px; cursor: pointer; }
.se-unit.active { background: var(--surface2); color: var(--accent); }
.se-readout { display: flex; align-items: center; gap: 14px; background: color-mix(in srgb, var(--accent) 7%, var(--surface)); border: 1px solid color-mix(in srgb, var(--accent) 20%, transparent); border-radius: 12px; padding: 14px 16px; }
.se-readout-ico { display: inline-flex; align-items: center; justify-content: center; width: 34px; height: 34px; border-radius: 9px; background: var(--surface); color: var(--accent); flex-shrink: 0; }
.se-readout-text { font-size: 0.95rem; color: var(--text-muted); line-height: 1.45; }
.se-readout-text strong { color: var(--text); font-family: ui-monospace, Menlo, monospace; font-size: 1.02rem; }
.se-readout.continuous .se-readout-ico { color: var(--teal); }
/* Clickable calendar on the right of the readout — set the end date directly.
   The native date input overlays the icon (opacity 0) so a click anywhere on
   the tile opens the picker; choosing a date back-computes Weeks/Days above. */
.se-readout-cal { margin-left: auto; position: relative; display: inline-flex; align-items: center; justify-content: center; width: 34px; height: 34px; border-radius: 9px; background: var(--surface); color: var(--accent); cursor: pointer; flex-shrink: 0; transition: box-shadow .12s, filter .12s; }
.se-readout-cal:hover { filter: brightness(1.04); box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 35%, transparent); }
.se-readout-cal .se-end-picker { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; margin: 0; padding: 0; border: 0; background: none; cursor: pointer; }
.se-readout-cal .se-end-picker::-webkit-calendar-picker-indicator { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }

/* SPEC-USE §6 — shared time-of-day pills (member + coach). */
.se-todblock { display: flex; flex-direction: column; gap: 9px; }
.se-todsub { font-weight: 600; color: var(--text-dim); margin-left: 6px; font-size: 0.85em; }
.se-todpills, .se-fpills { display: grid; grid-template-columns: repeat(auto-fill, minmax(84px, 1fr)); gap: 6px; }
.se-freqblock { display: flex; flex-direction: column; gap: 9px; }
.se-todpill, .se-fpill { text-align: center; background: var(--surface2); border: 1px solid var(--border); color: var(--text-muted); border-radius: 8px; padding: 8px 6px; font-family: inherit; font-size: 0.82rem; font-weight: 600; cursor: pointer; transition: background .12s, border-color .12s, color .12s; }
.se-todpill:hover, .se-fpill:hover { color: var(--text); border-color: var(--accent); }
.se-todpill.active, .se-fpill.active { background: var(--accent); border-color: var(--accent); color: #fff; }

/* SPEC-USE §6 — shared dose-days picker (member + coach parity). */
.se-daysblock { display: flex; flex-direction: column; gap: 9px; }
.se-daypills { display: grid; grid-template-columns: repeat(7, 1fr); gap: 5px; }
.se-daypill { text-align: center; background: var(--surface2); border: 1px solid var(--border); color: var(--text-muted); border-radius: 8px; padding: 8px 2px; font-family: inherit; font-size: 0.78rem; font-weight: 600; cursor: pointer; transition: background .12s, border-color .12s, color .12s; }
.se-daypill:hover { color: var(--text); border-color: var(--accent); }
.se-daypill.active { background: var(--accent); border-color: var(--accent); color: #fff; }

/* ===== Shared compound-type segmented tab (.ctype-seg) =====================
   Single-select Peptides | Supplements | Hormones control, matching the
   Compound Library's .lib-seg design. Rendered by
   window.compoundTypeFilter.renderSeg() and reused on the member Compounds
   tab (protocol.html) + the Compound Manager Catalog / Pricing / Categories
   tabs (compounds-admin.html). No "All" — Peptides is the default. */
.ctype-seg { display: inline-flex; background: var(--surface2); border: 1px solid var(--border); border-radius: 11px; padding: 3px; flex-shrink: 0; }
.ctype-seg button { appearance: none; border: 0; background: transparent; color: var(--text-muted); font-family: inherit; font-weight: 600; font-size: 0.82rem; padding: 7px 13px; border-radius: 8px; cursor: pointer; display: inline-flex; align-items: center; gap: 7px; white-space: nowrap; transition: 0.14s; }
.ctype-seg button:hover { color: var(--text); }
.ctype-seg button .seg-count { font-size: 0.68rem; color: var(--text-dim); font-weight: 600; }
.ctype-seg button.active { background: var(--accent); color: #fff; }
.ctype-seg button.active:hover { color: #fff; }
.ctype-seg button.active .seg-count { color: rgba(255,255,255,0.82); }
.ctype-seg .seg-ico { display: inline-flex; align-items: center; }
.ctype-seg .seg-ico svg { display: block; }
.ctype-seg button svg { flex-shrink: 0; }
@media (max-width: 768px) {
  .ctype-seg { display: flex; width: 100%; }
  .ctype-seg button { flex: 1; justify-content: center; padding: 8px 6px; }
  .ctype-seg button .seg-count { font-size: 0.62rem; }
}

/* ===== Mobile pull-to-refresh guard (oh-modal-open) =======================
   While a fly-out / modal editor is open, dragging a scrolled-to-top form
   further down would otherwise trigger the browser's native pull-to-refresh,
   reloading the page and discarding the open editor + unsaved changes. nav.js
   toggles html.oh-modal-open whenever a fly-out is open; here we disable
   overscroll-driven refresh page-wide for that state only. Main pages (no
   fly-out) keep native pull-to-refresh. */
html.oh-modal-open,
html.oh-modal-open body { overscroll-behavior-y: none; }

/* ===== SPEC-UAT-01 §P1 — collapsible roster cards =========================
   Shared mechanism for the Members (mobile) + My Team (all breakpoints) cards.
   nav.js (window.rosterCollapse) toggles .rost-open on the card; the body is
   collapsed by default. .rost-body is a wrapper, so its children keep their
   own display (flex/grid) when revealed. */
[data-rost-card] .rost-body { display: none; }
[data-rost-card].rost-open .rost-body { display: block; }
[data-rost-toggle] { cursor: pointer; }
/* Chevron affordance on the toggle header (optional; pages opt in by adding
   a .rost-chevron element). Rotates when open. */
.rost-chevron { transition: transform 0.15s ease; flex-shrink: 0; color: var(--text-muted); }
[data-rost-card].rost-open .rost-chevron { transform: rotate(90deg); }

/* ── Shared informational disclaimer (SPEC-SRI §6.4 / CRL §7.1) ──────────────
   Rendered via window.ohDisclaimer() in nav.js. Used on every surface that
   presents medication/supplement reference data (unified create flow now;
   member supplement-detail surface later). Token-only; the amber tint reuses
   the compound-warn tokens so it reads as "informational, not an error". */
.oh-disclaimer {
  display: flex; gap: 9px; align-items: flex-start;
  padding: 10px 12px; border-radius: var(--radius);
  background: var(--cmpd-warn-bg); border: 1px solid var(--cmpd-warn);
  color: var(--text-muted); font-size: 0.72rem; line-height: 1.45;
}
.oh-disclaimer svg { flex: 0 0 auto; color: var(--gold); margin-top: 1px; }
.oh-disclaimer b { color: var(--text); font-weight: 600; }

/* ── SPEC-PRB §6/§7 — Protocol Reference explorer card (reference-explorer.js) ──
   The ONE read-only render of the reference{} envelope, shared by the admin
   "Preview as member" toggle, the member config surface, and the library browse
   surface. Global so all three consume identical styling. Token-only. */
.rx-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);overflow:hidden}
.rx-head{padding:15px 16px;border-bottom:1px solid var(--border)}
.rx-eyebrow{font-size:10.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--teal)}
.rx-name{margin:6px 0 6px;font-size:20px;font-weight:800;color:var(--text)}
.rx-tag{font-size:10.5px;padding:3px 9px;border-radius:999px;color:var(--gold);border:1px solid color-mix(in srgb,var(--gold) 40%,transparent);background:color-mix(in srgb,var(--gold) 12%,transparent)}
.rx-disc{padding:12px 16px 0}
.rx-body{padding:8px 16px 16px}
.rx-sec{font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--text-muted);margin:16px 0 8px}
.rx-solvent{background:var(--surface2);border:1px solid var(--border);border-radius:var(--radius);padding:12px}
.rx-solvent b{font-size:14px;color:var(--text)} .rx-solvent p{margin:4px 0 0;font-size:12px;color:var(--text-dim);line-height:1.5}
.rx-dose{font-size:20px;color:var(--text)} .rx-dose.rx-band-val{color:var(--gold)} .rx-unit{font-size:13px;color:var(--text-dim)}
.rx-band{position:relative;height:6px;border-radius:999px;background:var(--surface2);margin:10px 0 4px}
.rx-band .b{position:absolute;top:0;bottom:0;left:12%;right:12%;background:color-mix(in srgb,var(--gold) 20%,transparent);border-left:1px solid var(--gold);border-right:1px solid var(--gold)}
.rx-leg{display:flex;justify-content:space-between;font-size:10px;color:var(--text-muted)} .rx-leg .mid{color:var(--gold)}
.rx-methods{display:flex;gap:7px;flex-wrap:wrap}
.rx-method{font-size:11.5px;color:var(--text-dim);background:var(--surface2);border:1px solid var(--border);padding:5px 10px;border-radius:8px}
.rx-method.primary{color:var(--text);border-color:var(--accent)}
.rx-p{font-size:12.5px;color:var(--text-dim);line-height:1.55;margin:6px 0}
.rx-list{margin:6px 0;padding-left:18px;color:var(--text-dim);font-size:12.5px;line-height:1.6}
.rx-empty{font-size:12px;color:var(--text-muted);font-style:italic;padding:6px 0}
/* SPEC-PRB §6 — explorer CTA (member config surface) */
.rx-cta{margin-top:12px;width:100%;font-weight:600;font-size:0.85rem;border:0;border-radius:9px;padding:10px 16px;cursor:pointer;background:var(--accent);color:#fff}
.rx-save{margin-top:14px;background:var(--teal);color:#06251f}
.rx-cta-ghost{background:transparent;border:1px solid var(--border);color:var(--text-dim)}
/* SPEC-PRB-2 §3 — method tabs + interactive reconstitution calculator */
.rx-tabs{display:flex;gap:6px;flex-wrap:wrap;margin:14px 0 4px}
.rx-tab{font-size:12px;color:var(--text-dim);background:var(--surface2);border:1px solid var(--border);padding:7px 13px;border-radius:999px;cursor:pointer}
.rx-tab.active{color:var(--text);border-color:var(--accent);background:color-mix(in srgb,var(--accent) 14%,transparent)}
.rx-panel{display:none}
.rx-panel.active{display:block}
.rx-calc{background:var(--surface2);border:1px solid var(--border);border-radius:var(--radius);padding:13px 14px;margin-top:6px}
.rx-calc-solvent{font-size:12.5px;color:var(--text-dim);margin-bottom:10px}
.rx-calc-solvent b{color:var(--text)}
.rx-calc-row{display:flex;align-items:center;justify-content:space-between;gap:10px;margin:9px 0}
.rx-calc-row label{font-size:12px;color:var(--text-muted)}
.rx-calc-row input[type=number],.rx-calc-row input[type=text]{width:90px;background:var(--surface);border:1px solid var(--border);border-radius:7px;color:var(--text);padding:7px 9px;font-size:13px}
.rx-calc-row input[type=range]{vertical-align:middle}
.rx-calc-row select{background:var(--surface);border:1px solid var(--border);border-radius:7px;color:var(--text);padding:7px 9px;font-size:13px}
.rx-calc-out{display:flex;gap:12px;margin-top:12px;padding-top:11px;border-top:1px solid var(--border)}
.rx-calc-out>div{flex:1;text-align:center}
.rx-calc-k{display:block;font-size:9.5px;letter-spacing:.06em;text-transform:uppercase;color:var(--text-muted);margin-bottom:3px}
.rx-calc-out b{font-size:19px;color:var(--text);font-weight:700}
.rx-calc-tip{font-size:11.5px;color:var(--text-muted);margin-top:9px;line-height:1.5}
.rx-cleanest{background:none;border:0;border-bottom:1px dashed var(--accent);color:var(--accent);cursor:pointer;font:inherit;padding:0}
.rx-calc-locked{display:flex;gap:8px;align-items:flex-start;font-size:12px;color:var(--text-muted);background:var(--surface2);border:1px dashed var(--border);border-radius:var(--radius);padding:11px 12px}

/* ── SPEC-LOS §3 — member lab-ordering widget (labs.html) ─────────────────── */
.lo-wrap{border:1px solid var(--border);border-radius:var(--radius);background:var(--surface2);padding:16px 18px;margin-bottom:18px}
.lo-head{display:flex;align-items:center;gap:14px;flex-wrap:wrap;margin-bottom:14px}
.lo-h2{margin:0;font-size:16px;font-weight:800}
.lo-tabs{display:inline-flex;gap:2px;background:var(--surface);border:1px solid var(--border);border-radius:10px;padding:2px}
.lo-tab{background:none;border:0;color:var(--text-dim);font:inherit;font-size:13px;font-weight:600;padding:6px 12px;border-radius:8px;cursor:pointer}
.lo-tab.on{background:var(--accent);color:#fff}
.lo-loading,.lo-empty{color:var(--text-dim);font-size:13px;padding:18px 4px}
.lo-grid{display:grid;grid-template-columns:1fr 1fr;gap:12px}
@media(max-width:640px){.lo-grid{grid-template-columns:1fr}}
.lo-test{border:1px solid var(--border);border-radius:var(--radius);background:var(--surface);padding:15px 16px;display:flex;flex-direction:column}
.lo-ttype{align-self:flex-start;font-size:10px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;padding:2px 8px;border-radius:6px;border:1px solid var(--border);color:var(--text-dim);margin-bottom:8px}
.lo-ttype.home{color:var(--accent-light,var(--accent));border-color:var(--accent-light,var(--accent))}
.lo-ttype.draw{color:var(--gold);border-color:var(--gold)}
.lo-test-name{margin:0 0 6px;font-size:16px;font-weight:700}
.lo-test-desc{color:var(--text-dim);font-size:13px;margin:0 0 14px;flex:1}
.lo-test-foot{display:flex;align-items:center;justify-content:space-between;gap:10px}
.lo-price{font-size:18px;font-weight:700}
.lo-btn{font:inherit;font-size:13px;font-weight:600;border-radius:8px;padding:8px 14px;cursor:pointer;border:1px solid var(--border);background:var(--surface2);color:var(--text)}
.lo-btn.primary{background:var(--accent);border-color:var(--accent);color:#fff}
.lo-btn:disabled{opacity:.5;cursor:default}
.lo-wide{width:100%;justify-content:center;padding:12px}
.lo-back{color:var(--text-dim);font-size:13px;cursor:pointer;margin-bottom:12px}
.lo-back:hover{color:var(--text)}
.lo-confirm{max-width:560px}
/* 2026-10-01 — the test page is wider so its marker groups sit two-up on a desktop; the
   text column inside stays readable. */
.lo-detail{max-width:920px}
.lo-detail .lo-td-head .lo-test-desc{max-width:680px}
/* SPEC-LOS-2 (IA revision) — richer catalog cards + test detail view. */
.lo-test-meta{font-family:ui-monospace,monospace;font-size:11px;color:var(--text-dim);margin:2px 0 10px}
.lo-td-head{margin-bottom:14px}
.lo-td-head .lo-ttype{display:inline-block}
.lo-td-head .lo-test-name{margin:8px 0 6px;font-size:20px}
.lo-td-head .lo-test-desc{font-size:13.5px;color:var(--text-muted);margin:0 0 8px}
.lo-marker-grid{display:flex;flex-wrap:wrap;gap:6px}
.lo-marker{font-size:12px;color:var(--text);background:var(--surface2);border:1px solid var(--border);border-radius:20px;padding:4px 11px}
/* 2026-10-01 — "What's measured", grouped (services/lab-marker-groups.js). Tokens only. */
.lo-wm-head{display:flex;align-items:baseline;justify-content:space-between;gap:12px;margin-bottom:12px;flex-wrap:wrap}
.lo-wm-n{font-size:12.5px;color:var(--text-dim)}
.lo-wm-toc{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:12px}
.lo-wm-tocb{display:inline-flex;align-items:center;gap:6px;padding:5px 11px;border-radius:999px;border:1px solid var(--border);background:var(--surface2);color:var(--text);font:inherit;font-size:12.5px;font-weight:600;cursor:pointer}
.lo-wm-tocb .c{font-size:11px;color:var(--text-dim);font-variant-numeric:tabular-nums}
.lo-wm-tocb:hover{border-color:var(--accent)}
.lo-wm-tocb:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.lo-wm-search{margin-bottom:14px}
.lo-wm-groups{columns:2 300px;column-gap:14px}
.lo-wm-g{break-inside:avoid;margin:0 0 14px;padding:13px 14px;border:1px solid var(--border);border-radius:10px;background:var(--bg);scroll-margin-top:80px}
.lo-wm-gh{display:flex;align-items:baseline;justify-content:space-between;gap:10px}
.lo-wm-gh h5{margin:0;font-size:14px;font-weight:800;color:var(--text)}
.lo-wm-c{font-size:11.5px;font-weight:700;color:var(--accent);font-variant-numeric:tabular-nums}
.lo-wm-blurb{margin:4px 0 8px;font-size:12.5px;line-height:1.45;color:var(--text-dim)}
.lo-wm-list{list-style:none;margin:0;padding:0}
.lo-wm-list li{display:flex;flex-wrap:wrap;align-items:baseline;gap:2px 8px;padding:6px 0;border-top:1px solid var(--border);font-size:13.5px}
.lo-wm-list li:first-child{border-top:0}
.lo-wm-list .nm{font-weight:600;color:var(--text)}
.lo-wm-list .gl{font-size:12px;color:var(--text-dim)}
.lo-wm-none{padding:18px 4px;font-size:13.5px;color:var(--text-dim)}
.lo-covers{font-size:12.5px;color:var(--text);margin:-2px 0 8px;line-height:1.45}
.lo-covers-l{font-size:10.5px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;color:var(--text-dim);margin-right:2px}
.lo-covers-more{color:var(--text-dim)}
.lo-instr{font-size:13px;color:var(--text-dim)}
/* SPEC-LMR §P6 — Test Detail: markers grouped by category + consumer "best for" */
.lo-catrow{margin-bottom:16px}
.lo-catrow:last-child{margin-bottom:0}
.lo-cath{margin:0 0 8px;font-size:10.5px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;color:var(--accent)}
.lo-best{background:color-mix(in srgb,var(--gold) 12%,transparent);border-radius:var(--radius-sm,10px);padding:12px 15px;margin-bottom:14px;font-size:13px;color:var(--text)}
.lo-best b{color:var(--gold)}
.lo-td-foot{display:flex;align-items:center;justify-content:space-between;gap:16px;margin-top:16px;padding-top:16px;border-top:1px solid var(--border)}
.lo-price-lg{font-size:24px;font-weight:800}
.lo-empty-cta{display:flex;flex-direction:column;align-items:center;text-align:center;gap:6px;padding:48px 24px;max-width:420px;margin:0 auto}
.lo-empty-ic{color:var(--accent);opacity:.8;margin-bottom:4px}
.lo-empty-t{font-size:17px;font-weight:800}
.lo-empty-s{font-size:13px;color:var(--text-dim);margin-bottom:12px}
.lo-empty-filter{padding:36px 24px}
/* 2026-10-01 — the member's messages with the lab, inside an order. Tokens only. */
.lo-msgbox{margin:16px 0;padding:14px;border:1px solid var(--border);border-radius:10px;background:var(--surface)}
.lo-msgh{display:flex;align-items:center;gap:8px;font-size:13.5px;font-weight:700;color:var(--text);margin-bottom:10px}
.lo-msgh svg{color:var(--accent);flex:none}
.lo-msgs{list-style:none;margin:0 0 10px;padding:0;display:flex;flex-direction:column;gap:8px;max-height:300px;overflow-y:auto}
.lo-msg{max-width:88%;padding:9px 12px;border-radius:10px;border:1px solid var(--border);background:var(--bg)}
.lo-msg.me{align-self:flex-end;background:color-mix(in srgb,var(--accent) 10%,var(--surface));border-color:color-mix(in srgb,var(--accent) 30%,var(--border))}
.lo-msg .who{font-size:12px;font-weight:700;color:var(--text);margin-bottom:2px}
.lo-msg .who span{font-weight:500;color:var(--text-dim);margin-left:4px}
.lo-msg .txt{font-size:13.5px;color:var(--text);white-space:pre-wrap;overflow-wrap:anywhere}
.lo-msgin{width:100%;box-sizing:border-box;background:var(--bg);border:1px solid var(--border);border-radius:8px;color:var(--text);font:inherit;font-size:13.5px;padding:9px 11px;resize:vertical}
.lo-msgin:focus{outline:none;border-color:var(--accent)}
.lo-msgfoot{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-top:8px;font-size:12px;color:var(--text-dim)}
.lo-msgerr{font-size:12.5px;color:var(--red);margin-top:6px}
.lo-msgerr:empty{display:none}
.lo-replypill{font-size:10px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;padding:4px 10px;border-radius:20px;background:color-mix(in srgb,var(--accent) 18%,transparent);color:var(--accent-light,var(--accent));margin-right:6px}
.lo-empty-filter .lo-flink{font-weight:700}
/* 2026-09-30 — the member's Orders toolbar: filter chips, search, sort. Tokens only. */
.lo-otools{display:flex;flex-wrap:wrap;align-items:center;gap:10px;margin-bottom:14px}
.lo-ofilter{display:flex;gap:6px;flex-wrap:wrap}
.lo-ochip{display:inline-flex;align-items:center;gap:6px;padding:6px 12px;border-radius:999px;border:1px solid var(--border);background:var(--surface);color:var(--text-dim);font:inherit;font-size:13px;font-weight:600;cursor:pointer}
.lo-ochip .c{font-size:11px;font-variant-numeric:tabular-nums;color:var(--text-dim)}
.lo-ochip[aria-selected="true"]{background:var(--accent);border-color:var(--accent);color:#fff}
.lo-ochip[aria-selected="true"] .c{color:#fff;opacity:.85}
.lo-ochip:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.lo-osearch{flex:1 1 220px;min-width:0;display:flex;align-items:center;gap:8px;padding:0 12px;border:1px solid var(--border);border-radius:8px;background:var(--surface);color:var(--text-dim)}
.lo-osearch input{flex:1;min-width:0;border:0;background:transparent;color:var(--text);font:inherit;font-size:13.5px;padding:9px 0;outline:none}
.lo-osearch:focus-within{border-color:var(--accent)}
.lo-osort{display:flex;align-items:center;gap:6px;font-size:12.5px;color:var(--text-dim)}
.lo-osort select{background:var(--surface);color:var(--text);border:1px solid var(--border);border-radius:8px;font:inherit;font-size:13px;padding:7px 8px}
@media (max-width:560px){.lo-osearch{flex-basis:100%;order:2}.lo-osort{order:3}}
.lo-csum{display:flex;justify-content:space-between;align-items:flex-start;gap:16px;padding-bottom:14px;border-bottom:1px solid var(--border);margin-bottom:14px}
.lo-field{display:block;margin-bottom:14px}
.lo-field span{display:block;font-size:10px;letter-spacing:.12em;text-transform:uppercase;color:var(--text-dim);margin-bottom:6px}
.lo-field input{width:100%;background:var(--bg);border:1px solid var(--border);border-radius:8px;color:var(--text);font:inherit;font-size:13.5px;padding:10px 12px}
.lo-info{display:flex;gap:8px;background:var(--surface);border:1px solid var(--border);border-radius:8px;padding:11px 13px;font-size:13px;color:var(--text-dim);margin-bottom:14px}
.lo-ack{display:flex;gap:10px;align-items:flex-start;border:1px solid var(--border);border-radius:8px;padding:12px;margin-bottom:16px;cursor:pointer;font-size:13px;color:var(--text-dim)}
.lo-ack.on{border-color:var(--accent)}
/* SPEC-LAB-CC-1 §5.1/§5.2 — collection-method tiles + the self-collection capture.
   Tokens only; mirrors the approved design pass (roadmap-spec/mockups/SPEC-LAB-CC_design_pass.html). */
.lo-tiles{display:flex;flex-direction:column;gap:10px;margin-bottom:14px}
.lo-tile{display:flex;gap:12px;align-items:flex-start;padding:13px 14px;border:1px solid var(--border);border-radius:8px;background:var(--surface);cursor:pointer;text-align:left;width:100%;font:inherit;color:var(--text)}
.lo-tile:hover{border-color:var(--accent)}
.lo-tile:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.lo-tile.on{border-color:var(--accent);background:color-mix(in srgb,var(--accent) 10%,transparent)}
.lo-tile-r{flex:none;width:15px;height:15px;border-radius:50%;border:2px solid var(--text-dim);margin-top:2px;position:relative}
.lo-tile.on .lo-tile-r{border-color:var(--accent)}
.lo-tile.on .lo-tile-r::after{content:"";position:absolute;inset:3px;border-radius:50%;background:var(--accent)}
.lo-tile-b{flex:1;min-width:0}
.lo-tile-t{display:block;font-size:13.5px;font-weight:600;margin-bottom:2px}
.lo-tile-d{display:block;font-size:12.5px;color:var(--text-dim)}
.lo-tile-m{display:block;font-size:11px;color:var(--text-muted);margin-top:4px}
.lo-dt{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:10px}
.lo-dt input{width:100%;background:var(--bg);border:1px solid var(--border);border-radius:8px;color:var(--text);font:inherit;font-size:13.5px;padding:10px 12px}
.lo-seg{display:flex;gap:6px;margin-bottom:10px}
.lo-sg{flex:1;text-align:center;font-size:12px;font-weight:600;padding:9px 6px;border-radius:8px;border:1px solid var(--border);background:var(--surface);color:var(--text-dim);cursor:pointer;font-family:inherit}
.lo-sg:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.lo-sg.on{color:var(--accent);border-color:color-mix(in srgb,var(--accent) 45%,transparent);background:color-mix(in srgb,var(--accent) 12%,transparent)}
.lo-facts{display:grid;grid-template-columns:repeat(2,1fr);gap:11px 20px;margin-bottom:10px}
.lo-fact{display:flex;flex-direction:column;gap:2px}
.lo-fk{font-size:10px;letter-spacing:.12em;text-transform:uppercase;color:var(--text-dim)}
.lo-fv{font-size:13.5px;font-weight:600;color:var(--text)}
.lo-fmissing{font-weight:500;color:var(--text-muted)}
.lo-finput{width:100%;background:var(--bg);border:1px solid var(--border);border-radius:6px;color:var(--text);font:inherit;font-size:13.5px;padding:7px 9px}
.lo-finput:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
.lo-flink{background:none;border:none;padding:0;margin-left:8px;font:inherit;font-size:11.5px;font-weight:600;color:var(--accent);cursor:pointer}
.lo-flink:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:3px}
.lo-reqlink{margin:-4px 0 14px}
/* SPEC-LAB-CC-2 §6.1 / D7 — the member-visible custody chain. */
.lo-chain{position:relative;padding-left:24px}
.lo-chain::before{content:"";position:absolute;left:5px;top:6px;bottom:6px;width:2px;background:var(--border)}
.lo-cev{position:relative;padding-bottom:15px}
.lo-cev:last-child{padding-bottom:0}
.lo-cev::before{content:"";position:absolute;left:-23px;top:4px;width:9px;height:9px;border-radius:50%;background:var(--surface);border:2px solid var(--text-dim)}
.lo-cev.done::before{background:var(--teal);border-color:var(--teal)}
.lo-cev.inferred::before{background:var(--gold);border-color:var(--gold)}
.lo-cev.blocked::before{background:var(--red);border-color:var(--red)}
.lo-cev-t{font-size:13px;font-weight:600}
.lo-cev.pending .lo-cev-t{color:var(--text-dim);font-weight:500}
.lo-cev-m{font-size:11px;color:var(--text-dim);margin-top:1px}
.lo-cev-d{font-size:12px;color:var(--text-muted);margin-top:2px}
.lo-lockline{display:flex;align-items:center;gap:6px;flex-wrap:wrap;font-size:11.5px;color:var(--text-muted);margin-bottom:14px}
.lo-lockline svg{width:12px;height:12px;flex:none}
.lo-lockline a{color:var(--accent)}
@media(max-width:520px){.lo-facts{grid-template-columns:1fr}}
.lo-cb{flex:none;width:16px;height:16px;border-radius:4px;border:2px solid var(--text-dim);display:grid;place-items:center;margin-top:1px}
.lo-cb.on{background:var(--accent);border-color:var(--accent)}
.lo-cb svg{width:10px;height:10px;color:#fff;opacity:0}
.lo-cb.on svg{opacity:1}
.lo-warn{display:flex;gap:8px;border:1px solid color-mix(in srgb,var(--gold) 45%,transparent);background:color-mix(in srgb,var(--gold) 10%,transparent);color:var(--text);border-radius:8px;padding:10px 12px;font-size:12.5px;margin-bottom:12px}
@media(max-width:520px){.lo-dt{grid-template-columns:1fr}}
.lo-olist{display:flex;flex-direction:column;gap:10px}
.lo-orow{display:flex;align-items:center;gap:14px;border:1px solid var(--border);border-radius:var(--radius);background:var(--surface);padding:14px 16px;cursor:pointer}
.lo-orow:hover{border-color:var(--accent)}
.lo-oinfo{flex:1;min-width:0}
/* SPEC-LMR §P4 — Orders accordion (list + detail merged) */
.lo-oacc{display:flex;flex-direction:column;gap:12px}
.lo-order{border:1px solid var(--border);border-radius:var(--radius);background:var(--surface);overflow:hidden}
.lo-order.active{border-color:var(--accent)}
.lo-ohd{display:flex;align-items:center;gap:14px;padding:15px 16px;cursor:pointer}
.lo-okit{width:40px;height:40px;border-radius:10px;display:grid;place-items:center;flex:none}
.lo-okit.k{background:color-mix(in srgb,var(--accent) 14%,transparent);color:var(--accent)}
.lo-okit.d{background:color-mix(in srgb,var(--teal) 16%,transparent);color:var(--teal)}
.lo-oright{margin-left:auto;display:flex;align-items:center;gap:12px}
.lo-ochev{color:var(--text-muted);transition:transform .2s;flex:none}
.lo-order.open .lo-ochev{transform:rotate(180deg)}
/* SPEC-LAB-OPS-1 probe — on a phone the chips (payment + a longer status such as "Draw
   supplies shipped") squeezed the test name to one word per line and overlapped the
   order id. They wrap to their own row under the name instead. */
@media(max-width:520px){.lo-ohd{flex-wrap:wrap;row-gap:8px}.lo-oinfo{flex:1 1 calc(100% - 54px)}.lo-oright{margin-left:54px;width:calc(100% - 54px);flex-wrap:wrap;gap:8px}.lo-oright .lo-ochev{margin-left:auto}}
.lo-obody{display:none;padding:4px 16px 18px;border-top:1px solid var(--border)}
.lo-order.open .lo-obody{display:block}
.lo-obody-load{padding:16px 0;color:var(--text-muted);font-size:13px}
.lo-sub2{font-size:11px;font-weight:800;letter-spacing:.07em;color:var(--text-dim);text-transform:uppercase;margin:20px 0 10px}
.lo-compl{display:flex;align-items:center;gap:10px;margin:6px 0 8px}
.lo-compl .lo-bar{flex:1;height:6px;background:var(--surface2);border-radius:20px;overflow:hidden}
.lo-compl .lo-bar i{display:block;height:100%;background:var(--green);border-radius:20px}
.lo-pct{font-family:ui-monospace,monospace;font-size:12px;font-weight:600;color:var(--green)}
.lo-mklist{display:grid;grid-template-columns:1fr 1fr;gap:6px 20px}
@media(max-width:600px){.lo-mklist{grid-template-columns:1fr}}
.lo-mkrow{display:flex;align-items:center;gap:9px;padding:5px 0;font-size:13px}
.lo-ck{width:17px;height:17px;border-radius:50%;flex:none;display:grid;place-items:center}
.lo-mkrow.done .lo-ck{background:var(--green);color:#fff}
.lo-mkrow.pend .lo-ck{background:var(--surface2);border:1.5px solid var(--border)}
.lo-mknm{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.lo-mkrow.pend .lo-mknm{color:var(--text-dim)}
.lo-mkst{margin-left:auto;font-family:ui-monospace,monospace;font-size:10px;font-weight:600}
.lo-mkrow.done .lo-mkst{color:var(--green)}
.lo-mkrow.pend .lo-mkst{color:var(--text-dim)}
.lo-oname{font-weight:700;font-size:14px}
.lo-oacc{font-size:11px;color:var(--text-dim);margin-top:3px}
.lo-status{font-size:10px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;padding:4px 10px;border-radius:20px}
.lo-status.progress{background:color-mix(in srgb,var(--accent) 16%,transparent);color:var(--accent-light,var(--accent))}
.lo-status.action{background:color-mix(in srgb,var(--gold) 18%,transparent);color:var(--gold)}
.lo-status.ready{background:color-mix(in srgb,var(--green) 18%,transparent);color:var(--green)}
.lo-status.done{background:var(--surface2);color:var(--text-dim)}
.lo-chev{color:var(--text-dim)}
.lo-det-head{margin-bottom:14px}
.lo-next{border:1px solid var(--accent);background:color-mix(in srgb,var(--accent) 10%,transparent);border-radius:var(--radius);padding:16px 17px;margin-bottom:16px}
.lo-next.ready{border-color:var(--green);background:color-mix(in srgb,var(--green) 12%,transparent)}
.lo-next h3{margin:0 0 6px;font-size:15px}
.lo-next p{margin:0 0 12px;font-size:13px;color:var(--text-dim)}
.lo-track{font-size:12px;color:var(--text);background:var(--bg);border:1px solid var(--border);border-radius:8px;padding:8px 11px;display:inline-block;text-decoration:none;font-family:ui-monospace,monospace}
a.lo-track:hover{border-color:var(--accent);color:var(--accent)}
/* SPEC-LSC — cash-pay "payment due" callout + at-a-glance accordion chip. */
.lo-paydue{display:flex;gap:11px;align-items:flex-start;background:color-mix(in srgb,var(--gold) 12%,transparent);border:1px solid color-mix(in srgb,var(--gold) 45%,transparent);border-radius:var(--radius);padding:13px 15px;margin-bottom:16px}
.lo-paydue-ic{color:var(--gold);flex:none;margin-top:1px}
.lo-paydue-t{font-weight:700;font-size:14px;color:var(--text);margin-bottom:2px}
.lo-paydue-s{font-size:12.5px;color:var(--text-dim);line-height:1.45}
.lo-paypill{font-size:9.5px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--gold);background:color-mix(in srgb,var(--gold) 15%,transparent);border-radius:20px;padding:3px 9px;white-space:nowrap}
.lo-card{border:1px solid var(--border);border-radius:var(--radius);background:var(--surface);padding:15px 16px}
.lo-card-h{margin:0 0 12px;font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--text-dim)}
.lo-timeline{position:relative;padding-left:20px}
.lo-timeline::before{content:"";position:absolute;left:5px;top:5px;bottom:5px;width:2px;background:var(--border)}
.lo-tev{position:relative;padding:0 0 14px}.lo-tev:last-child{padding-bottom:0}
.lo-tev::before{content:"";position:absolute;left:-19px;top:4px;width:10px;height:10px;border-radius:50%;background:var(--teal);border:2px solid var(--teal)}
.lo-ev{font-weight:600;font-size:13px}
.lo-meta{font-size:11px;color:var(--text-dim);margin-top:2px}
.lo-note{font-size:12px;color:var(--text-dim);margin-top:3px}
.lo-ref{font-size:11px;color:var(--teal);margin-top:3px}
/* SPEC-LOS-2 §Phase 5 (W1-E) — 5-step order status stepper + per-stage guidance. */
.lo-stepper{display:flex;align-items:flex-start;gap:0;margin:6px 0 20px}
.lo-step{flex:1;text-align:center;position:relative;font-size:11px;color:var(--text-dim)}
.lo-step::before{content:"";position:absolute;top:11px;left:-50%;width:100%;height:2px;background:var(--border);z-index:0}
.lo-step:first-child::before{display:none}
.lo-step .dot{position:relative;z-index:1;width:24px;height:24px;border-radius:50%;background:var(--surface);border:2px solid var(--border);margin:0 auto 6px;display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:700;color:var(--text-dim)}
.lo-step.done .dot{background:var(--teal);border-color:var(--teal);color:#fff}
.lo-step.done::before{background:var(--teal)}
.lo-step.cur .dot{border-color:var(--accent);color:var(--accent)}
.lo-step.cur{color:var(--text);font-weight:600}
.lo-geowrap{position:relative}
.lo-geodrop{position:absolute;top:calc(100% + 3px);left:0;right:0;background:var(--surface);border:1px solid var(--border);border-radius:8px;box-shadow:0 12px 30px rgba(0,0,0,.28);z-index:30;max-height:210px;overflow-y:auto}
.lo-geoopt{padding:9px 12px;font-size:13px;cursor:pointer}
.lo-geoopt:hover{background:var(--surface2)}
.lo-locked{text-align:center;padding:26px 20px}
.lo-lock-title{font-size:15px;font-weight:700;margin-bottom:6px}
.lo-lock-sub{font-size:13px;color:var(--text-dim);margin-bottom:16px}
/* Operator preview strip (lab ordering, SPEC-DISC-3b operator exemption). Only an
   admin ever sees this; it sits between the member-facing coming-soon banner and the
   live catalog. Gold reads as "attention, not error" against both themes. */
.lo-optest{display:flex;align-items:flex-start;gap:9px;margin:0 0 14px;padding:10px 12px;
  border:1px solid var(--gold);border-radius:8px;background:color-mix(in srgb,var(--gold) 9%,transparent);
  font-size:12.5px;line-height:1.5;color:var(--text)}
.lo-optest-ic{flex:0 0 auto;display:inline-flex;color:var(--gold);margin-top:1px}
.lo-toast{position:fixed;left:50%;bottom:26px;transform:translateX(-50%) translateY(20px);background:var(--surface2);border:1px solid var(--green);color:var(--green);font-weight:600;font-size:13px;padding:11px 18px;border-radius:12px;opacity:0;pointer-events:none;transition:.2s;z-index:70}
.lo-toast.show{opacity:1;transform:translateX(-50%) translateY(0)}
/* SPEC-LOS §5 — lab-ordered verified provenance badge (labs.html) */
.lab-verified-badge{color:var(--green);font-weight:700;font-size:0.72rem;background:color-mix(in srgb,var(--green) 14%,transparent);border:1px solid color-mix(in srgb,var(--green) 40%,transparent);border-radius:20px;padding:2px 9px}

/* ── SPEC-PXR §3.2–§3.7 — unified configurator (member Reference tab) ── */
.rxc{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);padding:18px}
.rxc-head{display:flex;justify-content:space-between;align-items:flex-start;gap:12px;margin-bottom:16px}
.rxc-eyebrow{font-size:10px;font-weight:800;letter-spacing:.1em;text-transform:uppercase;color:var(--green);margin-bottom:5px;display:flex;align-items:center;flex-wrap:wrap;gap:8px}
.rxc-eyebrow.free{color:var(--text-dim)}
.rxc-badge{font-size:9.5px;font-weight:700;color:var(--gold);background:color-mix(in srgb,var(--gold) 14%,transparent);border:1px solid color-mix(in srgb,var(--gold) 35%,transparent);padding:2px 8px;border-radius:999px;text-transform:none;letter-spacing:0}
/* Compact "reference only" marker — a small circled R (like the coach circle) that
   replaces the wrapping "reference · not a recommendation" pill. The full disclaimer
   still renders at the bottom of the surface, so this only needs to hint + tooltip. */
.rxc-rbadge{display:inline-grid;place-items:center;width:15px;height:15px;border-radius:50%;font-size:9px;font-weight:800;color:var(--gold);background:color-mix(in srgb,var(--gold) 14%,transparent);border:1px solid color-mix(in srgb,var(--gold) 45%,transparent);text-transform:none;letter-spacing:0;cursor:help;flex:0 0 auto}
.rxc-name{font-size:18px;font-weight:800;margin:0;letter-spacing:-.2px}
/* SPEC-MMS — delivery-method switcher (shown only for multi-method compounds) */
.rxc-methodseg{display:flex;gap:6px;flex-wrap:wrap;background:var(--surface2);border:1px solid var(--border);border-radius:12px;padding:6px;margin-bottom:20px}
.rxc-methodseg button{flex:1 1 auto;display:inline-flex;align-items:center;justify-content:center;gap:8px;border:1px solid transparent;background:transparent;color:var(--text-muted);font-size:13px;font-weight:700;padding:10px 14px;border-radius:9px;cursor:pointer;font-family:inherit;transition:.12s}
.rxc-methodseg button.on{background:var(--surface);color:var(--accent);border-color:var(--border);box-shadow:0 1px 3px rgba(0,0,0,.1)}
.rxc-methodseg button svg{flex:0 0 auto}
.rxc-mtag{font-size:8.5px;font-weight:800;text-transform:uppercase;letter-spacing:.04em;color:#fff;background:var(--accent);border-radius:999px;padding:2px 6px}
.rxc-methodseg button:not(.on) .rxc-mtag{background:var(--text-dim)}
.rxc-cols{display:grid;grid-template-columns:1fr 232px;gap:20px;align-items:start}
@media(max-width:720px){.rxc-cols{grid-template-columns:1fr}}
.rxc-left{min-width:0}
.rxc-block{margin-top:20px}.rxc-block:first-child{margin-top:0}
.rxc-label{font-size:11px;font-weight:800;letter-spacing:.06em;text-transform:uppercase;color:var(--text-dim);margin:0 0 10px;display:flex;justify-content:space-between;align-items:center}
.rxc-hint{font-weight:600;text-transform:none;letter-spacing:0;color:var(--text-dim);font-size:11px}
.rxc-dosetop{display:flex;align-items:baseline;gap:7px}
.rxc-dosenum{font-size:30px;font-weight:800;letter-spacing:-.5px;border:none;background:transparent;width:4.2ch;min-width:4.2ch;padding:2px 0;outline:none;font-family:inherit;color:var(--accent);border-bottom:2px dashed transparent}
.rxc-dosenum:focus{border-bottom-color:var(--border)}
.rxc-doseunit{font-size:12px;font-weight:800;color:var(--accent);background:color-mix(in srgb,var(--accent) 12%,transparent);border:1px solid color-mix(in srgb,var(--accent) 30%,transparent);padding:4px 10px;border-radius:8px;cursor:pointer;text-transform:uppercase;letter-spacing:.02em;font-family:inherit}
.rxc-slider{position:relative;height:30px;margin-top:12px}
.rxc-track{position:absolute;top:50%;left:0;right:0;height:8px;border-radius:999px;background:var(--surface2);transform:translateY(-50%)}
.rxc-zone{position:absolute;top:0;bottom:0;background:color-mix(in srgb,var(--gold) 22%,transparent);border-left:2px solid var(--gold);border-right:2px solid var(--gold);border-radius:3px}
.rxc-zone[hidden]{display:none}
.rxc-range{position:absolute;top:0;left:0;width:100%;height:30px;margin:0;background:transparent;-webkit-appearance:none;appearance:none;outline:none;cursor:pointer}
.rxc-range::-webkit-slider-runnable-track{background:transparent;height:30px;border:none}
.rxc-range::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:22px;height:22px;margin-top:4px;border-radius:50%;background:var(--surface);border:3px solid var(--accent);cursor:pointer;box-shadow:0 2px 6px rgba(0,0,0,.22)}
.rxc-range::-moz-range-thumb{width:22px;height:22px;border-radius:50%;background:var(--surface);border:3px solid var(--accent);cursor:pointer}
.rxc-ends{display:flex;justify-content:space-between;font-size:11px;color:var(--text-dim);margin-top:4px}
.rxc-ends .mid{color:var(--gold);font-weight:700}
/* 4-value dose scale: outer min/max (dim, at the ends) on the lower tier, and the
   commonly-referenced low/high pins (gold) on the upper tier at the band edges. */
.rxc-scale{position:relative;height:32px;margin-top:5px;font-size:11px}
.rxc-scale-min,.rxc-scale-max,.rxc-sc-min,.rxc-sc-max{position:absolute;bottom:0;color:var(--text-dim);font-weight:600;white-space:nowrap}
.rxc-sc-min{left:0}.rxc-sc-max{right:0}
.rxc-sc-cap{position:absolute;bottom:0;left:50%;transform:translateX(-50%);color:var(--gold);font-weight:600;white-space:nowrap}
.rxc-sc-pin{position:absolute;top:0;transform:translateX(-50%);color:var(--gold);font-weight:700;white-space:nowrap}
.rxc-sc-pin::before{content:"";position:absolute;top:-6px;left:50%;transform:translateX(-50%);width:1px;height:5px;background:var(--gold)}
.rxc-scale.free{height:16px}
/* Frequency: the admin's commonly-referenced options get a gold ring; still any-selectable. */
.rxc-chips button.ref{border-color:var(--gold);box-shadow:inset 0 0 0 1px var(--gold)}
.rxc-chips button.on.ref{box-shadow:inset 0 0 0 2px var(--gold)}
.rxc-reflegend{display:flex;align-items:center;gap:6px;font-size:11px;color:var(--text-muted);margin-top:9px}
.rxc-refdot{width:11px;height:11px;border-radius:4px;border:1px solid var(--gold);box-shadow:inset 0 0 0 1px var(--gold);flex:0 0 auto}
.rxc-out{display:block;font-size:11.5px;color:var(--gold);background:color-mix(in srgb,var(--gold) 12%,transparent);border:1px solid color-mix(in srgb,var(--gold) 35%,transparent);padding:8px 11px;border-radius:9px;margin-top:12px;line-height:1.45}
.rxc-out[hidden]{display:none}
.rxc-seg,.rxc-chips{display:flex;gap:8px;flex-wrap:wrap}
.rxc-seg button,.rxc-chips button{border:1px solid var(--border);background:var(--surface2);color:var(--text-muted);font-size:13px;font-weight:700;padding:9px 13px;border-radius:10px;cursor:pointer;transition:.12s;font-family:inherit}
.rxc-seg button.on,.rxc-chips button.on{background:var(--accent);color:#fff;border-color:var(--accent)}
.rxc-custom input{width:74px;padding:8px 9px;border:1px solid var(--border);border-radius:8px;font-size:13px;font-weight:700;color:var(--text);background:var(--surface);font-family:ui-monospace,monospace}
.rxc-subrow{font-size:11px;font-weight:700;color:var(--text-dim);margin:14px 0 8px}
.rxc-subrow b{color:var(--text-muted)}
.rxc-cycle{display:flex;gap:11px;align-items:center;background:var(--surface2);border:1px solid var(--border);border-radius:var(--radius);padding:12px 14px;margin-top:20px;cursor:pointer}
.rxc-cycle-ic{flex:0 0 auto;width:32px;height:32px;border-radius:9px;background:color-mix(in srgb,var(--green) 16%,transparent);color:var(--green);display:flex;align-items:center;justify-content:center}
.rxc-cycle b{font-size:14px}.rxc-cycle p{margin:2px 0 0;font-size:12px;color:var(--text-muted)}
.rxc-cycle-ar{margin-left:auto;color:var(--text-dim)}
/* SPEC-CYC — editable cycle card (member/coach configurator) */
.rxc-cycedit{background:var(--surface2);border:1px solid var(--border);border-radius:var(--radius);padding:14px;margin-top:20px}
.rxc-cyced-h{display:flex;align-items:center;gap:9px;margin-bottom:11px}
.rxc-cyced-h b{font-size:14px}
.rxc-cycseg{margin-bottom:2px}
.rxc-cycdays{display:grid;grid-template-columns:1fr 1fr auto;gap:10px;align-items:end;margin-top:12px;max-width:360px}
.rxc-cycdays label{display:flex;flex-direction:column;gap:5px;font-size:12px;font-weight:700;color:var(--text-muted)}
.rxc-cycdays input{border:1px solid var(--border);border-radius:9px;background:var(--surface);color:var(--text);font-size:15px;font-weight:700;padding:9px 11px;font-family:inherit;width:100%}
.rxc-cycdays input:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 2px color-mix(in srgb,var(--accent) 20%,transparent)}
/* SPEC-CYC — clickable days/weeks unit toggle (full label desktop, W/D on mobile) */
.rxc-cycunit{border:1px solid var(--border);background:var(--surface2);color:var(--text-dim);font-size:13px;font-weight:800;padding:9px 13px;border-radius:9px;cursor:pointer;font-family:inherit;white-space:nowrap;height:39px}
.rxc-cycunit:hover{border-color:var(--accent);color:var(--accent)}
.rxc-cycunit .abbr{display:none}
@media(max-width:600px){.rxc-cycunit .full{display:none}.rxc-cycunit .abbr{display:inline}.rxc-cycunit{padding:9px 12px}}
.rxc-cycseg button.ref{border-color:var(--gold);box-shadow:inset 0 0 0 1px var(--gold)}
.rxc-cycseg button.on.ref{box-shadow:inset 0 0 0 2px var(--gold)}
.rxc-cycref{margin-top:11px;flex-wrap:wrap}
.rxc-cycapply{border:1px solid var(--gold);background:color-mix(in srgb,var(--gold) 12%,transparent);color:var(--gold);font-size:11px;font-weight:700;padding:3px 9px;border-radius:8px;cursor:pointer;font-family:inherit}
.rxc-cycapply:hover{background:var(--gold);color:#fff}
.rxc-cychint{margin:11px 0 0;font-size:12px;color:var(--text-muted);line-height:1.5}
.rxc-cycle-link{display:flex;align-items:center;gap:8px;width:100%;margin-top:13px;padding:10px 12px;border:1px dashed var(--border);border-radius:11px;background:transparent;color:var(--accent);font-size:13px;font-weight:700;cursor:pointer;font-family:inherit;text-align:left}
.rxc-cycle-link:hover{border-color:var(--accent);background:color-mix(in srgb,var(--accent) 6%,transparent)}
.rxc-cycle-link .rxc-cycle-ar{margin-left:auto;color:var(--accent)}
/* Sleep tab — collapsible imported-nights history log */
.sleep-log{margin-top:18px}
.sleep-log>summary{list-style:none;cursor:pointer}
.sleep-log>summary::-webkit-details-marker{display:none}
.sleep-log>summary:hover{background:var(--surface2);border-radius:12px}
.sleep-log-chev{transition:transform .15s;flex:0 0 auto}
.sleep-log[open] .sleep-log-chev{transform:rotate(180deg)}
.sleep-log:not([open]) .sleep-log-showlbl::after{content:'Show'}
.sleep-log[open] .sleep-log-showlbl::after{content:'Hide'}
.rxc-rail{display:flex;flex-direction:column;gap:12px;position:sticky;top:8px}
@media(max-width:720px){.rxc-rail{position:static}}
.rxc-railcard{background:var(--surface2);border:1px solid var(--border);border-radius:var(--radius);padding:13px 12px;display:flex;flex-direction:column;align-items:center}
.rxc-rc-t{font-size:10px;font-weight:800;letter-spacing:.05em;text-transform:uppercase;color:var(--text-dim);align-self:flex-start}
.rxc-rc-r{font-size:12px;color:var(--text-muted);align-self:flex-start;margin:3px 0 6px}
.rxc-rc-r b{color:var(--text);font-family:ui-monospace,monospace}
.rxc-solnote{display:flex;align-items:center;gap:6px;font-size:11px;color:var(--text-muted);align-self:flex-start;margin:10px 0 0;line-height:1.3}
.rxc-solnote b{color:var(--text)}
.rxc-i{width:15px;height:15px;border-radius:50%;border:1.4px solid var(--text-dim);color:var(--text-dim);font-size:10px;font-weight:800;display:inline-flex;align-items:center;justify-content:center;cursor:help;flex:0 0 auto;font-style:normal}
/* vertical U-100 syringe visual in the injectable rail */
.rxc-syrwrap{display:flex;align-items:center;justify-content:center;gap:12px;margin-top:6px}
.rxc-syr{overflow:visible;flex:0 0 auto}
.rxc-syr [data-cfg-syrfill]{transition:y .45s cubic-bezier(.4,0,.2,1),height .45s cubic-bezier(.4,0,.2,1)}
.rxc-syr [data-cfg-syrplunger]{transition:y .45s cubic-bezier(.4,0,.2,1)}
.rxc-syrlbl{font-size:11px;font-weight:700;color:var(--text-dim);text-align:center;line-height:1.3}
/* SPEC-DELIV-1 — the member Calculator, grouped into what the member is doing:
   Your dose · Mix your vial · Your schedule. Mixing steps sit beside the water choice. */
.rxc-sec{border:1px solid var(--border);border-radius:14px;padding:16px 16px 18px;background:var(--surface);margin-bottom:14px}
.rxc-sec:last-child{margin-bottom:0}
.rxc-sec .rxc-block:first-of-type{margin-top:0}
.rxc-sec-h{display:flex;align-items:center;gap:9px;margin:0 0 14px;flex-wrap:wrap}
.rxc-sec-h b{font-size:14px;font-weight:800;letter-spacing:-.005em;color:var(--text)}
.rxc-sec-num{width:22px;height:22px;border-radius:50%;background:color-mix(in srgb,var(--accent) 12%,transparent);color:var(--accent);font-size:11.5px;font-weight:800;display:grid;place-items:center;flex:none}
.rxc-sec-sub{margin-left:auto;font-size:12px;color:var(--text-dim)}
.rxc-routefixed{display:flex;align-items:center;gap:10px;margin-top:16px;padding:10px 12px;border:1px solid var(--border);border-radius:10px;background:var(--surface2);font-size:13px;color:var(--text-muted)}
.rxc-routefixed svg{color:var(--accent);flex:none}
.rxc-routefixed b{color:var(--text)}
.rxc-howto{margin-top:18px;padding-top:14px;border-top:1px dashed var(--border);scroll-margin-top:80px}
.rxc-sec > .rxc-howto:first-of-type{margin-top:0;padding-top:0;border-top:0}
.rxc-howto.rxc-howto-bare{margin-top:4px;padding-top:0;border-top:0}
.rxc-howto-h{display:flex;align-items:center;gap:8px;font-size:12.5px;font-weight:800;color:var(--text);margin-bottom:10px}
.rxc-howto-h svg{color:var(--accent)}
.rxc-solv{display:inline-flex;align-items:center;gap:7px;font-size:12.5px;font-weight:700;color:var(--accent);background:color-mix(in srgb,var(--accent) 10%,transparent);border-radius:999px;padding:5px 11px;margin-bottom:12px}
.rxc-steps{list-style:none;margin:0;padding:0;counter-reset:rxcs}
.rxc-steps li{counter-increment:rxcs;position:relative;padding:0 0 10px 32px;font-size:13.5px;line-height:1.5;color:var(--text-muted)}
.rxc-steps li::before{content:counter(rxcs);position:absolute;left:0;top:0;width:21px;height:21px;border-radius:50%;background:var(--surface2);border:1px solid var(--border);font-size:11px;font-weight:800;color:var(--text-muted);display:grid;place-items:center}
.rxc-steps li b{color:var(--text)}
.rxc-steps li.rxc-stepgrp{counter-increment:none;padding:6px 0 8px;font-size:10.5px;font-weight:800;letter-spacing:.07em;text-transform:uppercase;color:var(--text-dim)}
.rxc-steps li.rxc-stepgrp::before{display:none}
.rxc-aside{display:block;font-size:12px;color:var(--text-dim);margin-top:2px}
.rxc-prepnote{margin-top:8px;padding:10px 12px;border-radius:10px;background:var(--surface2);border:1px solid var(--border);font-size:13px;line-height:1.5;color:var(--text-muted);white-space:pre-line}
.rxc-prepnote-t{display:block;font-size:10.5px;font-weight:800;letter-spacing:.07em;text-transform:uppercase;color:var(--text-dim);margin-bottom:4px}
.rxc-guide{display:block}
.rxc-bandread{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap}
.rxc-bandread b{font-size:22px;font-weight:800;color:var(--teal)}
.rxc-bandread span{font-size:13px;color:var(--text-dim)}
.rxc-strength{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.rxc-fld{display:block;border:1px solid var(--border);border-radius:10px;padding:8px 10px;background:var(--surface2)}
.rxc-fld small{display:block;font-size:10.5px;font-weight:800;letter-spacing:.06em;text-transform:uppercase;color:var(--text-dim);margin-bottom:3px}
.rxc-fld input{width:72px;border:1px solid var(--border);border-radius:7px;padding:4px 6px;font:inherit;background:var(--surface);color:var(--text)}
.rxc-fld b{font-size:14px;font-family:var(--mono,ui-monospace,monospace)}
.rxc-fld b.accent{color:var(--teal)}
.rxc-rochips{display:flex;flex-wrap:wrap;gap:6px}
.rxc-rochips span{font-size:12.5px;font-weight:700;color:var(--text-muted);border:1px solid var(--border);border-radius:999px;padding:5px 11px;background:var(--surface2)}
.rxc-empty{font-size:13px;color:var(--text-dim);margin:0}
@media(max-width:420px){.rxc-strength{grid-template-columns:1fr}.rxc-sec{padding:14px 12px 16px}.rxc-sec-sub{margin-left:0;flex-basis:100%}}
.rx-steps{margin:6px 0 4px;padding-left:20px;font-size:12.5px;line-height:1.55;color:var(--text-muted)}
.rx-steps li{margin-bottom:4px}
.rx-steps li b{color:var(--text)}
.rx-aside{display:block;font-size:11.5px;color:var(--text-dim)}
.rx-pre{white-space:pre-line}
.rxc-strip{background:var(--surface);border:1px solid var(--border);border-radius:12px;overflow:hidden}
.rxc-dr{display:flex;justify-content:space-between;align-items:baseline;gap:12px;padding:10px 13px}
.rxc-dr + .rxc-dr{border-top:1px solid var(--border)}
.rxc-dk{font-size:10px;font-weight:800;color:var(--text-dim);text-transform:uppercase;letter-spacing:.04em;white-space:nowrap;flex:0 0 auto}
.rxc-dv{font-size:16px;font-weight:800;font-family:ui-monospace,monospace;letter-spacing:-.3px;white-space:nowrap;text-align:right;min-width:0}
.rxc-dv.accent{color:var(--accent)}
.rxc-dv-sm{font-size:12px;font-weight:700;font-family:inherit;text-transform:capitalize}
.rxc-dv small,.rxc-suppbig small{font-size:.62em;font-weight:700;color:var(--text-muted);margin-left:2px}
/* intranasal — sprays-per-dose stepper (user-entered) */
.rxc-rc-sub{font-size:11px;color:var(--text-muted);line-height:1.35;margin:3px 0 8px}
/* injectable — draw-to whole-unit steppers */
.rxc-drawrow{display:flex;align-items:center;justify-content:center;gap:10px;margin:2px 0}
.rxc-ustep{width:28px;height:28px;border-radius:8px;border:1px solid var(--border2);background:var(--surface);font-size:16px;font-weight:800;color:var(--accent);cursor:pointer;font-family:inherit;line-height:1;flex:0 0 auto}
.rxc-ustep:hover{border-color:var(--accent)}
.rxc-drawhint{font-size:10px;color:var(--text-muted);text-align:center;margin:0 0 6px}
.rxc-sprays{display:flex;align-items:center;gap:12px;margin:2px 0 2px}
.rxc-sprays button{width:34px;height:34px;border-radius:9px;border:1px solid var(--border2);background:var(--surface);font-size:18px;font-weight:800;color:var(--accent);cursor:pointer;font-family:inherit;line-height:1}
.rxc-sprays button:hover{border-color:var(--accent)}
.rxc-sprayval{font-size:21px;font-weight:800;font-family:ui-monospace,monospace;min-width:26px;text-align:center;color:var(--text)}
/* supplement — capsule readout + with-food toggle */
.rxc-suppbig{font-size:23px;font-weight:800;font-family:ui-monospace,monospace;margin-top:4px;color:var(--text)}
.rxc-withmeal{display:flex;align-items:center;justify-content:space-between;gap:12px;background:var(--surface2);border:1px solid var(--border);border-radius:var(--radius);padding:12px 14px;margin-top:16px}
.rxc-wm-l b{font-size:14px;color:var(--text)}
.rxc-wm-l p{margin:2px 0 0;font-size:12px;color:var(--text-muted)}
.rxc-toggle{position:relative;width:44px;height:25px;border-radius:20px;border:none;background:var(--green);cursor:pointer;flex:0 0 auto;transition:background .15s;padding:0}
.rxc-toggle.off{background:var(--border2)}
.rxc-knob{position:absolute;top:3px;left:22px;width:19px;height:19px;border-radius:50%;background:#fff;transition:left .15s}
.rxc-toggle.off .rxc-knob{left:3px}
.rxc-save{margin-top:20px;width:100%;padding:14px;border-radius:12px;border:none;background:var(--green);color:#fff;font-weight:800;font-size:15px;cursor:pointer;font-family:inherit}
.rxc-save:hover{filter:brightness(1.05)}
.rxc-disc{margin-top:12px;font-size:11px;color:var(--text-dim);line-height:1.5}
.rxc-locked{display:flex;gap:10px;align-items:flex-start;background:var(--surface2);border:1px dashed var(--border);border-radius:var(--radius);padding:14px;color:var(--text-muted);font-size:13px;line-height:1.5}

/* ═══════════════════════════════════════════════════════════════════════════
   THE SCHEDULE CARD — "When you'll actually take this"
   ─────────────────────────────────────────────────────────────────────────
   Moved here from protocol.html's inline <style> (owner review 2026-08-11).
   TWO surfaces render this card and they must not drift:

     • protocol.html            — a member's real schedule, absolute dates,
                                  status derived from today
     • coach-library.html       — a library entry's schedule TEMPLATE, relative
                                  windows ("Wk 1 -> Wk 2"), no status

   The owner's note was that the library's schedule "should match the same
   schedule design" as the member protocol page. Two copies of a design cannot
   match for long, so there is one definition and both surfaces use these class
   names. Anything genuinely template-only is namespaced .schedt-* below.

   Class names are UNCHANGED from protocol.html — its render function was not
   touched when this moved.
   ═══════════════════════════════════════════════════════════════════════════ */
/* compound-schedule-cosmetic-overhaul-v1 §4 — redesigned Schedule
   card. Sits inside the legacy .sot-section wrapper (which keeps
   the external id="sot-slot-{id}" hook). Pure render-layer: no
   data model changes, no resolver changes. Four stacked regions:
   dark gradient header (§4.3) → two-cell stats strip (§4.5) →
   entry list (§4.6) → add-entry footer (§4.7). */
.sched-card {
  margin-top: 4px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
}
/* §4.3 — dark gradient header. Fixed dark color in both themes
   per §4.11 (intentional brand-rich element). */
.sched-card-header {
  position: relative;
  padding: 18px 18px 16px;
  background: linear-gradient(135deg, #1e1b4b 0%, #312e81 100%);
  color: #fff;
  overflow: hidden;
}
.sched-card-header::before {
  content: '';
  position: absolute;
  right: -20px; top: -20px;
  width: 120px; height: 120px;
  background: radial-gradient(circle, rgba(255,255,255,0.06) 0%, transparent 70%);
  pointer-events: none;
}
.sched-card-header-label {
  position: relative;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 10.5px; font-weight: 600;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: rgba(255,255,255,0.6);
  margin-bottom: 6px;
}
.sched-card-header-title {
  position: relative;
  font-size: 19px; font-weight: 800;
  letter-spacing: -0.01em; line-height: 1.2;
  margin-bottom: 4px;
}
.sched-card-header-subtitle {
  position: relative;
  font-size: 12.5px; line-height: 1.4;
  color: rgba(255,255,255,0.7);
}

/* §4.5 — two-cell aggregate stats strip. Hidden entirely on
   empty state (§4.10) — rendered conditionally by JS. */
.sched-stats {
  display: grid;
  grid-template-columns: 1fr 1fr;
  background: var(--surface2);
  border-bottom: 1px solid var(--border);
}
.sched-stat-cell {
  padding: 11px 10px;
  text-align: center;
  border-right: 1px solid var(--border);
}
.sched-stat-cell:last-child { border-right: none; }
.sched-stat-key {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 9.5px; font-weight: 700;
  letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: 3px;
}
.sched-stat-value {
  font-size: 14px; font-weight: 700;
  color: var(--text);
  line-height: 1.2;
}
.sched-stat-value.ongoing { color: #16a34a; }
.sched-stat-sub {
  display: block;
  margin-top: 1px;
  font-size: 10.5px;
  color: var(--text-muted);
}

/* §4.6 — entry list and row structure. Each row is a single
   <button> that opens the plan edit drawer (handler binds to
   data-sot-open; preserved from legacy markup). */
.sched-list { display: flex; flex-direction: column; }
.sched-row {
  position: relative;
  display: flex; align-items: center;
  gap: 12px;
  width: 100%;
  padding: 14px 16px 14px 19px; /* extra left padding so the 3px stripe doesn't sit under content */
  border: none;
  border-bottom: 1px solid var(--border);
  background: var(--surface);
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  transition: background .12s;
}
.sched-row:last-child { border-bottom: none; }
.sched-row:hover { background: var(--surface2); }
.sched-row-stripe {
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 3px;
}
.sched-row-stripe.active   { background: linear-gradient(180deg, #16a34a 0%, #15803d 100%); }
.sched-row-stripe.upcoming { background: linear-gradient(180deg, #d97706 0%, #b45309 100%); }
.sched-row-stripe.complete { background: #d4d7e6; }
.sched-row-icon {
  width: 36px; height: 36px;
  border-radius: 8px;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.sched-row-icon.active   { background: #dcfce7; color: #14532d; }
.sched-row-icon.upcoming { background: #fef3c7; color: #78350f; }
.sched-row-icon.complete { background: #f1f5f9; color: #334155; }
.sched-row-body {
  flex: 1; min-width: 0;
  display: flex; flex-direction: column;
  gap: 3px;
}
.sched-row-top {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px;
}
.sched-row-dates {
  font-size: 15px; font-weight: 700;
  color: var(--text);
  line-height: 1.25;
}
.sched-row-dates.complete { color: var(--text-muted); }
/* coach-schedule-management-v1 §6.5 (rev. 2026-05-22) — right-side
   cluster groups the C badge (when present) + status pill so dates
   stay left-aligned consistently across rows whether or not the
   badge renders. */
.sched-row-right {
  display: inline-flex; align-items: center;
  gap: 6px;
  flex-shrink: 0;
}
.sched-row-arrow {
  font-weight: 500;
  color: var(--text-muted);
  margin: 0 4px;
}
.sched-row-meta {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 6px;
  font-size: 12.5px; line-height: 1.4;
  color: var(--text-muted);
}
.sched-row-meta-item { font-weight: 500; }
.sched-row-meta-sep { color: var(--text-dim); font-weight: 700; }
.sched-row-chev {
  color: var(--text-muted);
  font-size: 18px; line-height: 1;
  flex-shrink: 0;
}
.sched-row:hover .sched-row-chev { color: var(--accent); }

/* §4.8 — status pills. Three signals together (stripe + icon +
   pill) so color is never the only status indicator per §7.4. */
.status-pill {
  display: inline-flex; align-items: center;
  gap: 4px;
  padding: 3px 7px;
  border-radius: 4px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 9.5px; font-weight: 700;
  letter-spacing: 0.08em; text-transform: uppercase;
  flex-shrink: 0;
}
.status-pill .p-dot {
  width: 5px; height: 5px;
  border-radius: 50%;
}
.status-pill.active   { background: #dcfce7; color: #14532d; }
.status-pill.active   .p-dot { background: #16a34a; box-shadow: 0 0 0 2px rgba(22,163,74,0.2); }
.status-pill.upcoming { background: #fef3c7; color: #78350f; }
.status-pill.upcoming .p-dot { background: #d97706; }
.status-pill.complete { background: #f1f5f9; color: #334155; }
.status-pill.complete .p-dot { background: #94a3b8; }

/* §4.7 — add-entry footer. Subtle backdrop, dashed accent button. */
.sched-add-footer {
  padding: 12px 16px;
  background: var(--surface2);
  border-top: 1px solid var(--border);
}
.sched-add-btn {
  display: block; width: 100%;
  padding: 10px 14px;
  background: var(--surface);
  border: 1px dashed var(--accent);
  color: var(--accent);
  border-radius: 8px;
  font-family: inherit;
  font-size: 13px; font-weight: 700;
  cursor: pointer;
  transition: background .12s, color .12s;
}
.sched-add-btn:hover { background: var(--accent); color: #fff; }

/* §4.11 — dark-theme overrides. The pure-light pill tints
   (#dcfce7 etc.) don't read well on a dark surface, so swap to
   translucent variants of the same hue. Icon containers follow
   suit. */
[data-theme="dark"] .status-pill.active   { background: rgba(22,163,74,0.18); color: #86efac; }
[data-theme="dark"] .status-pill.upcoming { background: rgba(217,119,6,0.18); color: #fcd34d; }
[data-theme="dark"] .status-pill.complete { background: rgba(148,163,184,0.18); color: #cbd5e1; }
[data-theme="dark"] .sched-row-icon.active   { background: rgba(22,163,74,0.18); color: #86efac; }
[data-theme="dark"] .sched-row-icon.upcoming { background: rgba(217,119,6,0.18); color: #fcd34d; }
[data-theme="dark"] .sched-row-icon.complete { background: rgba(148,163,184,0.18); color: #cbd5e1; }
[data-theme="dark"] .sched-row-stripe.complete { background: #475569; }
[data-theme="dark"] .sched-stat-value.ongoing { color: #86efac; }

/* Template-only additions. A library schedule has no dates and no status, so a
   row's leading cell is a WEEK SPAN and the stripe/pill carry no state. */
.sched-row.schedt-row { cursor: pointer; }
.sched-row-stripe.schedt { background: linear-gradient(180deg, var(--accent) 0%, color-mix(in srgb, var(--accent) 70%, #000) 100%); }
.sched-row-icon.schedt { background: color-mix(in srgb, var(--accent) 14%, var(--surface)); color: var(--accent-light, var(--accent)); }
.schedt-span {
  font-family: ui-monospace, 'JetBrains Mono', monospace;
  font-size: 0.82rem; font-weight: 700; color: var(--text);
  display: inline-flex; align-items: center; gap: 4px;
}
.schedt-wk { font-size: 0.68rem; letter-spacing: .06em; text-transform: uppercase; color: var(--text-dim); font-weight: 700; }
.status-pill.schedt { background: color-mix(in srgb, var(--accent) 14%, var(--surface)); color: var(--accent-light, var(--accent)); }
.status-pill.schedt .p-dot { background: var(--accent); }
.status-pill.ongoing { background: #dcfce7; color: #14532d; }
.status-pill.ongoing .p-dot { background: #16a34a; }
[data-theme="dark"] .status-pill.ongoing { background: rgba(22,163,74,0.18); color: #86efac; }
/* A schedule the platform DERIVED from a legacy cycle config rather than one the
   coach authored. Said plainly, because presenting a guess as their own work is
   how a wrong protocol reaches a member unnoticed. */
.schedt-draft {
  padding: 7px 14px; border-bottom: 1px solid var(--border); background: var(--surface2);
  font-size: 0.72rem; font-style: italic; color: var(--text-muted); line-height: 1.45;
}
/* COLLAPSIBLE — the library board's default. The header carries the whole
   summary (how many windows, how long), which is what the stats strip and the
   subtitle said at four times the height, so collapsed mode drops both. */
.sched-card.schedt-collapse { border-radius: 9px; }
/* Owner review 2026-08-11: the dark brand gradient is right for protocol.html,
   where the schedule IS the page. Repeated down a board of a dozen cards it
   became the only thing the eye could land on. Collapsed mode is a quiet
   surface header instead — same structure, tokenised colors, no gradient. */
.sched-card.schedt-collapse .sched-card-header.schedt-toggle {
  display: flex; align-items: center; gap: 7px; width: 100%; padding: 9px 10px;
  border: 0; border-bottom: 1px solid var(--border);
  background: var(--surface2);
  color: var(--text);
  font-family: inherit; text-align: left; cursor: pointer;
}
.sched-card.schedt-collapse .sched-card-header.schedt-toggle:hover { background: var(--border); }
/* The EDITOR's header: same quiet chrome, but it is a label rather than a
   control — the list below it is always open, so there is nothing to toggle. */
.sched-card.schedt-collapse .sched-card-header.schedt-static { cursor: default; }
.sched-card.schedt-collapse .sched-card-header.schedt-static:hover { background: var(--surface2); }
.sched-card.schedt-collapse .sched-add-footer { border-top: 1px solid var(--border); }
.sched-card-header.schedt-toggle::before { display: none; }   /* no decorative wash on a control */
.sched-card.schedt-collapse:not(.open) .sched-card-header.schedt-toggle { border-bottom-color: transparent; }
/* Sized to fit the summary WHOLE in a four-up library column (~262px of inner
   width). The line is the only thing a collapsed card says about its schedule,
   so "4 windows · 6 wks + ongo…" is a worse header than a slightly smaller
   one that reads in full. */
.schedt-cap {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 8.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--text-muted); flex: none;
}
.schedt-sum { font-size: 0.72rem; font-weight: 700; color: var(--text); min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.schedt-chip {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 8.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  background: var(--border); color: var(--text-muted); border-radius: 4px; padding: 2px 5px; flex: none;
}
.schedt-caret { margin-left: auto; color: var(--text-muted); font-size: 0.7rem; flex: none; }
.sched-card.schedt-collapse .sched-row { padding: 8px 12px 8px 15px; }
.sched-card.schedt-collapse .sched-row-meta { font-size: 0.72rem; }

/* Compacted for a library CARD, where the schedule is one block among several
   rather than the page's main subject. */
.sched-card.schedt-compact .sched-card-header { padding: 10px 14px; }
.sched-card.schedt-compact .sched-card-header-title { font-size: 0.92rem; }
.sched-card.schedt-compact .sched-row { padding: 8px 14px 8px 16px; }
.sched-card.schedt-compact .sched-row-meta { font-size: 0.72rem; }
.sched-card.schedt-compact .schedt-span { font-size: 0.78rem; }

/* ═══════════════════════════════════════════════════════════════════════════
   SPEC-LAB-RT-3 — THE MARKER ROW. One component, five bodies + a text
   fallback, rendered by window.renderMarkerRow (marker-row.js). Ported from
   roadmap-spec/mockups/RT-3_marker_row_variants.html; the mockup's
   [data-theme] blocks become the app's real :root.light mechanism, and every
   color is a token so the same component serves a member and a coach whichever
   theme each of them is running.
   ═══════════════════════════════════════════════════════════════════════════ */
.mrow { padding: 14px 0; border-bottom: 1px solid var(--border); }
.mrow:last-child { border-bottom: none; }
.mrow__head { display: flex; align-items: center; gap: 14px; }
.mrow__name { flex: 1 1 auto; min-width: 0; }
.mrow__name .t { font-size: 0.92rem; font-weight: 700; letter-spacing: -0.01em; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mrow__name .sub { font-size: 0.68rem; color: var(--text-dim); margin-top: 1px; }
.mrow__val { flex: none; text-align: right; font-size: 1rem; font-weight: 700; letter-spacing: -0.01em; }
.mrow__val .u { font-size: 0.68rem; color: var(--text-muted); font-weight: 500; margin-left: 3px; }
.mrow__val.faint { color: var(--text-muted); font-weight: 500; }
.mrow__body { margin-top: 12px; }

/* status pill — the one place a band becomes color */
.mrow-pill { flex: none; font-size: 0.68rem; font-weight: 700; letter-spacing: 0.02em; padding: 4px 9px; border-radius: 999px; border: 1px solid; white-space: nowrap; }
.mrow-pill.tone-optimal { color: var(--band-optimal); border-color: color-mix(in srgb, var(--band-optimal) 45%, transparent); background: color-mix(in srgb, var(--band-optimal) 13%, transparent); }
.mrow-pill.tone-caution { color: var(--band-caution); border-color: color-mix(in srgb, var(--band-caution) 45%, transparent); background: color-mix(in srgb, var(--band-caution) 13%, transparent); }
.mrow-pill.tone-danger  { color: var(--band-danger);  border-color: color-mix(in srgb, var(--band-danger) 45%, transparent);  background: color-mix(in srgb, var(--band-danger) 13%, transparent); }
.mrow-pill.tone-neutral { color: var(--band-neutral); border-color: color-mix(in srgb, var(--band-neutral) 40%, transparent); background: color-mix(in srgb, var(--band-neutral) 10%, transparent); }

/* body: numeric gauge — quiet zones, loud dot (mockup decision 2) */
.mrow-gauge { position: relative; }
.mrow-gauge__track { position: relative; height: 6px; border-radius: 999px; background: var(--gauge-track); overflow: hidden; }
.mrow-gauge__zones { position: absolute; inset: 0; background: linear-gradient(90deg,
  color-mix(in srgb, var(--band-danger) 34%, transparent) 0% 15%,
  color-mix(in srgb, var(--band-caution) 30%, transparent) 15% 35%,
  color-mix(in srgb, var(--band-optimal) 32%, transparent) 35% 65%,
  color-mix(in srgb, var(--band-caution) 30%, transparent) 65% 85%,
  color-mix(in srgb, var(--band-danger) 34%, transparent) 85% 100%); }
.mrow-gauge__zones.mode-standard { background: linear-gradient(90deg,
  color-mix(in srgb, var(--band-danger) 34%, transparent) 0% 20%,
  color-mix(in srgb, var(--band-optimal) 32%, transparent) 20% 80%,
  color-mix(in srgb, var(--band-danger) 34%, transparent) 80% 100%); }
.mrow-gauge__dot { position: absolute; top: 50%; width: 13px; height: 13px; border-radius: 50%; transform: translate(-50%, -50%); border: 2.5px solid var(--surface); z-index: 2; }
.mrow-gauge__dot.tone-optimal { background: var(--band-optimal); }
.mrow-gauge__dot.tone-caution { background: var(--band-caution); }
.mrow-gauge__dot.tone-danger  { background: var(--band-danger); }
.mrow-gauge__dot.tone-neutral { background: var(--band-neutral); }
.mrow-gauge__scale { display: flex; justify-content: space-between; font-size: 0.62rem; color: var(--text-dim); margin-top: 8px; gap: 8px; }
.mrow-gauge__scale .opt { color: var(--text-muted); }

/* body: no range established */
.mrow-norange { display: flex; align-items: center; gap: 8px; font-size: 0.74rem; color: var(--text-dim); }
.mrow-norange .dash { flex: 1; height: 1px; background: var(--border); }

/* body: not plotted — the D1 fix, made visible (mockup decision 5) */
.mrow-missing { display: flex; align-items: center; gap: 9px; font-size: 0.74rem; color: var(--text-muted); background: var(--surface2); border-radius: 8px; padding: 9px 12px; }
.mrow-missing svg { width: 15px; height: 15px; color: var(--text-dim); flex: none; }
.mrow-missing b { font-weight: 700; color: var(--text); }

/* body: genotype — three-state track (mockup decision 3) */
.mrow-geno { display: flex; flex-direction: column; gap: 12px; }
.mrow-geno__states { display: flex; gap: 6px; }
.mrow-geno__st { flex: 1; text-align: center; font-size: 0.66rem; font-weight: 700; padding: 6px 4px; border-radius: 6px; color: var(--text-dim); background: var(--surface2); border: 1px solid transparent; }
.mrow-geno__st.on.tone-optimal { color: var(--band-optimal); background: color-mix(in srgb, var(--band-optimal) 13%, transparent); border-color: color-mix(in srgb, var(--band-optimal) 40%, transparent); }
.mrow-geno__st.on.tone-caution { color: var(--band-caution); background: color-mix(in srgb, var(--band-caution) 13%, transparent); border-color: color-mix(in srgb, var(--band-caution) 40%, transparent); }
.mrow-geno__st.on.tone-danger  { color: var(--band-danger);  background: color-mix(in srgb, var(--band-danger) 13%, transparent);  border-color: color-mix(in srgb, var(--band-danger) 40%, transparent); }
.mrow-interp { font-size: 0.8rem; color: var(--text-muted); }
.mrow-interp b { color: var(--text); font-weight: 700; }

/* interpretation is disclosure, not default (mockup decision 4) */
.mrow-disclose { display: inline-flex; align-items: center; gap: 5px; cursor: pointer; font-size: 0.7rem; font-weight: 600; color: var(--accent-light); background: none; border: none; padding: 0; font-family: inherit; }
.mrow-disclose svg { width: 13px; height: 13px; transition: transform 0.2s ease; }
.mrow-disclose[aria-expanded="true"] svg { transform: rotate(90deg); }
.mrow-disclose:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 3px; }
.mrow-note { font-size: 0.74rem; color: var(--text-muted); line-height: 1.55; border-left: 2px solid var(--border); padding: 2px 0 2px 12px; margin-top: 10px; }
.mrow-note[hidden] { display: none; }
/* SPEC-LAB-PHASERANGE §4.3 — the context-range table inside the SAME .mrow-note the
   genotype interpretation uses. Only the interior layout is new; the control, the
   border-left, the type scale and the hidden state are all inherited, so the two
   disclosures read as one pattern. Tokens only. */
.mrow-cr { display: flex; flex-direction: column; gap: 3px; }
.mrow-cr__row { display: flex; align-items: baseline; gap: 10px; justify-content: space-between; }
.mrow-cr__l { color: var(--text-muted); }
.mrow-cr__v { font-variant-numeric: tabular-nums; color: var(--text); font-weight: 600; white-space: nowrap; }

/* body: qualitative + text fallback */
.mrow-qual { display: flex; align-items: center; gap: 10px; font-size: 0.74rem; color: var(--text-dim); }
.mrow-text { font-size: 0.8rem; color: var(--text-muted); line-height: 1.55; }

/* optional trend chip in the head */
.mrow-trend { flex: none; display: inline-flex; align-items: center; color: var(--text-muted); }
.mrow-trend svg { width: 46px; height: 18px; overflow: visible; }

@media (prefers-reduced-motion: reduce) {
  .mrow-disclose svg { transition: none; }
}
@media (max-width: 620px) {
  .mrow__head { flex-wrap: wrap; gap: 8px 10px; }
  .mrow__val { text-align: left; }
}

/* SPEC-LAB-RT-4 §5.5 — the panel frame: provenance stated once, the lab's own note,
   the source report, the verbatim regulatory footer. Tokens only. */
.pf { border: 1px solid var(--border); border-radius: 10px; background: var(--surface); padding: 14px 16px; margin-bottom: 14px; }
.pf-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
/* Wave 2 — the RT-4 panel title takes the display face via the token. The mockup's
   .ph__t is font-family:var(--display) at 22px/700; the size here stays as shipped
   (0.95rem) because only the face was in scope. */
.pf-title { font-family: var(--display); font-size: 0.95rem; font-weight: 700; color: var(--text); }
.pf-chip { font-size: 0.62rem; }
.pf-facts { display: flex; flex-wrap: wrap; gap: 6px 22px; margin-top: 10px; }
.pf-fact { display: flex; flex-direction: column; gap: 1px; }
.pf-k { font-size: 0.6rem; text-transform: uppercase; letter-spacing: 0.5px; color: var(--text-dim); }
.pf-v { font-size: 0.78rem; font-weight: 600; color: var(--text); }
.pf-report { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--border); }
.pf-report svg { width: 15px; height: 15px; color: var(--text-muted); flex: none; }
.pf-report-t { flex: 1; min-width: 140px; font-size: 0.76rem; color: var(--text-muted); }
.pf-btn { display: inline-flex; align-items: center; gap: 5px; font-family: inherit; font-size: 0.72rem; font-weight: 600; color: var(--text); background: var(--surface2); border: 1px solid var(--border); border-radius: 6px; padding: 5px 10px; cursor: pointer; }
.pf-btn:hover { border-color: var(--accent); }
.pf-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.pf-btn svg { width: 12px; height: 12px; }
.pf-note-btn { margin-top: 12px; }
/* `white-space: pre-line` is load-bearing, not cosmetic: buildRegulatoryFooter() joins the
   attribution line and the FDA sentence with a "\n", and that text is ESCAPED before it
   reaches the DOM (it originates from a lab profile, so injecting a literal <br> the way the
   mockup does would mean un-escaping lab-supplied text). pre-line honours the newline while
   the escaping stays intact. Without it the two sentences run together mid-line. */
.pf-reg { margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--border); font-size: 0.66rem; line-height: 1.5; color: var(--text-dim); white-space: pre-line; }
/* SPEC-LAB-MULTILAB §4.2/§4.4 — the pending banner and the inline per-lab attribution.
   Tokens only. The banner is caution-toned because something is outstanding, not wrong;
   the attribution block is a dashed neutral card so it reads as provenance rather than
   as an alert. */
.pf-reg-tag { display: block; font-size: 0.6rem; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; color: var(--text-dim); margin-bottom: 4px; }
.pf-pending { display: flex; gap: 11px; align-items: flex-start; margin: 12px 0; padding: 11px 13px; border-radius: 9px;
  background: color-mix(in srgb, var(--band-caution) 10%, transparent); border: 1px solid color-mix(in srgb, var(--band-caution) 34%, transparent); }
.pf-pending svg { flex: none; width: 16px; height: 16px; color: var(--band-caution); margin-top: 1px; }
.pf-pending-t { font-size: 0.8rem; font-weight: 700; color: var(--text); margin-bottom: 2px; }
.pf-pending-m { font-size: 0.75rem; color: var(--text-muted); line-height: 1.5; }
.pf-attrib { display: flex; gap: 11px; align-items: flex-start; margin: 12px 0; padding: 10px 12px; border-radius: 9px;
  background: var(--surface2); border: 1px dashed var(--border); }
.pf-attrib svg { flex: none; width: 15px; height: 15px; color: var(--accent-light); margin-top: 2px; }
.pf-attrib-b { font-size: 0.73rem; line-height: 1.6; color: var(--text-muted); }
.pf-attrib-b b { color: var(--text); font-weight: 600; }
.pf-attrib-tag { display: block; font-size: 0.6rem; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; color: var(--accent-light); margin-bottom: 3px; }
/* §4.3 — the per-section "run by" line, inside the section header. Floated right so it
   sits opposite the category name without the header needing to become a flex container
   (both surfaces' section headers are plain text nodes and one is an <h3>). It deliberately
   drops the header's letter-spacing and weight: it is provenance, not a title. */
/* SPEC-LAB-RECOLLECT §4.6 — the compromised caveat. Caution-toned, NOT danger: the result
   is usable, and painting it red would say something the lab did not. Deliberately quieter
   than .pf-pending, whose situation (nothing to show yet) is the more disruptive one. */
.pf-caveat { display: flex; gap: 11px; align-items: flex-start; margin: 12px 0; padding: 11px 13px; border-radius: 9px;
  background: color-mix(in srgb, var(--band-caution) 9%, transparent); border: 1px solid color-mix(in srgb, var(--band-caution) 30%, transparent); }
.pf-caveat svg { flex: none; width: 16px; height: 16px; color: var(--band-caution); margin-top: 1px; }
.pf-caveat-t { font-size: 0.8rem; font-weight: 700; color: var(--text); margin-bottom: 2px; }
.pf-caveat-m { font-size: 0.75rem; color: var(--text-muted); line-height: 1.5; }
.pf-caveat .mrow-disclose { margin-top: 8px; }

/* SPEC-LAB-RECOLLECT §4.3/§4.4 — the link line between an order and its replacement.
   ONE renderer (services/lab-orders.js orderLinkLineHtml), so this styles both the staff
   console and the member's order view. Optimal-toned: a link here means the dead end was
   resolved, which is good news. */
.lo-link { display: flex; align-items: center; gap: 9px; margin: 12px 0; padding: 11px 13px; border-radius: 9px; font-size: 0.78rem;
  background: color-mix(in srgb, var(--band-optimal) 8%, transparent); border: 1px solid color-mix(in srgb, var(--band-optimal) 30%, transparent); }
.lo-link svg { flex: none; width: 15px; height: 15px; color: var(--band-optimal); }
.lo-link-a { color: var(--band-optimal); font-weight: 700; font-family: var(--mono, inherit); background: none; border: none; padding: 0;
  cursor: pointer; border-bottom: 1px solid color-mix(in srgb, var(--band-optimal) 45%, transparent); font-size: inherit; }
.lo-link-a:hover { border-bottom-color: var(--band-optimal); }
.lo-link-a:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.pf-runby { float: right; font-weight: 400; font-size: 0.66rem; letter-spacing: 0; text-transform: none; color: var(--text-dim); }
