/* ============================================================
   HT-006 — the calm chart's ONE token set, in two modes.

   R-024 collapsed three light themes to a Light/Dark pair on one --q-* palette with the legacy names
   aliased onto it. HT-006 RE-AUTHORS the values of that same structure; it does not replace it. Every
   name below already existed or is new — no name was deleted — which is why ~600 rules across the
   modals, drawers, ledger, calendar and sign-in screen took the new palette without an edit.

   Two layers, and the order still matters:
     1. the --q-* palette and the --tok-* token species hues — the design's own names;
     2. the LEGACY names (--accent --bg --panel --head --border --text --dim --faint --ok --okSoft
        --warn --warnSoft --danger --dangerSoft --note --img --imgSoft --shadow --rad --fUi --fHead
        --fData) mapped ONTO them.

   HT-006's four rules, and where each one lives here:

   ONE ACCENT. --q-accent and --q-link are the same blue. Selection, links and the single primary
   action are that blue; nothing else is. --q-edge and --q-line are aliases of it, kept because rules
   name them.

   COLOUR CARRIES MEANING. Exactly three token hues (--tok-vit violet, --tok-dx terracotta, --tok-rx
   green) plus the two the visit table needs (--tok-order, --tok-fu), and three status tints
   (--q-warn = in progress, --q-ok = signed, --q-bad = record/danger). Nothing else is coloured.

   THE VITALS COLLAPSE. R-024 gave every vital its own hue (--tok-bp crimson, --tok-hr teal, …);
   HT-006 gives vitals ONE violet, because nine hues in a row is the noise the handoff was written
   against. The nine names SURVIVE as aliases of --tok-vit rather than being deleted: .hct-v.hct-bp
   and its eight siblings still resolve, so the token CSS and any future per-vital treatment keep a
   name to hang on. Re-hue --tok-vit and every vital follows.

   THREE SURFACES, NOT TWO. The design separates the page ground from a panel from a writing frame:
   --q-page is the workspace behind the panels, --q-bg is a panel, --q-frame is the ground of every
   section box you write in. --q-raise is pointed at --q-frame so the legacy --head/--note/--panel2
   land on the quiet frame tint rather than the old blue-grey raise.

   --q-rule vs --q-rule-strong: the design's "rule" is the hairline INSIDE a surface; its "line" is
   the heavier border on every writing frame, button and column divider. --border maps to the
   hairline; a frame or control asks for -strong by name. (The design calls the second one "line",
   but --q-line was already this app's accent line and rules read it that way, so the design's
   "line" lands on --q-rule-strong and the collision never happens.)
   ============================================================ */
[data-theme="light"] {
  --q-page:#f3f4f6; --q-bg:#ffffff; --q-frame:#fafbfc; --q-raise:#fafbfc;
  --q-rule:#dde1e6; --q-rule-strong:#c5cad2;
  /* A control's own boundary: 3:1 against the panel, the frame, the page and the selection wash (WCAG 1.4.11). */
  --q-field:#838a93;
  --q-ink:#15181d; --q-ink2:#454c56; --q-mute:#6b7380; --q-mute2:#7a828d;
  --q-link:#1d4ed8; --q-line:#1d4ed8; --q-ava:#e2e9fa; --q-avatx:#1d4ed8; --q-accent:#1d4ed8;
  --q-sel:#e8eefc; --q-knob:#ffffff;
  /* --q-dot is RESERVED: the unseen-change dot exists on the phone, and the desktop has no path
     that writes one, so P11 deliberately did NOT build a rail dot a workstation could never light. */
  --q-ok:#1e6b44; --q-ok-bg:#def3e6; --q-warn:#8a5a0b; --q-warn-bg:#fdf1d6;
  --q-bad:#b3261e; --q-dot:#1d4ed8; --q-danger:#b3261e;
  --q-ready-bg:#e8eefc; --q-ready-tx:#1d4ed8;

  /* The three token hues, each with the pale value half the "solid keys" chip puts beside it.
     Orders and follow-up carry the same anatomy for the visit table's counts and its tooltip; their
     value tints are derived at the same ~12% over white the three given pairs measure at. */
  --tok-vit:#6d5bb8; --tok-vit-v:#eeeaf8;
  --tok-dx:#b0662a;  --tok-dx-v:#f8eee4;
  --tok-rx:#2e7d5b;  --tok-rx-v:#e6f3ec;
  --tok-order:#1f5f96; --tok-order-v:#e4ecf2;
  --tok-fu:#5a6577;  --tok-fu-v:#ebedef;

  /* The nine R-024 per-vital names, now aliases of the one violet (see the header note). */
  --tok-bp:var(--tok-vit); --tok-hr:var(--tok-vit); --tok-t:var(--tok-vit); --tok-rr:var(--tok-vit);
  --tok-spo2:var(--tok-vit); --tok-wt:var(--tok-vit); --tok-ht:var(--tok-vit);
  --tok-bmi:var(--tok-vit); --tok-pain:var(--tok-vit);

  /* An allergy is the record's danger, not a fourth category hue. The "+ Add" split pills these
     four coloured are gone — HT-006 makes every add control a 28px outline button with its label in
     link blue — so the names point at the accent rather than keeping an orange and a teal alive. */
  --tok-al:#b3261e;
  --tok-add:var(--q-link); --tok-add2:var(--q-link);
  --tok-sec:var(--q-link); --tok-sec2:var(--q-link);

  /* The analysis review's two bands. The proposal green is RESERVED: it appears nowhere else in the
     app, so a proposal can never be read as a medication chip or a sync success. */
  --q-prop:#00a37a; --q-prop-bg:rgba(0,163,122,.14); --q-prop-tx:#007356;
  --q-rw:#8c6210;   --q-rw-bg:rgba(140,98,16,.16);   --q-rw-tx:#75510c;
  --q-new:#137a44;  --q-new-bg:rgba(19,122,68,.16);  --q-new-tx:#0f6238;

  /* R-025 — the two POINTER species (citation orchid, figure lime) with their derived alpha
     families. HT-006 does not govern them: a citation and a figure are pointers, not the value
     categories rule 2 counts, and the handoff is silent on both. Left exactly as R-025 tuned them.
     --tok-ci-faint is UNUSED BY DESIGN: the ladder is authored whole so a species family is never
     half-defined. Its figure twin --tok-fg-faint IS live — it draws .hct-fgspan's underline. */
  --tok-ci:#96246f; --tok-ci-line:rgba(150,36,111,.45); --tok-ci-faint:rgba(150,36,111,.22);
  /* HT-007 — the two names the one-sheet layout adds. --q-wash is the focused writing area's halo,
     which reads as a highlighted paragraph rather than a form control; --q-sheet-sh is what makes the
     sheet read as paper lying on the desk rather than as another panel. Keep it exactly this soft.
     (The FBQ-001 --hc-zero-edge trio went with the dashed empty box: an empty area is now its own
     italic placeholder on the sheet.) */
  --q-wash:rgba(29,99,234,.055);
  --q-sheet-sh:0 1px 2px rgba(16,24,40,.06), 0 8px 24px rgba(16,24,40,.07);
  /* HT-010 — the four names the transcript's speaker marker and its menu add. --q-ring is the focus
     ring a control wears while its menu is open (nothing else about it may change); --q-badge is the
     quiet fill a ghost control takes on hover; --q-rowh is a list row's hover; --q-menush is the
     shadow that lifts a dropdown off the panel. */
  --q-ring:rgba(29,99,234,.22); --q-badge:#e9ecf0; --q-rowh:rgba(16,24,40,.03);
  --q-menush:0 10px 28px rgba(16,24,40,.14), 0 1px 2px rgba(16,24,40,.08);
  --tok-ci-wash:rgba(150,36,111,.1); --tok-ci-sel:rgba(150,36,111,.15);
  --tok-fg:#4f6b0c; --tok-fg-line:rgba(79,107,12,.45); --tok-fg-faint:rgba(79,107,12,.24);
  --tok-fg-wash:rgba(79,107,12,.1); --tok-fg-sel:rgba(79,107,12,.15);

  --accent:var(--q-accent); --accentFg:#ffffff; --accentSoft:var(--q-sel);
  --bg:var(--q-bg); --panel:var(--q-bg); --head:var(--q-raise); --border:var(--q-rule);
  --text:var(--q-ink); --dim:var(--q-mute); --faint:var(--q-mute2);
  --ok:var(--q-ok); --okSoft:var(--q-ok-bg);
  --warn:var(--q-warn); --warnSoft:var(--q-warn-bg);
  --danger:var(--q-bad); --dangerSoft:rgba(179,38,30,.11);
  --note:var(--q-raise); --img:var(--tok-dx); --imgSoft:rgba(176,102,42,.11);
  --zebraAlt:#f5f6f8;
  --shadow:0 26px 64px rgba(6,9,14,.18); --rad:9px;
  --fUi:'IBM Plex Sans',system-ui,sans-serif;
  --fHead:'IBM Plex Sans',system-ui,sans-serif;
  --fData:'IBM Plex Mono',ui-monospace,monospace;
  /* P9 fix A10: ~10 components name --fMono and it was defined nowhere, so every one of them
     silently fell back to the default stack and misaligned with its --fData neighbours. One
     definition per theme, the same face --fData carries - the two are not meant to differ. */
  --fMono:'IBM Plex Mono',ui-monospace,monospace;
  /* R-025 P12: two names ~26 rules referenced through a fallback arm and NOBODY defined. Each is set
     here to exactly what its fallback resolved to, and the arms are gone from the call sites, so the
     next undefined name fails visibly instead of silently painting the fallback. */
  --q-edge:var(--q-accent);   /* was var(--q-edge, var(--accent)) -> --accent -> --q-accent */
  --q-hover:var(--q-raise);   /* was var(--q-hover, var(--head))  -> --head   -> --q-raise  */
  /* Five more arm-less ghosts the same sweep found: each was named by a rule and defined by nobody,
     so the WHOLE declaration was dropped and the border/colour never painted at all. */
  --accentBorder:rgba(29,78,216,.7); --okBorder:rgba(30,107,68,.72); --warnBorder:rgba(138,90,11,.72);
  --fg:var(--q-ink); --panel2:var(--q-raise);
}
[data-theme="dark"] {
  --q-page:#0b0e13; --q-bg:#12161c; --q-frame:#0e1116; --q-raise:#0e1116;
  --q-rule:#1f262f; --q-rule-strong:#2b333d;
  --q-ink:#e9ecf1; --q-ink2:#c4ccd6; --q-mute:#8a93a0; --q-mute2:#6f7885;
  --q-link:#8fb0f2; --q-line:#3b7bf0; --q-ava:#24303f; --q-avatx:#8fb0f2; --q-accent:#3b7bf0;
  --q-sel:#182238; --q-knob:#e9ecf1;
  --q-ok:#4fc98a; --q-ok-bg:color-mix(in srgb, var(--q-ok) 16%, transparent); --q-warn:#e0b45a; --q-warn-bg:color-mix(in srgb, var(--q-warn) 16%, transparent);
  --q-bad:#ff7b7b; --q-dot:#8fb0f2; --q-danger:#ff7b7b;
  --q-ready-bg:color-mix(in srgb, var(--q-accent) 16%, transparent); --q-ready-tx:#8fb0f2;

  /* Same three hues as light — that is the point: a chip stays recognisable across themes and only
     the value half changes character, from a pale tint to a 20% wash of its own hue. */
  --tok-vit:#7b69c9; --tok-vit-v:rgba(123,105,201,.2);
  --tok-dx:#c2783a;  --tok-dx-v:rgba(194,120,58,.2);
  --tok-rx:#3a9670;  --tok-rx-v:rgba(58,150,112,.2);
  --tok-order:#3f7fb8; --tok-order-v:rgba(63,127,184,.2);
  --tok-fu:#6f7885;  --tok-fu-v:rgba(111,120,133,.2);

  --tok-bp:var(--tok-vit); --tok-hr:var(--tok-vit); --tok-t:var(--tok-vit); --tok-rr:var(--tok-vit);
  --tok-spo2:var(--tok-vit); --tok-wt:var(--tok-vit); --tok-ht:var(--tok-vit);
  --tok-bmi:var(--tok-vit); --tok-pain:var(--tok-vit);

  --tok-al:#ff7b7b;
  --tok-add:var(--q-link); --tok-add2:var(--q-link);
  --tok-sec:var(--q-link); --tok-sec2:var(--q-link);

  --q-prop:#2de2a8; --q-prop-bg:rgba(45,226,168,.16); --q-prop-tx:#7ef0cd;
  --q-rw:#e0b45a;   --q-rw-bg:rgba(224,180,90,.22);   --q-rw-tx:#eccd8c;
  --q-new:#4fc98a;  --q-new-bg:rgba(79,201,138,.2);   --q-new-tx:#7fdcae;

  /* R-025 — the pointer species' DARK ladder (see the light block's note): line .5, ci-faint .26
     but fg-faint .28 (the lime reads weaker at equal alpha, so the design nudged it up), wash .14,
     sel .2. */
  --tok-ci:#e08ad0; --tok-ci-line:rgba(224,138,208,.5); --tok-ci-faint:rgba(224,138,208,.26);
  /* HT-007 — the one-sheet layout's two names (see the light block). */
  --q-wash:rgba(59,123,240,.1);
  --q-sheet-sh:0 1px 2px rgba(0,0,0,.5), 0 10px 28px rgba(0,0,0,.5);
  /* HT-010 — the light block's four names (see there). */
  --q-ring:rgba(59,123,240,.32); --q-badge:#232a34; --q-rowh:rgba(255,255,255,.03);
  --q-menush:0 12px 30px rgba(0,0,0,.55), 0 1px 2px rgba(0,0,0,.5);
  --tok-ci-wash:rgba(224,138,208,.14); --tok-ci-sel:rgba(224,138,208,.2);
  --tok-fg:#a8c93a; --tok-fg-line:rgba(168,201,58,.5); --tok-fg-faint:rgba(168,201,58,.28);
  --tok-fg-wash:rgba(168,201,58,.14); --tok-fg-sel:rgba(168,201,58,.2);

  --accent:var(--q-accent); --accentFg:#ffffff; --accentSoft:var(--q-sel);
  --bg:var(--q-bg); --panel:var(--q-bg); --head:var(--q-raise); --border:var(--q-rule);
  --text:var(--q-ink); --dim:var(--q-mute); --faint:var(--q-mute2);
  --ok:var(--q-ok); --okSoft:var(--q-ok-bg);
  --warn:var(--q-warn); --warnSoft:var(--q-warn-bg);
  --danger:var(--q-bad); --dangerSoft:rgba(255,123,123,.14);
  --note:var(--q-raise); --img:var(--tok-dx); --imgSoft:rgba(194,120,58,.14);
  --zebraAlt:#141920;
  --shadow:0 26px 64px rgba(0,0,0,.45); --rad:9px;
  --fUi:'IBM Plex Sans',system-ui,sans-serif;
  --fHead:'IBM Plex Sans',system-ui,sans-serif;
  --fData:'IBM Plex Mono',ui-monospace,monospace;
  /* P9 fix A10: ~10 components name --fMono and it was defined nowhere, so every one of them
     silently fell back to the default stack and misaligned with its --fData neighbours. One
     definition per theme, the same face --fData carries - the two are not meant to differ. */
  --fMono:'IBM Plex Mono',ui-monospace,monospace;
  --q-edge:var(--q-accent);
  --q-hover:var(--q-raise);
  --accentBorder:rgba(59,123,240,.45); --okBorder:rgba(79,201,138,.45); --warnBorder:rgba(224,180,90,.45);
  --fg:var(--q-ink); --panel2:var(--q-raise);
}

/* In light, a control draws its border in --q-field whichever rule name it was written with; dark keeps its own lines.
   The classes are boxes that draw an input's border for it. */
[data-theme="light"] :is(button, input, select, textarea, .sp-para, .ws-search, .pl-filterwrap, .pf-search, .fh-search, .tcm-shell) {
  --border:var(--q-field); --q-rule:var(--q-field); --q-rule-strong:var(--q-field);
}
/* Tinted badges keep a faint ring in their own colour: on the light page grey their tint alone disappears. */
[data-theme="light"] :is(.vh-status, .enc-status, .rxl-code, .orl-code) { box-shadow:inset 0 0 0 1px color-mix(in srgb, currentColor 30%, transparent); }

/* ============================================================
   HT-006 2 - the text size: ONE root font size, three steps (Regular 16 / Large 18 / Extra large
   20), with every type size in the app expressed as a rem against it. Geometry stays in px exactly
   as the prototype writes it, so a 38px control is 38px at every step and only its label grows.

   The marker class sits on the WORKSTATION root, not on <html>, because the sign-in screen and the
   print stylesheet are outside this scale. :root:has() is what lets a descendant class still set the
   root font size the rems resolve against - supported on both heads (WebKit 15.4+ / Chromium 105+),
   and an engine without it simply stays at Regular, which is the default.
   ============================================================ */
:root:has(.ws.hc-text-18) { font-size: 18px; }
:root:has(.ws.hc-text-20) { font-size: 20px; }

/* The hairline-ledger zebra stripe. Precomputed above for engines without color-mix
   (WKWebView < Safari 16.2); this keeps it exact everywhere else. */
@supports (color: color-mix(in srgb, red 50%, blue)) {
  [data-theme="light"], [data-theme="dark"] {
    --zebraAlt:color-mix(in srgb, var(--q-raise) 55%, var(--q-bg));
  }
}

/* ---- shared CPOE order chrome (kind badge + status pill), used by the note Plan block + Orders panel ---- */
.ord-kind { font:700 10px var(--fUi); letter-spacing:.04em; text-transform:uppercase; padding:2px 6px; border-radius:5px; flex:none; background:var(--accentSoft); color:var(--accent); }
.ord-kind.k-medication { background:var(--accentSoft); color:var(--accent); }
.ord-kind.k-lab { background:var(--okSoft); color:var(--ok); }
.ord-kind.k-imaging { background:var(--imgSoft); color:var(--img); }
.ord-kind.k-referral { background:var(--warnSoft); color:var(--warn); }
.ord-kind.k-procedure { background:var(--head); color:var(--dim); }
.ord-stpill { font:700 10px var(--fUi); letter-spacing:.03em; text-transform:uppercase; padding:2px 7px; border-radius:999px; flex:none; }
.ord-stpill.st-draft { background:var(--warnSoft); color:var(--warn); }
.ord-stpill.st-ordered { background:var(--accentSoft); color:var(--accent); }
.ord-stpill.st-ok { background:var(--okSoft); color:var(--ok); }
.ord-stpill.st-danger { background:var(--dangerSoft); color:var(--danger); }

/* The workstation paints the PAGE ground; every panel paints --bg (a panel) over it, and every
   writing surface paints --q-frame inside that. Three surfaces, per HT-006.

   font-size is 1rem, not 14px: HT-006 sets ONE root font size and expresses type in rem, so the
   Settings text-size control (Regular 16 / Large 18 / Extra large 20 -- see .hc-textsize on <html>)
   scales the whole app from one place. Geometry stays in px, exactly as the prototype writes it:
   a 38px control is 38px at every text size, and only its label grows. */
.ws {
  position:fixed; inset:0; display:flex; flex-direction:column; overflow:hidden;
  background:var(--q-page); color:var(--text); font-family:var(--fUi); font-size:1rem;
}

/* ---- first-load model download banner (Catalyst) ---- */
.ws-provbanner { flex:none; background:var(--accentSoft); border-bottom:1px solid var(--border); }
.ws-provbanner.fail { background:var(--dangerSoft); }
.ws-provbanner-main { display:flex; align-items:center; gap:10px; padding:9px 16px; font-size:13px; color:var(--text); }
.ws-provbanner.fail .ws-provbanner-main { color:var(--danger); }
.ws-provbanner-text { flex:1; min-width:0; }
.ws-provbanner-text b { font-variant-numeric:tabular-nums; }
.ws-provbanner-btn { flex:none; border:1px solid var(--danger); color:var(--danger); background:transparent; border-radius:6px; padding:4px 12px; font:inherit; font-size:12px; cursor:pointer; }
.ws-provbanner-btn:hover { background:var(--danger); color:#fff; }
.ws-provbanner-spin { flex:none; width:14px; height:14px; border-radius:50%; box-sizing:border-box; border:2px solid var(--accent); border-top-color:transparent; animation:ws-provbanner-rot .8s linear infinite; }
.ws-provbanner-track { height:3px; background:var(--border); overflow:hidden; }
.ws-provbanner-fill { height:100%; background:var(--accent); width:0; transition:width .3s ease; }
@keyframes ws-provbanner-rot { to { transform:rotate(360deg); } }

/* ---- top bar (HT-006) ----
   58px, not 46: the header gained height so its controls could become 38px and legible, and the app
   paid for it out of the tab rows and the sign-off bar further down. Order is the design's, left to
   right: brand · search · spacer · mode switch · gear · Calendar · bell · user chip. The gear sits
   IMMEDIATELY right of the switch (README §1) — the two are the app's own settings, and everything
   after them is clinical.

   The prototype pads the header 92px on the left to clear the macOS traffic lights its own window
   chrome draws. The real heads draw their own title bar above this, so the padding here is the
   design's plain 18px on both sides. */
.ws-top { flex:none; height:58px; display:flex; align-items:center; gap:14px; padding:0 18px; background:var(--panel); border-bottom:1px solid var(--border); }
.ws-brand { display:flex; align-items:center; gap:9px; flex:none; }
/* 30px, and the WORKSTATION tag under the wordmark is gone — the design's brand is one line. The
   prototype draws a 30px accent square lettered "H"; that is its stand-in for this badge (the
   handoff ships no new assets), so the app keeps its own logo at the design's size. */
.ws-logo { width:30px; height:30px; display:block; flex:none; }
.ws-wordmark { font:700 1.0625rem var(--fHead); letter-spacing:-.01em; color:var(--text); line-height:1; }
/* A 10px-radius framed field, not the old 20px pill: HT-006 gives every control the same 10px
   corner, and a pill in the header was the one shape that did not repeat anywhere else. */
.ws-search { flex:1; display:flex; align-items:center; gap:10px; height:38px; padding:0 14px; min-width:240px; max-width:620px; background:var(--q-frame); border:1px solid var(--q-rule-strong); border-radius:10px; color:var(--dim); }
.ws-search input { flex:1; min-width:0; border:none; background:none; outline:none; font:inherit; font-size:.9375rem; color:var(--text); }
.ws-search input::selection { background:var(--accentSoft); color:var(--accent); }  /* inline autocomplete suggestion */
.ws-search input::placeholder { color:var(--q-mute2); }
.ws-spacer { flex:1; }
/* The word in front of a value it names — "Created 10 Sep 2026", "Updated 7 Sep 2026", "Patient since
   1 Sep 2026". ONE rule serves the 15px header lines and the 11px tab tails because the size is
   relative, and both axes pull the same way: the label steps down and quiets off, so the date is what
   the eye lands on. It is deliberately not a weight change — the tails are already 700 and the header
   lines 400, so weight is the one axis that cannot move the same direction in both. */
.hc-lbl { font-size:.88em; color:var(--q-mute); }

/* The mode switch: a 60x30 track and a 22px knob, no icon inside it. Knob LEFT is dark, knob RIGHT
   is light — the knob shows where you are, and the title names the mode you would switch TO. There
   is no transition: the knob swaps sides with the theme, which is instant by design. */
.ws-thememode { flex:none; display:flex; align-items:center; width:60px; height:30px; padding:3px; border:1px solid var(--q-rule-strong); border-radius:999px; background:var(--q-frame); color:var(--dim); cursor:pointer; }
.ws-thememode:hover { border-color:var(--q-mute); }
.ws-themeknob { flex:none; width:22px; height:22px; border-radius:999px; background:var(--q-knob); box-shadow:0 1px 3px rgba(0,0,0,.25); }

/* One button shape for the whole header: 38px tall, 10px radius, panel ground, --line border.
   .ws-topbtn is the labelled one; .ws-bell is its icon-only 38x38 square. */
.ws-topbtn { display:inline-flex; align-items:center; gap:8px; height:38px; padding:0 14px; border:1px solid var(--q-rule-strong); border-radius:10px; background:var(--panel); color:var(--text); font:600 .9375rem var(--fUi); cursor:pointer; }
.ws-topbtn:hover { background:var(--q-frame); }
.ws-userchip { display:flex; align-items:center; gap:9px; padding-left:6px; flex:none; }
.ws-avatar { width:34px; height:34px; border-radius:50%; background:var(--q-ava); color:var(--q-avatx); display:flex; align-items:center; justify-content:center; font-weight:700; font-size:.8125rem; flex:none; }
.ws-username { font:600 .9375rem var(--fUi); color:var(--text); line-height:1.2; }
.ws-userrole { font:.75rem var(--fUi); color:var(--dim); line-height:1.2; }

/* The gear's dropdown died with the five modals it listed (R-025 P11 / C-DEC5): the Settings
   sheet's 196px nav is that list now, so .ws-menu* and .ws-menureset went with it. */
.ws-presetrow { display:flex; align-items:center; gap:4px; }
.ws-presetname { flex:1; min-width:0; text-align:left; border:none; background:none; cursor:pointer; color:var(--text); font-size:13px; padding:5px 6px; border-radius:6px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.ws-presetname:hover { background:var(--bg); }
.ws-presetdel { flex:none; border:none; background:none; color:var(--dim); cursor:pointer; font-size:15px; line-height:1; padding:0 6px; border-radius:6px; }
.ws-presetdel:hover { color:var(--danger); }
.ws-presetadd { display:flex; gap:4px; margin-top:4px; }
.ws-presetinput { flex:1; min-width:0; border:1.5px solid var(--faint); border-radius:7px; padding:5px 8px; font:inherit; font-size:12.5px; color:var(--text); background:var(--bg); }
.ws-presetinput:focus { outline:none; border-color:var(--accent); background:var(--panel); }
.ws-presetsave { flex:none; border:1px solid var(--accent); background:var(--accent); color:var(--accentFg); cursor:pointer; font:700 12px var(--fUi); padding:5px 11px; border-radius:7px; }
.ws-presetsave:disabled { opacity:.5; cursor:not-allowed; }
.ws-userchip { display:flex; align-items:center; gap:9px; }
.ws-avatar { width:26px; height:26px; border-radius:50%; background:var(--accentSoft); color:var(--accent); display:flex; align-items:center; justify-content:center; font-weight:700; font-size:12.5px; flex:none; }
.ws-username { font-weight:700; font-size:12px; line-height:1.2; }
.ws-userrole { font-size:10.5px; color:var(--dim); }
/* Offline session (L12): signed in from the local credential cache, no server behind it. */
.ws-offline { margin-left:6px; padding:0 5px; border-radius:999px; border:1px solid var(--warn,#d29922); color:var(--warn,#d29922); font-size:10px; font-weight:700; letter-spacing:.04em; text-transform:uppercase; }

/* ---- workspace + status bar ---- */
/* Static 3-panel workspace (redesign): a fixed flex row of panel cards. The old floating .ws-stage /
   .ws-panel / .ws-rz rules below are now unused (kept until the Phase H cleanup). */
/* HT-006: a 262px rail and a 10px gutter -- the space the tab rows and the old header gave back. */
.ws-workspace { --ws-patient-width:262px; --chart-head:calc(3.125rem + 2px); --chart-tabs:41px; --chart-gap:8px; position:relative; flex:1; min-height:0; display:flex; gap:10px; padding:10px; overflow:hidden; transition:padding-right .15s ease; }
.ws-workspace.patients-collapsed { --ws-patient-width:52px; }
/* HT-006: 12px corners and NO shadow. Stacked shadows were the "too much containerisation" the
   handoff names; a 1px rule is the whole edge of a panel now. */
.wp { display:flex; flex-direction:column; min-height:0; background:var(--panel); border:1px solid var(--border); border-radius:12px; overflow:hidden; }
.wp-patients { width:var(--ws-patient-width); flex:none; transition:width .18s ease; }
.wp-patients.collapsed { width:var(--ws-patient-width); }
/* HT-007 — ONE border per column instead of one per section. The two chart columns go page-grey and
   carry a single white sheet each (.re-sheet / .vp-top), so the sheet is the only framed object in the
   column and cannot be missed. The 262px rail above keeps its card. */
.wp-summary, .wp-visit { background:none; border:0; border-radius:0; overflow:visible; }
.wp-summary { flex:1 1 0; min-width:0; }
.wp-visit { flex:1.18 1 0; min-width:0; }
.wp-head { flex:none; height:36px; display:flex; align-items:center; gap:8px; padding:0 10px 0 14px; background:var(--head); border-bottom:1px solid var(--border); }
.wp-title { font:700 12.5px var(--fUi); }
.ws-topbtn.on { background:var(--accentSoft); border-color:var(--accent); color:var(--accent); }

/* Inbox bell (top bar) — square icon button with a red unread-count badge. */
.ws-bell { position:relative; display:flex; align-items:center; justify-content:center; width:38px; padding:0; color:var(--q-ink2); }
.ws-bell-badge { position:absolute; top:-6px; right:-6px; min-width:17px; height:17px; padding:0 4px; border-radius:999px; background:var(--danger); color:#fff; font:700 10px var(--fUi); line-height:1; display:flex; align-items:center; justify-content:center; border:2px solid var(--panel); }
/* A change of ours the record refused is work already done that is silently NOT in the record, and it
   stays until someone resolves it — so the bell asks again every ten seconds. Ordinary notifications
   never do this: a noise that fires all day stops meaning anything. The shake is over in 0.9s and the
   rest of the cycle is still, and it is dropped entirely for a reader who asked for less motion. */
.ws-bell.jingle { animation: ws-bell-jingle 10s ease-in-out infinite; transform-origin: 50% 4px; }
@keyframes ws-bell-jingle {
    0%, 9%, 100% { transform: rotate(0); }
    1% { transform: rotate(-13deg); }
    2.2% { transform: rotate(11deg); }
    3.4% { transform: rotate(-8deg); }
    4.6% { transform: rotate(6deg); }
    5.8% { transform: rotate(-4deg); }
    7%   { transform: rotate(2deg); }
}
@media (prefers-reduced-motion: reduce) { .ws-bell.jingle { animation: none; } }

/* Fixed design-space "stage"; panels.js scales it to fit the window so all panels scale together. */
.ws-stage { position:absolute; top:0; left:0; width:1408px; height:864px; transform-origin:top left; }
/* Layout lock: no move cursor on headers, hide the resize handles. */
.ws-stage.ws-locked .ws-head { cursor:default; }
.ws-stage.ws-locked .ws-rz { display:none; }

/* Aero-snap / drag-to-split landing preview (positioned in the scaled stage, design px). The dragged panel
   rides at z 100000, so 99999 keeps the preview above every other panel but under the one being dragged. */
.ws-snap-preview { position:absolute; z-index:99999; pointer-events:none; display:none; background:var(--accentSoft); border:2px solid var(--accent); border-radius:var(--rad); box-shadow:inset 0 0 0 1px var(--accent); transition:left .08s, top .08s, width .08s, height .08s; }
.ws-snap-preview.secondary { background:transparent; border-style:dashed; box-shadow:none; }
.ws-status { flex:none; height:28px; display:flex; align-items:center; gap:14px; padding:0 14px; background:var(--head); border-top:1px solid var(--border); font-size:12px; color:var(--dim); }
.ws-mono { font-family:var(--fData); }

/* ---- hotkey advertisement badge (<HotkeyChord>) ---- */
.hc-kbd { display:inline-block; font:600 10.5px var(--fData, monospace); color:var(--dim); background:var(--bg); border:1px solid var(--border); border-radius:5px; padding:1px 5px; line-height:1.35; vertical-align:middle; white-space:nowrap; }
/* Reveal-mode badges are in the DOM but hidden until the shell flags a hold-Alt reveal on <body>. */
.hc-kbd.reveal { display:none; }
body.hc-reveal .hc-kbd.reveal { display:inline-block; animation:hc-kbd-pop .12s ease; }
@keyframes hc-kbd-pop { from { opacity:0; transform:scale(.85); } to { opacity:1; transform:none; } }

/* ---- panel chrome ---- */
.ws-panel { position:absolute; display:flex; flex-direction:column; overflow:hidden; background:var(--panel); border:1px solid var(--border); border-radius:var(--rad); box-shadow:var(--shadow); }
.ws-head { flex:none; height:36px; display:flex; align-items:center; gap:8px; padding:0 6px 0 12px; background:var(--head); border-bottom:1px solid var(--border); cursor:move; user-select:none; }
.ws-title { font:700 12.5px var(--fUi); color:var(--text); }
.ws-pill { font:700 10.5px var(--fUi); padding:2px 7px; border-radius:20px; background:var(--accentSoft); color:var(--accent); }
.ws-win { margin-left:auto; display:flex; gap:2px; position:relative; z-index:8; } /* above the resize handles so Max/Close stay clickable */
.ws-winbtn { width:26px; height:26px; border:none; background:none; cursor:pointer; color:var(--dim); border-radius:6px; font-size:13px; display:flex; align-items:center; justify-content:center; }
.ws-winbtn:hover { background:var(--bg); color:var(--text); }
.ws-close:hover { background:var(--dangerSoft); color:var(--danger); }
/* overflow-x:auto (scrollbar hidden): the strip has no wrap, its buttons refuse to shrink below
   their text, and the columns clip overflow — so on a narrow column the TAIL tabs (Media is last)
   were silently unreachable, reading as "unimplemented" (R-025 feedback #12). Scrolling keeps every
   tab reachable at any width. */
.ws-tabs { flex:none; display:flex; gap:2px; padding:0 10px; background:var(--head); border-bottom:1px solid var(--border); overflow-x:auto; scrollbar-width:none; }
.ws-tabs::-webkit-scrollbar { display:none; }
.ws-body { flex:1; overflow:auto; }

/* Intra-panel tab split (a tab detached into a sub-region). TabbedPanel fills the body and manages its
   own column; each region scrolls independently. Tabs are draggable (panels.js drives the detach). */
.ws-tabbed { display:flex; flex-direction:column; height:100%; min-height:0; }
/* Each tab's content scrolls in its own area (the panel .ws-body no longer scrolls it). A flex column so
   content with flex:1 fills, and taller content scrolls. */
.ws-tab-body { flex:1 1 0; min-height:0; display:flex; flex-direction:column; overflow:auto; }
/* (R-025 feedback #12: the `.ws-tab[data-tab] { cursor:grab }` rule is gone — it advertised the
   pre-R-025 tab-detach drag, which has been uncreatable since data-panel-id left the tree. Tabs are
   buttons; they show the button cursor.) */
/* The Patient panel keeps a fixed header above the tabs, so its TabbedPanel fills the remaining space. */
.sum-root { display:flex; flex-direction:column; height:100%; min-height:0; }
.sum-tabwrap { flex:1 1 0; min-height:0; display:flex; flex-direction:column; }
.ws-tabsplit { flex:1; display:flex; min-height:0; min-width:0; }
.ws-tabsplit.row { flex-direction:row; }
.ws-tabsplit.col { flex-direction:column; }
.ws-tabsplit-region { display:flex; flex-direction:column; min-height:0; min-width:0; overflow:hidden; }
.ws-tabsplit-region.primary { flex:1 1 0; }
.ws-tabsplit-region.secondary { flex:none; } /* sized by inline flex-basis (the split ratio) */
.ws-tabsplit-div { flex:none; background:var(--border); }
.ws-tabsplit.row > .ws-tabsplit-div { width:4px; cursor:col-resize; }
.ws-tabsplit.col > .ws-tabsplit-div { height:4px; cursor:row-resize; }
.ws-tabsplit-div:hover { background:var(--accent); }
.ws-tabsplit-sec-head { flex:none; display:flex; align-items:center; gap:6px; padding:5px 8px; background:var(--head); border-bottom:1px solid var(--border); }
.ws-tabsplit-sec-head .sec-title { flex:1; font:700 12.5px var(--fUi); color:var(--text); }
.ws-tabsplit-redock { border:none; background:none; color:var(--dim); cursor:pointer; font-size:13px; line-height:1; padding:0 2px; }
.ws-tabsplit-redock:hover { color:var(--accent); }
/* drag ghost for a tab being detached */
.ws-tabghost { position:fixed; z-index:100001; pointer-events:none; font:700 12.5px var(--fUi); color:var(--text); background:var(--panel); border:1px solid var(--accent); border-radius:6px; padding:4px 10px; box-shadow:var(--shadow); opacity:.9; }
/* The whole panel body is a drag-to-move surface (panels.js), so stop the browser starting a native image
   drag inside a panel — it would fight the move gesture and there's nowhere to drop the image anyway. */
.ws-stage img { -webkit-user-drag:none; user-drag:none; }
/* While a panel move is live, panels.js sets .ws-moving on <body>; force the move cursor everywhere (the
   pointer rides over arbitrary body content, not just the header) so a body-drag reads like a header drag. */
body.ws-moving, body.ws-moving * { cursor:move !important; }
/* 8-way resize handles — invisible grab strips on the edges + corners, kept INSIDE the panel (it is
   overflow:hidden, so negative offsets would be clipped). A subtle gripper shows on the SE corner. */
.ws-rz { position:absolute; z-index:6; }
.ws-rz.n { top:0; left:14px; right:14px; height:6px; cursor:ns-resize; }
.ws-rz.s { bottom:0; left:14px; right:14px; height:6px; cursor:ns-resize; }
.ws-rz.w { left:0; top:14px; bottom:14px; width:6px; cursor:ew-resize; }
.ws-rz.e { right:0; top:14px; bottom:14px; width:6px; cursor:ew-resize; }
.ws-rz.nw { top:0; left:0; width:14px; height:14px; cursor:nwse-resize; z-index:7; }
.ws-rz.ne { top:0; right:0; width:14px; height:14px; cursor:nesw-resize; z-index:7; }
.ws-rz.sw { bottom:0; left:0; width:14px; height:14px; cursor:nesw-resize; z-index:7; }
.ws-rz.se { bottom:0; right:0; width:16px; height:16px; cursor:nwse-resize; z-index:7; background:linear-gradient(135deg,transparent 52%,var(--border) 52%); }

/* ---- placeholder panel bodies (Phase 3 fills these) ---- */
.pl-pad { padding:12px 14px; }
.pl-h { font:700 16px var(--fHead); margin-bottom:6px; color:var(--text); }
.pl-empty { color:var(--dim); font-size:13px; padding:12px 14px; }
.pl-list { padding:6px; display:flex; flex-direction:column; gap:1px; }
.pl-row { display:flex; align-items:center; gap:10px; width:100%; text-align:left; cursor:pointer; border:none; background:none; padding:8px; border-radius:8px; }
.pl-row:hover { background:var(--bg); }
.pl-row.on { background:var(--accentSoft); box-shadow:inset 3px 0 0 var(--accent); }
.pl-row.on .pl-av { background:var(--accent); color:var(--accentFg); }
.pl-row.on .pl-name { color:var(--accent); font-weight:700; }
/* R-023 #17: the patient's own hue arrives as CSS VARIABLES on the element (InitialsHue.CssVariables),
   never as an inline color — an inline declaration outranks every selector, and the selected-row
   rule above has to keep winning. No variables (a user avatar, an unstyled call site) falls back
   to the theme accent, which is exactly what these chips looked like before. */
.pl-av { width:34px; height:34px; border-radius:50%; background:rgba(var(--avatar-rgb,47,111,235),.16); color:var(--avatar-color,var(--accent)); display:flex; align-items:center; justify-content:center; font-weight:700; font-size:12.5px; flex:none; }
.pl-name { font-weight:600; font-size:13.5px; color:var(--text); }
.pl-meta { font-size:11.5px; color:var(--dim); }
.pl-record { display:flex; flex-direction:column; gap:7px; padding:11px 12px; }
.pl-recbtn { display:flex; align-items:center; justify-content:center; gap:7px; min-height:32px; cursor:pointer; border:1px solid var(--border); background:var(--panel); color:var(--text); border-radius:8px; font:700 13px var(--fUi); }
.pl-recbtn.primary { background:var(--accent); color:var(--accentFg); border-color:var(--accent); }
.pl-recbtn:hover { filter:brightness(.97); }

/* ---- tabs (shown on tabbed panels) ---- */
.ws-tab { border:none; background:none; cursor:pointer; font:700 12px var(--fUi); color:var(--faint); padding:6px 8px; border-bottom:2px solid transparent; }
.ws-tab:hover { color:var(--text); }
.ws-tab.on { color:var(--text); border-bottom-color:var(--accent); }

/* ---- generic list rows (recordings / transcriptions) ---- */
/* user-select:none so a link-drag off these rows never starts a text selection (WebView2 ignores
   preventDefault on pointerdown for selection, which otherwise highlights text + auto-scrolls). */
.pl-li { display:flex; align-items:center; gap:10px; padding:9px 12px; border-bottom:1px solid var(--head); user-select:none; -webkit-user-select:none; }
.pl-li-tile { width:30px; height:30px; border-radius:8px; background:var(--accentSoft); color:var(--accent); display:flex; align-items:center; justify-content:center; flex:none; }
.pl-li-main { flex:1; min-width:0; }
.pl-li-name { font-weight:600; font-size:12.5px; color:var(--text); }
.pl-li-sub { font-size:11px; color:var(--dim); }
.pl-li-act { display:flex; gap:6px; }
/* Clickable list row (e.g. visits): a button reset so the native button border doesn't draw a
   clipped box. Same layout + divider as .pl-li, with a clear selected (.on) state. */
.pl-lirow { display:flex; align-items:center; gap:8px; width:100%; text-align:left; padding:7px 10px; border:none; border-bottom:1px solid var(--head); background:none; color:inherit; font:inherit; cursor:pointer; user-select:none; -webkit-user-select:none; }
.pl-lirow:hover { background:var(--bg); }
.pl-lirow.on { background:var(--accentSoft); box-shadow:inset 3px 0 0 var(--accent); }
.pl-lirow.on .pl-li-name { color:var(--accent); }
.pl-btn { border:1px solid var(--border); background:var(--panel); color:var(--text); cursor:pointer; font:700 11.5px var(--fUi); padding:5px 10px; border-radius:7px; }
.pl-btn.accent { background:var(--accent); color:var(--accentFg); border-color:var(--accent); }
.pl-btn.danger { background:var(--danger); color:#fff; border-color:var(--danger); }
.pl-btn.danger:disabled { opacity:.6; cursor:default; }
/* Pill form of .pl-btn: an icon + label sitting in a row of controls (the transcript footer's Print,
   the row's Delete Recording). Same visual weight, rounder, icon-aligned. */
.pl-btn.pill { display:inline-flex; align-items:center; gap:6px; border-radius:999px; padding:5px 12px; }
.pl-btn.pill:hover:not(:disabled) { border-color:var(--accent); color:var(--accent); }
/* Danger as an OUTLINE, not a fill. A destructive control that has to sit beside a neutral one in the
   same row reads as a warning when it is outlined and as the call to action when it is filled — and
   "Delete" is never the call to action next to "Print". The filled .pl-btn.danger stays for confirm
   buttons, where being the call to action is exactly the point. */
.pl-btn.danger-outline { background:var(--panel); color:var(--danger); border-color:var(--danger); }
.pl-btn.danger-outline:hover:not(:disabled) { background:var(--dangerSoft); border-color:var(--danger); color:var(--danger); }
/* There was no generic disabled rule for .pl-btn — only .pl-btn.danger:disabled — so a button held
   disabled while an export runs looked fully enabled. */
.pl-btn:disabled { opacity:.55; cursor:default; }
/* Patient-list row body: take the free space so the row's delete button sits flush right. */
.pl-main { flex:1; min-width:0; }
.pl-pill { font:700 10.5px var(--fUi); padding:3px 8px; border-radius:20px; background:var(--okSoft); color:var(--ok); }

/* ---- subtle "has recording / has transcript" presence icons on a visit (clickable) ---- */
.vmeta { display:inline-flex; align-items:center; gap:4px; }
.vmeta-ic { display:inline-flex; align-items:center; color:var(--faint); cursor:pointer; padding:2px; border-radius:5px; }
.vmeta-ic:hover { color:var(--accent); background:var(--accentSoft); }

/* ---- drag-to-link: draggable orphan rows + drop targets ---- */
.pl-li.linkable { cursor:grab; user-select:none; -webkit-user-select:none; touch-action:none; }
.pl-li.linkable:active { cursor:grabbing; }
.pl-lirow.drop-ready { outline:1.5px dashed var(--accent); outline-offset:-3px; }
.pl-lirow.drop-over { outline:2px solid var(--accent); outline-offset:-3px; background:var(--accentSoft); }
.note-drop { min-height:100%; }
.note-drop.drop-ready { outline:2px dashed var(--accent); outline-offset:-6px; border-radius:10px; }
.note-drop.drop-over { outline:2.5px solid var(--accent); outline-offset:-6px; border-radius:10px; background:var(--accentSoft); }
/* Medical Record drop target (link a recording/dictation to the patient). */
.mr-drop { min-height:100%; }
.mr-drop.drop-ready { outline:2px dashed var(--accent); outline-offset:-6px; border-radius:10px; }
.mr-drop.drop-over { outline:2.5px solid var(--accent); outline-offset:-6px; border-radius:10px; background:var(--accentSoft); }
.mr-drophint { margin:6px 12px; padding:8px 10px; border-radius:8px; background:var(--accentSoft); color:var(--accent); font:700 12px var(--fUi); text-align:center; }
.pl-li.linkable { cursor:grab; }

/* floating label that follows the cursor during a link drag */
.ws-dragghost { position:fixed; z-index:200002; pointer-events:none; background:var(--accent); color:var(--accentFg); font:700 12px var(--fUi); padding:6px 11px; border-radius:8px; box-shadow:var(--shadow); white-space:nowrap; }

/* row-clone drag ghost (segment / recording-row drags): the actual line item floats with the cursor
   in a card, with a hint strip underneath narrating the current drop target. panels.js sizes it at
   design width and applies the stage's CSS scale so it matches the on-screen row exactly. */
.ws-rowghost { position:fixed; z-index:200002; pointer-events:none; transform-origin:top left; background:var(--panel); border:1px solid var(--accent); border-radius:10px; box-shadow:0 12px 30px rgba(0,0,0,.35); overflow:hidden; opacity:.95; }
.ws-rowghost .recp-seg, .ws-rowghost .pl-li { border-bottom:none; margin:0; }
.ws-rowghost-hint { font:700 10.5px var(--fUi); color:var(--accentFg); background:var(--accent); padding:4px 10px; }
/* the dragged row stays in place while its clone rides the cursor — dim it so it reads as "lifted" */
.ws-dragging-src { opacity:.35; }

/* row highlight when navigated to from a presence icon — blinks a few times with an accent ring */
@keyframes it-flash {
    0%, 100%      { background:transparent;      box-shadow:inset 0 0 0 0 var(--accent); }
    10%, 40%, 70% { background:var(--accentSoft); box-shadow:inset 0 0 0 3px var(--accent); }
    25%, 55%, 85% { background:transparent;      box-shadow:inset 0 0 0 0 var(--accent); }
}
.it-flash { animation:it-flash 1.6s ease-in-out; position:relative; z-index:1; }

/* ---- media-navigation popover (visit has >1 linked recording/transcript) ---- */
.ws-popscrim { position:fixed; inset:0; z-index:200000; }
.ws-pop { position:fixed; z-index:200001; transform:translate(-100%, 12px); min-width:210px; max-width:300px; max-height:320px; overflow:auto; background:var(--panel); border:1px solid var(--border); border-radius:10px; box-shadow:var(--shadow); padding:5px; }
.ws-pop-h { font:700 10px var(--fUi); letter-spacing:.05em; text-transform:uppercase; color:var(--dim); padding:6px 8px 4px; }
.ws-pop-item { display:flex; align-items:center; gap:9px; width:100%; text-align:left; background:none; border:none; cursor:pointer; padding:7px 8px; border-radius:7px; color:var(--text); }
.ws-pop-item:hover { background:var(--bg); }
.ws-pop-item svg { color:var(--accent); flex:none; }
.ws-pop-main { display:flex; flex-direction:column; min-width:0; }
.ws-pop-name { font-size:13px; font-weight:600; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.ws-pop-sub { font-size:11px; color:var(--dim); }

/* ---- header action row (e.g. + New visit) ---- */
.pl-hrow { display:flex; align-items:center; justify-content:space-between; padding:8px 12px; border-bottom:1px solid var(--head); }
.pl-hbtn { border:1px solid var(--border); background:var(--panel); color:var(--accent); cursor:pointer; font:700 12px var(--fUi); padding:5px 11px; border-radius:7px; display:inline-flex; align-items:center; gap:5px; }
.pl-hbtn.rec { color:var(--danger); border-color:var(--danger); }
.pl-hbtn.rec:hover:not(:disabled) { background:var(--dangerSoft); }
.pl-hbtn:disabled { opacity:.5; cursor:default; }

/* ---- inline add-patient ---- */
.pl-add { width:100%; text-align:left; border:none; background:none; cursor:pointer; color:var(--accent); font:700 13px var(--fUi); padding:9px 8px; border-radius:8px; }
.pl-add:hover { background:var(--bg); }
.pl-newrow { display:flex; gap:6px; padding:6px 8px 0; }
.pl-input { flex:1; min-width:0; min-height:32px; border:1.5px solid var(--faint); border-radius:7px; padding:0 9px; font:inherit; font-size:13px; background:var(--bg); color:var(--text); }
.pl-input:focus { outline:none; border-color:var(--accent); background:var(--panel); }
.pl-newact { display:flex; gap:6px; padding:6px 8px 8px; }

/* ---- patient summary ---- */
.sum-head { display:flex; align-items:center; gap:10px; padding:7px 14px; border-bottom:1px solid var(--head); }
.sum-name { font:700 15px var(--fHead); color:var(--text); }
.sum-meta { font-size:11.5px; color:var(--dim); }
.sum-body { padding:2px 14px 14px; }
.sum-sec { padding:10px 0; border-bottom:1px solid var(--head); }
.sum-lbl { font:700 11px var(--fUi); letter-spacing:.07em; text-transform:uppercase; color:var(--dim); margin-bottom:6px; }
.sum-lbl.danger { color:var(--danger); }
.sum-item { font-size:13px; color:var(--text); padding:2px 0; }
.sum-none { font-size:12.5px; color:var(--faint); }
/* ---- pf-*: the PATIENT FIELDS vocabulary (owner, 2026-09-03) -------------------------------
   One field layout, two hosts: the New-patient sheet and the chart's Demographics tab. It lived in
   NewPatientModal's own <style> until the tab was asked to look the same — and a component's style
   block is only in the document while that component RENDERS, so a closed modal took its rules with
   it. Shared form vocabulary belongs here, beside .pl-input and .demo-*, for exactly that reason.
   Sections with an eyebrow rule, a two-column grid of label-over-control cells, .pf-wide for the
   ones that span. */
.pf-sec { display:flex; flex-direction:column; gap:11px; }
.pf-eyebrow { display:flex; align-items:center; gap:10px; font:600 10px var(--fUi); letter-spacing:.11em; color:var(--q-mute); }
.pf-note { font:10.5px var(--fUi); letter-spacing:0; color:var(--q-mute); }
.pf-rule { flex:1; height:1px; background:var(--q-rule); }

.pf-grid { display:grid; grid-template-columns:1fr 1fr; gap:11px; }
.pf-cell { display:flex; flex-direction:column; gap:6px; min-width:0; }
.pf-wide { grid-column:1 / -1; }
.pf-cell > label, .pf-labelline > label { font:11px var(--fUi); color:var(--q-mute); }
.pf-labelline { display:flex; align-items:center; gap:8px; min-height:17px; }
.pf-labelline > label { flex:1; min-width:0; }
.pf-same { display:inline-flex; align-items:center; gap:5px; font:11px var(--fUi); color:var(--q-mute); cursor:pointer; }
.pf-same input { width:14px; height:14px; accent-color:var(--q-accent); cursor:pointer; }
.pf-dim { opacity:.55; }

.pf-input {
    width:100%; box-sizing:border-box; height:34px; padding:0 11px;
    border:1px solid var(--q-rule); border-radius:9px; background:var(--q-bg);
    color:var(--q-ink); font:13.5px var(--fUi); outline:none;
}
.pf-input:focus { border-color:var(--q-line); }
.pf-dob { display:flex; align-items:center; gap:6px; }
.pf-box { width:52px; flex:none; text-align:center; font-family:var(--fMono); }
.pf-year { flex:1; min-width:0; text-align:center; font-family:var(--fMono); }
.pf-sep { color:var(--q-mute); }
.pf-select { width:100%; box-sizing:border-box; }
/* HcDateEntry draws its own three boxes out of .pl-input; inside a cell it wears the cell's input. */
.pf-cell .hcde-part { height:34px; border:1px solid var(--q-rule); border-radius:9px; background:var(--q-bg); color:var(--q-ink); font:13.5px var(--fMono); text-align:center; }
.pf-cell .hcde-part:focus { border-color:var(--q-line); background:var(--q-bg); }

.pf-search { display:flex; align-items:center; gap:8px; height:34px; padding:0 11px; box-sizing:border-box;
    border:1px solid var(--q-rule); border-radius:9px; background:var(--q-bg); color:var(--q-mute); }
.pf-searchin { flex:1; min-width:0; border:0; background:none; color:var(--q-ink); font:13.5px var(--fUi); outline:none; }
.pf-clear { flex:none; width:20px; height:20px; border:0; border-radius:6px; background:none; color:var(--q-mute); display:flex; align-items:center; justify-content:center; cursor:pointer; }
.pf-langmenu { max-height:204px; overflow:auto; margin-top:5px; background:var(--q-raise);
    border:1px solid var(--q-rule); border-radius:10px; box-shadow:0 18px 40px rgba(0,0,0,.42); }
.pf-langrow { display:block; width:100%; box-sizing:border-box; padding:9px 11px; border:0; background:transparent;
    color:var(--q-ink2); font:13px var(--fUi); text-align:left; cursor:pointer; }
.pf-langrow:hover { color:var(--q-ink); background:var(--q-bg); }
.pf-nomatch { display:block; padding:9px 11px; font:12px var(--fUi); color:var(--q-mute); }

.pf-chips { display:flex; flex-wrap:wrap; gap:6px; }
.pf-chip { display:inline-flex; align-items:center; gap:6px; height:28px; padding:0 11px; border-radius:999px;
    border:1px solid var(--q-rule); background:var(--q-bg); color:var(--q-ink2);
    font:500 12px var(--fUi); cursor:pointer; }
/* The selected chip's trailing glyph is an x, not a check -- it is a REMOVE affordance in place. */
.pf-chip.on { border-color:var(--accentBorder); background:var(--q-sel); color:var(--q-link); font-weight:600; }

/* The patient's pharmacy (2026-09-22): the chosen one, and the search's rows, which wear the same card. */
.pf-pharm { display:flex; align-items:flex-start; gap:10px; padding:10px 12px; box-sizing:border-box;
    border:1px solid var(--q-rule); border-radius:10px; background:var(--q-bg); }
.pf-pharm-who { flex:1; min-width:0; display:flex; flex-direction:column; gap:2px; }
.pf-pharm-name { font:600 13px var(--fUi); color:var(--q-ink); }
.pf-pharm-line { font:12px var(--fUi); color:var(--q-mute); }
.pf-pharm-none { flex:1; font:12.5px var(--fUi); color:var(--q-mute); align-self:center; }
.pf-pharm-acts { flex:none; display:flex; gap:6px; }
.pf-pharm-find { display:grid; grid-template-columns:110px 1fr auto; gap:8px; align-items:center; }
.pf-pharm-list { display:flex; flex-direction:column; gap:6px; }
.pf-pharm-row { width:100%; text-align:left; cursor:pointer; }
.pf-pharm-row:hover { border-color:var(--q-line); }
.pf-pharm-status { font:12px var(--fUi); color:var(--q-mute); }
.pf-pharm-pager { display:flex; align-items:center; justify-content:flex-end; gap:8px; }
.pf-pharm-search { display:flex; flex-direction:column; gap:10px; }

.demo-grid { display:grid; grid-template-columns:auto 1fr; gap:8px 16px; padding:12px 14px; }
.demo-edit { padding:12px 14px; display:flex; flex-direction:column; gap:8px; }
.demo-row { display:flex; flex-direction:column; gap:4px; }
.demo-row label { font-size:11px; color:var(--dim); }
.demo-k { font-size:12px; color:var(--dim); }
.demo-v { font-size:13px; color:var(--text); }

/* ---- visit note ---- */
.note-empty { padding:22px 14px; color:var(--dim); font-size:13px; }
.note-bigbtns { display:flex; gap:16px; justify-content:center; }
.note-bigbtn { display:flex; align-items:center; justify-content:center; width:88px; height:88px; border-radius:18px; border:1px solid var(--border); background:var(--panel); color:var(--text); cursor:pointer; transition:border-color .12s, color .12s; }
.note-bigbtn:hover { border-color:var(--accent); color:var(--accent); }
.note-bigbtn.accent { background:var(--accent); color:var(--accentFg); border-color:var(--accent); }
.note-bigbtn.accent:hover { filter:brightness(.97); color:var(--accentFg); }
.note-bighint { text-align:center; color:var(--faint); font-size:12px; margin-top:12px; }
.note-body { padding:12px 14px; }
.note-sec { margin-bottom:14px; }
.note-lbl { font:700 11px var(--fUi); letter-spacing:.07em; text-transform:uppercase; color:var(--accent); margin-bottom:5px; }
.note-lbl-row { display:flex; align-items:center; justify-content:space-between; gap:8px; margin-bottom:5px; }
.note-lbl-row .note-lbl { margin-bottom:0; }
.note-lbl-tools { display:flex; align-items:center; gap:6px; flex:none; }
/* ---- shared line-item controls: one design for the SOAP note's O/A/P sub-section items
   (Objective→vitals, Assessment→diagnosis, Plan→orders) — compact display row + inline edit form. ---- */
.li-list { display:flex; flex-direction:column; gap:3px; }
.li-row { display:flex; align-items:center; gap:10px; padding:9px 10px; border-radius:10px; border:1px solid transparent; }
.li-row:hover { background:var(--head); border-color:var(--border); }
.li-row-main { flex:1; min-width:0; }
.li-row-title { font:600 14px var(--fUi); color:var(--text); }
.li-row-title .li-tag { font:700 10.5px var(--fUi); color:var(--dim); background:var(--head); border-radius:5px; padding:1px 6px; margin-right:7px; }
.li-row-title .li-code { font:700 11.5px var(--fData, monospace); color:var(--dim); margin-left:7px; }
.li-row-sub { font-size:12px; color:var(--dim); margin-top:3px; white-space:pre-wrap; overflow:hidden; text-overflow:ellipsis; }
.li-row-acts { flex:none; display:flex; align-items:center; gap:2px; }
.li-iconbtn { width:26px; height:26px; border:none; background:none; cursor:pointer; color:var(--faint); border-radius:6px; display:inline-flex; align-items:center; justify-content:center; }
.li-iconbtn:hover { background:var(--bg); color:var(--text); }
.li-iconbtn.del:hover { background:var(--dangerSoft); color:var(--danger); }
/* inline edit form (accent-outlined) + shared field label + Save/Cancel(/Delete) footer */
.li-edit { border:1.5px solid var(--accent); background:var(--panel); border-radius:var(--rad, 8px); padding:11px; margin-bottom:7px; display:flex; flex-direction:column; gap:9px; }
.li-fld { display:flex; flex-direction:column; gap:4px; }
.li-flbl { font:700 10px var(--fUi); letter-spacing:.05em; text-transform:uppercase; color:var(--dim); }
.li-foot { display:flex; align-items:center; justify-content:flex-end; gap:8px; padding-top:2px; }
.li-save { border:1px solid var(--accent); background:var(--accent); color:var(--accentFg); font:700 12.5px var(--fUi); padding:7px 15px; border-radius:7px; cursor:pointer; display:inline-flex; align-items:center; gap:5px; }
.li-save:hover:not(:disabled) { filter:brightness(1.05); }
.li-save:disabled { opacity:.5; cursor:default; }
.li-cancel { border:1px solid var(--border); background:none; color:var(--dim); font:700 12.5px var(--fUi); padding:7px 15px; border-radius:7px; cursor:pointer; }
.li-cancel:hover { color:var(--text); }
.li-del { margin-right:auto; border:1px solid var(--border); background:none; color:var(--danger); font:700 12.5px var(--fUi); padding:7px 15px; border-radius:7px; cursor:pointer; }
.li-del:hover { background:var(--dangerSoft); border-color:var(--danger); }

.note-dx { display:flex; flex-direction:column; gap:8px; margin-top:8px; }
.note-dx-row { display:flex; align-items:flex-start; gap:6px; border-left:2px solid var(--head); padding-left:8px; }
.note-dx-fields { flex:1; min-width:0; display:flex; flex-direction:column; gap:6px; }
.note-dx-acts { display:flex; flex-direction:column; align-items:flex-end; gap:4px; flex:none; }
.note-dx-add { align-self:flex-start; border:1px dashed var(--border); background:var(--panel); color:var(--accent); cursor:pointer; font:700 12px var(--fUi); padding:6px 12px; border-radius:8px; }
.note-dx-add:hover { background:var(--bg); }
.note-dx-tobtn { border:1px solid var(--border); background:var(--panel); color:var(--accent); cursor:pointer; font:700 10.5px var(--fUi); padding:2px 7px; border-radius:6px; white-space:nowrap; }
.note-dx-tobtn:hover { background:var(--bg); }
.note-dx-save { display:inline-flex; align-items:center; gap:4px; border:1px solid var(--accent); background:var(--accent); color:var(--accentFg); cursor:pointer; font:700 10.5px var(--fUi); padding:2px 8px; border-radius:6px; white-space:nowrap; }
.note-dx-save:hover { filter:brightness(1.05); }
.note-dx-read { padding:3px 0; }
.note-dx-line { display:flex; align-items:center; justify-content:space-between; gap:8px; font-size:13px; color:var(--text); }
.note-dx-note { font-size:12px; color:var(--dim); padding:1px 0 0 14px; white-space:pre-wrap; }
.note-text { font-size:13.5px; color:var(--text); line-height:1.55; white-space:pre-wrap; }
/* Vitals linked to the visit, rendered above the Objective field as read-only badges (with unlink ×),
   plus a drop zone while a reading is dragged in and a link-count summary. */
.note-lbl-left { display:flex; align-items:baseline; gap:6px; min-width:0; }
.note-lbl-sub { font:600 11px var(--fUi); color:var(--faint); }
.note-vitals { display:flex; gap:7px; flex-wrap:wrap; margin-bottom:9px; }
.note-vital { display:inline-flex; align-items:center; gap:6px; padding:6px 11px; border-radius:8px; background:var(--bg); border:1px solid var(--border); }
.note-vital.abn { background:var(--dangerSoft); border-color:var(--danger); }
.nv-tag { font:700 10px var(--fUi); text-transform:uppercase; letter-spacing:.04em; color:var(--dim); }
.note-vital.abn .nv-tag { color:var(--danger); }
.nv-val { font:600 13px var(--fData); color:var(--text); }
.note-vital.abn .nv-val { color:var(--danger); }
.nv-x { border:none; background:none; cursor:pointer; color:var(--faint); padding:0; display:flex; font-size:14px; line-height:1; }
.nv-x:hover { color:var(--danger); }
.note-vnone { font-size:11.5px; color:var(--faint); margin-bottom:9px; padding:9px 11px; border:1px dashed var(--border); border-radius:8px; }
.note-vdrop { display:flex; align-items:center; justify-content:center; gap:8px; padding:16px; margin-bottom:9px; border:2px dashed var(--accent); border-radius:10px; background:var(--accentSoft); color:var(--accent); font-size:12.5px; font-weight:700; }
.note-field { width:100%; border:1.5px solid var(--faint); border-radius:8px; padding:9px 11px; font:inherit; font-size:13.5px; color:var(--text); background:var(--bg); resize:vertical; line-height:1.5; box-shadow:inset 0 1px 2px rgba(0,0,0,.06); }
.note-field:focus { outline:none; border-color:var(--accent); box-shadow:0 0 0 3px var(--accentSoft); }
/* Sign-off footer is pinned to the bottom of the SOAP tab's scroll area (above the Visits list). */
/* HT-006: the sign-off bar is 9px of padding over a hairline, the draft status in body ink2 on the
   left, and ONE primary action on the right at 42px. It is the app's single primary button, so it
   takes the app's single accent -- not the green it used to wear, which said "signed" before it was.
   The tick glyph goes with the colour: a 42px button whose label is "Sign off & save" does not need
   an icon to say what it is. */
.note-foot { flex:none; display:flex; align-items:center; gap:12px; padding:8px 18px; border-top:1px solid var(--q-rule); background:var(--panel); }
.note-status { flex:1; min-width:0; font-size:.9375rem; color:var(--q-ink2); }
.note-signoff { flex:none; display:inline-flex; align-items:center; gap:8px; height:42px; padding:0 20px; border:none; border-radius:10px; background:var(--q-accent); color:#fff; font:700 1rem var(--fUi); cursor:pointer; }
.note-signoff:hover:not(:disabled) { filter:brightness(1.07); }
.note-signoff:disabled { background:var(--q-rule-strong); color:var(--q-mute2); cursor:not-allowed; }

/* ---- record panel (capture) ---- */
@keyframes rec-blink { 0%,100% { opacity:1; } 50% { opacity:.35; } }
.rec-live { display:flex; align-items:center; justify-content:center; gap:8px; padding:2px 0; }
.rec-dot { width:9px; height:9px; border-radius:50%; background:var(--danger); animation:rec-blink 1.2s infinite; }
.rec-timer { font:600 20px var(--fData); color:var(--text); }
.rec-types { display:flex; gap:6px; }
.rec-type { flex:1; border:1px solid var(--border); background:var(--panel); color:var(--text); cursor:pointer; font:700 12.5px var(--fUi); padding:7px 0; border-radius:8px; }
.rec-type.on { background:var(--accent); color:var(--accentFg); border-color:var(--accent); }
.rec-type:disabled { color:var(--faint); opacity:.6; cursor:not-allowed; }
.rec-stop { display:inline-block; width:11px; height:11px; border-radius:2px; background:var(--danger); vertical-align:middle; margin-right:6px; }
.rec-err { color:var(--danger); font-size:12px; }
.rec-q { font-size:13px; color:var(--text); text-align:center; padding:2px 0; }
.pl-recbtn:disabled { opacity:.55; cursor:not-allowed; }

/* ---- transcript viewer ---- */
.tv-head { padding:11px 14px; border-bottom:1px solid var(--head); }
.tv-title { font-weight:700; font-size:14px; color:var(--text); }
.tv-sub { font-size:11.5px; color:var(--dim); margin-top:2px; }
.tv-body { padding:8px 14px 14px; overflow:auto; }
.tv-seg { display:flex; gap:10px; padding:4px 0; align-items:baseline; }
.tv-ts { font:600 11px var(--fData); color:var(--faint); flex:none; min-width:42px; }
.tv-text { font-size:13px; color:var(--text); line-height:1.5; }
.tv-full { font-size:13.5px; color:var(--text); line-height:1.6; white-space:pre-wrap; }
/* speaker-attributed transcript (diarization): turn groups + renameable speaker chips */
.tv-turn { margin:2px 0 8px; }
.tv-turnhead { display:flex; align-items:center; gap:8px; margin:6px 0 2px; position:relative; }
/* Fallback first, color-mix behind @supports — the tint must degrade, not vanish, on WKWebView
   engines older than Safari 16.2 (same convention as --zebraAlt above). */
.tv-spk { --spkc:var(--accent); font:700 11px var(--fUi); color:var(--spkc); background:transparent; border:1px solid var(--spkc); border-radius:999px; padding:2px 10px; cursor:pointer; }
.tv-spk:hover { background:var(--accentSoft); }
@supports (background: color-mix(in srgb, red 50%, transparent)) {
  .tv-spk { background:color-mix(in srgb, var(--spkc) 13%, transparent); border-color:color-mix(in srgb, var(--spkc) 30%, transparent); }
  .tv-spk:hover { background:color-mix(in srgb, var(--spkc) 22%, transparent); }
}
.tv-spk.spk-0 { --spkc:#4f8ef7; }
.tv-spk.spk-1 { --spkc:#e0762e; }
.tv-spk.spk-2 { --spkc:#3fae6a; }
.tv-spk.spk-3 { --spkc:#b06ae0; }
.tv-spk.spk-x { --spkc:var(--faint); }
/* Paragraph view: the transcript as prose, each statement opened by a small coloured marker (the
   1-based speaker number, or the initial of a renamed speaker). The markers are inline so the text
   reflows across statement boundaries and reads as speech; colour is what separates two speakers
   whose names share a first letter. Text is read-only here, as it is in every desktop transcript
   view — the marker keeps the rename/reassign gestures. */
.tv-para { font-size:13.5px; color:var(--text); line-height:1.95; margin:0; }
.tv-mark { --spkc:var(--accent); display:inline-flex; align-items:center; justify-content:center; width:17px; height:17px; margin-right:3px; border-radius:5px; border:1px solid var(--spkc); color:var(--spkc); background:transparent; font:700 10px var(--fData); vertical-align:-3px; cursor:pointer; user-select:none; }
@supports (background: color-mix(in srgb, red 50%, transparent)) {
  .tv-mark { background:color-mix(in srgb, var(--spkc) 13%, transparent); border-color:color-mix(in srgb, var(--spkc) 30%, transparent); }
  .tv-mark:hover { background:color-mix(in srgb, var(--spkc) 26%, transparent); }
}
.tv-mark.spk-0 { --spkc:#4f8ef7; }
.tv-mark.spk-1 { --spkc:#e0762e; }
.tv-mark.spk-2 { --spkc:#3fae6a; }
.tv-mark.spk-3 { --spkc:#b06ae0; }
.tv-mark.spk-x { --spkc:var(--faint); }
.tv-viewrow { display:flex; justify-content:flex-end; padding:8px 12px 0; }
.tv-seg-toggle { display:inline-flex; border:1px solid var(--border); border-radius:999px; background:var(--bg); padding:2px; }
.tv-seg-toggle button { border:none; background:transparent; color:var(--dim); font:700 11px var(--fUi); padding:4px 11px; border-radius:999px; cursor:pointer; }
.tv-seg-toggle button.on { background:var(--accentSoft); color:var(--accent); }

.tv-spkscrim { position:fixed; inset:0; z-index:200010; background:transparent; }
.tv-spkmenu { z-index:200011; box-sizing:border-box; overflow:auto; background:var(--panel); border:1px solid var(--border); border-radius:10px; box-shadow:0 8px 24px rgba(0,0,0,.25); padding:10px; display:flex; flex-direction:column; gap:8px; min-width:240px; }
.tv-spkmenu-row { display:flex; align-items:center; gap:6px; flex-wrap:wrap; font:600 11px var(--fUi); color:var(--dim); }
.tv-spkmenu input { flex:1; min-width:120px; font:600 12px var(--fUi); color:var(--text); background:var(--bg); border:1px solid var(--border); border-radius:7px; padding:5px 8px; }
.tv-spkbtn { font:600 11px var(--fUi); color:var(--text); background:var(--bg); border:1px solid var(--border); border-radius:7px; padding:3px 9px; cursor:pointer; }
.tv-spkbtn:hover { background:var(--accentSoft); color:var(--accent); }
.pl-li.on { background:var(--accentSoft); box-shadow:inset 3px 0 0 var(--accent); }

/* ---- shared workstation modal shell ---- */
.ws-scrim { position:fixed; inset:0; background:rgba(10,12,16,.5); display:flex; align-items:center; justify-content:center; z-index:200000; padding:24px; }
.ws-modal { width:min(680px,100%); max-height:88vh; display:flex; flex-direction:column; background:var(--panel); border:1px solid var(--border); border-radius:16px; box-shadow:0 24px 60px rgba(0,0,0,.4); overflow:hidden; }
.ws-modal-head { display:flex; align-items:flex-start; justify-content:space-between; gap:12px; padding:16px 18px; border-bottom:1px solid var(--head); }
.ws-modal-title { font:700 16px var(--fHead); color:var(--text); }
.ws-modal-sub { font-size:12px; color:var(--dim); margin-top:2px; }
.ws-iconbtn { border:none; background:none; cursor:pointer; color:var(--dim); padding:4px; border-radius:7px; display:inline-flex; }
.ws-iconbtn:hover { background:var(--bg); color:var(--text); }
.ws-iconbtn.danger:hover { background:var(--dangerSoft); color:var(--danger); }
.ws-iconbtn:disabled { opacity:.35; cursor:default; }
.ws-iconbtn:disabled:hover { background:none; color:var(--dim); }
/* Delete-confirmation modal body text. */
.del-body { font-size:13px; color:var(--text); line-height:1.5; }
.ws-modal-body { padding:16px 18px; overflow:auto; display:flex; flex-direction:column; gap:12px; }
.ws-modal-foot { display:flex; justify-content:flex-end; gap:10px; padding:13px 18px; border-top:1px solid var(--head); }
.ws-modal-busy { display:flex; flex-direction:column; align-items:center; gap:14px; padding:42px 18px; color:var(--dim); font-size:13.5px; text-align:center; }
.rec-spin-sm { width:38px; height:38px; border-radius:50%; border:4px solid var(--head); border-top-color:var(--accent); animation:hc-spin 1s linear infinite; }
@keyframes hc-spin { to { transform:rotate(360deg); } }

/* ---- panel focus/highlight flash (when a button targets an already-open panel) ---- */
@keyframes ws-flash {
    0%   { box-shadow:0 0 0 3px var(--accent), var(--shadow); }
    55%  { box-shadow:0 0 0 3px var(--accent), var(--shadow); }
    100% { box-shadow:0 0 0 0 rgba(0,0,0,0), var(--shadow); }
}
.ws-panel.ws-flash { animation:ws-flash .66s ease-out 2; border-color:var(--accent); }

/* ---- FBQ-001 #17 — every modal drags by its header (js/hcdrag.js) ----
   The handle is grabbable and its text does not select under the drag. One attribute rule rather
   than a list of header classes: the annotation IS the contract, and a header that gains the
   attribute gains the cursor with it. */
[data-drag-handle] { cursor:move; user-select:none; -webkit-user-select:none; }

/* ---- FBQ-001 #20 — the section an open modal is adding to ----
   The scrim darkens the workspace at z 200000; the one section being written into lifts above it,
   paints its own panel ground back over the darkening, and pulses a hairline ring. That is the whole
   answer to "where is this going?" — the screen says it, not the dialog's title.

   position:relative + a z-index above the scrim is all the lift takes: no ancestor of a record or a
   note section creates a stacking context (.re and .rps are checked, .wp and .ws-workspace carry no
   z-index or transform), so 200001 is resolved against the root one. The 6px box-shadow bleed is the
   ground, and the ring is painted behind it from 6px out, so the two never fight. */
.add-target { position:relative; z-index:200001; background:var(--panel); border-radius:10px; animation:hc-add-pulse 1.9s ease-in-out infinite; }
@keyframes hc-add-pulse {
    0%   { box-shadow:0 0 0 6px var(--panel), 0 0 0 7px rgba(0,0,0,0); }
    50%  { box-shadow:0 0 0 6px var(--panel), 0 0 0 8px var(--accentBorder); }
    100% { box-shadow:0 0 0 6px var(--panel), 0 0 0 7px rgba(0,0,0,0); }
}

/* ---- visit note status banners ---- */
.note-signed { display:flex; align-items:center; gap:8px; padding:9px 20px; font:600 .9375rem var(--fUi); color:var(--q-ok); background:var(--q-ok-bg); }
.note-signed svg { flex:none; }
.note-void { display:flex; align-items:flex-start; gap:8px; padding:9px 20px; font:600 .9375rem var(--fUi); color:var(--q-warn); background:var(--q-warn-bg); line-height:1.5; }
.note-void svg { flex:none; margin-top:1px; }

/* ---- status-bar deselect patient ---- */
.ws-deselect { border:1px solid var(--border); background:none; color:var(--dim); cursor:pointer; font:700 10.5px var(--fUi); padding:2px 8px; border-radius:6px; }
.ws-deselect:hover { color:var(--text); border-color:var(--accent); }

/* ============================================================
   Hairline ledger (.hl-*) — the Medical Record + SOAP Notes
   field-entry redesign. Values are exact from the design
   prototype (Field Entry Re-Design). All reveals are pure CSS
   (:hover / :focus / :focus-within — no C# mouse state); the
   focus rules must stay AFTER the hover rules (equal
   specificity, last wins). Line-heights are explicit or set
   via the font: shorthand — the app body's 1.5 must not leak.
   ============================================================ */

/* -- section shell -- */
.hl-sec { margin-bottom:13px; }
.hl-sec.soap { margin-bottom:15px; }
.hl-sec.soap.last { margin-bottom:6px; }
.hl-head { display:flex; align-items:center; gap:9px; margin-bottom:3px; height:18px; }
.hl-head.soap { margin-bottom:5px; height:auto; }
.hl-lbl { font:700 10.5px var(--fUi); letter-spacing:.08em; text-transform:uppercase; color:var(--dim); }
.hl-lbl.danger { color:var(--danger); }   /* Allergies */
.hl-lbl.accent { color:var(--accent); }   /* S / O / A / P */
.hl-rule { flex:1; height:1px; background:var(--border); }

/* SOAP header history clock (24px; the "on" state mirrors hover — production keeps it wired) */
.hl-histbtn { display:flex; align-items:center; justify-content:center; width:24px; height:24px; border:1px solid var(--border); border-radius:6px; color:var(--dim); cursor:pointer; flex:none; background:var(--panel); padding:0; }
.hl-histbtn:hover, .hl-histbtn.on { color:var(--accent); border-color:var(--accent); }

/* -- wall (2px left rule + accent overlay: 0 rest → .35 section hover → 1 while writing) -- */
.hl-wall { position:relative; border-left:2px solid var(--border); padding-left:11px; }
.hl-wallbar { position:absolute; left:-2px; top:0; bottom:0; width:2px; background:var(--accent); opacity:0; transition:opacity .15s; pointer-events:none; }
.hl-wallbar.soap { left:0; }   /* prototype places SOAP bars inside the border, MR bars over it */

/* -- free-text fields (borderless, auto-grown by hcAutogrow — no inner scrollbars ever) --
      .hl-note is R-025 P3's HyperText surface now, not a textarea: `resize` and `overflow:hidden`
      were textarea-only and are dropped, and the height floor `rows="1"` used to give it comes from
      .rtf's min-height. It still takes :focus, so the wall/pencil reveals below are untouched. -- */
.hl-note { display:block; width:100%; margin:0 0 2px; border:none; background:transparent; padding:2px 0; font-size:12.5px; line-height:1.5; color:var(--text); font-family:inherit; outline:none; }
.hl-fieldwrap { position:relative; }
.hl-soapfield { display:block; width:100%; border:none; border-radius:0; background:transparent; padding:1px 0; font-size:13.5px; line-height:1.6; color:var(--text); font-family:inherit; resize:none; outline:none; overflow:hidden; }
.hl-soapfield.walled { border-left:2px solid var(--border); padding:1px 0 1px 11px; transition:border-color .15s; }   /* Subjective: wall on the textarea itself */
.hl-read { font-size:13.5px; line-height:1.6; color:var(--text); white-space:pre-wrap; padding:1px 0; }   /* signed read-only text block */

/* -- edit pencil (plain icon — no border/bg/shadow) -- */
.hl-pen { position:absolute; display:flex; align-items:center; justify-content:center; width:18px; height:18px; color:var(--dim); opacity:0; transition:opacity .15s; pointer-events:none; }
.hl-pen.mr { top:2px; right:0; }
.hl-pen.soap { right:2px; bottom:4px; }

/* -- light divider (visibly lighter than the header hairline) -- */
.hl-div { height:1px; background:var(--border); opacity:.45; margin:2px 0 3px; }
.hl-div.soap { margin:6px 0 6px; }

/* -- ledger rows (wrapper holds ONLY rows so :nth-child zebra counts cleanly) -- */
.hl-rows { }
.hl-row { display:grid; grid-template-columns:1fr auto auto; gap:10px; align-items:center; padding:2px 5px; margin:0 -5px; border-radius:4px; }
.hl-row.status { grid-template-columns:1fr auto auto auto; }   /* dx / orders / rx: + status-tag column */
.hl-rows > .hl-row:nth-child(odd) { background:var(--head); }          /* 1st, 3rd… = darker stripe */
.hl-rows > .hl-row:nth-child(even) { background:var(--zebraAlt); }
.hl-rowtext { font-size:13.5px; line-height:1.5; }
.hl-meta { font:500 11px var(--fData); color:var(--faint); white-space:nowrap; cursor:pointer; }
.hl-meta:hover { color:var(--accent); }
.hl-tag { font:600 10.5px var(--fData); }   /* lowercase status tag: "draft" etc. */
.hl-tag.warn { color:var(--warn); }
.hl-tag.dim { color:var(--dim); }
.hl-tag.ok { color:var(--ok); }
.hl-tag.danger { color:var(--danger); }

/* -- row actions (revealed per row; hidden = also unclickable) -- */
.hl-acts { display:flex; gap:2px; opacity:0; pointer-events:none; transition:opacity .15s; }
.hl-act { width:18px; height:18px; border:none; background:none; color:var(--dim); cursor:pointer; padding:0; display:flex; align-items:center; justify-content:center; border-radius:4px; }
.hl-act:hover { color:var(--accent); background:var(--accentSoft); }
.hl-act.del:hover { color:var(--danger); background:var(--dangerSoft); }

/* -- add action (always visible — it doubles as the list's zero-state; user revision over the
      prototype's hover-reveal + "None recorded") -- */
.hl-add { display:flex; align-items:center; gap:5px; border:none; background:none; color:var(--accent); cursor:pointer; padding:0; margin-top:1px; height:18px; font:600 12px var(--fUi); }
.hl-add:hover { text-decoration:underline; }
.hl-add.vital { gap:4px; margin:0 0 0 3px; height:auto; font:600 11.5px var(--fUi); }

/* -- sub-list micro-labels (Vitals / Diagnosis / Orders / Prescriptions) -- */
.hl-sublbl { font:700 10px var(--fUi); letter-spacing:.06em; text-transform:uppercase; color:var(--dim); }
.hl-sublbl.list { margin-bottom:1px; }
.hl-sublbl.stack { margin:7px 0 1px; }    /* Prescriptions — second list in Plan */
.hl-sublbl.inline { margin-right:2px; }   /* "Vitals" inside the pill row */
.hl-sublbl-row { display:flex; align-items:center; gap:8px; margin-bottom:1px; }   /* label row */
.hl-sublbl-row.stack { margin:7px 0 1px; }   /* second list in Plan (Prescriptions) */

/* -- vitals pills (zebra-exempt; inner actions toggle display, not opacity) -- */
.hl-pillrow { display:flex; align-items:center; gap:6px; flex-wrap:wrap; }
.hl-pill { display:inline-flex; align-items:center; gap:5px; background:var(--head); border:1px solid var(--border); border-radius:999px; padding:3px 10px; }
.hl-pill-tag { font:700 9.5px var(--fUi); letter-spacing:.04em; text-transform:uppercase; color:var(--dim); }
.hl-pill-val { font:600 12px var(--fData); color:var(--text); }
.hl-pill-val.abn { color:var(--danger); }   /* out-of-range reading */
.hl-pill-acts { display:none; gap:1px; align-items:center; margin:0 -5px 0 -1px; }
.hl-pill:hover .hl-pill-acts { display:flex; }
.hl-pill-btn { width:16px; height:16px; border:none; background:none; color:var(--dim); cursor:pointer; padding:0; display:flex; align-items:center; justify-content:center; border-radius:50%; }
.hl-pill-btn:hover { color:var(--accent); }
.hl-pill-btn.del:hover { color:var(--danger); }

/* -- reveals: section hover -- */
.hl-sec:hover .hl-pen { opacity:1; }
.hl-sec:hover .hl-wallbar { opacity:.35; }
.hl-row:hover .hl-acts, .hl-row:focus-within .hl-acts { opacity:1; pointer-events:auto; }

/* -- reveals: field focus (AFTER the hover rules — wall to 100%, pencil hides).
      DOM contract: the wallbar/pen spans render after their textarea (as in the prototype). -- */
.hl-note:focus ~ .hl-wallbar,
.hl-soapfield:focus ~ .hl-wallbar,
.hl-fieldwrap:focus-within ~ .hl-wallbar { opacity:1; }
.hl-note:focus ~ .hl-pen,
.hl-soapfield:focus ~ .hl-pen { opacity:0; }

/* history-insert flash: the wall lights up instead of the old boxed-border flash */
.hl-wallbar.fh-flash { opacity:1; }

/* -- signed read-only sections: no reveals at all -- */
.hl-sec.readonly .hl-add, .hl-sec.readonly .hl-acts, .hl-sec.readonly .hl-pen { display:none; }
.hl-sec.readonly:hover .hl-wallbar { opacity:0; }
.hl-sec.readonly .hl-pill:hover .hl-pill-acts { display:none; }

/* -- panel scroll bodies (fixed header stack above, fixed footer below) -- */
.hl-body { flex:1 1 0; min-height:0; overflow:auto; overflow-x:hidden; padding:14px 20px 20px; }   /* Medical Record */
.hl-body.soap { padding:16px 20px 12px; }                                        /* SOAP Notes */

/* Prototype's dual scrollbar declaration: Chromium ≥121 honors the standard properties (thin,
   .4 thumb); WKWebView below Safari 18.2 uses the webkit rules. Matches per-engine rendering. */
.hl-scroll { scrollbar-width:thin; scrollbar-color:rgba(130,140,150,.4) transparent; }
.hl-scroll::-webkit-scrollbar { width:9px; height:9px; }
.hl-scroll::-webkit-scrollbar-thumb { background:rgba(130,140,150,.35); border-radius:6px; border:2px solid transparent; background-clip:padding-box; }
.hl-scroll::-webkit-scrollbar-track { background:transparent; }

/* ============================================================
   Hairline-ledger add/edit dialog (.hld-*) — the card hosted by
   DockedModalHost's centred modal (FBQ-001 #14 reversed R-025
   P6.5's divider dock; the .dmod-card that sizes it is in that
   component's own style block).

   FBQ item 3 (owner): the dialog used to open with a HORIZONTAL
   scrollbar and no way to make it bigger. Two causes, both fixed
   here — the card was drawn for a fixed 372px that the six-field
   medication form does not fit, and .hld-body scrolled on BOTH
   axes, so any child a pixel too wide bought a scrollbar rather
   than a wrap. The body now scrolls vertically only and every
   field box is bounded to the content width; anything that
   cannot shrink must wrap instead.
   ============================================================ */
/* HT-006 7 — ONE shell, seven bodies. The header is no longer a tinted bar: it is the card's own
   ground with a hairline under it, so the dialog reads as one surface rather than as a strip over a
   form. Title 18px/700; the close is a 30px glyph button. */
.hld-modal { display:flex; flex-direction:column; min-height:0; width:100%; max-width:100%; background:var(--q-bg); border:1px solid var(--q-rule-strong); border-radius:13px; overflow:hidden; box-sizing:border-box; }
.hld-head { flex:none; display:flex; align-items:center; gap:12px; padding:15px 18px 13px; border-bottom:1px solid var(--q-rule); background:transparent; }
.hld-title { flex:1; min-width:0; overflow-wrap:anywhere; font:700 1.125rem var(--fUi); color:var(--q-ink); }
.hld-close { flex:none; margin-left:0; width:30px; height:30px; border:none; background:none; color:var(--q-mute); cursor:pointer; border-radius:8px; display:flex; align-items:center; justify-content:center; padding:0; }
.hld-close:hover { background:var(--q-frame); color:var(--q-ink); }
/* padding 16px, not 14: the hosted vitals composer pulls its own footer out to the card edge with
   -16px margins and .hld-foot's buttons sit 16px in, so a 14px body left that footer 4px too wide —
   one of the two things the clinician saw as an x-scrollbar.
   max-height uses min() and not a bare vh: under Windows' CSS-zoom leg viewport units are NOT
   scaled, so the px arm is the one that wins there — degraded to the old fixed cap rather than a
   modal running off the screen. */
/* The ONLY scrolling region. No vh cap: the layer's 78/40 padding already caps the card, and
   viewport units are unscaled under the Windows CSS-zoom leg (CLAUDE.md). */
.hld-body { flex:1; min-height:0; padding:16px 18px 18px; display:flex; flex-direction:column; gap:13px; overflow-x:hidden; overflow-y:auto; }
/* Every field slot is a flex item; without this a long word or an unshrinkable control widens the
   whole column instead of wrapping inside its own box. */
.hld-body > * { min-width:0; max-width:100%; }
.hld-lbl { font:700 .6875rem var(--fUi); letter-spacing:.1em; text-transform:uppercase; color:var(--q-mute); margin-bottom:6px; }
/* 38px on the FRAME ground with the heavier --line border. Focus is the accent BORDER only — the
   prototype has no ring, and a ring plus a border read as two states at once. */
.hld-input { box-sizing:border-box; width:100%; max-width:100%; height:38px; border:1px solid var(--q-rule-strong); border-radius:9px; padding:0 12px; font-family:var(--fUi); font-size:.9375rem; color:var(--q-ink); background:var(--q-frame); outline:none; }
.hld-input::placeholder, .hld-area::placeholder { color:var(--q-mute2); }
/* A measurement, a time or a date wears the mono face — the field's own signal about what it holds. */
.hld-input.mono { font-family:var(--fMono); }
/* Free-text notes WRAP instead of scrolling sideways inside a one-line box (owner, item 3), and the
   drag handle is also the answer to "there's no way to make it bigger" for the one field that
   sometimes needs to be. */
.hld-area { height:auto; min-height:74px; padding:10px 12px; line-height:1.6; resize:none; white-space:pre-wrap; overflow-wrap:anywhere; }
.hld-select { width:100%; max-width:100%; height:38px; border:1px solid var(--q-rule-strong); border-radius:9px; padding:0 10px; font-family:var(--fUi); font-size:.9375rem; color:var(--q-ink); background:var(--q-frame); outline:none; }
.hld-input:focus, .hld-select:focus, .hld-tokfield:focus { border-color:var(--q-accent); box-shadow:none; }
/* Two fields side by side — the design's grid, used by every body that has a natural pair. */
.hld-two { display:grid; grid-template-columns:1fr 1fr; gap:12px; }
.hld-field { display:flex; flex-direction:column; gap:6px; }
.hld-field .hld-lbl { margin-bottom:0; }
/* R-025 P3 — a narrative field that holds a citation, shown in the entry dialog's field slot. It
   keeps the input's box so the form does not reflow, and grows instead of scrolling. */
.hld-tokfield { width:100%; max-width:100%; min-height:38px; border:1px solid var(--q-rule-strong); border-radius:9px; padding:9px 12px; font-size:.9375rem; color:var(--q-ink); background:var(--q-frame); overflow-wrap:anywhere; }
/* A coded field that was typed but never picked from the list — refused at Save (EntryDialog). */
.hld-err { margin-top:5px; color:var(--q-bad); font:600 .8125rem var(--fUi); }
/* The footer is the card's ground too, with room on the LEFT for a red Delete in edit mode. */
.hld-foot { flex:none; display:flex; flex-wrap:wrap; justify-content:flex-end; align-items:center; gap:10px; padding:13px 18px; border-top:1px solid var(--q-rule); background:transparent; }
.hld-btn { height:38px; display:inline-flex; align-items:center; border:1px solid var(--q-rule-strong); background:var(--q-bg); color:var(--q-ink); cursor:pointer; border-radius:9px; font:600 .9375rem var(--fUi); padding:0 16px; }
.hld-btn:hover { background:var(--q-frame); }
/* The primary NAMES ITS DESTINATION ("Add to note" / "Add to record"), and is the app's one accent. */
.hld-btn.primary { border:none; background:var(--q-accent); color:#fff; font:700 .9375rem var(--fUi); }
.hld-btn.primary:hover { filter:brightness(1.07); }
.hld-btn.danger { margin-right:auto; border-color:var(--q-bad); color:var(--q-bad); background:transparent; }
.hld-btn.danger:hover { background:var(--dangerSoft); }
/* status-move footer extra (Stop/Resume · Resolve/Reactivate) sits left of the spacer */
.hld-move { margin-right:auto; height:38px; display:inline-flex; align-items:center; border:1px solid var(--q-rule-strong); background:var(--q-bg); color:var(--q-mute); cursor:pointer; border-radius:9px; font:600 .875rem var(--fUi); padding:0 14px; }
.hld-move:hover { color:var(--accent); border-color:var(--accent); }
.hld-move.on { color:var(--warn); border-color:var(--warn); background:var(--warnSoft); }

/* Coded typeahead (CodedSearch / CodeSearch) restyled to the dialog's 36px input spec —
   scoped here so the panel composers keep their existing look. */
/* The coded search takes the dialog's own field box: 38px on the frame ground, 9px corners, and a
   34px left inset for the magnifier the design puts inside every code field. */
.hld-modal .cds-input { min-height:38px; height:38px; max-width:100%; border:1px solid var(--q-rule-strong); border-radius:9px; padding:0 12px 0 34px; font-size:.9375rem; background:var(--q-frame); color:var(--q-ink); }
.hld-modal .cds-input:focus { border-color:var(--q-accent); box-shadow:none; }
.hld-modal .cds-chip { min-height:38px; max-width:100%; border-radius:9px; }
/* The magnifier and the system tag (ICD-10 / SNOMED / RxNorm / LOINC) that ride inside the box. */
.hld-codewrap { position:relative; display:flex; }
.hld-codeglass { position:absolute; left:11px; top:11px; display:flex; color:var(--q-mute); pointer-events:none; z-index:2; }
.hld-codetag { position:absolute; right:11px; top:10px; color:var(--q-mute); font:.75rem var(--fMono); pointer-events:none; z-index:2; }
.hld-codewrap .cds-input { padding-right:64px; }

/* Sync-conflict before/after cards retain the old diff-state vocabulary. */
.an-diff { display:flex; flex-direction:column; gap:7px; border:1px solid var(--border); border-radius:11px; padding:10px 12px; }
.an-diff-head { display:flex; align-items:center; gap:9px; }
.an-state { font:700 9.5px var(--fUi); letter-spacing:.05em; text-transform:uppercase; padding:2px 7px; border-radius:6px; }
.an-state.replace { color:var(--warn); background:var(--warnSoft); }
.an-state.same { color:var(--faint); background:var(--bg); }

/* ---- R-024: the note's manage links, now that the line-item sub-lists are gone ---- */

/* ================================================================================================
   R-025 P3 — the HyperText TOKEN rules, hoisted out of NoteTokenField.razor.

   Everything `hcNoteTokens.set` puts inside a HyperText surface is styled HERE, globally, because a
   component <style> block is only live while that component RENDERS. The note field renders under
   the SOAP tab; the record's narrative fields render under Medical Record. Left in the component,
   every token in a record field would have painted as a bare unstyled span.

   What stayed behind in NoteTokenField.razor is the note's own chrome — the editable surface, the
   typing preview, the floating + Add, the coded-search dropdown and the schema hint — none of which
   a record field has (a citation resolves nothing: no composer, no grammar, no reconciler).

   `.hct-ro` is the read-only opt-in a non-note surface carries; the note keeps `.hct-field.frozen`,
   so its rendering is byte-for-byte what P2 shipped.
   ================================================================================================ */

/* ---- the token itself: HT-006's "solid key" — two halves, no gap, no border, one atom ----
   R-024 drew a token as a bordered pill with a 3px coloured left edge and a grey name half, so the
   hue was a hairline and the chip read as chrome. HT-006 makes the NAME the colour: 26px tall, 6px
   radius, no border at all; the name half is the solid category hue with white text at 700, and the
   value half is that same hue at ~12% over white (light) or a 20% wash (dark), with the value in
   mono at body ink. The hue pair is passed down as --hct-hue / --hct-hue-v so the species rules
   below are two lines each and a re-hue is one edit in the palette. */
.hct {
    --hct-hue: var(--tok-fu);
    --hct-hue-v: var(--tok-fu-v);
    position: relative;
    display: inline-flex;
    align-items: stretch;
    vertical-align: middle;
    height: 26px;
    margin: -2px 3px 0;
    padding: 0;
    border: 0;
    border-radius: 6px;
    background: none;
    font-family: var(--fUi);
    font-size: .875rem;
    cursor: pointer;
    user-select: none;
}
.hct-field.frozen .hct, .hct-ro .hct { cursor: default; }

/* The chip does not clip (its hover-x floats outside it), so each half rounds its own outer corners. */
.hct-k {
    display: flex; align-items: center; padding: 0 9px; border-radius: 6px 0 0 6px;
    background: var(--hct-hue); color: #fff;
    font-weight: 700; line-height: 1; white-space: nowrap;
}
.hct-k:last-child, .hct-k:has(+ .hct-x) { border-radius: 6px; }
.hct-v2 {
    display: flex; align-items: center; padding: 0 9px; border-radius: 0 6px 6px 0;
    background: var(--hct-hue-v); color: var(--q-ink);
    font-family: var(--fData); font-weight: 400; line-height: 1; white-space: nowrap;
}

/* Species. HT-006 counts three token hues — vitals violet, diagnoses terracotta, medications green —
   plus the two the visit table's counts also need. Nothing else in the app is coloured. */
.hct-v  { --hct-hue: var(--tok-vit);   --hct-hue-v: var(--tok-vit-v); }
.hct-dx { --hct-hue: var(--tok-dx);    --hct-hue-v: var(--tok-dx-v); }
.hct-rx { --hct-hue: var(--tok-rx);    --hct-hue-v: var(--tok-rx-v); }
.hct-or { --hct-hue: var(--tok-order); --hct-hue-v: var(--tok-order-v); }
.hct-fu { --hct-hue: var(--tok-fu);    --hct-hue-v: var(--tok-fu-v); }

/* The nine per-vital names R-024 gave a hue each are all --tok-vit now (see the palette header), so
   these nine rules resolve to one violet. They are KEPT rather than collapsed to the one selector
   above: the class still names the vital, so a future per-vital treatment has somewhere to land and
   a re-hue of any single name still works without touching this file. */
.hct-v.hct-bp   { --hct-hue: var(--tok-bp); }
.hct-v.hct-hr   { --hct-hue: var(--tok-hr); }
.hct-v.hct-tp   { --hct-hue: var(--tok-t); }
.hct-v.hct-rr   { --hct-hue: var(--tok-rr); }
.hct-v.hct-ox   { --hct-hue: var(--tok-spo2); }
.hct-v.hct-wt   { --hct-hue: var(--tok-wt); }
.hct-v.hct-ht   { --hct-hue: var(--tok-ht); }
.hct-v.hct-bmi  { --hct-hue: var(--tok-bmi); }
.hct-v.hct-pain { --hct-hue: var(--tok-pain); }

/* ---- the review's decorations: HT-006 marks a proposal with a BAND, not a label ----
   The section editor IS the review surface, so what a decision would do is painted onto the words
   themselves. R-024 said it with a wash plus a dashed underline plus, in the margin, the words NEW
   and REWORDED. HT-006 says it with one capsule: a 3px solid left rule and a matching wash, green
   for an addition and amber for a rewrite. No label — the band is the signal.

   The left rule is an INSET BOX-SHADOW, never a border: a border on an inline span inside running
   prose adds 3px to the line box and reflows the sentence the moment a proposal appears, which is
   the one thing a reviewer reading a paragraph must not see happen.

   The green is RESERVED. It is #00a37a / #2de2a8 — a hue that appears nowhere else in the app — so
   a proposal can never be mistaken for the medications chip, a sync success or a signed visit. */
/* display:inline, not inline-flex: a reworded CLAUSE is prose and has to wrap, and an inline-flex
   band cannot. box-decoration-break:clone repeats the padding, the radius AND the 3px rule on every
   line fragment, so a wrapped band still reads as one banded thing rather than as a box with a
   ragged tail. */
.hct-rv-fresh, .hct-rv-amber {
    display: inline; -webkit-box-decoration-break: clone; box-decoration-break: clone;
    padding: 3px 6px 3px 7px; border-radius: 8px;
}
.hct-rv-fresh { background: var(--q-prop-bg); box-shadow: inset 3px 0 0 var(--q-prop); }
.hct-rv-amber { background: var(--q-rw-bg);   box-shadow: inset 3px 0 0 var(--q-rw); }
/* Wording on its way out keeps the strike, in the record-danger red. */
.hct-rv-struck { text-decoration: line-through; text-decoration-color: var(--q-bad); color: var(--q-mute); cursor: pointer; }
/* A token the analysis PROPOSES wears the same green band as proposed prose. R-024's dashed border
   is gone with the token's border — a solid key has none to dash. */
.hct.hct-rv-proposed { box-shadow: inset 3px 0 0 var(--q-prop); }
.hct.hct-rv-withdrawn { opacity: .45; cursor: pointer; }
.hct.hct-rv-withdrawn .hct-k, .hct.hct-rv-withdrawn .hct-v2 { text-decoration: line-through; }
.hct-rv-deco { user-select: none; }
.hct-rv[data-edit]:hover, .hct[data-edit]:hover { outline: 2px solid var(--accentBorder); outline-offset: 1px; border-radius: 4px; }

/* ---- the pointer species (R-025 P2) ---- */

/* The citation: the token family's pill at citation scale (HT-001 anatomy) — 3px orchid left
   rule, a filled 9px quote glyph, the label in 10px mono; radius 5px, riding 2px above the
   baseline, several stacking after one phrase. */
.hct-ci {
    height: auto;
    align-items: center;
    gap: 4px;
    padding: 1px 6px 1px 5px;
    margin: 0 0 0 5px;
    vertical-align: 2px;
    border: 1px solid var(--q-rule, var(--border));
    border-left: 3px solid var(--tok-ci);
    border-radius: 5px;
    background: var(--q-raise, var(--head));
}
.hct-ci .hct-cig { display: flex; align-items: center; color: var(--tok-ci); }
.hct-ci .hct-k { padding: 0; background: none; color: var(--q-ink2, var(--dim)); font: 500 10px/1.6 var(--fData); }
.hct-field.frozen .hct-ci, .hct-ro .hct-ci { cursor: pointer; }   /* the popover is read-only — it works on a signed note */

/* The figure: a text-less 30×25 glyph prefacing its phrase — lime left rule, 15px photo icon,
   a count badge when figures stack. The words are the object; the glyph only points. */
.hct-fg {
    width: 30px;
    height: 25px;
    margin: -2px 6px 0 0;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    border: 1px solid var(--q-rule, var(--border));
    border-left: 3px solid var(--tok-fg);
    border-radius: 7px;
    background: var(--q-raise, var(--head));
    color: var(--tok-fg);
}
.hct-fg .hct-fgg { display: flex; align-items: center; justify-content: center; }
.hct-fgn { font: 700 9px/1 var(--fData); padding-left: 2px; }
.hct-fg-more { display: none; }   /* stacked figures collapse to one glyph with a count */
.hct-fg.hov, .hct-field.frozen .hct-fg, .hct-ro .hct-fg { cursor: pointer; }

/* The covered phrase. One mechanism, two anchors: a citation underlines the text BEFORE its
   pill, a figure the text AFTER its glyph. The CITED phrase is deliberately DEMOTED to a
   neutral grey rule at rest (HT-002 2a) — a citation is a reference, not a picture; the token
   pill carries the orchid, the words stay quiet. */
.hct-pspan { border-radius: 2px; }
.hct-cispan { padding: 0 2px; border-radius: 4px; border-bottom: 1px solid var(--q-rule, var(--border)); cursor: pointer; }
.hct-cispan.clause-hov { border-bottom-color: var(--q-ink2, var(--dim)); background: rgba(124, 140, 166, .14); }
.hct-cispan.chip-hov { border-bottom: 2px solid var(--tok-ci); background: var(--tok-ci-wash); }
.hct-fgspan { text-decoration: underline 2px var(--tok-fg-faint); text-underline-offset: 3px; }
.hct-fgspan.hov { text-decoration-color: var(--tok-fg); background: var(--tok-fg-wash); }
/* Hover never touches the 3px species rule — it is the constant mark of the species. */
.hct-fg.hov { border-color: var(--tok-fg-line); border-left-color: var(--tok-fg); background: var(--tok-fg-wash); }
.hct-ci.chip-hov {
    border-top-color: var(--tok-ci-line); border-right-color: var(--tok-ci-line);
    border-bottom-color: var(--tok-ci-line); border-left-color: var(--tok-ci);
    border-left-width: 3px; background: var(--tok-ci-wash); color: var(--q-ink);
}
.hct-ci.chip-hov .hct-k { color: var(--q-ink); }


/* The caret INSIDE a cited or figured phrase (R-025 P3.5, owner 2026-08-27). The model is a
   markdown code span: the phrase is a live region of text, so editing inside it should look and feel
   like editing inside a delimited thing rather than like editing prose that happens to be underlined.
   The wash is the species' own, so a citation and a figure each read as themselves; the rule firms up
   at the same time so the region's EDGES are legible — knowing where it ends is what tells you
   whether the next character you type will join the citation or fall outside it. */
.hct-cispan.incaret { border-bottom-color: var(--tok-ci); background: var(--tok-ci-wash); }
.hct-fgspan.incaret { text-decoration-color: var(--tok-fg); background: var(--tok-fg-wash); }
/* The mark itself lights with its phrase, so the pair reads as one object while the caret is in it. */
.hct-ci.incaret { border-color: var(--tok-ci-line); border-left-color: var(--tok-ci); background: var(--tok-ci-wash); }
.hct-fg.incaret { border-color: var(--tok-fg-line); border-left-color: var(--tok-fg); background: var(--tok-fg-wash); }

/* The hover-x: the only destructive control in the reading surface. It floats at the chip's top right
   exactly as the record pill's strip does (RecordProseSection.razor), with the same hover pad above the
   chip, so showing it never widens the chip or reflows the line. */
.hct-x {
    position: absolute; left: 100%; bottom: calc(100% - 9px); margin-left: -14px; z-index: 9;
    display: none; align-items: center; box-sizing: content-box; height: 21px; padding: 0 6px;
    border: 1px solid var(--q-line); border-radius: 7px;
    background: color-mix(in srgb, var(--q-bad) 18%, var(--q-raise)); color: var(--q-bad);
    box-shadow: 0 8px 20px rgba(0,0,0,.5);
    font: 700 13px/1 var(--fUi); cursor: pointer;
}
.hct:hover .hct-x { display: flex; }
.hct:hover:has(.hct-x)::after { content: ""; position: absolute; left: -4px; right: -46px; bottom: 100%; height: 14px; }

/* ---- R-025 P3: the record narrative field's own surface (RecordTokenField.razor) ----
   A contenteditable div, unlike the textarea it replaced, does not preserve newlines and has no
   intrinsic height — `rows="1"` used to set the floor. It grows natively, which is what let P3 drop
   the hcAutogrow dependency for these fields (autogrow.js stays: the note's follow-up reason is
   still a textarea). Everything else about how a field LOOKS is its host's — the ledger passes
   .hl-note, the entry dialogs pass their own. */
.rtf { white-space: pre-wrap; overflow-wrap: break-word; min-height: 19px; outline: none; }
/* A chip armed for removal by one Backspace (hcNoteTokens: the second press removes it). A constant,
   not a theme token: it is the same red in both themes. */
.hct.hct-doomed { outline: 2px solid var(--q-bad); outline-offset: 1px; border-radius: 6px; }
.rtf[data-empty]:not(:focus)::before { content: attr(data-placeholder); color: var(--q-mute); }
/* P3's `.rtf.locked` is GONE (P3.5): a field holding a citation used to freeze its prose entirely,
   which meant correcting one word cost every citation in the sentence. A cited phrase is a live
   region now — see .hct-*span.incaret above. */

/* ---- the browser app on narrower screens ----
   The browser's host page marks its root .hc-web, so the desktop app never takes these rules. At desktop sizes
   nothing changes; below them only these media queries change the layout, because the screens' markup is shared. */

/* Below 1,320px the patient rail folds to its 52px strip and opens over the chart while the pointer or focus
   is in it. A rail the person collapsed themselves keeps its chips. */
@media (max-width: 1319.98px) {
  .hc-web .ws-workspace:not(.patients-collapsed) { --ws-patient-width:52px; }
  .hc-web .wp-patients { position:relative; z-index:20; }
  .hc-web .ws-workspace:not(.patients-collapsed) > .wp-patients:is(:hover, :focus-within) { width:262px; margin-right:-210px; box-shadow:var(--shadow); }
}

/* Tablets: one chart column. The summary and the visit each keep a full workspace height, so their own
   scrolling is unchanged, and the workspace scrolls from one to the other. */
@media (max-width: 1024px) {
  .hc-web .ws-workspace { display:grid; grid-template-columns:var(--ws-patient-width) minmax(0, 1fr); grid-auto-rows:100%; overflow-y:auto; }
  .hc-web .ws-workspace > .wp-patients { grid-row:1; position:sticky; top:0; }
  .hc-web .ws-workspace > :not(.wp-patients) { grid-column:2; }
  .hc-web .ws-coldiv { display:none; }
}

/* Phones: everything stacked, the patient list on top, then the summary, then the visit. The important padding
   beats the inline padding the workstation reserves for an open drawer: on a phone the drawer covers the chart
   instead of squeezing it to nothing. */
@media (max-width: 640px) {
  .hc-web .ws-top { height:auto; flex-wrap:wrap; gap:8px; padding:8px; }
  .hc-web .ws-search { order:1; flex-basis:100%; min-width:0; }
  .hc-web .ws-workspace { grid-template-columns:minmax(0, 1fr); grid-template-rows:minmax(0, 40%); gap:8px; padding:8px; padding-right:8px !important; }
  .hc-web .ws-workspace > .wp-patients,
  .hc-web .ws-workspace:not(.patients-collapsed) > .wp-patients:is(:hover, :focus-within) { position:static; width:auto; margin-right:0; box-shadow:none; }
  .hc-web .ws-workspace > :not(.wp-patients) { grid-column:1; }
}
