/* ═══════════════════════════════════════════════════════════════════════════
   DESIGN SYSTEM — Step 1 foundation (font · type scale · semantic colour ·
   spacing · component states). One Inter UI font with tabular figures; teal as
   the single brand anchor; colour used only semantically and always paired with a
   label/icon; a strict type + spacing scale; defined interactive states. Existing
   variable names are kept as aliases so every rule inherits the new foundation.
   ═══════════════════════════════════════════════════════════════════════════ */
:root{
  /* — type — */
  --font-ui:'Inter',system-ui,'Segoe UI',Roboto,sans-serif;
  --font-mono:'Inter',ui-monospace,Menlo,monospace;
  --fs-title:26px;     /* page title   */
  --fs-section:18px;   /* section head */
  --fs-body:15px;      /* body         */
  --fs-label:13px;     /* label        */
  --fs-caption:12px;   /* caption      */
  --lh-body:1.5; --lh-tight:1.25;
  --fw-regular:400; --fw-medium:500; --fw-semibold:600; --fw-bold:700;

  /* — semantic colour — teal brand anchor + one positive / warning / negative,
       an informational + review accent, and a neutral ramp for all structure. — */
  --primary:#0F6E56; --primary-d:#0b5946; --primary-bg:#e6f6ef;
  --positive:#3fb389; --positive-d:#0b5946; --positive-bg:#e6f6ef; --positive-line:#b7e3cf;
  --warning:#d98a1f; --warning-bg:#fbf0db; --warning-line:#e8cfa0;
  --negative:#b3402f; --negative-bg:#fbe3e3; --negative-line:#e7b4ab;
  --info:#2f6fb0; --info-bg:#e7f0f9;
  --review:#6b3fb0; --review-bg:#efe6fb;
  /* metric-series colours — these identify WHICH metric (category), never its status.
     The two gauge arms (Time, Budget) and the two EV lines (CPI, SPI) each swing
     independently across better/on-track/worse, so position on the axis carries good/bad;
     colour only says which metric it is. Teal vs violet = maximum hue separation and clear
     of the amber/green status zones; series-b also renders DASHED so the pair is
     distinguishable without relying on hue (colour-vision-deficiency safe). */
  --series-a:var(--primary);   /* Time · CPI — solid teal  */
  --series-b:#6b3fb0;          /* Budget · SPI — dashed violet */
  /* neutral ramp */
  --ink:#1b2a26; --muted:#6b7d77; --line:#dde6e2;
  --surface:#ffffff; --surface-2:#eef3f1; --bg:#f6f9f7;

  /* — spacing scale (4 / 8 / 12 / 16 / 24 / 32) — */
  --sp-1:4px; --sp-2:8px; --sp-3:12px; --sp-4:16px; --sp-5:24px; --sp-6:32px;

  /* — radii · elevation · motion · focus — */
  --radius-sm:6px; --radius:10px; --radius-lg:12px;
  --shadow-1:0 1px 2px rgba(20,40,33,.06);
  --shadow-2:0 6px 20px rgba(20,40,33,.10);
  --speed:.15s; --ease:cubic-bezier(.2,.6,.3,1);
  --focus-ring:0 0 0 3px rgba(63,179,137,.45);
  --ctx-h:53px;        /* sticky context-bar height — table headers stick just below it */

  /* — legacy aliases: keep every existing rule working off the new tokens — */
  --teal:var(--primary); --teal-d:var(--primary-d);
  --mint:var(--positive); --mint-bg:var(--positive-bg);
  --amber:var(--warning); --amber-bg:var(--warning-bg);
  --blue:var(--info); --blue-bg:var(--info-bg);
}
*{box-sizing:border-box}
/* Accessibility: skip-to-content link, off-screen until keyboard-focused. */
.skip{position:absolute;left:-9999px;top:0;z-index:100;background:var(--primary);color:#fff;padding:8px 14px;border-radius:0 0 8px 0;text-decoration:none;font-weight:var(--fw-semibold)}
.skip:focus{left:0}
body{
  margin:0;
  font-family:var(--font-ui);
  font-size:var(--fs-body);
  line-height:var(--lh-body);
  color:var(--ink);
  background:var(--bg);
  font-variant-numeric:tabular-nums;            /* tabular figures for ALL numbers */
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
}
/* ── Step 2 navigation: persistent left sidebar (primary) + main + context bar ── */
.app{display:flex;min-height:100vh;align-items:stretch}
.sidebar{
  flex:none;width:224px;background:var(--primary-d);color:#dff1ea;
  display:flex;flex-direction:column;
  position:sticky;top:0;height:100vh;overflow:hidden;
  transition:width var(--speed) var(--ease);
}
.sidebar .brand{
  display:flex;align-items:center;gap:var(--sp-2);text-decoration:none;color:#fff;
  font-weight:var(--fw-bold);letter-spacing:.2px;
  padding:var(--sp-4) var(--sp-4) var(--sp-3);
}
.brand-mark{
  display:none;width:30px;height:30px;flex:none;border-radius:8px;
  background:var(--mint);color:var(--primary-d);font-weight:800;font-size:13px;
  align-items:center;justify-content:center;
}
.brand-full{display:flex;flex-direction:column;line-height:1.15}
.brand-sub{font-weight:var(--fw-regular);opacity:.75;font-size:11px}
.sidenav{display:flex;flex-direction:column;gap:2px;padding:var(--sp-2);flex:1;overflow-y:auto}
.snav{
  display:flex;align-items:center;gap:11px;padding:9px var(--sp-3);border-radius:8px;
  color:#cfe7dd;text-decoration:none;font-size:var(--fs-body);font-weight:var(--fw-medium);white-space:nowrap;
}
.snav .ic{width:18px;height:18px;flex:none;opacity:.85}
.snav:hover{background:rgba(255,255,255,.08);color:#fff}
.snav.on{background:rgba(255,255,255,.14);color:#fff;font-weight:var(--fw-semibold)}
.snav.on .ic{color:var(--mint);opacity:1}
/* Inert/greyed item (context-unavailable, e.g. Patient Grid with no single study). NOT
   removed — primary nav stays a stable shape. Kept hoverable (no pointer-events:none) so
   the title tooltip fires; cursor signals it's not actionable; the <span>+no-href makes it
   inert. aria-disabled/aria-label (in the markup) carry the reason to AT users too. */
.snav.disabled{color:#8fb3a8;cursor:not-allowed;opacity:.6}
.snav.disabled .ic{opacity:.6}
.snav.disabled:hover{background:transparent;color:#8fb3a8}
.snav-div{height:1px;background:rgba(255,255,255,.12);margin:var(--sp-2) var(--sp-3)}
/* "soon" chip on the single greyed lifecycle stage (Patient payments) in the left nav. */
.soon{margin-left:auto;font-size:10px;text-transform:uppercase;letter-spacing:.5px;color:#8fb3a8;
  border:1px solid rgba(255,255,255,.18);border-radius:6px;padding:0 5px}
body.side-collapsed .soon{display:none}
.side-foot{
  display:flex;align-items:center;justify-content:space-between;gap:var(--sp-2);
  padding:var(--sp-3) var(--sp-4);border-top:1px solid rgba(255,255,255,.12);
  font-size:var(--fs-caption);color:#bfe0d4;
}
.side-foot .who{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.side-toggle{
  background:none;border:none;color:#bfe0d4;cursor:pointer;padding:5px;border-radius:6px;
  display:flex;flex:none;transition:transform var(--speed) var(--ease),background var(--speed) var(--ease);
}
.side-toggle:hover{background:rgba(255,255,255,.12);color:#fff}
.side-toggle .ic{width:18px;height:18px}
/* collapsed / icon-only state */
body.side-collapsed .sidebar{width:62px}
body.side-collapsed .snav{justify-content:center;padding:9px}
body.side-collapsed .snav .lbl,
body.side-collapsed .brand-full,
body.side-collapsed .side-foot .who{display:none}
body.side-collapsed .brand{justify-content:center;padding:var(--sp-4) 0 var(--sp-3)}
body.side-collapsed .brand-mark{display:flex}
body.side-collapsed .side-foot{justify-content:center}
body.side-collapsed .side-toggle .ic{transform:rotate(180deg)}

.main{flex:1;min-width:0;display:flex;flex-direction:column}
.wrap{width:100%;max-width:1040px;margin:var(--sp-5) auto;padding:0 var(--sp-5)}
h1{font-size:var(--fs-title);line-height:var(--lh-tight);font-weight:var(--fw-bold);letter-spacing:-.01em;margin:.2em 0 .6em}
h2{font-size:var(--fs-section);line-height:var(--lh-tight);font-weight:var(--fw-semibold);margin:1.6em 0 .5em;color:var(--teal-d)}
.muted{color:var(--muted)}.mono{font-family:ui-monospace,Menlo,monospace;font-size:12px}
.foot{max-width:1040px;margin:30px auto;padding:14px var(--sp-5);color:var(--muted);font-size:var(--fs-caption);border-top:1px solid var(--line)}
/* breadcrumbs — a complement to the sidebar on drill-down views */
.crumbs{display:flex;align-items:center;flex-wrap:wrap;gap:7px;margin:0 0 var(--sp-4);font-size:var(--fs-label);color:var(--muted)}
.crumbs a{color:var(--muted);text-decoration:none}
.crumbs a:hover{color:var(--teal);text-decoration:underline}
.crumbs a:last-child{color:var(--ink);font-weight:var(--fw-semibold)}
.crumbs .crumb-here{color:var(--ink);font-weight:var(--fw-semibold)}   /* current level — not a link */
.crumbs .sep{color:var(--line)}
/* config tab panels (Step 2: Configuration off collapsibles, onto the shared tab pattern) */
.cfg-panel{margin-top:var(--sp-2)}
a.link,a.back{color:var(--teal);text-decoration:none}a.back{font-size:13px}
.cards{list-style:none;padding:0;display:flex;gap:16px;flex-wrap:wrap}
.card{background:#fff;border:1px solid var(--line);border-radius:10px;min-width:240px}
.card a{display:block;padding:18px 20px;text-decoration:none;color:var(--ink)}
.card-title{font-weight:600;font-size:17px;color:var(--teal-d)}

/* pacing */
.pacing{background:#fff;border:1px solid var(--line);border-radius:10px;padding:18px 20px}
.bar{height:22px;border-radius:6px;background:#eef2f0;overflow:hidden;display:flex}
.seg{height:100%}
.seg.paid{background:var(--blue)} .seg.accrued{background:var(--mint)}
.legend{display:flex;gap:20px;margin-top:12px;font-size:13px;color:var(--muted)}
.dot{display:inline-block;width:10px;height:10px;border-radius:50%;margin-right:6px;vertical-align:middle}
.dot.paid{background:var(--blue)}.dot.accrued{background:var(--mint)}.dot.budget{background:#c4d2cc}
.metrics{display:flex;gap:16px;margin-top:18px}
.metric{flex:1;background:#fff;border:1px solid var(--line);border-radius:10px;padding:16px 18px}
.metric.flagged{border-color:var(--amber);background:var(--amber-bg)}
.m-val{font-size:22px;font-weight:700;color:var(--teal-d)}
.metric.flagged .m-val{color:var(--amber)}
.m-lbl{color:var(--muted);font-size:13px;margin-top:2px}

/* five filter boxes (they ARE the filter; selected = inverse) */
.boxes{display:flex;gap:12px;margin:18px 0}
.box{flex:1;background:#fff;border:2px solid var(--line);border-radius:10px;padding:14px 16px;text-align:left;cursor:pointer;font:inherit;text-decoration:none;display:block}
.box-lbl{color:var(--muted);font-size:12px;font-weight:700;text-transform:uppercase;letter-spacing:.5px}
.box-amt{font-size:21px;font-weight:700;color:var(--teal-d);margin-top:5px}
.box.on{background:var(--teal);border-color:var(--teal)}
.box.on .box-lbl,.box.on .box-amt{color:#fff}
.box.flagged-box{border-color:var(--amber)}
.box.flagged-box:not(.on) .box-amt{color:var(--amber)}
.box.flagged-box.on{background:var(--amber);border-color:var(--amber)}

/* activity filters + sortable */
.filters{display:flex;gap:8px;margin:12px 0}
.ftab{border:1px solid var(--line);background:#fff;border-radius:7px;padding:5px 13px;cursor:pointer;font:inherit;font-size:13px;color:var(--muted)}
.ftab.on{background:var(--teal);color:#fff;border-color:var(--teal);font-weight:600}
.subtoggle{display:flex;align-items:center;gap:8px;margin:8px 0 4px;font-size:13px}
.sortable th{cursor:pointer;user-select:none}

/* tables — sticky headers (just under the sticky context bar), generous rows, tabular
   right-aligned numbers, status TAGS (pills) rather than full-colour rows. */
/* NB: no `overflow:hidden` here. It would make the table its own scroll container, which makes
   the sticky thead honour `top:var(--ctx-h)` RELATIVE TO THE TABLE — shifting the header ~53px
   down and permanently hiding the first data row on every grid. The viewport must remain the
   thead's scrollport so the header only sticks on scroll. Corners are rounded on the header/last
   cells instead of clipped by overflow. */
.grid{width:100%;border-collapse:collapse;background:var(--surface);border:1px solid var(--line);border-radius:10px}
.grid th,.grid td{padding:12px 14px;border-bottom:1px solid var(--line);text-align:left;vertical-align:top}
.grid th{background:var(--surface-2);color:var(--teal-d);font-size:var(--fs-caption);font-weight:var(--fw-semibold);text-transform:uppercase;letter-spacing:.4px}
.grid thead th{position:sticky;top:var(--ctx-h);z-index:1;box-shadow:inset 0 -1px 0 var(--line)}
.grid thead tr:first-child th:first-child{border-top-left-radius:10px}
.grid thead tr:first-child th:last-child{border-top-right-radius:10px}
.grid tr:last-child td{border-bottom:none}
.num{text-align:right;font-variant-numeric:tabular-nums}
.over{color:var(--amber);font-weight:600}
.reason{color:var(--muted);font-size:13px}

/* pills */
.pill{display:inline-block;padding:2px 9px;border-radius:11px;font-size:12px;font-weight:600;text-transform:capitalize}
.pill.accrued,.pill.pass{background:var(--mint-bg);color:var(--teal-d)}
.pill.flagged,.pill.fail{background:var(--amber-bg);color:var(--amber)}
.pill.paid{background:var(--blue-bg);color:var(--blue)}
.pill.pending{background:var(--blue-bg);color:var(--blue)}
.pill.review{background:var(--review-bg);color:var(--review)}
.pill.unvalidated,.pill.not_applicable{background:#eee;color:#777}
.pill.rejected{background:var(--negative-bg);color:var(--negative)}
.pill.held,.pill.held_term{background:var(--amber-bg);color:var(--amber)}
.pill.reconciling{background:var(--review-bg);color:var(--review)}

/* Decision modals (native <dialog>) — a real modal per action; Cancel closes without submitting,
   so nothing is written. Explanations come from Nif's knowledge catalog. */
dialog.modal{border:none;border-radius:12px;padding:1.25rem 1.5rem;max-width:520px;width:92%;
  box-shadow:0 12px 44px rgba(20,28,38,.28)}
dialog.modal.modal-wide{max-width:660px}
dialog.modal::backdrop{background:rgba(20,28,38,.45)}
dialog.modal h3{margin:0 0 .6rem}
.modal-help{background:var(--mint-bg);border-radius:8px;padding:.6rem .8rem;margin:0 0 1rem;
  font-size:13px;line-height:1.5}
.modal-actions{display:flex;gap:.5rem;justify-content:flex-end;margin-top:1.1rem;flex-wrap:wrap}
.pill.eliminated{background:#eceff1;color:#55606b}

/* dossier */
.summary{display:flex;gap:26px;background:#fff;border:1px solid var(--line);border-radius:10px;padding:16px 20px}
.summary .k{display:block;color:var(--muted);font-size:12px}.summary .v{font-size:19px;font-weight:700}
.struck{text-decoration:line-through;color:var(--muted);font-weight:500}
.kv{border-collapse:collapse}.kv td{padding:5px 16px 5px 0}
.timeline{list-style:none;padding:0;margin:0}
.tl{padding:8px 12px;border-left:3px solid var(--line);margin-left:6px}
.tl-actor{color:var(--muted);font-size:13px;margin-left:6px}.tl-detail{color:var(--muted);margin-left:4px}
.tl-date{color:var(--teal-d);font-size:12px;margin-right:8px}
.tl.validated_accrued{border-color:var(--mint)}
.tl.validated_flagged{border-color:var(--amber)}
.tl.validated_eliminated{border-color:#9aa4ad}
.tl.approved{border-color:var(--blue)}
.tl.rejected{border-color:var(--negative)}
.tl.reconcile_sent{border-color:var(--review)}
.tl.reconcile_conceded{border-color:var(--blue)}
.tl.reconcile_disagreed{border-color:var(--amber);background:var(--amber-bg)}
.actions{margin-top:8px}
.act{display:flex;gap:8px;margin:8px 0}
.act input{padding:7px 10px;border:1px solid var(--line);border-radius:7px;font:inherit}
.act input[name=reason]{flex:1}
.btn{border:0;border-radius:7px;padding:7px 16px;color:#fff;font-weight:600;cursor:pointer;background:var(--teal)}
.btn.approve{background:var(--teal)} .btn.reject{background:var(--negative)} .btn.reconcile{background:var(--review)} .btn.disburse{background:var(--blue)}
.btn.primary{background:var(--teal)}
/* Clear hover/active feedback for solid action buttons + the outlined ghost variant. */
.btn:hover{filter:brightness(.93)}
.btn:active{filter:brightness(.88)}
.closed{opacity:.6}
.choice-note{color:var(--muted);font-size:13px;margin:4px 0 8px}
/* SDR-validation activity context — a dense single-line strip (not a card): blinded ref · site ·
   activity · occurred-at. Tight + tabular so it never grows tall enough to push State History down. */
.sdr-ctx,.item-ident{display:block;margin:2px 0 6px;padding:5px 10px;background:var(--surface-2);
  border:1px solid var(--line);border-radius:8px;font-size:13px;color:var(--ink);
  font-variant-numeric:tabular-nums;white-space:normal;line-height:1.35}
/* A rare exception reported inside a banner about the routine case — present, findable, but
   deliberately not competing with it. `loud` restores the emphasis when it is actually overdue. */
/* Menu-access columns in the permissions matrix: same table, visibly a different KIND of
   permission (what a person can SEE, not what they can DO). */
.matrix th.mx-area{background:var(--surface-2);border-left:2px solid var(--line)}
.matrix td.mx-cell.mx-area{background:rgba(0,0,0,.02);border-left:2px solid var(--line)}
.exception-note{margin:6px 0 0;font-size:12px;color:var(--muted);line-height:1.4}
.exception-note.loud{color:var(--negative);font-size:13px}
/* The CTA term behind a flag: its own line under the reason, hover for the governing wording. */
.cta-evidence{margin:6px 0 0;font-size:13px}
.act select{padding:7px 10px;border:1px solid var(--line);border-radius:7px;font:inherit}
.banner.err{background:var(--negative-bg);color:var(--negative);border:1px solid var(--negative-line);padding:10px 14px;border-radius:8px;margin:10px 0}
.empty{color:var(--muted);background:#fff;border:1px dashed var(--line);border-radius:10px;padding:22px;text-align:center}
.banner.warn{background:var(--amber-bg);color:var(--amber);border:1px solid #e8cfa0;padding:10px 14px;border-radius:8px;margin:10px 0;font-size:13px}
.banner.ok{background:var(--mint-bg);color:var(--teal-d);border:1px solid #b7e3cf;padding:10px 14px;border-radius:8px;margin:10px 0}
.banner.info{background:var(--info-bg);color:var(--info);border:1px solid #bcd6ef;padding:10px 14px;border-radius:8px;margin:10px 0;font-size:13px}

/* A6 master cascading filter — re-housed as the data context bar (Step 2). Distinct from
   the sidebar: the sidebar changes WHICH SECTION; this bar changes WHICH DATA. Behaviour
   (mutual conditional filtering) is unchanged — only the display. */
.contextbar{
  display:flex;align-items:center;gap:var(--sp-3);flex-wrap:wrap;
  background:var(--surface);border-bottom:1px solid var(--line);
  padding:10px var(--sp-5);position:sticky;top:0;z-index:5;
}
.ctx-label{
  font-size:var(--fs-caption);font-weight:var(--fw-semibold);text-transform:uppercase;
  letter-spacing:.5px;color:var(--muted);flex:none;
}
.cascade{display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap}
.cz-portfolio{font-weight:var(--fw-semibold);color:var(--teal);text-decoration:none;padding:5px 12px;border:1px solid var(--line);border-radius:999px;background:var(--surface)}
.cz-portfolio.on,.cz-portfolio:hover{background:var(--teal);color:#fff;border-color:var(--teal)}
.cz-sep{color:var(--muted)}
.cz-sel{padding:6px 12px;border:1px solid var(--line);border-radius:999px;font:inherit;font-size:var(--fs-label);background:var(--surface);min-width:120px;color:var(--ink)}
/* DEMO-ONLY tenant switcher — pushed to the upper-right, and visibly marked as a demo control
   (amber warning treatment) so it is never mistaken for a real product feature. Removed entirely
   under real auth (the markup is gated on synthetic mode). */
.demo-switch{margin-left:auto;display:flex;align-items:center;gap:var(--sp-2);
  padding:4px 8px;border:1px dashed var(--warning);border-radius:10px;background:var(--warning-bg)}
.demo-badge{font-size:10px;font-weight:var(--fw-semibold);letter-spacing:.5px;color:var(--warning);
  text-transform:uppercase;border:1px solid var(--warning);border-radius:6px;padding:1px 6px}
.demo-switch-lbl{display:flex;align-items:center;gap:6px;font-size:var(--fs-caption);
  text-transform:uppercase;letter-spacing:.4px;color:var(--muted)}
.cz-sel:disabled{background:var(--surface-2);color:#aab8b2}
/* Real-auth identity chrome (replaces the demo switcher's spot). */
.user-identity{margin-left:auto;display:flex;align-items:center;gap:var(--sp-2);font-size:var(--fs-caption)}
.user-identity .who{color:var(--ink);font-weight:var(--fw-semibold)}
.role-chip{font-size:10px;text-transform:uppercase;letter-spacing:.4px;color:var(--teal-d);
  border:1px solid var(--line);border-radius:6px;padding:1px 6px}
.user-identity .link{border:none;background:none;color:var(--teal);cursor:pointer;font:inherit;font-size:var(--fs-caption)}
.user-identity .link:hover{text-decoration:underline}
/* Zone A — personal / account cluster (mailbox · notifications · settings), top-right. Reuses the
   established tokens (teal accent, muted/ink, surface, line) — no new palette. */
/* 12px, not 4px. Four was fine when these were bare 32px icons; once each one carries its name
   ("Messages", "Alerts", "Settings") a 4px gap puts one item's TEXT hard against the next item's
   ICON, and they read as one run-on control. */
.acct{margin-left:auto;display:flex;align-items:center;gap:12px}
/* An icon with no words is a control the user cannot identify without hovering and waiting.
   These three (Messages / Alerts / Settings) now carry their name; the label is dropped on narrow
   screens where the icon alone has to do the work. */
.acct-ic{position:relative;display:inline-flex;align-items:center;justify-content:center;gap:6px;
  min-width:32px;height:32px;padding:0 8px;border-radius:8px;border:1px solid transparent;
  background:none;color:var(--muted);cursor:pointer;text-decoration:none}
.acct-lbl{font-size:var(--fs-label);font-weight:var(--fw-semibold);white-space:nowrap}
@media (max-width:1100px){
  .acct-lbl{display:none}
  .acct-ic{padding:0;width:32px}
  .acct{gap:4px}                       /* bare icons need no separation from words */
  .acct-badge{left:auto;right:-2px}    /* square button again - corner anchoring is right here */
}
.acct-ic:hover{background:var(--surface-2);color:var(--ink)}
.acct-ic .ic{width:18px;height:18px}
.acct-ic.lit{color:var(--teal-d)}
/* The count sits on ITS OWN ICON, not at the far right of the button. Anchoring it to `right`
   was correct while the button was a 32px square; with a label the button became several times
   wider, so the badge drifted past the end of the text and landed against the neighbouring
   control - which is what made Messages and Settings look joined. `left` keeps it on the icon
   whatever the label says. */
.acct-badge{position:absolute;top:-2px;left:20px;min-width:15px;height:15px;padding:0 3px;
  border-radius:999px;background:var(--teal);color:#fff;font-size:10px;font-weight:var(--fw-semibold);
  line-height:15px;text-align:center}
.acct-bell{position:relative}
.acct-panel{position:absolute;right:0;top:calc(100% + 6px);width:280px;z-index:20;
  background:var(--surface);border:1px solid var(--line);border-radius:12px;
  box-shadow:0 8px 24px rgba(0,0,0,.10);padding:10px 12px}
.acct-panel-h{font-size:var(--fs-caption);font-weight:var(--fw-semibold);text-transform:uppercase;
  letter-spacing:.5px;color:var(--muted);margin-bottom:6px}
.acct-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:2px}
.acct-list a{display:flex;justify-content:space-between;gap:8px;padding:6px 8px;border-radius:8px;
  color:var(--ink);text-decoration:none;font-size:var(--fs-label)}
.acct-list a:hover{background:var(--surface-2)}
.acct-n{color:var(--teal-d);font-weight:var(--fw-semibold)}
.acct-empty{font-size:var(--fs-label);margin:4px 0}
.acct-all{display:inline-block;margin-top:8px;color:var(--teal);text-decoration:none;
  font-size:var(--fs-label);font-weight:var(--fw-semibold)}
.acct-all:hover{text-decoration:underline}
.acct-foot{margin:8px 0 0;font-size:10px;color:var(--muted);line-height:1.4}
/* Personal settings page */
.settings-grid{display:flex;flex-direction:column;gap:var(--sp-4);max-width:640px}
.settings-card{border:1px solid var(--line);border-radius:12px;padding:var(--sp-4);background:var(--surface)}
.settings-card h2{margin-top:0}
.settings-kv{display:flex;gap:var(--sp-2);font-size:var(--fs-label);color:var(--muted)}
.settings-kv b{color:var(--ink);font-weight:var(--fw-semibold)}
/* Dashboard durable queues — Awaiting you + Flagged (role-aware, persistent). */
.queues{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-4);margin:var(--sp-3) 0 var(--sp-4)}
@media (max-width:820px){.queues{grid-template-columns:1fr}}
.queue{border:1px solid var(--line);border-radius:12px;padding:var(--sp-4);background:var(--surface)}
.q-title{margin:0 0 var(--sp-2)}
.q-list{list-style:none;margin:0 0 var(--sp-2);padding:0;display:flex;flex-direction:column;gap:6px}
.q-item a{display:flex;flex-direction:column;gap:1px;padding:8px 10px;border:1px solid var(--line);
  border-radius:8px;text-decoration:none;color:var(--ink)}
.q-item a:hover{background:var(--surface-2)}
.q-item-title{font-weight:var(--fw-semibold)}
.q-item-detail{font-size:var(--fs-label)}
.q-n{color:var(--teal-d);font-weight:var(--fw-semibold)}
.q-clear{color:var(--muted);font-size:var(--fs-label);padding:6px 0}
/* Intake routing — unassigned (gap) rows in the overview. */
.gap-row{background:var(--warning-bg)}
/* Read-only attribute summary under each review term — surfaces cap/pass-through/SDR/effective
   date that otherwise hide inside Edit, so a reviewer can approve responsibly at a glance. Compact,
   wraps, never eats a column. Shown in both the approve and revise views. */
.attr-summary{display:flex;flex-wrap:wrap;gap:4px 6px;margin-top:5px}
.attr-summary .attr{padding:1px 7px;border-radius:9px;font-size:11px;color:var(--muted);
  background:#f2f4f6;border:1px solid var(--line)}
/* Refused-value list on the review page — born-correct never drops a value silently. */
.refusal-list{margin:6px 0 0;padding-left:20px;font-size:13px}
.refusal-list li{margin:2px 0}
/* Multi-file upload — a named, height-capped scrollable list so 50 files stay clean (each row
   truncates a long filename with an ellipsis; the full name is on hover). */
.bulk-results{list-style:none;margin:6px 0 0;padding:0;max-height:200px;overflow-y:auto;
  border:1px solid var(--line);border-radius:8px}
.bulk-results:empty{display:none}
.bulk-results li{padding:4px 10px;font-size:13px;border-bottom:1px solid var(--line);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.bulk-results li:last-child{border-bottom:none}
/* Multi-column variant — a picked-file list of many files stays compact so the Upload button
   remains above the fold. Rows keep their own line (no cross-column border seams). */
.bulk-results.cols{columns:2 17rem;column-gap:14px;max-height:230px}
.bulk-results.cols li{border-bottom:none;break-inside:avoid}
/* Submitted claims surfaced on the payment surfaces (visible when claimed, before approval). */
.claim-list{list-style:none;margin:6px 0 0;padding:0;max-height:200px;overflow-y:auto;font-size:13px}
.claim-list li{padding:2px 0}
/* Permissions matrix */
.matrix-controls{display:flex;align-items:center;gap:var(--sp-2);margin:10px 0;flex-wrap:wrap}
.matrix-wrap{overflow-x:auto}
table.matrix{border-collapse:collapse;width:100%;font-size:13px}
table.matrix th,table.matrix td{border:1px solid var(--line);padding:6px 8px;text-align:center}
table.matrix th.mx-cap{cursor:pointer;white-space:nowrap;font-size:11px}
table.matrix th.mx-cap:hover{background:var(--surface-2)}
table.matrix .mx-person{text-align:left;min-width:170px}
table.matrix th.mx-gap{background:var(--warning-bg);color:var(--warning)}
.gap-dot{color:var(--warning)}
tr.resp-gap{background:var(--warning-bg)}
.preset-select{margin-top:4px;font-size:11px}
/* Month-end close */
.close-scope{display:flex;gap:8px;align-items:center;margin:10px 0;flex-wrap:wrap}
.close-scope a{text-decoration:none;color:var(--teal);padding:2px 10px;border:1px solid var(--line);border-radius:14px;font-size:12px}
.close-scope a.on{background:var(--teal);color:#fff;border-color:var(--teal)}
.banner.warn{background:var(--warning-bg);border:1px solid var(--warning);color:var(--warning)}
.warn-text{color:var(--warning);font-weight:var(--fw-semibold)}
.blocker-list{list-style:none;padding:0;margin:8px 0}
.blocker{border:1px solid var(--line);border-left:3px solid var(--warning);border-radius:8px;padding:10px 12px;margin:8px 0}
.blk-head{display:flex;gap:10px;align-items:baseline;flex-wrap:wrap}
.close-flow{margin:8px 0;padding-left:18px}
.close-step{padding:6px 8px;border-bottom:1px solid var(--line);display:flex;gap:12px;align-items:baseline;flex-wrap:wrap}
.close-step .cs-label{font-weight:var(--fw-semibold);min-width:200px}
.close-step.is-blocker{background:var(--warning-bg)}
.cs-status{text-transform:capitalize;font-size:12px;color:var(--muted)}
.close-step.status-done .cs-status{color:#2e7d32}
.cs-count{font-size:12px;color:var(--warning)}
.cs-owner{font-size:12px}

/* §3 sites dial is a drill link */
.dial-drill{display:block;text-decoration:none;cursor:pointer}
.dial-drill:hover .dial{filter:brightness(.97)}
.drill-link{display:inline-block;margin-top:6px;font-size:13px}
.site-stats{display:flex;flex-wrap:wrap;gap:18px;margin:8px 0 14px;font-size:14px}
.site-stats .stat{display:flex;align-items:center;gap:6px;color:var(--muted)}
.site-stats .stat b{color:var(--ink)}

/* §4 bulk approve */
.bulkbar{display:flex;align-items:center;gap:12px;margin:6px 0;font-size:13px;color:var(--muted)}
.bulkbar input[type=text]{padding:7px 10px;border:1px solid var(--line);border-radius:7px;font:inherit}
/* Review redesign: three actions (Approve/Edit/Reject) + a type-driven editor. */
.rev-actions{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.rev-edit{margin-top:6px}
.rev-edit>summary{display:inline-block;cursor:pointer;list-style:none}
.rev-edit>summary::-webkit-details-marker{display:none}
.rev-form{margin-top:8px;padding:12px;border:1px solid var(--line);border-radius:9px;background:var(--mint-bg,#f6faf8)}
.rev-form .rev-lab{display:block;font-size:13px;color:var(--muted);margin-bottom:8px}
.rev-fields{display:flex;flex-wrap:wrap;gap:10px 16px;margin-bottom:10px}
.rev-fields .ft-field{display:flex;flex-direction:column;font-size:12px;color:var(--muted);gap:3px}
.rev-fields .ft-field.chk{flex-direction:row;align-items:center;gap:6px}
.nif-hint{font-size:13px;margin:0 0 8px;color:var(--ink)}
/* CP-B: study lifecycle timeline (Dashboard orientation strip). */
.lifecycle{margin:8px 0 4px}
.timeline{list-style:none;display:flex;flex-wrap:wrap;gap:0;margin:6px 0 0;padding:0;align-items:flex-start}
.timeline .tl-step{position:relative;flex:1 1 0;min-width:110px;padding:20px 8px 0;text-align:center;font-size:12px}
.timeline .tl-step::before{content:"";position:absolute;top:7px;left:50%;right:-50%;height:2px;background:var(--line)}
.timeline .tl-step:last-child::before{display:none}
.timeline .tl-dot{position:absolute;top:2px;left:50%;transform:translateX(-50%);width:12px;height:12px;
  border-radius:50%;background:#fff;border:2px solid var(--line)}
.timeline .tl-label{display:block;color:var(--muted);font-weight:600}
.timeline .tl-next{display:block;margin-top:3px;color:var(--teal-d);font-size:11px;line-height:1.3}
.timeline .tl-done .tl-dot{background:var(--mint);border-color:var(--mint)}
.timeline .tl-done .tl-label{color:var(--ink)}
.timeline .tl-done::before{background:var(--mint)}
.timeline .tl-current .tl-dot{background:var(--teal);border-color:var(--teal);box-shadow:0 0 0 4px var(--mint-bg)}
.timeline .tl-current .tl-label{color:var(--teal-d);font-weight:800}
.timeline .tl-unbuilt{opacity:.55}
.timeline .tl-unbuilt .tl-dot{border-style:dashed}
/* CP-B: slim dashboard activity — "new since last login" marker. */
.dash-activity{margin-top:10px}
.new-star{color:var(--teal);font-weight:800}
.period-filter{display:flex;align-items:center;gap:12px;margin:6px 0;font-size:13px;color:var(--muted)}
.period-filter input[type=month]{padding:6px 9px;border:1px solid var(--line);border-radius:7px;font:inherit}
/* CP-C: credentialed add-user + capability checkboxes + bulk responsibility assign. */
.user-add{margin:8px 0}
.user-add>summary{display:inline-block;cursor:pointer;list-style:none;margin-bottom:6px}
.user-add>summary::-webkit-details-marker{display:none}
.cred-form{padding:12px;border:1px solid var(--line);border-radius:9px;background:var(--mint-bg,#f6faf8)}
.cred-row{display:flex;flex-wrap:wrap;gap:10px;margin-bottom:10px}
.cred-row input,.cred-row select{padding:7px 10px;border:1px solid var(--line);border-radius:7px;font:inherit}
.capgrid,.respgrid{border:1px solid var(--line);border-radius:8px;padding:8px 12px;margin:8px 0;
  display:flex;flex-wrap:wrap;gap:6px 18px}
.capgrid legend,.respgrid legend{font-size:12px;color:var(--muted);padding:0 4px}
.capgrid label,.respgrid label{display:flex;align-items:center;gap:6px;font-size:13px}
.bulk-assign{padding:12px;border:1px solid var(--line);border-radius:9px;background:var(--mint-bg,#f6faf8);margin:8px 0}
.bulk-assign .bulk-owner{display:block;font-size:13px;color:var(--muted);margin-bottom:6px}
.gap-list{margin:6px 0}
.gap-list code{background:#eef2f6;padding:1px 5px;border-radius:4px;font-size:12px}
/* CP-D: operator per-sponsor stat tiles. */
.op-stats{display:flex;flex-wrap:wrap;gap:10px;margin:10px 0}
.op-stat{flex:1 1 120px;border:1px solid var(--line);border-radius:9px;padding:10px 12px;text-align:center;background:#fff}
.op-stat .op-n{display:block;font-size:22px;font-weight:800;color:var(--teal-d)}
.op-stat .op-l{display:block;font-size:11px;color:var(--muted);margin-top:2px}
/* Guiding empty state (onboarding prompt) — used where a fresh tenant has no data yet. */
.empty-hero{background:var(--mint-bg,#f6faf8);border:1px dashed var(--line);border-radius:12px;
  padding:28px 24px;text-align:center;margin:12px 0}
.empty-hero h2{margin:0 0 8px;color:var(--teal-d)}
.empty-hero p{max-width:560px;margin:8px auto}
/* CP-D: enrollment-trend chart — faint per-site "part" lines under the bold study line. */
.enroll-chart .etoggle{float:right;font-size:12px}
.en-svg .ln.part{stroke:var(--line);stroke-width:1.2;opacity:.75}
.chart-key .nk.part{background:var(--line)}
/* Source verification: the location labels it; hover reveals the actual document-text excerpt. */
.src-cite{position:relative;cursor:help;border-bottom:1px dotted var(--muted)}
.src-cite .src-pop{display:none;position:absolute;left:0;top:1.5em;z-index:40;min-width:340px;
  max-width:560px;background:#1e2530;color:#eef2f6;border-radius:8px;padding:10px 12px;
  box-shadow:0 8px 24px rgba(0,0,0,.28)}
.src-cite:hover .src-pop{display:block}
.src-cite .src-pop pre{margin:0;white-space:pre-wrap;font-size:12px;line-height:1.4;
  font-family:ui-monospace,Menlo,Consolas,monospace}
.btn:disabled{opacity:.45;cursor:not-allowed}
.btn:disabled:hover{filter:none}   /* keep disabled visibly distinct from active buttons */
.btn.ghost{background:#fff;color:var(--ink);border:1px solid var(--line)}
.btn.ghost:hover{border-color:var(--teal);color:var(--teal);background:var(--mint-bg)}
th.chk,td.chk{width:34px;text-align:center}
.review-badge{display:inline-block;margin-left:8px;padding:1px 8px;border-radius:10px;font-size:11px;font-weight:600;background:var(--amber-bg);color:var(--amber);vertical-align:middle}
.modal-back{display:none;position:fixed;inset:0;background:rgba(20,30,26,.45);align-items:center;justify-content:center;z-index:50}
.modal{background:#fff;border-radius:12px;padding:22px 24px;max-width:440px;box-shadow:0 12px 40px rgba(0,0,0,.25)}
.modal h3{margin:0 0 8px;color:var(--teal-d)}
.modal-actions{display:flex;justify-content:flex-end;gap:10px;margin-top:16px}
/* The MEANING of an attestation (21 CFR 11.50) — the sentence the approver is asserting, shown as
   the quoted statement it is rather than as more body copy, because it is what gets stored. */
.meaning{margin:.7rem 0 0;padding:.6rem .8rem;border-left:3px solid var(--teal-d);
  background:var(--mint-bg);font-style:italic;font-size:13px;line-height:1.5}
/* The §11.50 manifestation on a payment order (CP-5): printed name, time, meaning — one block per
   signature, on the record it authorised. */
.sig-block{margin-top:.8rem;border-top:1px dashed var(--line);padding-top:.6rem}
.sig-block h3{margin:0 0 .4rem;font-size:12px;text-transform:uppercase;letter-spacing:.04em;color:var(--teal-d)}
.sig{margin:.4rem 0 .8rem}
.sig .meaning{margin-top:.4rem}

/* Configuration tab (Sequence 3) */
.grid.roles th.cap,.grid.roles td.cap{text-align:center;width:78px}
.role-name{font-weight:600;color:var(--teal-d)}
.grid.roles .yes{color:var(--teal);font-weight:700}
.grid.roles .no{color:#c4d2cc}
code.cond{background:#eef3f1;color:var(--teal-d);padding:2px 8px;border-radius:6px;font-size:13px}
.cfg-sec{background:#fff;border:1px solid var(--line);border-radius:10px;margin:10px 0}
.cfg-head{cursor:pointer;margin:0;padding:14px 18px;font-size:16px;user-select:none}
.cfg-head:hover{background:#f4f7f5}
.cfg-head .caret{display:inline-block;width:16px;color:var(--teal)}
.cfg-body{padding:0 18px 16px}
.cfg-body h3:first-child{margin-top:6px}
/* Static (non-collapsible) cfg-sec boxes (Intake): pad the box itself so the heading and
   content don't sit flush against the edge — matches the cfg-head/cfg-body padding. */
.cfg-sec.pad{padding:14px 18px 16px}
.cfg-sec.pad > h2:first-child{margin-top:0}
/* parked feature awaiting relocation — visually set apart, not part of the tab set */
.cfg-sec.parked{border-style:dashed;background:var(--surface-2);margin-top:var(--sp-5)}
.doc-type{display:inline-block;padding:2px 9px;border-radius:10px;font-size:12px;font-weight:600;background:var(--blue-bg);color:var(--blue)}
h3{font-size:var(--fs-label);font-weight:var(--fw-semibold);color:var(--teal-d);margin:1.2em 0 .4em}

/* Export bar (Sequence 3) */
.exportbar{display:flex;align-items:center;gap:8px;margin:2px 0 10px;font-size:13px}
.btn-export{display:inline-block;padding:4px 12px;border:1px solid var(--line);border-radius:7px;background:#fff;color:var(--teal);text-decoration:none;font-weight:600;font-size:13px;cursor:pointer}
.btn-export:hover{border-color:var(--teal);background:var(--mint-bg)}

/* patient grid (bingo card) */
.bingo td,.bingo th{vertical-align:middle}
/* Fully-contained data rows, consistent with the header: the status glyphs fall back
   outside Inter, so give the cells room + a comfortable line-height (fixes text clipped
   at the top of short rows). The wide grid opts out of the sticky header — its offset
   under the context bar isn't worth the layout cost on a many-column table. */
.bingo td{line-height:1.5}
.bingo td.cell{padding:10px 6px}
.bingo thead th{position:static;box-shadow:none}
.bingo .vcol{text-align:center;white-space:nowrap}
.bingo .pref{white-space:nowrap;font-size:13px}
.bingo .barcell{min-width:160px;width:200px}
.bingo .barcell .bar{margin:0}
.cell{text-align:center;font-weight:700;width:34px;padding:8px 6px}
.cell .cell-link{text-decoration:none;color:inherit;display:block}
.cell.paid{background:var(--blue-bg);color:var(--blue)}
.cell.accrued{background:var(--mint-bg);color:var(--teal-d)}
.cell.review{background:var(--review-bg);color:var(--review)}
.cell.reconciling{background:var(--review-bg);color:var(--review)}
.cell.eliminated{background:#eceff1;color:#9aa4ad}
.cell.pending{background:#e7f0f9;color:#2f6fb0}
.cell.unvalidated{background:#eef2f0;color:#90a39b}
.cell.flagged{background:var(--amber-bg);color:var(--amber)}
.cell.rejected{background:var(--negative-bg);color:var(--negative)}
.cell.not_reached{background:#fff;color:#d4ddd8}
.cohort-head td{background:#eef3f1;color:var(--teal-d);font-size:12px;text-transform:uppercase;letter-spacing:.4px;padding:7px 12px}
.cohort-summary{cursor:pointer;background:#f7faf8}
.cohort-summary:hover{background:#eef3f1}
.cohort-summary .caret{display:inline-block;width:14px;color:var(--teal)}
.prow.hidden{display:none}
.gridlegend{display:flex;flex-wrap:wrap;gap:16px;margin:16px 0 4px;font-size:13px;color:var(--muted);align-items:center}
.gridlegend .lg{display:flex;align-items:center;gap:7px}
.gridlegend .cell{display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;padding:0;border:1px solid var(--line);border-radius:5px;font-size:12px}
.note{font-size:12px;margin-top:6px}
.note .dot.paid{background:var(--blue)}.note .dot.accrued{background:var(--mint)}

/* ── §3 dashboard "what needs you" lead (F-pattern: highest-stakes, top-left) ─── */
.attention{margin:0 0 var(--sp-5)}
.att-title{font-size:var(--fs-section);font-weight:var(--fw-semibold);color:var(--ink);margin:0 0 var(--sp-3)}
.att-cards{display:flex;gap:var(--sp-3);flex-wrap:wrap}
.att-card{
  display:flex;align-items:center;gap:var(--sp-3);flex:1;min-width:260px;
  background:var(--surface);border:1px solid var(--line);border-left-width:4px;
  border-radius:var(--radius);padding:var(--sp-3) var(--sp-4);text-decoration:none;color:var(--ink);
  box-shadow:var(--shadow-1);transition:box-shadow var(--speed) var(--ease),transform var(--speed) var(--ease);
}
.att-card:hover{box-shadow:var(--shadow-2);transform:translateY(-1px)}
.att-card .att-n{font-size:30px;font-weight:var(--fw-bold);line-height:1;flex:none}
.att-meta{display:flex;flex-direction:column;gap:2px}
.att-lbl{font-weight:var(--fw-semibold);font-size:var(--fs-label)}
.att-amt{color:var(--muted);font-size:var(--fs-label)}
.att-card.flagged{border-left-color:var(--warning)}
.att-card.flagged .att-n{color:var(--warning)}
.att-card.accrued{border-left-color:var(--positive)}
.att-card.accrued .att-n{color:var(--positive-d)}
.att-clear{
  display:flex;align-items:center;gap:var(--sp-2);
  background:var(--positive-bg);border:1px solid var(--positive-line);color:var(--positive-d);
  border-radius:var(--radius);padding:var(--sp-3) var(--sp-4);font-weight:var(--fw-medium);
}
.att-check{font-weight:var(--fw-bold);font-size:16px}

/* ── dashboard dials (Budget / Sites / Forecast) ───────────────────────────── */
.dials{display:flex;gap:16px;flex-wrap:wrap;margin:.6em 0}
.dial-card{flex:1;min-width:240px;background:#fff;border:1px solid var(--line);border-radius:10px;padding:16px 18px}
.dial-card h3{margin:0 0 6px;font-size:14px;text-transform:uppercase;letter-spacing:.5px;color:var(--teal-d)}
.dial{display:block;width:128px;height:128px;margin:6px auto 10px}
.dial-track{stroke:#eef3f1}
.dial-arc{stroke-linecap:butt;transition:stroke-dashoffset .3s}
.dial-top{font-size:21px;font-weight:700;fill:var(--teal-d)}
.dial-sub{font-size:9px;fill:var(--muted);text-transform:uppercase;letter-spacing:.5px}
.forecast-dial .dial-top{font-size:15px}
/* arc + swatch colours share one vocabulary with pills/segments */
.dial-arc.paid,.sw.paid{stroke:var(--blue);background:var(--blue)}
.dial-arc.pending,.sw.pending{stroke:#7ba7d4;background:#7ba7d4}
.dial-arc.accrued,.sw.accrued{stroke:var(--mint);background:var(--mint)}
.dial-arc.flagged,.sw.flagged{stroke:var(--amber);background:var(--amber)}
.dial-arc.projected,.sw.projected{stroke:#cdd9d3;background:#cdd9d3}
.dial-arc.committed,.sw.committed{stroke:var(--teal);background:var(--teal)}
.dial-arc.enrolling,.sw.enrolling{stroke:var(--mint);background:var(--mint)}
.dial-arc.setup,.sw.setup{stroke:var(--amber);background:var(--amber)}
.dial-arc.closed,.sw.closed{stroke:#9fb0aa;background:#9fb0aa}
.sw.budget{background:#c4d2cc}
.dial-legend{list-style:none;margin:0;padding:0;font-size:13px}
.dial-legend li{display:flex;align-items:center;gap:7px;padding:2px 0;color:var(--muted)}
.dial-legend li b{margin-left:auto;color:var(--ink);font-variant-numeric:tabular-nums}
.dial-legend li.tot{border-top:1px solid var(--line);margin-top:4px;padding-top:5px}
.dial-legend li.over b{color:var(--amber)}
.sw{display:inline-block;width:10px;height:10px;border-radius:2px;flex:none}
.dial-flag{margin:8px 0 0;font-size:12px;color:var(--amber);font-weight:600}
.dial-card .note{color:var(--muted)}

/* ── Forecast (Phase F.2): two-needle gauge + live/static total-cost view ─────── */
.forecast{background:#fff;border:1px solid var(--line);border-radius:10px;padding:16px 18px;margin:.6em 0}
.fc-bar{display:flex;align-items:baseline;gap:12px}
.fc-bar h2{margin:0;color:var(--teal-d)}
.fc-meta{color:var(--muted);font-size:12px}
.fc-body{display:flex;gap:22px;flex-wrap:wrap;margin-top:10px}
.fc-gaugewrap{flex:0 0 220px;text-align:center}
.gauge{display:block;width:220px;height:140px;margin:0 auto}
/* snapshot tile: the gauge is a peer to the Budget/Sites donuts (same footprint) */
.dial-card .gauge{width:150px;height:auto;margin:6px auto 6px}
.fc-verdicts{margin:2px 0 4px}
.verdict{display:flex;align-items:baseline;gap:8px;padding:3px 0;font-size:14px}
.verdict .vk{color:var(--muted);font-size:11px;text-transform:uppercase;letter-spacing:.4px;width:52px;flex:none}
.verdict b{font-weight:700;margin-left:auto;font-variant-numeric:tabular-nums}
.verdict.ok b{color:var(--teal)}
.verdict.over b{color:var(--amber)}
.verdict.muted b{color:var(--muted);font-weight:600}
.dial-cap{font-size:11px;text-align:center;margin:2px 0 8px}
/* F.3 forecasting page: Overview / Drivers tabs + the drivers table */
.fc-tabs{display:flex;gap:4px;border-bottom:1px solid var(--line);margin:.6em 0 1em}
.fc-tab{background:none;border:none;border-bottom:2px solid transparent;padding:8px 14px;font-size:14px;font-weight:600;color:var(--muted);cursor:pointer;text-decoration:none}
.fc-tab.on{color:var(--teal-d);border-color:var(--teal)}
.fc-tab.disabled{color:#aebbb5;cursor:not-allowed}
.fc-tab.disabled:hover{color:#aebbb5;background:none}
.grid.drivers td{vertical-align:top}
.self-correct{display:inline-block;font-size:10px;font-weight:600;color:var(--teal-d);background:var(--mint-bg);border-radius:9px;padding:1px 7px;margin-left:4px}
.eff{display:inline-block;font-size:12px;border-radius:5px;padding:2px 7px;margin:1px 4px 1px 0;white-space:nowrap}
.eff.over{background:var(--amber-bg);color:var(--amber)}
.eff.ok{background:var(--mint-bg);color:var(--teal-d)}
.eff.flat{background:#eef3f1;color:var(--muted)}

/* F.4 Earned Value: metric cards + trend / band charts */
.ev-cards{display:flex;flex-wrap:wrap;gap:12px;margin:.4em 0 1.2em}
.ev-card{flex:1;min-width:150px;display:flex;flex-direction:column;gap:2px;background:#fff;border:1px solid var(--line);border-radius:9px;padding:11px 13px;text-decoration:none;color:var(--ink)}
.ev-card:hover{border-color:var(--teal)}
.ev-lbl{font-size:11px;text-transform:uppercase;letter-spacing:.4px;color:var(--teal-d);font-weight:600}
.ev-val{font-size:22px;font-weight:700;font-variant-numeric:tabular-nums}
.ev-sub{font-size:11px;color:var(--muted)}
.ev-src{font-size:11px;color:var(--teal);margin-top:2px}
.ev-charts{display:flex;flex-wrap:wrap;gap:20px}
.chart{flex:1;min-width:280px;margin:0}
.chart.wide{flex-basis:100%}
.chart figcaption{font-size:13px;font-weight:600;color:var(--teal-d);margin-bottom:4px}
.chart svg{width:100%;height:auto;background:#fff;border:1px solid var(--line);border-radius:8px}
.chart .ax{stroke:var(--line);stroke-width:1}
.chart .ref{stroke:#c4cfca;stroke-width:1;stroke-dasharray:3 3}
.chart .ln{stroke-width:2;fill:none}
.chart .ln.cpi,.chart .ln.med{stroke:var(--series-a)}
.chart .ln.spi{stroke:var(--series-b);stroke-dasharray:5 3}
.chart .ln.planned{stroke:#aab8b2;stroke-dasharray:4 3}
.chart .pband{fill:var(--mint);opacity:.22}
.chart-x{display:flex;justify-content:space-between;font-size:11px;color:var(--muted);margin-top:2px}
.chart-key{display:flex;gap:14px;font-size:12px;color:var(--muted);margin-top:3px}
.chart-key .nk{display:inline-block;width:14px;height:3px;border-radius:2px;margin-right:5px;vertical-align:middle}
.nk.cpi,.nk.med{background:var(--series-a)}
.nk.spi{background:repeating-linear-gradient(90deg,var(--series-b) 0 4px,transparent 4px 7px)}
.nk.planned{background:#aab8b2}

/* F.4 Site Performance: spread bar + rescue */
.grid.siteperf tr.rescue{background:var(--amber-bg)}
.spread{display:inline-block;width:84px;height:8px;background:#eef3f1;border-radius:4px;overflow:hidden;vertical-align:middle;margin-right:7px}
.spread-bar{display:block;height:100%}
.spread-bar.star{background:var(--mint)}.spread-bar.on{background:var(--blue)}
.spread-bar.laggard,.spread-bar.idle{background:var(--amber)}
.band-chip{font-size:11px;font-weight:600;border-radius:9px;padding:1px 8px}
.band-chip.star{background:var(--mint);color:#fff}
.band-chip.laggard,.band-chip.idle{background:var(--amber-bg);color:var(--amber)}
.band-chip.on{background:#eef3f1;color:var(--muted)}
.rescue-badge{font-size:11px;font-weight:700;color:var(--amber);margin-left:6px}

/* F.5 Scenarios — the what-if workbench */
.scen-banner{background:var(--mint-bg);border:1px solid var(--mint);border-radius:8px;padding:9px 13px;font-size:13px;color:var(--teal-d);margin:.4em 0 1em}
.scen-grid{display:flex;flex-wrap:wrap;gap:16px}
.scen-card{flex:1;min-width:300px;background:#fff;border:1px solid var(--line);border-radius:10px;padding:14px 16px}
.scen-card.faded{opacity:.72}
.scen-card h4{margin:0 0 2px;font-size:15px;color:var(--teal-d)}
.scen-q{margin:0 0 6px;font-size:13px;font-weight:600}
.scen-in{margin:0 0 8px;font-size:12px;color:var(--muted)}
.scen-rows{list-style:none;margin:0 0 8px;padding:0}
.scen-rows li{display:grid;grid-template-columns:auto auto 1fr;align-items:baseline;gap:8px;padding:3px 0;border-top:1px solid var(--line)}
.scen-rows li:first-child{border-top:none}
.sr-lbl{font-size:13px;color:var(--muted)}
.scen-rows b{font-size:15px;font-variant-numeric:tabular-nums}
.scen-rows b.ok{color:var(--teal)}.scen-rows b.over{color:var(--amber)}.scen-rows b.flat{color:var(--ink)}
.sr-sub{font-size:11px;color:var(--muted);text-align:right}
.scen-note{font-size:11px;color:var(--muted);margin:6px 0 8px;line-height:1.45}
.gz.good{stroke:#e3f1ea}.gz.over{stroke:#f6e6cf}
.gband{stroke:var(--amber);opacity:.5;stroke-linecap:round}
.gtick{stroke:var(--muted);stroke-width:1.5}
.gneedle{stroke-linecap:round}
.gneedle.time{stroke:var(--series-a);stroke-width:3}
.gneedle.budget{stroke:var(--series-b);stroke-width:3;stroke-dasharray:4 3}
.ghub{fill:var(--ink)}
.gscale{font-size:7px;fill:var(--muted);text-transform:uppercase;letter-spacing:.4px}
.gauge-key{display:flex;justify-content:center;gap:14px;font-size:12px;color:var(--muted);margin-top:2px}
.gauge-key .nk{display:inline-block;width:14px;height:3px;border-radius:2px;margin-right:5px;vertical-align:middle}
.nk.time{background:var(--series-a)}
.nk.budget{background:repeating-linear-gradient(90deg,var(--series-b) 0 4px,transparent 4px 7px)}
.nk.band{background:var(--amber);opacity:.5}
.fc-col{flex:1;min-width:240px}
.fc-col h4{margin:0 0 6px;font-size:13px;text-transform:uppercase;letter-spacing:.4px;color:var(--teal-d);display:flex;align-items:center;gap:8px}
.fc-col.primary{background:var(--mint-bg);border-radius:8px;padding:10px 12px;margin:-4px 0}
.scope{font-size:10px;font-weight:600;color:var(--muted);background:#eef3f1;border-radius:9px;padding:2px 8px;letter-spacing:.3px}
.scope.live{background:var(--mint);color:#fff}
.fc-list{list-style:none;margin:0;padding:0;font-size:13px}
.fc-list li{display:flex;align-items:center;gap:7px;padding:2px 0;color:var(--muted)}
.fc-list li b{margin-left:auto;color:var(--ink);font-variant-numeric:tabular-nums}
.fc-list li.tot{border-top:1px solid var(--line);margin-top:4px;padding-top:5px}
.fc-list b.over{color:var(--amber)}.fc-list b.ok{color:var(--teal)}
.fc-list .cl-lbl{display:flex;align-items:center;gap:6px}
.srcbadge{font-style:normal;font-size:9px;font-weight:700;letter-spacing:.4px;border-radius:4px;padding:1px 5px}
.srcbadge.live{background:var(--mint);color:#fff}
.srcbadge.static{background:#e4ebe8;color:var(--muted)}
.forecast .note{color:var(--muted);font-size:12px;margin:8px 0 0}
/* site lifecycle table */
.grid.sites td .muted{font-weight:400;font-size:12px;margin-left:4px}
.grid.sites tr.gap{background:var(--amber-bg)}
.stage{display:inline-block;padding:2px 9px;border-radius:11px;font-size:12px;font-weight:600}
.stage.setup{background:var(--amber-bg);color:var(--amber)}
.stage.enrolling{background:var(--mint-bg);color:var(--teal-d)}
.stage.closed{background:#eceff1;color:#55606b}
.stage.pending{background:#eee;color:#777}
.empty{color:var(--muted);text-align:center;padding:16px}
/* source-of-truth requirement badges (Eligibility Hub, Group B) */
.sot{display:inline-block;padding:2px 9px;border-radius:11px;font-size:12px;font-weight:600}
.sot.edc_sdr{background:var(--review-bg);color:var(--review)}
.sot.edc_condition{background:var(--amber-bg);color:var(--amber)}
.sot.edc_alone{background:var(--mint-bg);color:var(--teal-d)}
.onb{display:inline-block;padding:2px 9px;border-radius:11px;font-size:12px;font-weight:600}
.onb.new{background:var(--mint-bg);color:var(--teal-d)}
.onb.rescue{background:var(--amber-bg);color:var(--amber)}
.onb.reconciliation{background:var(--review-bg);color:var(--review)}
.rem-form{display:grid;grid-template-columns:1fr 1fr;gap:12px 18px;max-width:680px;margin:14px 0}
.rem-form label{display:flex;flex-direction:column;font-size:13px;font-weight:600;gap:4px}
.rem-form input{padding:7px 9px;border:1px solid var(--line);border-radius:6px;font:inherit;font-weight:400}
.rem-form .req{color:var(--negative)}
.rem-actions{grid-column:1 / -1}
.inv-form{margin:12px 0 6px}
.inv-head{display:flex;flex-wrap:wrap;gap:10px 16px;margin-bottom:10px}
.inv-head label{display:flex;flex-direction:column;font-size:12px;font-weight:600;gap:3px}
.inv-head input,.inv-head select,.inv-lines input,.inv-lines select{padding:6px 8px;border:1px solid var(--line);border-radius:6px;font:inherit;font-weight:400}
.inv-lines input{width:100%}
.inv-actions{display:flex;align-items:center;gap:12px;margin:8px 0}
.inv-card{border:1px solid var(--line);border-radius:8px;padding:12px;margin:10px 0}
.inv-card-head{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:8px}
.inv-total{margin-left:auto;font-variant-numeric:tabular-nums;font-weight:600}
.dup-ctx{margin-top:5px;padding:6px 8px;border-left:3px solid var(--amber);background:var(--amber-bg);color:var(--amber);font-size:12px;border-radius:0 4px 4px 0}
.cap-meter{display:inline-block;margin-top:4px;padding:1px 7px;font-size:11px;font-weight:600;border-radius:10px;background:var(--chip-bg,#eef1f5);color:var(--muted,#5a6472);border:1px solid var(--border,#d6dbe2)}
.cap-meter.over{background:var(--amber-bg);color:var(--amber);border-color:var(--amber)}
.commit-pending{margin:0 0 16px;padding:14px 16px;border:1px solid var(--border,#d6dbe2);border-radius:8px;background:var(--card-bg,#fff)}
.commit-pending .cp-pair{display:flex;align-items:stretch;gap:14px;flex-wrap:wrap}
.commit-pending .cp{flex:1 1 240px;min-width:220px;display:flex;flex-direction:column;gap:3px;padding:10px 12px;border-radius:6px}
.commit-pending .cp.committed{background:var(--green-bg,#eaf6ee);border:1px solid var(--green,#2e7d46)}
.commit-pending .cp.pending{background:var(--amber-bg,#fdf3e3);border:1px solid var(--amber,#a86b00)}
.commit-pending .cp.pending.none{background:var(--chip-bg,#eef1f5);border-color:var(--border,#d6dbe2)}
.commit-pending .cp-plus{align-self:center;font-size:22px;font-weight:700;color:var(--muted,#5a6472)}
.commit-pending .cp-lbl{font-size:12px;font-weight:600;text-transform:uppercase;letter-spacing:.03em}
.commit-pending .cp-val{font-size:22px;font-weight:700}
.commit-pending .cp-count{font-size:13px;font-weight:600;color:var(--muted,#5a6472)}
.commit-pending .cp-note{font-size:11px;color:var(--muted,#5a6472)}
.commit-pending .cp-breakdown{margin:10px 0 0;padding:0;list-style:none;display:flex;flex-wrap:wrap;gap:6px 16px}
.commit-pending .cp-breakdown a{font-size:12px;color:var(--muted,#5a6472);text-decoration:none;border-bottom:1px dotted currentColor}
.commit-pending .cp-empty{margin:10px 0 0;font-size:12px}
.op-rollup{display:flex;flex-wrap:wrap;gap:10px 22px;margin:6px 0 4px}
.op-rollup > div{display:flex;flex-direction:column}
.op-rollup .op-k{font-size:11px;text-transform:uppercase;letter-spacing:.03em;color:var(--muted,#5a6472)}
.op-rollup .op-v{font-size:18px;font-weight:700}
.op-rollup .op-v.over{color:var(--amber,#a86b00)}
.op-secrets{display:flex;flex-wrap:wrap;gap:6px}
.sec-chip{font-size:11px;font-weight:600;padding:1px 8px;border-radius:10px;border:1px solid var(--border,#d6dbe2)}
.sec-chip.on{background:var(--green-bg,#eaf6ee);color:var(--green,#2e7d46);border-color:var(--green,#2e7d46)}
.sec-chip.off{background:var(--chip-bg,#eef1f5);color:var(--muted,#5a6472)}
@media (prefers-color-scheme:dark){
  .commit-pending .cp.committed{background:rgba(46,125,70,.16)}
  .commit-pending .cp.pending{background:rgba(168,107,0,.18)}
}
.rpt-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:12px;margin:10px 0 20px}
.rpt-card{display:flex;flex-direction:column;gap:4px;border:1px solid var(--line);border-radius:8px;padding:12px 14px;text-decoration:none;color:inherit}
.rpt-card:hover{border-color:var(--primary)}
.rpt-card.disabled{opacity:.55;cursor:not-allowed}
.rpt-na{font-size:11px;color:var(--amber)}
.rpt-out{list-style:none;margin:0;padding:0}
.rpt-out li{padding:5px 0;border-bottom:1px solid var(--line)}
.rpt-params{display:flex;gap:14px;align-items:flex-end;margin:10px 0}
.rpt-params label{display:flex;flex-direction:column;font-size:12px;font-weight:600;gap:3px}
.rpt-params input,.rpt-params select{padding:6px 8px;border:1px solid var(--line);border-radius:6px;font:inherit;font-weight:400}
.rpt-bar{display:flex;align-items:center;justify-content:space-between;gap:12px;margin:8px 0}
.rpt-bar input{padding:7px 10px;border:1px solid var(--line);border-radius:6px;min-width:240px;font:inherit}
.rpt-cols{display:flex;flex-wrap:wrap;align-items:center;gap:10px 16px;margin:8px 0;font-size:13px}
.rpt-cols select{padding:6px 8px;border:1px solid var(--line);border-radius:6px;font:inherit}
.rpt-dirty{color:var(--amber);font-weight:600}
.col-del{margin-left:6px;color:var(--negative);text-decoration:none;font-weight:700;cursor:pointer}
.col-del:hover{color:var(--negative)}
.contact-actions{white-space:nowrap}
.override-box{border:1px solid #e8cfa0;background:var(--amber-bg);border-radius:8px;padding:10px 12px;margin:8px 0}
.override-why{margin:6px 0;font-size:13px}
.rpt-save{margin-top:16px}
.rpt-save-form{display:flex;flex-wrap:wrap;gap:12px;align-items:flex-end;margin-top:8px}
.rpt-save-form label{display:flex;flex-direction:column;font-size:12px;font-weight:600;gap:3px}
.rpt-save-form input,.rpt-save-form select{padding:6px 8px;border:1px solid var(--line);border-radius:6px;font:inherit;font-weight:400}
.pi-card{border:1px solid var(--line);border-radius:8px;padding:8px 12px;margin:8px 0}
.pi-card summary{cursor:pointer;font-weight:600}
.pi-form{display:flex;flex-wrap:wrap;gap:10px 16px;margin-top:10px}
.pi-form label{display:flex;flex-direction:column;font-size:12px;font-weight:600;gap:3px}
.pi-form input,.pi-form select{padding:6px 8px;border:1px solid var(--line);border-radius:6px;font:inherit;font-weight:400}
.pi-form .pi-addr{flex:1 1 100%}
.pi-actions{flex:1 1 100%}
.rpt-th-drag{cursor:grab}
.ps-metrics{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:12px;margin:12px 0}
.ps-card{border:1px solid var(--line);border-radius:8px;padding:12px 14px}
.ps-card h3{margin:0 0 6px;font-size:13px;color:var(--muted)}
.ps-big{font-size:22px;font-weight:600;font-variant-numeric:tabular-nums}
.ps-flag{color:var(--negative);font-weight:600;margin:4px 0 0}
.pos{color:var(--positive)}
.ps-learnings{margin:8px 0;padding-left:20px}
.ps-learnings li{padding:4px 0}
.rem-doc{max-width:780px}
.rem-head{display:flex;justify-content:space-between;align-items:flex-start;gap:16px;border-bottom:2px solid var(--primary);padding-bottom:10px;margin-bottom:14px}
.rem-sponsor h1{margin:0 0 2px}
.rem-facts{border-collapse:collapse;margin:8px 0 4px;width:100%}
.rem-facts th{text-align:left;color:var(--muted);font-weight:600;padding:3px 12px 3px 0;width:1%;white-space:nowrap;font-size:13px}
.rem-facts td{padding:3px 24px 3px 0;font-size:13px}
.rem-totals td{padding:5px 8px}
.rem-totals .rem-net td{border-top:2px solid var(--line)}
.holdback-list{list-style:none;margin:0;padding:0}
.holdback-list li{padding:6px 0;border-bottom:1px solid var(--line);font-size:14px}
.holdback-list li:last-child{border-bottom:0}

/* ═══════════════════════════════════════════════════════════════════════════
   COMPONENT STATES + ACCESSIBILITY (Step 1) — one defined set of interactive
   states (hover / active / disabled / focus) applied consistently, plus visible
   keyboard focus and restrained motion. Defined once here; inherited everywhere.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Visible keyboard focus on every interactive control (zero-specificity :where so
   it never fights component rules — it only adds the ring). */
:where(a, button, select, input, textarea, summary, [tabindex]):focus-visible{
  outline:2px solid var(--primary);
  outline-offset:2px;
  border-radius:var(--radius-sm);
}

/* Restrained transitions on the things that change state. */
.btn, .btn-export, .box, .ftab, .fc-tab, .card, .dial-card, .ev-card, .scen-card,
.metric, .cz-sel, .cz-portfolio, .dial-drill, a.link, a.back{
  transition:border-color var(--speed) var(--ease),
             background-color var(--speed) var(--ease),
             box-shadow var(--speed) var(--ease),
             transform var(--speed) var(--ease),
             color var(--speed) var(--ease);
}

/* Surfaces get gentle depth so cards read as discrete, premium objects. */
.card, .dial-card, .ev-card, .scen-card, .metric, .forecast, .pacing, .summary{
  box-shadow:var(--shadow-1);
}

/* Cards — clickable ones lift on hover; the affordance is unmistakable. */
.card:hover{border-color:var(--primary);box-shadow:var(--shadow-2)}
.dial-card:hover, .ev-card:hover{box-shadow:var(--shadow-2);transform:translateY(-1px)}
.ev-card:hover{border-color:var(--primary)}

/* Filter boxes / tab buttons — clear, consistent hover (the "looked inactive" fix). */
.box:hover:not(.on){border-color:var(--primary)}
.box:active{transform:translateY(1px)}
.ftab:hover:not(.on), .fc-tab:hover:not(.on){color:var(--ink);background:var(--surface-2)}

/* Dropdowns. */
.cz-sel:hover:not(:disabled){border-color:var(--primary)}

/* Tables — a defined row-hover state + right-aligned tabular numbers (already tnum). */
.grid tbody tr:hover{background:var(--surface-2)}

/* Links underline on hover/focus for unambiguous affordance. */
a.link:hover, a.back:hover, a.link:focus-visible, a.back:focus-visible{text-decoration:underline}

/* Disabled is always visibly distinct and inert. */
button:disabled, .btn:disabled, [aria-disabled="true"]{opacity:.5;cursor:not-allowed}

/* ── Site Communication System ───────────────────────────────────────────────
   The hosted, site-facing action page (public — no app chrome). */
body.hosted{background:var(--bg);display:flex;justify-content:center;align-items:flex-start;padding:40px 16px}
.hosted-card{background:#fff;border:1px solid var(--line);border-radius:var(--radius);max-width:520px;
  width:100%;padding:28px 30px;box-shadow:0 8px 30px rgba(27,42,38,.12)}
.hosted-brand{display:flex;align-items:center;gap:8px;font-weight:var(--fw-semibold);color:var(--primary-d);
  margin-bottom:14px}
.hosted-brand .brand-mark{background:var(--mint);color:var(--primary-d);width:26px;height:26px;
  border-radius:6px;display:inline-flex;align-items:center;justify-content:center;font-size:12px;font-weight:800}
.hosted-terms{margin:14px 0}
.hosted-actions{margin:16px 0 8px}
.hosted-dispute{margin-top:12px;border-top:1px solid var(--line);padding-top:12px;display:flex;
  flex-direction:column;gap:7px;align-items:flex-start}
.hosted-dispute textarea{width:100%;border:1px solid var(--line);border-radius:8px;padding:8px;font:inherit}
.hosted-foot{margin-top:18px;font-size:11px;color:var(--muted)}
/* Compose + review forms (sponsor side). */
.comm-cta{margin:10px 0 4px}
.comm-trigger{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.comm-link{border:none;background:none;padding:0;color:var(--teal);cursor:pointer;font:inherit;font-size:13px}
.comm-link:hover{text-decoration:underline}
.comm-form fieldset,.comm-edit label{display:block;margin:14px 0;border:1px solid var(--line);
  border-radius:9px;padding:12px 14px}
.comm-form legend,.comm-edit label{font-weight:var(--fw-semibold);color:var(--teal-d)}
.comm-form label{display:inline-flex;align-items:center;gap:6px;margin-right:16px;font-weight:400}
.comm-form textarea,.comm-edit textarea,.comm-edit input[type=text]{width:100%;border:1px solid var(--line);
  border-radius:8px;padding:8px 10px;font:inherit;margin-top:6px}
.comm-newcontact{margin-top:10px}.comm-newcontact input,.comm-newcontact select{margin:4px 6px 0 0}
.comm-sent{white-space:pre-wrap;background:var(--surface-2);border:1px solid var(--line);border-radius:8px;
  padding:12px;font:inherit;font-size:13px;line-height:1.45}
/* Attachments (user-chosen documents, both directions). */
.doc-list{list-style:none;margin:8px 0;padding:0}
.doc-list .doc{display:flex;align-items:baseline;gap:8px;padding:5px 0}
.doc-dir{font-size:11px;font-weight:var(--fw-semibold);color:var(--teal-d);min-width:96px}
.doc-upload,.hosted-upload{margin-top:12px;border-top:1px solid var(--line);padding-top:12px;
  display:flex;flex-direction:column;gap:7px;align-items:flex-start}
.hosted-docs{margin-top:14px}
.hosted-note{background:var(--surface-2);border:1px solid var(--line);border-radius:8px;
  padding:10px 12px;margin-bottom:12px;font-size:13px;color:var(--teal-d)}
/* MFA enrollment QR — centered, framed, on white so authenticator apps scan cleanly. */
.mfa-qr{display:flex;justify-content:center;margin:14px 0}
.mfa-qr svg{width:200px;height:200px;background:#fff;border:1px solid var(--line);
  border-radius:8px;padding:8px}

/* ── Nif AI Advisor panel (Phase 2) ──────────────────────────────────────────
   Fixed bottom-right (floats over the layout — never reflows content). Design-system tokens. */
.nif{position:fixed;right:20px;bottom:20px;z-index:90;font-size:14px}
/* "Explain this" — deliberately the quietest interactive thing on the page. This is a finance
   surface: the numbers are the content, and a loud control next to every figure would compete with
   them. It sits at --muted, shows its intent on hover/focus, and never takes layout space away from
   the value it annotates. Keyboard-reachable like any button. */
.nif-x{margin-left:6px;padding:0;width:15px;height:15px;line-height:13px;flex:0 0 auto;
  border:1px solid var(--line);border-radius:50%;background:transparent;color:var(--muted);
  font-size:10px;font-weight:600;cursor:pointer;vertical-align:middle;opacity:.55;
  transition:opacity .12s ease,color .12s ease,border-color .12s ease}
.nif-x:hover,.nif-x:focus-visible{opacity:1;color:var(--primary-d);border-color:var(--primary-d)}
.nif-x:focus-visible{outline:2px solid var(--primary-d);outline-offset:1px}
/* An EV card's whole body is a drill link, so the control sits in a positioned CELL beside it
   rather than inside it - siblings in the DOM, one card to the eye. */
.ev-cell{position:relative;flex:1;min-width:150px;display:flex}
.ev-cell>.ev-card{flex:1}
.ev-cell>.nif-x{position:absolute;top:7px;right:7px;margin:0}

.nif-mark{display:inline-flex;align-items:center;justify-content:center;width:26px;height:26px;
  flex:none;border-radius:50%;background:var(--mint);color:var(--primary-d);font-weight:800;
  font-size:13px}
/* Visibility: the small launcher OR the panel, switched by body.nif-open (set by the early inline
   script + JS). Default = COLLAPSED (launcher only) so content stays unobstructed until called. */
.nif-backdrop{display:none}
.nif-launch{display:inline-flex;align-items:center;gap:7px;padding:8px 14px 8px 8px;
  border:none;border-radius:999px;background:var(--primary);color:#fff;cursor:pointer;
  font:inherit;font-size:13px;font-weight:var(--fw-semibold);box-shadow:0 4px 14px rgba(15,110,86,.30)}
.nif-launch:hover{background:var(--primary-d)}
.nif-launch .nif-mark{width:22px;height:22px;font-size:12px;background:#fff;color:var(--primary-d)}
/* Compact side panel — smaller footprint so it feels helpful, not dominant. */
.nif-panel{display:none;flex-direction:column;width:300px;max-width:calc(100vw - 32px);
  height:400px;max-height:calc(100vh - 32px);background:var(--surface);border:1px solid var(--line);
  border-radius:var(--radius);box-shadow:0 12px 40px rgba(27,42,38,.22);overflow:hidden}
body.nif-open .nif-launch{display:none}
body.nif-open .nif-panel{display:flex}
.nif-head{display:flex;align-items:center;gap:7px;padding:9px 11px;background:var(--primary-d);
  color:#fff}
.nif-title{display:flex;flex-direction:column;line-height:1.1;font-weight:var(--fw-semibold);flex:1;
  min-width:0}
.nif-sub{font-size:11px;font-weight:var(--fw-regular);color:#cfe7dd}
.nif-voice,.nif-new{flex:none;border:1px solid rgba(255,255,255,.5);background:transparent;color:#fff;
  border-radius:999px;padding:3px 9px;font:inherit;font-size:12px;cursor:pointer}
.nif-voice[aria-pressed="true"]{background:var(--mint);color:var(--primary-d);border-color:var(--mint)}
.nif-wake{flex:none;border:1px solid rgba(255,255,255,.5);background:transparent;border-radius:999px;
  padding:2px 6px;font-size:13px;line-height:1;cursor:pointer}
.nif-wake[aria-pressed="true"]{background:var(--mint);border-color:var(--mint)}
.nif-min{flex:none;border:none;background:transparent;color:#fff;font-size:16px;cursor:pointer;padding:2px 4px}
.nif-log{flex:1;overflow-y:auto;padding:12px;display:flex;flex-direction:column;gap:8px;
  background:var(--bg)}
.nif-msg{max-width:85%;padding:8px 11px;border-radius:12px;white-space:pre-wrap;line-height:1.4}
.nif-user{align-self:flex-end;background:var(--primary);color:#fff;border-bottom-right-radius:3px}
.nif-nif{align-self:flex-start;background:#fff;border:1px solid var(--line);color:var(--ink);
  border-bottom-left-radius:3px}
/* Input row must fit the compact (300px) panel with NOTHING clipped: the text box flexes and is
   allowed to shrink (min-width:0 — otherwise its content width pushes the round Send button off the
   right edge), and the mic/Send circles are trimmed slightly so all three sit balanced in the row. */
.nif-form{display:flex;align-items:center;gap:5px;padding:8px;border-top:1px solid var(--line)}
.nif-input{flex:1;min-width:0;border:1px solid var(--line);border-radius:999px;padding:8px 11px;
  font:inherit;color:var(--ink)}
.nif-input:focus{outline:2px solid var(--primary-bg);border-color:var(--primary)}
.nif-mic,.nif-send{flex:none;width:32px;height:32px;border:none;border-radius:50%;cursor:pointer;
  font:inherit;font-size:14px;line-height:1;padding:0}
.nif-mic{background:var(--surface-2);color:var(--ink)}
.nif-send{background:var(--primary);color:#fff;font-weight:700}
.nif-send:hover,.nif-mic:hover{filter:brightness(.95)}
.nif-foot{margin:0;padding:6px 12px 10px;font-size:11px;color:var(--muted);background:var(--surface)}
/* Usage health meter — a soft, muted transparency line; never prominent or anxiety-inducing. */
.nif-meter{display:block;margin-top:3px;font-size:10px;color:var(--muted);opacity:.8}
/* Small screens (deliberate): she starts collapsed (forced by the inline script's width guard);
   when expanded she OVERLAYS as a dismissible panel — fixed and capped to the viewport so the
   layout is never pushed and there is NO horizontal scroll. A backdrop dims content + dismisses. */
@media (max-width:760px){
  .nif{right:12px;bottom:12px;left:auto}
  body.nif-open .nif-backdrop{display:block;position:fixed;inset:0;background:rgba(15,42,36,.35);z-index:89}
  body.nif-open .nif-panel{position:fixed;left:10px;right:10px;bottom:10px;top:auto;width:auto;
    max-width:none;height:min(72vh,440px);z-index:90}
}

/* Respect reduced-motion preferences. */
@media (prefers-reduced-motion: reduce){
  *, *::before, *::after{transition:none !important; animation:none !important}
}

/* Round-2 #5 — SOURCE column badges (EDC · INVOICE · SPONSOR-CREATED). Same vocabulary the patient
   grid uses, so origin reads consistently across surfaces. */
.src-badge{font-size:.68rem;font-weight:600;letter-spacing:.02em;padding:1px 6px;border-radius:3px;
  white-space:nowrap;border:1px solid transparent}
.src-edc{background:#e8f0fe;color:#1a56c4;border-color:#c3d7fb}
.src-invoice{background:#fef1e0;color:#9a5b00;border-color:#f3d6a3}
.src-sponsorcreated{background:#eeeef4;color:#4a4a5a;border-color:#dadae4}
@media (prefers-color-scheme: dark){
  .src-edc{background:#16233f;color:#8fb4ff;border-color:#274372}
  .src-invoice{background:#3a2a10;color:#e6b877;border-color:#5c431c}
  .src-sponsorcreated{background:#26262e;color:#b4b4c4;border-color:#3a3a46}
}

/* Round-2 #c — patient-grid DOUBLE-PAY conflict cell: a visit with two payments must SHOUT, never a
   quiet single tick. Distinct from every status glyph. */
.cell.conflict{background:#c0392b;color:#fff;font-weight:700;border:2px solid #7d1f16}
.cell.conflict .cell-link{color:#fff}
@media (prefers-color-scheme: dark){
  .cell.conflict{background:#e04a3a;color:#1a1a1a;border-color:#ff8f80}
  .cell.conflict .cell-link{color:#1a1a1a}
}

/* ── Info affordance (see templates/_info.html) ─────────────────────────────────────────────────
   Replaces permanent paragraphs of help text under headers. Quiet enough to ignore, present enough
   to find. Shown three independent ways so no input method is excluded: :hover (mouse),
   :focus-within (keyboard), and .open (touch/click, set by uftInfo). The first two are pure CSS, so
   help survives a JavaScript failure. */
.info{position:relative;display:inline-block;vertical-align:middle;margin-left:6px;line-height:1}
.info-btn{width:16px;height:16px;padding:0;border-radius:50%;border:1px solid var(--line);
  background:none;color:var(--muted);font-size:11px;font-weight:var(--fw-semibold);
  font-style:italic;line-height:14px;text-align:center;cursor:help;vertical-align:middle}
.info-btn:hover{background:var(--surface-2);color:var(--ink);border-color:var(--muted)}
/* A visible focus ring: keyboard users must be able to SEE where they are. */
.info-btn:focus-visible{outline:2px solid var(--teal);outline-offset:1px;color:var(--ink)}
.info-bubble{position:absolute;left:0;top:calc(100% + 6px);z-index:60;display:none;
  width:max-content;max-width:320px;padding:8px 10px;border:1px solid var(--line);border-radius:8px;
  background:var(--surface);color:var(--ink);box-shadow:0 6px 18px rgba(0,0,0,.12);
  font-size:var(--fs-label);font-weight:400;font-style:normal;line-height:1.45;
  white-space:normal;text-align:left;text-transform:none;letter-spacing:normal}
.info:hover .info-bubble,
.info:focus-within .info-bubble,
.info.open .info-bubble{display:block}
/* Near the right edge the bubble would overflow the viewport; flip it to hang leftward. */
.info.flip .info-bubble{left:auto;right:0}
@media (max-width:700px){.info-bubble{max-width:min(320px,78vw)}}

/* ── operator ribbon — the platform operator is inside this sponsor's app under a logged grant.
   Deliberately loud and deliberately NOT the app's palette: it must never blend into a page the
   operator's brain has filed as "the customer app". Sponsor users never see it (see base.html). */
.op-ribbon{position:sticky;top:0;z-index:1000;display:flex;align-items:center;gap:14px;
  padding:8px 16px;background:#0f1614;color:#e6efec;border-bottom:3px solid #4fd1a5;font-size:13px}
.op-ribbon-mark{background:#4fd1a5;color:#062117;font-weight:700;font-size:11px;letter-spacing:.08em;
  padding:2px 8px;border-radius:3px;white-space:nowrap}
.op-ribbon-text{flex:1}
.op-ribbon-exit{margin:0}
.op-ribbon-btn{background:transparent;color:#e6efec;border:1px solid #4fd1a5;border-radius:4px;
  padding:4px 12px;font:inherit;cursor:pointer;white-space:nowrap}
.op-ribbon-btn:hover{background:#4fd1a5;color:#062117}

/* CP-3: the reason field every sponsor-side config verb now requires. Sized so it reads as part of
   the form rather than an afterthought bolted on the end — a field people resent is a field that
   gets filled with "update". */
.cfg-why{min-width:12rem;flex:1 1 14rem}
