  /* ---------- Home (two-patient) ---------- */
  /* Tiles size to their own content. Stretching both panels to the tallest
     left a dead zone of several hundred pixels under the quieter patient —
     and the chat launcher floating in the middle of it. */
  .home-grid{
    display:grid;
    grid-template-columns:1fr;
    gap:18px;
    align-items:start;
  }
  @media (min-width:1100px){
    .home-grid.two{grid-template-columns:1fr 1fr}
  }

  /* Ward / ER board: one ordered column of identity bands, each console folded
     behind its own disclosure. Single column at every width on purpose — the
     board is read top to bottom in priority order, and two columns would put
     the second-sickest patient beside the sickest instead of under them. */
  .home-board{display:flex;flex-direction:column;gap:10px}
  .home-board-head{
    display:flex;align-items:center;gap:12px;padding:10px 12px;
    border:1px solid var(--border);border-radius:var(--radius-3);background:var(--card-2);
  }
  .home-board-head > div{display:flex;align-items:baseline;gap:9px;min-width:0}
  .home-board-head b{font-size:13px;color:var(--ink);white-space:nowrap}
  .home-board-head span{font-size:10.5px;color:var(--muted)}
  .home-board-count{margin-left:auto;white-space:nowrap;font-weight:750}
  .home-board[data-board-unit="ward"] .home-board-head{border-left:3px solid var(--purple)}
  .home-board[data-board-unit="er"] .home-board-head{border-left:3px solid var(--warn)}
  .home-board .board-row .ppanel-head{padding:12px 14px}
  .board-more{border-top:1px solid var(--hairline)}
  .board-more > summary{
    padding:8px 14px;cursor:pointer;list-style:none;
    font-size:11px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;
    color:var(--muted);
  }
  .board-more > summary::-webkit-details-marker{display:none}
  .board-more > summary::before{content:"▸ ";color:var(--faint)}
  .board-more[open] > summary::before{content:"▾ "}
  .board-more > summary:hover{color:var(--ink-2);background:var(--card-2)}
  .board-more > summary:focus-visible{outline:2px solid var(--brand);outline-offset:-2px}

  .ppanel{
    background:var(--card);border:1px solid var(--border);
    border-radius:var(--radius-4);overflow:hidden;
    box-shadow:var(--shadow-1);
    position:relative;
  }
  /* Tier-colored top ribbon — restrained accent, not a glowing halo. */
  .ppanel.tier-resus{border-color:rgba(59,130,246,.45)}
  .ppanel.tier-stab {border-color:rgba(255,82,102,.50)}
  .ppanel.tier-enh  {border-color:rgba(251,191,36,.45)}
  .ppanel.tier-std  {border-color:rgba(46,204,113,.40)}
  .ppanel-tier-ribbon{
    height:3px;width:100%;background:var(--inact);
  }
  .ppanel.tier-resus .ppanel-tier-ribbon{background:linear-gradient(90deg,var(--resus),#60a5fa)}
  .ppanel.tier-stab  .ppanel-tier-ribbon{background:linear-gradient(90deg,var(--stab),#ff8a9b)}
  .ppanel.tier-enh   .ppanel-tier-ribbon{background:linear-gradient(90deg,var(--enh),#fcd34d)}
  .ppanel.tier-std   .ppanel-tier-ribbon{background:linear-gradient(90deg,var(--std),#6ee7b7)}
  .ppanel-head{
    padding:16px 18px;
    background:linear-gradient(180deg,var(--card-2),var(--card));
    border-bottom:1px solid var(--hairline);
  }
  .ppanel-id{display:flex;align-items:flex-start;gap:12px}
  .ppanel-id .avatar{
    width:48px;height:48px;border-radius:12px;
    color:#fff;font-weight:700;font-size:16px;flex-shrink:0;
    display:flex;align-items:center;justify-content:center;
    box-shadow:var(--shadow-1);
    border:1px solid rgba(255,255,255,.06);
  }
  .ppanel-id .grow{min-width:0}
  .ppanel-name{font-size:18px;font-weight:700;letter-spacing:-.01em;line-height:1.25;color:var(--ink)}
  .ppanel-topline{display:flex;align-items:center;flex-wrap:wrap;gap:4px 8px}
  .ppanel-status{margin-left:auto;display:flex;align-items:center;gap:6px;flex-shrink:0}
  /* The care tier is the patient's status — the tier the bridge sends, what the
     roster and board colour from — so in the header it outranks the scores that
     support it rather than sitting among them as one chip of several. */
  .ppanel-status .chip[class*="triage-"]{font-size:12px;padding:5px 12px;letter-spacing:.02em}
  .ppanel-status .chip[class*="triage-"].dot::before{width:7px;height:7px}
  /* …and the supporting scores read as supporting. */
  .ppanel-chips .chip.auto{font-weight:650;color:var(--ink-2)}
  /* Care tier is an explicit bedside orientation fact, not a trigger score.
     Keep the context visible rather than hiding it in a hover-only title. */
  .chip.bedside-care-tier{
    min-height:32px;padding:4px 10px;border-radius:10px;gap:8px;
    box-shadow:0 1px 2px rgba(15,23,42,.08);white-space:nowrap;
  }
  .bedside-care-tier-label{
    font-size:8.5px;font-weight:800;letter-spacing:.065em;text-transform:uppercase;
    opacity:.78;
  }
  .bedside-care-tier-value{
    display:inline-flex;align-items:center;gap:6px;padding-left:8px;
    border-left:1px solid color-mix(in srgb,currentColor 28%,transparent);
    font-size:12.5px;font-weight:850;letter-spacing:.01em;
  }
  .bedside-care-tier-value::before{
    content:"";width:7px;height:7px;border-radius:50%;background:currentColor;flex-shrink:0;
  }
  /* Bed leads the name line: at the bedside you find a patient by bed, not by
     MRN, so it gets the roster card's token treatment rather than a column in
     the identifier row. */
  .ppanel-bed{
    display:inline-flex;align-items:center;gap:5px;min-width:0;max-width:100%;
    padding:3px 9px;border-radius:8px;
    background:var(--bg-soft);border:1px solid var(--border);
    font-size:13px;font-weight:750;color:var(--ink);
    font-variant-numeric:tabular-nums;
  }
  .ppanel-bed svg{width:12px;height:12px;color:var(--muted);flex-shrink:0}
  .ppanel-bed .chip{padding:1px 6px;font-size:9px;letter-spacing:0;flex-shrink:0}
  .care-unit-chip{
    display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;
    min-height:21px;padding:2px 7px;border:1px solid var(--border);border-radius:999px;
    background:var(--card-2);font-size:9px;font-weight:850;letter-spacing:.075em;
    text-transform:uppercase;color:var(--ink-2);vertical-align:middle;
  }
  .care-unit-chip.unit-icu{border-color:var(--brand-ring);color:var(--brand-2);background:var(--brand-soft)}
  .care-unit-chip.unit-ward{border-color:rgba(168,85,247,.32);color:var(--purple);background:rgba(168,85,247,.10)}
  .care-unit-chip.unit-er{border-color:var(--warn-border);color:var(--warn);background:var(--warn-soft)}

  /* ── Transitions of care ──────────────────────────────────────────────
     Where the patient has been this admission, and — for one shift after a
     move — a standing reminder that the record below starts before they
     arrived here. Quiet by design: this is orientation, not an alarm. */
  .care-path{
    margin-top:6px;font-size:10.5px;font-weight:650;letter-spacing:.02em;
    color:var(--muted);display:flex;gap:6px;align-items:center;flex-wrap:wrap;
  }
  .care-path-label{
    font-size:8.5px;font-weight:800;letter-spacing:.07em;text-transform:uppercase;color:var(--faint);
  }
  .transfer-banner{
    margin-top:9px;padding:9px 11px;border-radius:var(--radius-3, 10px);
    border:1px solid var(--brand-ring);background:var(--brand-soft);
    display:flex;gap:10px;align-items:center;flex-wrap:wrap;
    font-size:12px;line-height:1.4;color:var(--ink-2);
  }
  .transfer-banner b{color:var(--ink)}
  .transfer-banner .btn{padding:5px 10px;font-size:11px}
  .transfer-banner.compact{margin:0 0 12px}
  /* Why the patient is here. Two lines maximum — a long problem list is a
     reference, not a banner; the full string stays in the title attribute. */
  .ppanel-dx{
    margin-top:7px;font-size:12.5px;line-height:1.35;color:var(--ink-2);
    padding-left:9px;border-left:2px solid var(--border-2);
    display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
  }
  .ppanel-dx-label{color:var(--muted);font-weight:750;margin-right:6px}
  /* The tile's alarm. It rides the sticky band so it stays on screen while the
     console scrolls, and it is the only place the critical count is stated. */
  .critical-alert-chip{
    display:inline-flex;align-items:center;gap:5px;
    padding:3px 10px;border-radius:999px;
    border:1px solid var(--crit-border);background:var(--crit-soft);color:var(--crit);
    font-size:10.5px;font-weight:800;letter-spacing:.03em;white-space:nowrap;
  }
  .critical-alert-chip:hover{background:var(--crit);color:#fff;border-color:var(--crit)}
  .critical-alert-chip:focus-visible{box-shadow:0 0 0 3px var(--brand-ring)}
  .critical-alert-icon{font-weight:900;line-height:1}
  /* Identifier facts — labelled groups split by hairline dividers so the
     banner scans as discrete fields (who · record · where) instead of one
     dot-separated line. Divider colors resolve per theme. */
  .ppanel-facts{margin-top:8px;display:flex;flex-wrap:wrap;align-items:stretch;row-gap:6px}
  .pfact{display:flex;flex-direction:column;gap:2px;padding:0 12px;border-left:1px solid var(--border);min-width:0}
  .pfact:first-child{padding-left:0;border-left:0}
  .pfact-label{font-size:8.5px;font-weight:750;letter-spacing:.07em;text-transform:uppercase;color:var(--faint);line-height:1}
  .pfact-value{display:flex;align-items:center;gap:6px;font-size:12.5px;font-weight:600;color:var(--ink);line-height:1.2;font-variant-numeric:tabular-nums;white-space:nowrap}
  .pfact-value .chip{font-size:9.5px;padding:1px 7px}
  /* ER time-to-disposition against the four-hour decision standard, and the
     boarding clock that starts where it stops. Scoped to .pfact-value alone,
     these matched nothing: bedsidePatientHeadHtml routes an ER patient's stay
     into the unit-focus strip instead of the identifier row, so every ED breach
     the renderer marked up rendered in plain body colour. */
  .pfact-value .er-clock-warn,.unit-focus-value .er-clock-warn{color:var(--warn)}
  .pfact-value .er-clock-breach,.unit-focus-value .er-clock-breach{color:var(--crit);font-weight:750}
  /* Feed-integrity warning, not a claim about the ordered observation slot. */
  .obs-outside-window{color:var(--crit);font-weight:750}
  /* Past the frequency this patient's own NEWS2 band requires. Amber, not red:
     the chart is being written to and is trustworthy, the interval has simply
     run out — a different and less severe statement than obs-outside-window. */
  .obs-overdue{color:var(--warn);font-weight:750}
  /* Risk scores + safety flags ride one hairline-separated band below the
     identifiers, so clinical status reads as its own scannable row. */
  .ppanel-chips{margin-top:9px;padding-top:8px;border-top:1px solid var(--hairline);display:flex;flex-wrap:wrap;gap:5px;align-items:center}
  .ppanel-chips .patient-safety-chips{display:contents}
  .unit-transfer-control{
    min-height:25px;display:inline-flex;align-items:center;gap:5px;padding:3px 8px;
    border:1px solid var(--border);border-radius:999px;background:var(--card-2);color:var(--ink-2);
    font-size:10px;font-weight:750;cursor:pointer
  }
  .unit-transfer-control svg{width:12px;height:12px}
  .unit-transfer-control em{padding-left:5px;border-left:1px solid var(--border);color:var(--warn);font-size:8px;font-style:normal;text-transform:uppercase;letter-spacing:.045em}
  .unit-transfer-control:hover,.unit-transfer-control:focus-visible{border-color:var(--brand);box-shadow:0 0 0 3px var(--brand-ring)}
  .unit-transfer-control.pending{background:var(--warn-soft);border-color:var(--warn-border)}
  .unit-transfer-current{display:flex;align-items:center;gap:9px;margin-bottom:14px;padding:10px 12px;border:1px solid var(--border);border-radius:9px;background:var(--bg-soft)}
  .unit-transfer-current span{color:var(--muted);font-size:10px;text-transform:uppercase;letter-spacing:.05em}
  .unit-transfer-current b{color:var(--ink);font-size:13px}
  .unit-focus{
    display:flex;align-items:stretch;flex-wrap:wrap;gap:0;margin-top:9px;
    border:1px solid var(--border);border-radius:9px;background:var(--card-2);overflow:hidden;
  }
  .unit-focus-heading,.unit-focus-item{display:flex;flex-direction:column;justify-content:center;gap:2px;padding:7px 10px;min-height:46px}
  .unit-focus-heading{min-width:165px;border-right:1px solid var(--border)}
  .unit-focus-heading b{font-size:10.5px;letter-spacing:.055em;text-transform:uppercase;color:var(--ink)}
  .unit-focus-heading small{font-size:9px;color:var(--muted);white-space:nowrap}
  .unit-focus-item{border-right:1px solid var(--border);min-width:118px}
  .unit-focus-item:last-child{border-right:0}
  .unit-focus-label{font-size:8px;font-weight:800;letter-spacing:.07em;text-transform:uppercase;color:var(--faint)}
  .unit-focus-value{font-size:11.5px;font-weight:700;color:var(--ink);font-variant-numeric:tabular-nums;white-space:nowrap}
  .unit-focus-ward{border-left:3px solid var(--purple);background:linear-gradient(90deg,rgba(168,85,247,.07),var(--card-2) 38%)}
  .unit-focus-er{border-left:3px solid var(--warn);background:linear-gradient(90deg,var(--warn-soft),var(--card-2) 38%)}
  .unit-focus-alert,.unit-focus-direction.worse{color:var(--warn)}
  .unit-focus-alert.critical{color:var(--crit)}
  .unit-focus-direction.better{color:var(--ok)}
  /* The window a NEWS2 move happened over. Quieter than the scores either side
     of it: it qualifies the trajectory, it is not a third number to read. */
  .unit-focus-since{font-weight:600;color:var(--muted)}
  @media(max-width:720px){
    .home-board-head,.home-board-head > div{align-items:flex-start}
    .home-board-head > div{flex-direction:column;gap:2px}
    .unit-focus{display:grid;grid-template-columns:1fr 1fr}
    .unit-focus-heading{grid-column:1/-1;border-right:0;border-bottom:1px solid var(--border);min-width:0}
    .unit-focus-item{border-right:0;border-bottom:1px solid var(--border);min-width:0}
    .unit-focus-item:nth-last-child(-n+2){border-bottom:0}
    .unit-focus-value{white-space:normal}
  }

  /* CMT-style segmented vital strip — hairline-divided, tabular numerics */
  .vitals-strip{
    display:grid;grid-template-columns:repeat(4,1fr);
    gap:1px;background:var(--border);
    border-top:1px solid var(--border);
    padding:1px;
  }
  .vital{
    background:var(--card);padding:10px 12px;
    display:flex;flex-direction:column;gap:2px;
  }
  .vital-label{
    font-size:9.5px;color:var(--muted);font-weight:700;
    text-transform:uppercase;letter-spacing:.08em;
  }
  .vital-val{
    font-size:18px;font-weight:700;color:var(--ink);line-height:1.1;
    font-variant-numeric:tabular-nums;letter-spacing:-.2px;
  }
  .vital-val.crit{color:var(--crit)}
  .vital-val.warn{color:var(--warn)}
  .vital-sub{font-size:10px;color:var(--faint);margin-top:1px}

  /* Time-anchor band — shift end · next med · last vitals · due in next hour */
  .shift-band{
    display:flex;flex-wrap:wrap;gap:10px 18px;
    padding:9px 18px;
    background:linear-gradient(180deg,var(--bg-soft),var(--card));
    border-bottom:1px solid var(--hairline);
    font-size:12px;
  }
  .shift-band .sb-item{display:flex;align-items:center;gap:6px;color:var(--muted);line-height:1.3}
  .shift-band .sb-item b{color:var(--ink);font-weight:600;font-variant-numeric:tabular-nums}
  .shift-band .sb-icon{display:inline-flex;width:13px;height:13px;color:var(--faint)}
  .shift-band .sb-icon svg{width:13px;height:13px}
  .shift-band .sb-item.warn b{color:var(--warn)}
  .shift-band .sb-item.crit b{color:var(--crit)}

  /* "Now" hero card — ranked attention list above the priority grid. */
  .now-card{
    border:1px solid var(--border);border-radius:var(--radius-2);
    background:var(--card);
    padding:12px 14px;display:flex;flex-direction:column;gap:6px;
    position:relative;overflow:hidden;
  }
  .now-card.has-crit{border-color:var(--border);border-left:4px solid var(--crit);background:var(--surface-crit)}
  .now-card.has-warn{border-color:var(--border);border-left:4px solid var(--warn);background:var(--surface-warn)}
  .now-card.is-clear{border-color:var(--border);border-left:4px solid var(--ok);background:var(--surface-ok)}
  .now-head{display:flex;align-items:center;gap:8px}
  .now-head .now-pulse{
    width:9px;height:9px;border-radius:50%;background:var(--ok);
    box-shadow:0 0 0 3px rgba(34,197,94,.18);
  }
  .now-card.has-crit .now-pulse{background:var(--crit);box-shadow:0 0 0 3px rgba(239,68,68,.25);animation:pulseDot 1.6s ease-in-out infinite}
  .now-card.has-warn .now-pulse{background:var(--warn);box-shadow:0 0 0 3px rgba(245,158,11,.20)}
  @keyframes pulseDot{
    0%,100%{box-shadow:0 0 0 3px rgba(239,68,68,.25)}
    50%   {box-shadow:0 0 0 6px rgba(239,68,68,.10)}
  }
  .now-title{font-size:11px;font-weight:700;letter-spacing:.10em;text-transform:uppercase;color:var(--ink-2)}
  .now-count{margin-left:auto;font-size:11px;font-weight:600;color:var(--muted);font-variant-numeric:tabular-nums}
  /* Jump chips for the two summaries whose detail is already on this screen
     (abnormal vitals in the cockpit above, urgent tasks in the card below).
     Border-only in status colour: enough to be found, not enough to outrank
     the insight rows underneath, which are the card's actual content. */
  .now-jumps{display:flex;flex-wrap:wrap;gap:7px;margin:3px 1px 1px}
  .now-jump{
    display:inline-flex;align-items:center;gap:5px;min-height:34px;
    padding:5px 8px 5px 11px;border:1px solid var(--border);border-radius:999px;
    background:var(--card);color:var(--ink-2);font-size:11.5px;font-weight:700;
    cursor:pointer;transition:background .14s,border-color .14s,color .14s;
  }
  .now-jump svg{width:13px;height:13px;color:var(--faint);flex:none}
  .now-jump:hover{background:var(--surface-hover);color:var(--ink)}
  .now-jump:hover svg{color:var(--brand-2)}
  .now-jump:focus-visible{box-shadow:0 0 0 3px var(--brand-ring)}
  .now-jump.crit{border-color:var(--crit-border);color:var(--crit)}
  .now-jump.warn{border-color:var(--warn-border);color:var(--warn)}
  .now-quiet{padding:5px 2px;font-size:12px;color:var(--muted)}
  .now-list{display:flex;flex-direction:column}
  .now-item{
    width:100%;display:flex;align-items:center;gap:10px;padding:9px 4px;
    border-top:1px solid var(--hairline);cursor:pointer;
    border-right:0;border-bottom:0;border-left:0;background:transparent;text-align:left;
    transition:background .12s,box-shadow .12s;
  }
  .now-item:first-child{border-top:none}
  .now-item:hover{background:var(--surface-hover)}
  .now-item:focus-visible{box-shadow:0 0 0 3px var(--brand-ring);border-radius:7px}
  .now-item .ni-bar{width:3px;align-self:stretch;border-radius:2px;flex-shrink:0}
  .now-item.crit .ni-bar{background:var(--crit)}
  .now-item.warn .ni-bar{background:var(--warn)}
  .now-item .ni-body{display:flex;flex-direction:column;gap:1px;min-width:0;flex:1}
  .now-item .ni-label{
    font-size:13px;font-weight:600;color:var(--ink);line-height:1.3;
    white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  }
  .now-item .ni-sub{font-size:11px;color:var(--muted);line-height:1.3}
  /* The row is already a button and already carries a chevron; a pill on top
     of both was a third affordance for the same tap, repeated on every row.
     The state stays — it is the one non-colour cue for what the row does — as
     quiet text. */
  .now-item .ni-state{display:inline-flex;align-items:center;justify-content:flex-end;color:var(--muted);font-size:9.5px;font-weight:800;letter-spacing:.05em;text-transform:uppercase;white-space:nowrap}
  .now-item:hover .ni-state{color:var(--brand-2)}
  .now-item .ni-arrow{color:var(--faint);flex-shrink:0;display:inline-flex;width:14px;height:14px}
  .now-item .ni-arrow svg{width:14px;height:14px}
  .now-clear{
    display:flex;align-items:center;gap:8px;padding:4px 2px;
    font-size:13px;color:var(--ink-2);
  }
  .now-clear .nc-check{
    width:18px;height:18px;border-radius:50%;
    background:var(--ok);color:#fff;display:flex;align-items:center;justify-content:center;
  }
  .now-clear .nc-check svg{width:11px;height:11px}

  .ppanel-body{padding:16px;display:flex;flex-direction:column;gap:14px}

  /* Single-patient bedside cockpit — current physiology before workflows. */
  .bedside-cockpit{
    border:1px solid var(--border);border-radius:var(--radius-2);padding:10px 12px;
    background:var(--card);box-shadow:none;container-type:inline-size;
  }
  /* Cockpit header: label + at-a-glance verdict + one freshness stamp. Replaces
     the per-tile time/source rows so the six vitals read as one clean block. */
  .cockpit-head{display:flex;align-items:center;gap:10px;margin:0 1px 9px}
  .cockpit-title{font-size:10.5px;font-weight:800;letter-spacing:.09em;text-transform:uppercase;color:var(--muted)}
  .cockpit-verdict{display:inline-flex;align-items:center;gap:5px;padding:2px 9px;border:1px solid var(--border);border-radius:999px;font-size:10px;font-weight:800;letter-spacing:.04em;text-transform:uppercase;line-height:1.5}
  .cockpit-verdict .cvd-dot{width:7px;height:7px;border-radius:50%;background:var(--ok);flex:none}
  .cockpit-verdict.ok{color:var(--ok);border-color:var(--ok-border);background:var(--ok-soft)}
  .cockpit-verdict.warn{color:var(--warn);border-color:var(--warn-border);background:var(--warn-soft)}
  .cockpit-verdict.warn .cvd-dot{background:var(--warn)}
  .cockpit-verdict.crit{color:var(--crit);border-color:var(--crit-border);background:var(--crit-soft)}
  .cockpit-verdict.crit .cvd-dot{background:var(--crit);animation:cvpulse 1.7s ease-in-out infinite}
  /* --faint against the card is 3.6:1 — under the 4.5:1 AA floor for text this
     size. The freshness stamp is how you know the numbers are current, so it
     has to be legible; same for the units below. */
  .cockpit-fresh{margin-left:auto;font-size:10px;color:var(--muted);font-variant-numeric:tabular-nums;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  /* Six vitals as LANES on one time axis, not six independent tiles: the value
     is the left column, the trace is the right, and every lane shares the same
     x so a vertical scan reads one instant across the whole patient. */
  .cockpit-strip{position:relative;--vs-col:132px}
  .vs-lanes{display:flex;flex-direction:column;gap:5px;min-width:0}
  .vs-lane{display:grid;grid-template-columns:var(--vs-col) minmax(0,1fr);gap:8px;align-items:stretch;min-width:0}
  .cockpit-vital{position:relative;overflow:visible;display:flex;flex-direction:column;justify-content:center;gap:2px;padding:6px 10px;border:1px solid var(--border);border-radius:10px;background:var(--card);min-width:0;cursor:pointer;text-align:left;transition:border-color .14s,box-shadow .14s,transform .14s}
  .cockpit-vital::before{content:"";position:absolute;left:0;top:0;bottom:0;width:3px;background:var(--border-2)}
  /* PRE-389: one hover treatment for all six tiles. The status rules below
     (.warn/.crit/.stale) share the base rule's specificity and come later in
     the sheet, so a plain .cockpit-vital:hover lost its border-color on any
     non-ok tile and each status hovered differently. The compound selectors
     out-rank the status rules; border-style pins the dashed stale border so
     the lift/ring/border animation is identical everywhere. */
  .cockpit-vital:hover,
  .cockpit-vital.warn:hover,
  .cockpit-vital.crit:hover,
  .cockpit-vital.missing:hover,
  .cockpit-vital.stale:hover{border-color:var(--brand);box-shadow:0 0 0 2px var(--brand-ring);transform:translateY(-1px)}
  .cv-top{display:flex;align-items:center;gap:6px;min-height:17px}
  .cv-k{font-size:9.5px;font-weight:750;letter-spacing:.06em;color:var(--muted);text-transform:uppercase}
  /* The live dot that used to sit here was the fourth copy of one fact: the
     tile already states status in its left bar, its value colour and its
     sparkline colour. Its worst effect was a green pip on every stable tile,
     six marks all competing for the eye with the one or two that were red. */
  /* 8.5px was too small for the one label that says a vital is out of range. */
  .cv-status{font-size:9.5px;font-weight:850;letter-spacing:.055em;text-transform:uppercase;white-space:nowrap}
  .cv-status.crit{color:var(--crit)} .cv-status.warn{color:var(--warn)} .cv-status.missing{color:var(--muted)}
  .cv-mid{display:flex;align-items:baseline;gap:3px;min-width:0}
  .cv-v{font-size:22px;line-height:1;font-weight:800;color:var(--ink);font-variant-numeric:tabular-nums;white-space:nowrap;overflow:visible}
  .cv-u{font-size:9.5px;color:var(--muted);font-weight:600;flex:none}
  .cv-arrow{margin-left:auto;font-size:12px;font-weight:800;line-height:1;color:var(--muted);flex:none}
  .cv-arrow.rising,.cv-arrow.falling{color:var(--ink-2)}

  /* ---- The trace ------------------------------------------------------
     Marks come from the chart kit (05-chart-kit.css) — band, line, envelope,
     severity rule, head dot — so a lane here and a card in the full chart are
     the same drawing at two sizes. What is local is the layout around them. */
  .vs-plot-cell{position:relative;min-width:0}
  .vs-plot{position:relative;border:1px solid var(--hairline);border-radius:8px;background:var(--card-2);overflow:hidden;min-width:0}
  .vs-svg{width:100%;height:100%;display:block}
  .vs-noplot{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;font-size:10px;color:var(--muted)}
  /* Gridline labels are HTML: SVG text inside a stretched viewBox is squashed. */
  .vs-scale{position:absolute;left:4px;transform:translateY(-50%);font-size:8.5px;line-height:1;color:var(--muted);
    font-variant-numeric:tabular-nums;pointer-events:none;background:var(--card-2);padding:0 2px;border-radius:2px;opacity:.9}
  /* The support sub-band: the oxygen under SpO₂, the vasopressor under MAP.
     A filled step, so it never reads as another vital's line. */
  .vs-support-area{fill:var(--brand);opacity:.2}
  .vs-support-rule{stroke:var(--hairline);stroke-width:1}
  /* A zoomed lane whose normal range is off-frame must say so, or it implies
     the patient is sitting mid-range. */
  .vs-offscale{position:absolute;left:4px;font-size:8px;font-weight:800;letter-spacing:.02em;color:var(--warn);
    background:var(--card-2);padding:0 3px;border-radius:3px;pointer-events:none;white-space:nowrap}
  .vs-offscale.above{top:2px}
  .vs-offscale.below{bottom:2px}
  .vs-support-tag{position:absolute;right:5px;bottom:2px;font-size:8.5px;font-weight:750;color:var(--ink-2);background:var(--card-2);padding:0 3px;border-radius:3px;pointer-events:none;font-variant-numeric:tabular-nums}
  /* The affordance that says a fuller chart exists. A title attribute did not:
     there is no hover on the tablet this screen is used from. */
  .vs-open{position:absolute;top:4px;right:4px;width:20px;height:20px;padding:0;display:flex;align-items:center;justify-content:center;
    border:1px solid var(--border);border-radius:6px;background:var(--card);color:var(--ink-2);font-size:11px;line-height:1;
    cursor:pointer;opacity:0;transition:opacity .12s}
  .vs-lane:hover .vs-open,.vs-open:focus-visible{opacity:1}
  @media (pointer: coarse){ .vs-open{opacity:.75} }

  /* ---- Shared foot: early-warning ribbon, events, time axis ---------- */
  .vs-foot{margin-top:7px;min-width:0;display:flex;flex-direction:column;gap:4px}
  /* One row per thing shown, each on the lanes' own column grid, so a label
     always sits beside what it names rather than in a stack that has to be
     counted off against a stack of plots. */
  .vs-foot-row{display:grid;grid-template-columns:var(--vs-col) minmax(0,1fr);gap:8px;align-items:center;min-width:0}
  .vs-foot-label{display:flex;flex-direction:column;justify-content:flex-start;gap:9px;padding-top:1px}
  .vs-foot-k{font-size:9px;font-weight:800;letter-spacing:.05em;text-transform:uppercase;color:var(--ink-2);text-align:right}
  .vs-foot-plot{position:relative;min-width:0}
  /* Tall enough to carry the score's own shape. A flat colour block could only
     say which band the patient was in, so a shift spent at NEWS2 10 and a shift
     that crossed into it an hour ago drew the same solid red. */
  .vs-ribbon{position:relative;height:30px;border-radius:4px;background:var(--card-2);border:1px solid var(--hairline);overflow:hidden}
  /* A score is a short row: it moves between a handful of integers, so it needs
     enough height for a single step to be visible and no more. It carries no
     band wash — on any patient this row exists for, the wash covered the whole
     row and took the contrast from both the reading and its threshold. */
  .vs-ribbon.vs-score{height:34px;background:var(--card-2)}
  .vs-score-area{fill:var(--ink-2);opacity:.16}
  .vs-score-line{fill:none;stroke:var(--ink);stroke-width:2;stroke-linejoin:round;stroke-linecap:round}
  .vs-ribbon.vs-score.warn .vs-score-area{fill:var(--warn-graphic);opacity:.20}
  .vs-ribbon.vs-score.crit .vs-score-area{fill:var(--crit);opacity:.18}
  .vs-ribbon.is-empty{height:9px;opacity:.45}
  /* The band, as a wash behind the line rather than the whole mark. Lighter
     than it was: the line and its current value are what get read, and a strong
     fill behind them cost both of those their contrast. */
  .vs-rb{position:absolute;top:0;bottom:0;opacity:.13}
  .vs-rb.ok{background:var(--ok-graphic)}
  .vs-rb.warn{background:var(--warn-graphic)}
  .vs-rb.crit{background:var(--crit)}

  .vs-rb-svg{position:absolute;inset:0;width:100%;height:100%;display:block}
  .vs-rb-line{fill:none;stroke:var(--ink);stroke-width:2;stroke-linejoin:round;stroke-linecap:round}
  /* The escalation threshold, drawn and labelled. Without it a height on this
     row could not be read as a number — the axis had no stated maximum. */
  /* The escalation line is a REFERENCE, so it is drawn as one. In crit red on a
     red wash it was invisible as a mark and redundant as a signal — the row was
     already red. Neutral, it reads against everything. */
  .vs-rb-threshold{stroke:var(--ink-2);stroke-width:1;opacity:.5;stroke-dasharray:3 3}
  .vs-rb-scale{position:absolute;left:4px;top:2px;font-size:9px;font-weight:800;color:var(--ink-2);opacity:.85;
    font-variant-numeric:tabular-nums;pointer-events:none}
  /* A crossing between bands is the moment a nurse is looking for, so it is
     ticked and labelled with the score it became. */
  .vs-rb-cross{position:absolute;top:0;bottom:0;width:0;border-left:1px solid var(--ink-2);opacity:.75}
  .vs-rb-cross b{position:absolute;top:1px;left:2px;font-size:8px;font-weight:850;line-height:1;
    color:var(--ink);background:var(--card);padding:0 2px;border-radius:2px;font-variant-numeric:tabular-nums}
  .vs-rb-cross.up b{color:var(--crit)}
  .vs-rb-cross.down b{color:var(--ok)}
  /* The current score, as a chip rather than text floated over a coloured wash
     with a shadow to survive it. It is the number this row exists to state. */
  .vs-rb-now{position:absolute;right:4px;top:50%;transform:translateY(-50%);min-width:20px;text-align:center;
    padding:2px 6px;border-radius:999px;font-size:12px;font-weight:850;line-height:1.1;
    font-variant-numeric:tabular-nums;pointer-events:none;
    background:var(--card);border:1px solid var(--border);color:var(--ink)}
  .vs-ribbon.warn .vs-rb-now{border-color:var(--warn-border);color:var(--warn)}
  .vs-ribbon.crit .vs-rb-now{border-color:var(--crit-border);color:var(--crit)}
  .vs-rb-now{font-size:12px;letter-spacing:.02em}
  .vs-events{position:relative;height:23px;margin-top:4px}
  .vs-events.is-empty{height:6px}
  /* Bigger and filled. These were 17px outlines in --border on a card of nearly
     the same value: at a glance the row read as specks, and a mark you cannot
     see is a mark you never hover. */
  .vs-ev{position:absolute;top:0;transform:translateX(-50%);width:21px;height:21px;padding:0;display:flex;align-items:center;justify-content:center;
    border:1.5px solid var(--border-2);border-radius:50%;background:var(--card);font-size:9px;line-height:1;cursor:pointer;color:var(--ink)}
  .vs-ev:hover,.vs-ev:focus-visible{border-color:var(--brand);box-shadow:0 0 0 2px var(--brand-ring);z-index:3;outline:none}
  .vs-ev .ck-ev-glyph{width:10px;height:10px}
  /* Marks that would overlap collapse into one that says how many it holds —
     at a 24-hour window most of them collide, and drawn individually they smear
     into something that can be neither read nor clicked. */
  .vs-ev-cluster{width:auto;min-width:21px;padding:0 5px;gap:3px;border-radius:11px;font-weight:850}
  .vs-ev-cluster .vs-ev-n{font-size:9.5px;line-height:1;font-variant-numeric:tabular-nums}
  .vs-ev.vs-ev-pump.dir-up{border-color:var(--warn);color:var(--warn)}
  .vs-ev.vs-ev-pump.dir-down{border-color:var(--ok);color:var(--ok)}
  .vs-ev-mixed{border-style:dashed}

  /* Event detail. A native title tooltip waits about a second and cannot be
     styled; on marks this small that made the content feel unreachable. */
  .vs-ev-tip{position:fixed;z-index:60;max-width:320px;padding:7px 10px;border:1px solid var(--border);border-radius:8px;
    background:var(--card);box-shadow:var(--shadow-2);font-size:11px;color:var(--ink);
    opacity:0;visibility:hidden;transition:opacity .08s;pointer-events:none}
  .vs-ev-tip.is-on{opacity:1;visibility:visible}
  .vs-ev-tip-head{font-weight:850;font-size:10px;letter-spacing:.03em;text-transform:uppercase;color:var(--muted);margin-bottom:3px}
  .vs-ev-tip-line{font-variant-numeric:tabular-nums;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  /* The "in the N min after" divider inside a popover. */
  .vs-ev-tip-line.is-rule{color:var(--muted);font-size:9.5px;letter-spacing:.02em;margin:3px 0 1px}

  /* One ruler across the whole strip. Six lanes of short gridlines were
     clutter; one continuous line the eye can follow from any lane down to a
     label is what makes the time of a feature readable. Faint on purpose —
     continuity carries it, not weight. */
  .vs-timegrid{position:absolute;left:calc(var(--vs-col) + 8px);right:0;top:16px;bottom:30px;pointer-events:none;z-index:2}
  .vs-tg{position:absolute;top:0;bottom:0;width:1px;background:var(--ink-2);opacity:.13}
  :root[data-theme="dark"] .vs-tg{opacity:.16}
  /* A rule at each event, through every lane, so the events row and the vitals
     it explains are one picture rather than two. Faint until the event is being
     read, then unmistakable. */
  .vs-tg.is-event{background:var(--brand);opacity:.22;transition:opacity .1s}
  .vs-tg.is-event.is-on{opacity:.85;width:1.5px}

  /* Labels at the head as well as the foot: with six lanes between them, one
     row of times is a long way from most of the data. */
  .vs-head-axis{display:grid;grid-template-columns:var(--vs-col) minmax(0,1fr);gap:8px;min-width:0;margin-bottom:2px}
  .vs-axis{position:relative;height:14px;margin-top:3px}
  .vs-axis.is-head{margin-top:0;height:13px}
  .vs-tick{position:absolute;top:0;transform:translateX(-50%);font-size:10px;color:var(--ink-2);
    font-variant-numeric:tabular-nums;white-space:nowrap;font-weight:650}
  /* A tick above the label, so it reads as attached to the ruler it marks. */
  .vs-tick::before{content:"";position:absolute;left:50%;top:-3px;width:1px;height:3px;background:var(--border-2)}
  .vs-axis.is-head .vs-tick::before{top:auto;bottom:-3px}
  .vs-tick.vs-now{right:0;left:auto;transform:none;font-weight:850;color:var(--brand)}
  .vs-tick.vs-now::before{display:none}

  /* ---- Scrub ---------------------------------------------------------
     Reading one instant across every lane is a hover, not a chart visit. */
  .vs-crosshair{position:absolute;top:0;bottom:14px;width:1px;background:var(--brand);opacity:0;pointer-events:none;transition:opacity .1s}
  .vs-crosshair.is-on{opacity:.85}
  .cockpit-strip.is-scrubbing .cv-v{font-size:15px}
  .cockpit-scrub{font-size:10px;font-weight:800;color:var(--brand);font-variant-numeric:tabular-nums;min-width:0}
  .cockpit-open{padding:2px 9px;border:1px solid var(--border);border-radius:999px;background:var(--card);color:var(--ink-2);
    font-size:10px;font-weight:800;cursor:pointer;white-space:nowrap;line-height:1.5}
  .cockpit-open:hover{border-color:var(--brand);color:var(--brand)}

  /* ---- Window + size controls ---------------------------------------- */
  .cockpit-window{display:flex;align-items:center;gap:2px;margin-left:4px}
  .cw-chip{padding:2px 8px;border:1px solid var(--border);border-radius:999px;background:var(--card);color:var(--ink-2);font-size:10px;font-weight:800;cursor:pointer;line-height:1.5}
  .cw-chip:hover{border-color:var(--brand)}
  .cw-chip.is-on{background:var(--brand);border-color:var(--brand);color:#fff}
  .cw-size{margin-left:4px;padding:3px 7px;border:1px solid var(--border);border-radius:8px;background:var(--card);cursor:pointer;line-height:0}
  /* Three heights, cycling. The bar shows which one is active. */
  .cw-size-bar{display:block;width:11px;background:var(--ink-2);border-radius:1px}
  .cw-size-bar[data-size="short"]{height:4px}
  .cw-size-bar[data-size="medium"]{height:8px}
  .cw-size-bar[data-size="tall"]{height:12px}
  .cw-size:hover{border-color:var(--brand)}

  /* ---- Support strip --------------------------------------------------
     FiO₂, PEEP, the running vasopressor and urine output decide what the
     traces above them mean, and every one of them used to cost a trip to
     Monitoring or Input/Output. */
  .cockpit-support{display:flex;flex-wrap:wrap;gap:6px;margin-top:9px;padding-top:8px;border-top:1px dashed var(--hairline)}
  .cs-chip{display:inline-flex;align-items:baseline;gap:5px;padding:2px 8px;border:1px solid var(--border);border-radius:999px;background:var(--card-2);font-size:10px}
  .cs-chip .cs-k{font-weight:800;letter-spacing:.04em;text-transform:uppercase;color:var(--muted);font-size:9px}
  .cs-chip .cs-v{font-weight:750;color:var(--ink);font-variant-numeric:tabular-nums}
  .cs-chip.warn{border-color:var(--warn-border);background:var(--warn-soft)}
  .cs-chip.warn .cs-v{color:var(--warn)}
  .bedside-cockpit .ck-legend{margin-top:8px;padding-top:7px;border-top:1px dashed var(--hairline)}
  .cv-meta{display:flex;align-items:center;gap:4px;min-width:0;font-size:8.5px;line-height:1.2;color:var(--muted);white-space:nowrap}
  .cv-meta-source{overflow:hidden;text-overflow:ellipsis}
  .cv-kind{padding:1px 4px;border:1px solid var(--border);border-radius:4px;background:var(--card-2);font-size:8px;font-weight:800;letter-spacing:.04em;text-transform:uppercase;color:var(--ink-2)}
  .cockpit-vital.warn{border-color:var(--border);background:var(--card)}
  .cockpit-vital.warn::before{background:var(--warn)}
  .cockpit-vital.warn .cv-v{color:var(--warn)}
  .cockpit-vital.crit{border-color:var(--border);background:var(--card)}
  /* The crit pulse rode the live dot; with the dot gone it moves to the status
     bar, which is the mark that survives at a glance across the room. */
  .cockpit-vital.crit::before{background:var(--crit);animation:cvbarpulse 1.7s ease-in-out infinite}
  .cockpit-vital.crit .cv-v{color:var(--crit)}
  .cockpit-vital.stale{border-style:dashed}
  .cockpit-vital.stale::after{content:"STALE";position:absolute;right:8px;bottom:7px;color:var(--crit);font-size:8px;font-weight:850;letter-spacing:.06em}
  @keyframes cvpulse{0%,100%{box-shadow:0 0 0 3px var(--crit-soft)}50%{box-shadow:0 0 0 5px transparent}}
  /* cvpulse spreads a box-shadow, which on a 3px full-height bar bleeds past
     the tile edge (.cockpit-vital is overflow:visible). Opacity stays inside. */
  @keyframes cvbarpulse{0%,100%{opacity:1}50%{opacity:.45}}
  @media(prefers-reduced-motion:reduce){
    .cockpit-vital.crit::before,.cockpit-verdict.crit .cvd-dot,.now-card.has-crit .now-pulse{animation:none}
  }
  /* A narrower panel shrinks the value column and the lane height rather than
     reflowing the lanes: the shared time axis is the whole point, and it does
     not survive being broken into a grid. */
  @container (max-width:860px){.cockpit-strip{--vs-col:104px}.cockpit-strip .cv-v{font-size:18px}}
  @container (max-width:500px){.cockpit-strip{--vs-col:88px}.cockpit-strip .cv-u{display:none}}
  @media(max-width:1400px){.home-grid .cockpit-strip{--vs-col:104px}}
  @media(max-width:900px){.cockpit-strip{--vs-col:92px}.cockpit-head{flex-wrap:wrap}.cockpit-fresh{margin-left:0}}

  /* Single patient gets a quiet cockpit; multi-patient home keeps the full grid. */
  /* Fill the shared 1600px app container (same as the workflow/monitoring
     views) so the detail page aligns with its own header and doesn't sit in a
     narrow column with big empty margins on a desktop browser. */
  .single-bedside-shell{max-width:none;margin:0 auto;padding-bottom:4px}
  .single-bedside-shell .ppanel,.home-grid .ppanel{overflow:visible}
  .single-bedside-shell .ppanel-head,.home-grid .ppanel-head{
    position:sticky;top:var(--topbar-height);z-index:35;
    padding:10px 14px;background:var(--surface-sticky);
    border-radius:var(--radius-4) var(--radius-4) 0 0;
    box-shadow:0 1px 0 var(--border),var(--shadow-1);
  }
  .single-bedside-shell .ppanel-id .avatar,.home-grid .ppanel-id .avatar{width:40px;height:40px;border-radius:10px;font-size:14px}
  .single-bedside-shell .ppanel-name,.home-grid .ppanel-name{font-size:16px}
  .patient-safety-chips{display:flex;flex-wrap:wrap;gap:5px;margin-top:6px}
  .safety-chip{display:inline-flex;align-items:center;gap:4px;padding:3px 7px;border:1px solid var(--border);border-radius:999px;background:var(--card-2);font-size:9.5px;font-weight:750;color:var(--ink-2)}
  .safety-chip.allergy{border-color:var(--crit-border);color:var(--crit)}
  .safety-chip.isolation{border-color:var(--warn-border);color:var(--warn)}
  .safety-chip.unknown{border-style:dashed;color:var(--muted)}
  /* An escalation past its response window. Same two-step warn→crit ladder as
     the allergy/isolation chips so the ward reads it without new vocabulary. */
  .safety-chip.awaiting{border-color:var(--warn-border);color:var(--warn)}
  .safety-chip.awaiting-crit{border-color:var(--crit-border);color:var(--crit)}
  .single-bedside-head{display:flex;align-items:flex-start;gap:12px;margin-bottom:14px}
  /* Single-patient: no h1, so the row collapses to one line of controls and
     gets out of the vitals' way. */
  .single-bedside-head.is-single{align-items:center;margin-bottom:8px}
  .single-bedside-updated{display:inline-flex;align-items:center;gap:6px;color:var(--muted);font-size:11px;margin-left:auto}
  .single-bedside-updated::before{content:"";width:7px;height:7px;border-radius:50%;background:var(--ok);box-shadow:0 0 0 3px var(--ok-soft)}
  /* Stretch, not start: on a quiet patient the task list is much shorter than
     the five write actions beside it, and aligning to the top left a ragged
     hole between the two columns and the rail below them. */
  .single-focus-grid{display:grid;grid-template-columns:minmax(0,1.5fr) minmax(300px,.75fr);gap:14px;align-items:stretch}
  /* Multi-patient panels keep Tasks beside Assess & Prescribe. Each panel is
     ~half the page, so soften the right column's min width and gap so the two
     columns fit without overflowing. Insights now lives in patient chat. */
  .home-grid .single-focus-grid{grid-template-columns:minmax(0,1.4fr) minmax(0,1fr);gap:12px}
  .single-right-col{display:flex;flex-direction:column;gap:14px;min-width:0}
  /* Actions living in the narrow right column stack full-width for tap size. */
  .single-right-col .bedside-actions{margin:0}
  .single-right-col .ba-grid{grid-template-columns:1fr}
  .single-todo-card{min-height:230px;cursor:default}
  .single-focus-grid > .single-todo-card.todo{border-color:var(--border);border-left:4px solid var(--warn);background:var(--surface-warn);box-shadow:none}
  .single-todo-card .remaining-label{font-size:10px;font-weight:800;letter-spacing:.055em;text-transform:uppercase;color:var(--muted);margin:4px 1px 6px}
  .task-assessment-actions{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;margin-top:10px}
  .task-assessment-action{display:flex;align-items:center;gap:9px;padding:10px;border:1px solid var(--border);border-radius:9px;background:var(--card);text-align:left;cursor:pointer;transition:.14s}
  .task-assessment-action:hover{border-color:var(--brand);box-shadow:0 0 0 2px var(--brand-ring)}
  .task-assessment-action .ico{width:30px;height:30px;border-radius:8px;display:flex;align-items:center;justify-content:center;color:#fff;flex:none}
  .task-assessment-action .ico svg{width:15px;height:15px}
  .task-assessment-action b{display:block;font-size:11.5px;color:var(--ink)}
  .task-assessment-action small{display:block;margin-top:2px;font-size:10px;color:var(--muted)}
  .single-todo-summary{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin:11px 0 9px}
  .single-todo-stat{display:flex;align-items:center;gap:8px;padding:9px 10px;border:1px solid var(--border);border-radius:9px;background:var(--card)}
  .single-todo-stat strong{font-size:21px;line-height:1;font-variant-numeric:tabular-nums}
  .single-todo-stat span{font-size:9.5px;font-weight:750;letter-spacing:.045em;text-transform:uppercase;color:var(--muted)}
  .single-todo-stat.critical{border-color:var(--crit-border);background:var(--crit-soft);color:var(--crit)}
  .single-todo-stat.pending{border-color:var(--warn-border);background:var(--warn-soft);color:var(--warn)}
  .single-todo-stat.done{border-color:var(--ok-border);background:var(--ok-soft);color:var(--ok)}
  .task-summary-inline{margin-left:auto;display:flex;align-items:center;gap:5px}
  .task-summary-inline span{display:inline-flex;align-items:center;gap:3px;padding:3px 6px;border:1px solid var(--border);border-radius:999px;background:var(--card-2);font-size:9px;font-weight:800;text-transform:uppercase;letter-spacing:.035em}
  .task-summary-inline .critical{color:var(--crit)} .task-summary-inline .pending{color:var(--warn)} .task-summary-inline .done{color:var(--ok)}
  .single-todo-card .pri-list{gap:8px}
  .task-open-btn{min-height:30px;padding:5px 8px;border:1px solid var(--border);border-radius:7px;background:var(--card-2);font-size:10px;font-weight:750;color:var(--ink-2)}
  .task-open-btn:hover{border-color:var(--brand);color:var(--brand-2)}
  .task-open-btn:focus-visible{box-shadow:0 0 0 3px var(--brand-ring)}
  .task-open-btn{margin-left:auto}
  /* Every bedsideNavigate target has to clear the two sticky layers above it —
     the app topbar and the panel's own identity band — or the jump parks the
     section underneath them. The topbar half is measured, so this tracks a
     wrapped topbar on a narrow tablet instead of guessing one number. */
  .bedside-now-section,
  .now-card,
  .single-todo-card,
  .bedside-actions{scroll-margin-top:calc(var(--topbar-height) + 150px)}
  /* Bedside clinical console. Actions are grouped into recessed panels with a
     ruled section header; each destination is a raised tile with a duotone
     (soft-tint + accent glyph) icon. Colour is a quiet wayfinding cue, not a
     shout — reserved-loud colour stays on clinical status/badges. Every action
     shares one system so it reads as designed, not as a row of buttons. */
  .bedside-actions{display:flex;flex-direction:column;gap:14px;margin:0}
  .ba-group{background:var(--card);border:1px solid var(--border);border-radius:12px;padding:11px 13px 13px}
  .ba-group-label{display:flex;align-items:center;gap:11px;font-size:10.5px;font-weight:800;letter-spacing:.09em;text-transform:uppercase;color:var(--muted);margin:2px 1px 11px}
  .ba-group-label::after{content:"";flex:1;height:1px;background:var(--border)}
  .ba-grid{display:grid;gap:10px}
  .ba-grid-3{grid-template-columns:repeat(3,minmax(0,1fr))}
  .ba-grid-4{grid-template-columns:repeat(4,minmax(0,1fr))}
  /* Multi-patient panels are ~half-width, so the 4-up / 3-up action rows are
     cramped there. Show two actions per row instead (e.g. Monitoring + Labs,
     Input/Output + Imaging); the full-width single-patient view keeps 4/3-up.
     Scoped to the "more actions" block (a direct child of .ppanel-body) so the
     right-column primary actions keep their full-width stack. */
  .home-grid .ppanel-body > .bedside-actions .ba-grid-3,
  .home-grid .ppanel-body > .bedside-actions .ba-grid-4{grid-template-columns:repeat(2,minmax(0,1fr))}
  .bedside-action{position:relative;display:flex;align-items:center;gap:13px;padding:13px 14px;border:1px solid var(--border);border-radius:10px;background:var(--card);text-align:left;cursor:pointer;transition:border-color .16s,box-shadow .16s,transform .16s;box-shadow:none;min-width:0}
  .bedside-action:hover{border-color:color-mix(in srgb,var(--ba-accent,var(--brand)) 48%,var(--border));box-shadow:var(--shadow-2);transform:translateY(-1px)}
  .bedside-action:active{transform:translateY(0);box-shadow:var(--shadow-1)}
  .bedside-action:focus-visible{border-color:var(--ba-accent,var(--brand));box-shadow:0 0 0 3px color-mix(in srgb,var(--ba-accent,var(--brand)) 22%,transparent)}
  /* Five stacked write actions set the height of the whole focus row, so every
     pixel of padding here is a pixel of empty card beside the task list. */
  .ba-group.primary .bedside-action{padding:11px 13px}
  .ba-group.primary .ba-icon{width:36px;height:36px;border-radius:10px}
  .ba-icon{width:40px;height:40px;border-radius:11px;display:flex;align-items:center;justify-content:center;flex:none;color:var(--ba-accent,var(--brand));background:color-mix(in srgb,var(--ba-accent,var(--brand)) 14%,transparent);box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--ba-accent,var(--brand)) 24%,transparent)}
  .ba-icon svg{width:19px;height:19px}
  .ba-text{min-width:0;display:flex;flex-direction:column;gap:2px}
  .ba-title{font-size:13.5px;font-weight:700;color:var(--ink);line-height:1.15;letter-spacing:-.005em;overflow-wrap:anywhere}
  /* Wrap to a second line rather than ellipsing. In the narrow right column of
     a multi-patient tile every subtitle clipped mid-word ("Doctor assessment ·
     p…"), which reads as broken rather than abbreviated. */
  .ba-sub{font-size:11px;color:var(--muted);line-height:1.25;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
  .ba-arrow{margin-left:auto;color:var(--faint);flex:none;display:flex;transition:transform .16s,color .16s}
  .bedside-action:hover .ba-arrow{color:var(--ba-accent,var(--brand));transform:translateX(2px)}
  .ba-arrow svg{width:16px;height:16px}
  .ba-badge{margin-left:auto;flex:none;font-size:10px;font-weight:800;letter-spacing:.02em;padding:3px 9px;border-radius:999px;white-space:nowrap;text-transform:uppercase}
  .ba-badge.crit{background:var(--crit);color:#fff}
  /* Wayfinding rail. Same accent system as the write actions so the tile still
     reads as one family, but stripped to icon + name: no subtitle, no arrow,
     no card of its own. Eight destinations in the height the old four
     full-size buttons took, which is what buys the physiology room to breathe
     on a two-patient shift. */
  .ba-group.ba-rail{background:transparent;border:0;padding:0}
  .ba-rail .ba-grid{gap:8px}
  .bedside-action.ba-chip{
    gap:9px;padding:9px 11px;border-radius:9px;background:var(--card-2);
    min-height:44px;
  }
  .bedside-action.ba-chip .ba-icon{
    width:26px;height:26px;border-radius:7px;box-shadow:none;
  }
  .bedside-action.ba-chip .ba-icon svg{width:14px;height:14px}
  .bedside-action.ba-chip .ba-title{font-size:12px;font-weight:700;line-height:1.2}
  .bedside-action.ba-chip:hover{background:var(--card)}
  .single-workflows{display:grid;gap:14px;margin-top:14px}
  .single-workflows .tile-section{margin:0}
  .single-workflows .tile-section-head{margin-bottom:9px}
  .single-workflows .tile-grid{grid-template-columns:repeat(4,minmax(0,1fr))}
  .single-workflows .single-workflow-reports .tile-grid{grid-template-columns:repeat(5,minmax(0,1fr))}
  .single-workflows .single-communication-grid{grid-template-columns:repeat(2,minmax(0,210px))}
  .single-workflows .single-communication-grid .tile{min-height:92px}
  @media(max-width:1000px){
    .single-workflows .tile-grid,.single-workflows .single-workflow-reports .tile-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
  }
  @media(max-width:900px){.ba-grid-3,.ba-grid-4{grid-template-columns:repeat(2,minmax(0,1fr))}}
  @media(max-width:780px){
    :root{--topbar-height:62px}
    .single-focus-grid{grid-template-columns:1fr}
  }
  @media(max-width:460px){.ba-grid-3,.ba-grid-4{grid-template-columns:1fr}.single-bedside-head{flex-wrap:wrap}.single-bedside-updated{margin-left:0}}

  /* Priority cards */
  .priority-grid{display:grid;grid-template-columns:1fr 1fr;gap:12px;min-width:0}
  @media (max-width:560px){.priority-grid{grid-template-columns:1fr}}

  .pri-card{
    background:var(--card);border:1px solid var(--border);
    border-radius:var(--radius-2);padding:13px 14px;
    cursor:pointer;transition:border-color .15s, box-shadow .15s, transform .15s;
    display:flex;flex-direction:column;gap:10px;
    min-height:160px;min-width:0;
  }
  .pri-card:hover{border-color:var(--border-2);box-shadow:var(--shadow-2);transform:translateY(-1px)}
  .pri-card.todo{
    border-color:var(--border);background:var(--surface-warn);
  }
  .pri-head{display:flex;align-items:center;gap:8px;min-width:0}
  .pri-icon{
    width:30px;height:30px;border-radius:8px;
    display:flex;align-items:center;justify-content:center;color:#fff;
    box-shadow:0 4px 10px rgba(0,0,0,.30);
  }
  .pri-icon.todo{background:var(--warn)}
  .pri-icon.insights{background:var(--brand)}
  .pri-icon svg{width:16px;height:16px}
  .pri-title{font-size:13px;font-weight:700;color:var(--ink);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .pri-count{
    margin-left:auto;background:var(--card);border:1px solid var(--border);
    color:var(--ink);padding:2px 8px;border-radius:999px;
    font-size:11px;font-weight:700;
  }
  .pri-count.crit{background:var(--crit);color:#fff;border-color:var(--crit)}
  .pri-list{display:flex;flex-direction:column;gap:6px;flex:1;min-width:0}
  .pri-item{
    display:flex;gap:8px;align-items:flex-start;
    font-size:12px;line-height:1.4;color:var(--ink-2);
  }
  .pri-item .bul{
    width:4px;height:4px;border-radius:50%;background:var(--faint);
    margin-top:7px;flex-shrink:0;
  }
  .pri-item .bul.crit{background:var(--crit)}
  .pri-item .bul.warn{background:var(--warn)}
  .pri-item .when{color:var(--faint);font-size:10.5px;margin-left:auto;flex-shrink:0;padding-left:6px}

  /* ---------- Home task rows (manageable inline, no navigation) ----------
     The home Tasks card used to be a readout. These rows carry the same
     affordances as the action queue — complete, edit, skip, jump to source —
     at bedside-tap size, so routine work never costs a page change. */
  .home-task{
    display:grid;grid-template-columns:auto minmax(0,1fr) auto;gap:9px;align-items:center;
    padding:7px 8px;border:1px solid var(--hairline);border-radius:8px;background:var(--card);
    transition:opacity .2s ease,border-color .14s,background .14s;
  }
  .home-task:hover{border-color:var(--border-2)}
  /* No fill. On a septic patient every visible row is overdue, so a red wash
     per row painted the whole list red and left nothing to rank it by — the
     due chip already states the exact minutes, and .is-critical below is what
     separates "act now" from "late". Border only. */
  .home-task.is-overdue{border-color:var(--crit-border)}
  /* Declared after .is-overdue so a task that is both keeps the critical rail —
     otherwise the overdue border-color wins and the two read identically. */
  .home-task.is-critical{border-left:3px solid var(--crit)}
  /* Optimistic completion: the row strikes through and fades but keeps its
     box, so the list underneath does not jump while the Undo window is open. */
  .home-task.is-recording{opacity:.6}
  .home-task.is-recording .home-task-check{border-color:var(--crit);background:var(--crit-soft);animation:homeTaskPulse 1s ease-in-out infinite}
  @keyframes homeTaskPulse{0%,100%{opacity:1}50%{opacity:.45}}
  .home-task.is-completing{opacity:.45}
  .home-task.is-completing .home-task-title{text-decoration:line-through}
  .home-task.is-completing .home-task-check{background:var(--ok);border-color:var(--ok);color:#fff}
  /* 24px is the WCAG 2.5.8 (AA) floor for a pointer target; this one is tapped
     with a gloved finger at the bedside and used to be 22px. */
  .home-task-check{
    width:24px;height:24px;border-radius:6px;padding:0;
    border:2px solid var(--border-2);background:var(--card);
    display:flex;align-items:center;justify-content:center;cursor:pointer;flex:none;
    transition:all .14s;
    /* Empty at rest, deliberately: an empty box is the universally-read
       "not done yet" state. Tinting the tick in at rest — even faintly — makes
       a task a nurse still has to perform look like one already completed,
       which is the one misreading this control must never invite. The tick
       arrives on hover/press as confirmation of what the tap will do. */
    color:transparent;
  }
  .home-task-check svg{width:12px;height:12px}
  .home-task-check:hover{border-color:var(--ok);color:var(--ok)}
  .home-task-check:focus-visible{border-color:var(--ok);box-shadow:0 0 0 3px var(--ok-soft)}
  .home-task-check:active{transform:scale(.9)}
  .home-task-check[disabled]{cursor:default;opacity:.6}
  .home-task-check.give{border-color:var(--crit-border);color:var(--crit)}
  .home-task-check.give:hover{border-color:var(--crit);background:var(--crit-soft)}
  .home-task-body{min-width:0}
  .home-task-title{
    font-size:12.5px;font-weight:600;color:var(--ink-2);line-height:1.35;
    display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
  }
  .home-task-meta{display:flex;align-items:center;gap:5px;flex-wrap:wrap;margin-top:3px}
  /* Was 13px tall — a real button, but too thin to hit reliably. The padding
     lifts the target without moving the text: the negative margin gives the
     padding back to the layout, so the metadata row keeps its original rhythm. */
  .home-task-src{
    display:inline-flex;align-items:center;gap:4px;font-size:9.5px;font-weight:700;
    letter-spacing:.03em;text-transform:uppercase;color:var(--muted);
    background:none;border:0;cursor:default;
    padding:6px 4px;margin:-6px -4px;
  }
  .home-task-src[data-link]{cursor:pointer}
  .home-task-src[data-link]:hover{color:var(--brand);text-decoration:underline}
  .home-task-due{
    display:inline-flex;align-items:center;gap:3px;font-size:9.5px;font-weight:750;
    padding:1px 6px;border-radius:999px;border:1px solid var(--border);color:var(--muted);
    font-variant-numeric:tabular-nums;
  }
  .home-task-due.soon{border-color:var(--warn-border);background:var(--warn-soft);color:var(--warn)}
  .home-task-due.late{border-color:var(--crit-border);background:var(--crit-soft);color:var(--crit)}
  .home-task-more{
    width:28px;height:28px;border-radius:7px;padding:0;flex:none;
    border:1px solid transparent;background:none;color:var(--faint);cursor:pointer;
    display:flex;align-items:center;justify-content:center;
  }
  .home-task-more svg{width:14px;height:14px}
  .home-task-more:hover{background:var(--bg-soft);border-color:var(--border);color:var(--ink-2)}
  .home-task-menu{
    position:absolute;z-index:60;min-width:172px;padding:5px;
    border:1px solid var(--border);border-radius:10px;background:var(--card);box-shadow:var(--shadow-3);
  }
  .home-task-menu button{
    display:flex;align-items:center;gap:8px;width:100%;padding:7px 9px;
    border:0;border-radius:7px;background:none;color:var(--ink-2);
    font-size:12.5px;font-weight:600;text-align:left;cursor:pointer;
  }
  .home-task-menu button:hover{background:var(--bg-soft)}
  .home-task-menu button svg{width:13px;height:13px;color:var(--muted);flex:none}
  .home-task-add{
    display:inline-flex;align-items:center;gap:4px;padding:3px 9px;border-radius:7px;
    border:1px dashed var(--border-2);background:none;color:var(--brand);
    font-size:11px;font-weight:750;cursor:pointer;
  }
  .home-task-add svg{width:12px;height:12px}
  .home-task-add:hover{background:var(--brand-soft);border-style:solid}
  .pri-foot{
    display:flex;align-items:center;justify-content:space-between;
    padding-top:8px;border-top:1px dashed var(--hairline);
    font-size:11px;color:var(--muted);min-width:0;gap:8px;
  }
  .pri-foot span:first-child{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .pri-foot .arrow{color:var(--brand);font-weight:600;flex:0 0 auto;white-space:nowrap}

  /* Tile section grouping (home) */
  .tile-section{margin-top:6px}
  .tile-section + .tile-section{margin-top:14px}
  .tile-section-head{
    display:flex;align-items:center;gap:10px;margin-bottom:8px;
    padding:0 2px;
  }
  .tile-section-bar{
    width:3px;height:22px;border-radius:2px;flex-shrink:0;
  }
  .tile-section-bar.review{background:linear-gradient(180deg,var(--info),var(--resus))}
  .tile-section-bar.document{background:linear-gradient(180deg,var(--brand-2),var(--brand))}
  .tile-section-bar.communication{background:linear-gradient(180deg,#2563eb,#ec4899)}
  .tile-section-bar.config{background:linear-gradient(180deg,var(--enh),#f59e0b)}
  .tile-section-bar.reports{background:linear-gradient(180deg,#8b5cf6,#6366f1)}
  .tile-section-name{
    font-size:11px;font-weight:700;color:var(--ink);
    letter-spacing:.12em;text-transform:uppercase;
  }
  .tile-section-sub{font-size:11px;color:var(--muted);margin-top:1px}
  /* 4-column tile grids for Review and Document on wide enough panels */
  @media (min-width:760px){
    .tile-section-4 .tile-grid{grid-template-columns:repeat(4,minmax(0,1fr))}
  }
  @media (max-width:520px){
    .tile-section-4 .tile-grid{grid-template-columns:repeat(2,1fr)}
  }

  /* Tile grid */
  .tile-grid{
    display:grid;grid-template-columns:repeat(3,1fr);gap:10px;
  }
  /* Hub pages hold two tiles, not the four or five the bedside console does.
     In a fixed 3-column track that left an empty third column reading as a
     missing card; sizing to content keeps the pair deliberate. */
  .tile-grid.hub{grid-template-columns:repeat(auto-fit,minmax(240px,1fr));max-width:760px}
  @media (max-width:520px){.tile-grid{grid-template-columns:repeat(2,1fr)}}
  .tile{
    background:var(--card);border:1px solid var(--border);
    border-radius:var(--radius-2);padding:14px 12px;
    cursor:pointer;transition:all .15s;
    display:flex;flex-direction:column;gap:8px;align-items:flex-start;
    min-height:104px;text-align:left;
  }
  .tile:hover{border-color:var(--border-2);box-shadow:var(--shadow-2);transform:translateY(-1px)}
  .tile-icon{
    width:34px;height:34px;border-radius:9px;
    display:flex;align-items:center;justify-content:center;color:#fff;
  }
  .tile-icon svg{width:18px;height:18px}
  .tile-name{font-size:12.5px;font-weight:600;color:var(--ink);line-height:1.3}
  .tile-sub{font-size:11px;color:var(--muted);line-height:1.35;margin-top:-3px}
  .tile-badge{
    margin-top:auto;align-self:stretch;
    display:flex;align-items:center;gap:6px;
    font-size:10.5px;color:var(--muted);font-weight:500;
  }
  /* Navigation affordance for tiles with no status to report. */
  .tile-badge .tile-go{display:inline-flex;color:var(--faint);transition:transform .14s,color .14s}
  .tile-badge .tile-go svg{width:13px;height:13px}
  .tile:hover .tile-go{color:var(--brand);transform:translateX(2px)}
  .tile-badge .led{width:7px;height:7px;border-radius:50%;background:var(--faint)}
  .tile-badge .led.ok{background:var(--ok)}
  .tile-badge .led.warn{background:var(--warn);box-shadow:0 0 0 3px var(--warn-soft)}
  .tile-badge .led.crit{background:var(--crit);box-shadow:0 0 0 3px var(--crit-soft);animation:pulse 1.6s infinite}
  @keyframes pulse{0%,100%{opacity:1}50%{opacity:.45}}

  /* ---------- Custom Rules (Phase 9) ---------- */
  /* `align-items:stretch` (the grid default) is what the two panels want: the
     builder is a fixed 540px reading surface, and letting the rules rail stop
     at its content left a 340px step between two side-by-side cards. */
  .cr-layout{display:grid;grid-template-columns:minmax(420px, 1fr) minmax(360px, 1fr);gap:16px;align-items:stretch}
  @media (max-width: 920px){.cr-layout{grid-template-columns:1fr}}
  .cr-chat{background:var(--card);border:1px solid var(--border);border-radius:12px;padding:14px;display:flex;flex-direction:column;gap:8px;min-height:540px}
  .cr-chat-stream{flex:1;overflow-y:auto;display:flex;flex-direction:column;gap:10px;padding-right:4px;max-height:520px}
  .cr-msg{padding:10px 12px;border-radius:10px;line-height:1.45;font-size:13px}
  .cr-msg-ai{background:rgba(99,102,241,.08);border:1px solid rgba(99,102,241,.18);color:var(--ink-2);align-self:flex-start;max-width:92%}
  .cr-msg-clin{background:var(--brand-fill);color:#fff;align-self:flex-end;max-width:80%}
  .cr-suggestions{display:flex;flex-direction:column;gap:6px;margin-top:8px}
  .cr-sugg{display:flex;align-items:center;gap:10px;background:transparent;border:1px solid var(--hairline);border-radius:8px;padding:9px 11px;cursor:pointer;text-align:left;font-size:12.5px;color:var(--ink-2);transition:background 0.15s}
  .cr-sugg:hover{background:rgba(99,102,241,.08);border-color:var(--brand)}
  .cr-sugg-icon{display:inline-flex;width:18px;height:18px;color:var(--brand);flex-shrink:0}
  .cr-sugg-icon svg{width:18px;height:18px}
  .cr-chat-input{display:flex;gap:6px;border-top:1px solid var(--hairline);padding-top:10px;margin-top:auto}
  .cr-chat-input input{flex:1;padding:10px 14px;border:1px solid var(--border);border-radius:10px;font-size:13px;background:var(--card);color:var(--ink)}
  .cr-chat-input input:focus{outline:none;border-color:var(--brand);box-shadow:0 0 0 3px var(--brand-ring)}
  .cr-trigger-confirm{background:var(--ok-soft);border-color:var(--ok-border)}
  .cr-trigger-card{background:var(--card);border:1px solid var(--hairline);border-radius:8px;padding:10px 12px}
  .cr-task-editor{display:flex;align-items:center;gap:7px;margin-top:8px;color:var(--ink-2)}
  .cr-task-editor label{font-weight:600;white-space:nowrap}
  .cr-task-input{min-width:0;flex:1;padding:5px 8px;border:1px solid var(--border);border-radius:6px;background:var(--card);color:var(--ink);font:inherit}
  .cr-task-input:focus{outline:none;border-color:var(--brand);box-shadow:0 0 0 3px var(--brand-ring)}
  .cr-task-priority{color:var(--muted);white-space:nowrap}
  @media (max-width:520px){
    .cr-task-editor{align-items:stretch;flex-wrap:wrap}
    .cr-task-input{flex-basis:calc(100% - 58px)}
    .cr-task-priority{margin-left:51px}
  }
  .cr-active{background:var(--card);border:1px solid var(--border);border-radius:12px;padding:14px;min-height:200px;display:flex;flex-direction:column}
  .cr-active .cr-active-list{flex:1}
  .cr-active-icon{display:inline-flex;width:32px;height:32px;background:var(--ok-soft);color:var(--ok);border-radius:8px;align-items:center;justify-content:center}
  .cr-active-icon svg{width:18px;height:18px}
  .cr-active-title{font-size:14px;font-weight:700;color:var(--ink)}
  .cr-active-list{display:flex;flex-direction:column;gap:10px}
  .cr-rule-card{background:rgba(99,102,241,.05);border:1px solid var(--hairline);border-radius:8px;padding:10px 12px}

  /* ---------- Workflow / sticky patient ---------- */
  .wf-bar{
    position:sticky;top:55px;z-index:40;
    background:var(--glass-bg);
    backdrop-filter:saturate(180%) blur(12px);
    -webkit-backdrop-filter:saturate(180%) blur(12px);
    border-bottom:1px solid var(--border);
  }
  .wf-bar-inner{
    max-width:1600px;margin:0 auto;padding:10px 22px;
    display:flex;align-items:center;gap:14px;flex-wrap:wrap;
  }
  .back-btn{
    display:inline-flex;align-items:center;gap:6px;
    padding:7px 12px 7px 8px;border-radius:8px;
    background:var(--card-2);border:1px solid var(--border);
    color:var(--ink-2);font-size:13px;font-weight:500;
  }
  .back-btn:hover{background:var(--card);border-color:var(--border-2)}
  .wf-pat{
    display:flex;align-items:center;gap:10px;min-width:0;flex:1;
  }
  .wf-pat .avatar{
    width:32px;height:32px;border-radius:9px;color:#fff;
    font-weight:700;font-size:12px;
    display:flex;align-items:center;justify-content:center;flex-shrink:0;
  }
  .wf-pat .grow{min-width:0}
  .wf-pat .nm{font-size:14px;font-weight:700;line-height:1.15}
  .wf-pat .mt{font-size:11.5px;color:var(--muted);margin-top:1px}
  .wf-pat .mt b{color:var(--ink-2);font-weight:600}
  .patient-data-label{
    display:flex;align-items:center;justify-content:center;gap:6px;
    width:100%;margin:0 0 14px;padding:8px 12px;
    border:2px solid var(--crit-border);border-radius:8px;
    background:var(--crit-soft);color:var(--crit);
    font-size:12px;font-weight:900;letter-spacing:.075em;line-height:1.3;
    text-align:center;text-transform:uppercase;
  }
  .patient-data-label.demo{
    border-color:var(--warn-border);background:var(--warn-soft);color:var(--warn);
  }
  .patient-data-label.compact{
    width:auto;align-self:flex-start;margin:0;padding:4px 8px;
    border-width:1px;border-radius:6px;font-size:9.5px;letter-spacing:.055em;
  }
  .pcard > .patient-data-label.compact{align-self:stretch}
  .ppanel-head .patient-data-label{margin:8px 0 0}
  .wf-actions{display:flex;align-items:center;gap:8px;flex-wrap:wrap}

  /* Documented invasive devices stay in the patient-identity band on the
     bedside home and on every patient workflow. Absence is worded as an
     incomplete documentation state, never as proof that no device is present. */
  .patient-device-strip{
    display:flex;align-items:center;gap:5px;flex-wrap:wrap;min-width:0;margin-top:7px;
  }
  .patient-device-label{
    font-size:8.5px;font-weight:800;letter-spacing:.075em;text-transform:uppercase;color:var(--faint);
  }
  .patient-device-chip,.patient-device-empty{
    display:inline-flex;align-items:center;min-height:20px;padding:2px 7px;
    border:1px solid var(--border);border-radius:999px;background:var(--card-2);
    color:var(--ink-2);font-size:10px;font-weight:650;line-height:1.25;
  }
  .patient-device-empty{border-style:dashed;color:var(--muted);font-weight:500}
  .patient-device-strip.workflow{margin-top:4px}

  /* Persistent clinical context. The aside comes first in markup so it sits
     immediately below demographics on narrow screens; desktop grid placement
     moves it beside the active workflow without changing reading order. */
  .clinical-workflow-layout,.clinical-bedside-layout{
    display:grid;grid-template-columns:minmax(0,1fr) minmax(270px,310px);
    gap:16px;align-items:start;min-width:0;
  }
  .clinical-workflow-main,.clinical-bedside-main{grid-column:1;grid-row:1;min-width:0}
  .clinical-summary-rail{
    grid-column:2;grid-row:1;position:sticky;
    top:calc(var(--topbar-height) + 100px);z-index:20;
    overflow:hidden;background:var(--card);border:1px solid var(--border);
    border-radius:var(--radius-3);box-shadow:var(--shadow-1);
  }
  .clinical-summary-rail.home{top:calc(var(--topbar-height) + 170px);margin:14px 14px 14px 0}
  .clinical-summary-title{
    display:flex;align-items:baseline;justify-content:space-between;gap:8px;
    padding:10px 12px;border-bottom:1px solid var(--hairline);background:var(--card-2);
  }
  .clinical-summary-title span{font-size:12px;font-weight:800;color:var(--ink)}
  .clinical-summary-title small{font-size:9.5px;color:var(--muted);white-space:nowrap}
  .clinical-summary-rail dl{margin:0}
  .clinical-summary-row{padding:9px 12px;border-bottom:1px solid var(--hairline)}
  .clinical-summary-row:last-child{border-bottom:0}
  .clinical-summary-row dt{
    margin:0 0 4px;font-size:8.5px;font-weight:800;letter-spacing:.075em;
    text-transform:uppercase;color:var(--faint);
  }
  .clinical-summary-row dd{margin:0;color:var(--ink-2);font-size:11.5px;font-weight:600;line-height:1.35}
  .clinical-summary-row.diagnosis dd{color:var(--ink);font-size:12px}
  .clinical-summary-empty{color:var(--muted);font-weight:500}
  .clinical-summary-numeric{font-variant-numeric:tabular-nums}
  .clinical-summary-devices{display:flex;gap:4px;flex-wrap:wrap}
  .clinical-summary-devices > span{
    padding:2px 6px;border:1px solid var(--border);border-radius:999px;
    background:var(--card-2);font-size:10px;line-height:1.25;
  }
  .clinical-summary-row.alerts dd{display:flex;flex-direction:column;gap:3px}
  .clinical-summary-alert-count{color:var(--warn);font-size:10.5px;font-weight:800}
  .clinical-summary-alert-count.critical{color:var(--crit)}
  .clinical-summary-alert-text{font-weight:550}

  @media (max-width:900px){
    .clinical-workflow-layout,.clinical-bedside-layout{grid-template-columns:minmax(0,1fr);gap:12px}
    .clinical-summary-rail,.clinical-summary-rail.home{
      grid-column:1;grid-row:1;position:static;top:auto;margin:0;
    }
    .clinical-workflow-main,.clinical-bedside-main{grid-column:1;grid-row:2}
    .clinical-summary-rail dl{display:grid;grid-template-columns:repeat(2,minmax(0,1fr))}
    .clinical-summary-row{border-right:1px solid var(--hairline)}
    .clinical-summary-row:nth-child(2n){border-right:0}
    .clinical-summary-row:nth-last-child(-n+2){border-bottom:0}
  }
  @media (max-width:520px){
    .patient-device-strip{align-items:flex-start}
    .patient-device-label{flex-basis:100%}
    .clinical-summary-rail dl{grid-template-columns:minmax(0,1fr)}
    .clinical-summary-row,.clinical-summary-row:nth-child(2n),.clinical-summary-row:nth-last-child(-n+2){
      border-right:0;border-bottom:1px solid var(--hairline);
    }
    .clinical-summary-row:last-child{border-bottom:0}
  }

  /* Workflow titlebar */
  .wf-title{
    display:flex;align-items:center;gap:14px;flex-wrap:wrap;
    margin-bottom:18px;
  }
  .wf-title .h1{flex:1;min-width:200px}
  .source-summary-inline{
    scroll-margin-top:72px;margin:-4px 0 18px;
    background:var(--card);border:1px solid var(--border);
    border-radius:var(--radius-3);box-shadow:var(--shadow-2);overflow:hidden;
  }
  .source-summary-inline-head{
    display:flex;align-items:flex-start;gap:14px;padding:14px 18px;
    background:linear-gradient(90deg,var(--brand-soft),var(--card));
    border-bottom:1px solid var(--hairline);
  }
  .source-summary-inline-title{
    display:flex;align-items:center;gap:8px;
    color:var(--ink);font-size:14px;font-weight:700;
  }
  .source-summary-inline-title svg{width:17px;height:17px;color:var(--brand)}
  .source-summary-inline-sub{margin-top:3px;color:var(--muted);font-size:11.5px;line-height:1.45}
  .source-summary-inline-close{margin-left:auto;flex-shrink:0}
  .source-summary-inline-body{padding:18px}
  .btn.source-summary-pill{
    border-radius:999px;background:var(--brand-soft);border-color:var(--brand-ring);
    color:var(--brand-2);box-shadow:none;
  }
  .btn.source-summary-pill:hover{background:var(--card);border-color:var(--brand)}
  .source-summary-inline-body > .ai-summary-card{
    margin:0;padding:0;border:0;border-radius:0;box-shadow:none;background:transparent;
  }
  .source-summary-inline-body > .ai-summary-card > .ai-foot{display:none}
  .source-summary-inline-body > .report-section:last-child{margin-bottom:0}
  .source-summary-inline-body > .row{display:none}
  .source-summary-inline-foot{
    display:flex;align-items:center;gap:12px;flex-wrap:wrap;
    padding:12px 18px;border-top:1px solid var(--hairline);background:var(--bg-soft);
  }
  .source-summary-inline-status{color:var(--muted);font-size:11.5px;line-height:1.45}
  .source-summary-inline-refresh{margin-left:auto}
  @media(max-width:640px){
    .source-summary-inline-head{padding:12px 14px}
    .source-summary-inline-body{padding:14px}
    .source-summary-inline-foot{padding:12px 14px}
    .source-summary-inline-refresh{width:100%;justify-content:center}
  }
