/* ------------------------------------------------------------------
   Enterprise Clinical Copilot — application shell.

   Loaded by the application base (demo/templates/demo/app_base.html), so every
   page that extends it — the public front door, the guarded application, and the
   sign-in form — shares one voice. The base is standalone, so there is no
   marketing chrome to suppress: the shell simply owns the viewport.

   The first two rules replace what Bootstrap supplied on the marketing pages and
   what this base therefore lost. Without border-box a declared 264px menu renders
   289px wide, because padding and border add to the declared width; without the
   margin reset the shell is inset from the viewport edge.
   ------------------------------------------------------------------ */
*, *::before, *::after { box-sizing: border-box; }
body { margin: 0; }

.cp {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: #fff;
  color: #0f172a;
  font-family: Inter, system-ui, -apple-system, "Segoe UI", sans-serif;
}

/* ---------- top bar: account actions and the menu ---------- */
.cp-head { display: flex; justify-content: flex-end; padding: 14px 20px 0; }
.cp-actions { display: flex; align-items: center; gap: 10px; }

.cp-btn {
  font: inherit; font-size: 0.85rem; font-weight: 600; line-height: 1.2;
  padding: 8px 16px; border-radius: 999px; cursor: pointer;
  border: 1px solid transparent; text-decoration: none;
}
.cp-btn-quiet { color: #334155; background: transparent; }
.cp-btn-quiet:hover { background: #f1f5f9; color: #0f172a; }
.cp-btn-solid { background: #2563eb; color: #fff; border-color: #2563eb; }
.cp-btn-solid:hover { background: #1d4ed8; }

.cp-icon-btn {
  width: 38px; height: 38px; border-radius: 10px; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 1rem; color: #334155; background: transparent;
  border: 1px solid transparent;
}
.cp-icon-btn:hover { background: #f1f5f9; color: #0f172a; }
.cp-icon-btn[aria-expanded="true"] { background: #f1f5f9; color: #0f172a; }

.cp-menu-anchor { position: relative; }
.cp-menu {
  position: absolute; top: calc(100% + 8px); right: 0; z-index: 20;
  min-width: 240px; padding: 6px;
  display: flex; flex-direction: column; gap: 2px;
  /* Declared here rather than per item so the button below can inherit it. */
  font-size: 0.85rem;
  background: #fff; border: 1px solid #e2e8f0; border-radius: 12px;
  box-shadow: 0 12px 30px rgba(15, 23, 42, 0.12);
}
.cp-menu[hidden] { display: none; }
.cp-menu-item {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 10px; border-radius: 8px;
  color: #1f2937; text-decoration: none;
}
.cp-menu-item i { width: 16px; text-align: center; color: #64748b; }
a.cp-menu-item:hover,
button.cp-menu-item:hover { background: #f1f5f9; color: #0f172a; }
/* The menu is authored for links and readouts. Sign-out has to POST, so it is a
   button carrying the same item shape with the browser's button styling
   removed. */
button.cp-menu-item {
  width: 100%; font-family: inherit; font-size: inherit;
  text-align: left; cursor: pointer;
  background: transparent; border: none;
}
/* The request count is a readout, not a control: same row shape as the guide
   link so the menu reads as one list, but nothing to click. */
.cp-menu-quota { color: #475569; }
.cp-menu-quota strong {
  margin-left: auto; color: #0f172a; font-variant-numeric: tabular-nums;
}

/* A slim state strip under the top bar. Only rendered in fixture mode, where it
   is the difference between an offline demo and a demo pretending to be live. */
.cp-note {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  margin: 10px 20px 0; padding: 8px 14px;
  font-size: 0.8rem; color: #475569;
  background: #f1f5f9; border: 1px solid #e2e8f0; border-radius: 10px;
}
.cp-note i { color: #64748b; }

/* ---------- the front door: the mark and the ask bar, centred ---------- */
/* The public page has no answer region to make room for, so it centres what it
   holds. The application's own head is `.cp-top`, below. */
.cp-hero {
  flex: 1; display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  padding: 0 20px 12vh; gap: 26px;
}

/* ---------- the head of the canvas: the mark, the question, the run ---------- */
/* One column serves both states. It holds the mark and nothing else: the question
   and the run it produced belong to the turn that carries them, and are built by
   the client inside the feed. */
.cp-top {
  flex: none; width: 100%;
  /* Pane-relative, at the sidebar icon's own inset (2026-10-16). The ECC badge and the
     sidebar's collapse icon are the two marks at the top-left of the page, and symmetry
     between them means one number, not two columns that have to be kept equal by hand.
     Measured: the aside is at 0 with 12px padding and its icon button adds 6px, so the
     icon's left edge is 21px from the page. This block is at 264 (the main pane's edge)
     and therefore starts at 264 + 21 = 285 — the same 21px, mirrored into the second
     pane.
     It used to be `max-width: 960px; margin: 0 auto`, a centred column: that put the
     badge at 272 (8px inside the pane, because a 960 column centred in a 975px pane is
     not flush) and left it matching neither the icon above it nor the content below. */
  max-width: none; margin: 0 0 26px; padding: 0 20px 0 21px;
  display: flex; flex-direction: column; align-items: flex-start; gap: 18px;
}
.cp-brand { display: flex; align-items: center; gap: 12px; }
.cp-logo { width: 44px; height: 44px; display: block; }
.cp-brand-name {
  margin: 0; font-size: 1.35rem; font-weight: 600;
  letter-spacing: -0.01em; color: #0f172a;
}

/* The run, while it runs. The dots say it is still going and the label says where
   it is; each stage replaces the label as it arrives.

   Once the run settles the live row is replaced by `.cp-stages` below — the same
   labels, kept, behind a chevron. Nothing is hidden while the run is moving: the
   disclosure only exists after there is nothing left to watch. */
.cp-status { width: 100%; display: flex; align-items: center; gap: 10px; }
.cp-status[hidden] { display: none; }
/* Takes its natural width and no more, so the label sits beside the dots rather
   than running to the far edge of the canvas; it still shrinks when it is long. */
.cp-status-text { flex: 0 1 auto; min-width: 0; font-size: 0.85rem; color: #475569; }

/* The dots, carried over from the earlier demo's typing indicator so both
   surfaces say "working" the same way. */
.typing-dots { display: inline-flex; gap: 4px; align-items: center; flex: none; }
.typing-dots span {
  width: 6px; height: 6px; border-radius: 50%;
  background: #2563eb; animation: typing-blink 1.2s infinite ease-in-out;
}
.typing-dots span:nth-child(2) { animation-delay: 0.18s; }
.typing-dots span:nth-child(3) { animation-delay: 0.36s; }
@keyframes typing-blink {
  0%, 60%, 100% { opacity: 0.25; transform: translateY(0); }
  30% { opacity: 1; transform: translateY(-3px); }
}
/* Each stage's wording replaces the last, and arrives fading in, so the change
   reads as the run moving on rather than the page flickering. */
.cp-status-text { animation: status-fade 260ms ease-out; }
@keyframes status-fade { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
  .typing-dots span, .cp-status-text { animation: none !important; }
}

/* What the run did, under the turn's HEADER rather than under its answer.

   Deliberately quiet: a chevron the width of its own words, not a panel. The answer below
   it is what the reader came for, and this is the line that says how it got there — read on
   demand, out of the way when it is not. It moved here from the foot of the turn: at the
   bottom of a long /ehr answer it sat below the fold of a screen the reader had already
   read past, and the question it answers (did it look in the right places?) is asked
   before the answer is read, not after. The arrow is the browser's own marker, rotated by
   `[open]` rather than replaced by a glyph, so the control is still a `details` element to
   a screen reader and to the keyboard. */
.cp-stages { font-size: 0.78rem; color: #64748b; margin: 0 0 10px; }
.cp-stages-summary {
  cursor: pointer; list-style: none; display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 0; border-radius: 6px;
}
.cp-stages-summary::-webkit-details-marker { display: none; }
.cp-stages-summary::before {
  content: '\203a'; font-size: 0.9rem; line-height: 1;
  transition: transform 140ms ease-out;
}
.cp-stages[open] .cp-stages-summary::before { transform: rotate(90deg); }
.cp-stages-summary:hover { color: #475569; }
.cp-stages-list {
  margin: 6px 0 0; padding: 0 0 0 16px; list-style: none;
  display: flex; flex-direction: column; gap: 3px;
}
.cp-stages-item { position: relative; }
/* The rail, drawn per item so the last label does not trail a line into nothing. */
.cp-stages-item::before {
  content: ''; position: absolute; left: -10px; top: 0.55em;
  width: 4px; height: 4px; border-radius: 50%; background: #cbd5e1;
}

.cp-ask {
  display: flex; align-items: center; gap: 8px;
  /* The form is a child of the canvas now, so it carries its own inset: nothing
     above it supplies one any more. */
  width: calc(100% - 40px); max-width: 720px;
  margin: 0 auto;
  padding: 8px 8px 8px 18px;
  background: #fff; border: 1px solid #cbd5e1; border-radius: 999px;
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
}
.cp-ask:focus-within {
  border-color: #2563eb; box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.12);
}
.cp-ask-input {
  flex: 1; min-width: 0; padding: 10px 0;
  border: none; outline: none; background: transparent;
  font: inherit; font-size: 1rem; line-height: 1.45; color: #0f172a;
  /* A `<textarea>`, not an `<input>`, so a long clinical question wraps and stays
     readable while it is being written. `rows="1"` and this rule are what make the
     one-line case look exactly as the input did. The ceiling lives here, once, and the
     script reads it from here; the height itself is set from `scrollHeight`.

     Past the ceiling the box scrolls internally rather than growing, so it can never
     take the feed's height away from the answer it is asking about. */
  display: block; resize: none; overflow-y: hidden;
  max-height: 200px;
}
/* An empty box is one line, and the placeholder is longer than a narrow viewport can
   show. `nowrap` with the ellipsis is what keeps that box one line and makes the
   clipping read as deliberate — the same treatment the `<input>` had. The moment there
   is something to read, the text wraps and the box grows instead. */
.cp-ask.is-empty .cp-ask-input {
  white-space: nowrap; text-overflow: ellipsis; overflow: hidden;
}
/* One line is a pill; several lines would make a lozenge, so the radius relaxes once the
   box has wrapped. The send button drops to the baseline with the last line, because
   that is where the reader's eye is. The patient pill centres against the whole box
   instead: it names what the question is about rather than belonging to its last line,
   and against a half-screen-tall composer a pill pinned to the bottom reads as though it
   had slid out of place. */
.cp-ask.is-multiline { align-items: flex-end; border-radius: 24px; }
.cp-ask.is-multiline .patient-pill { align-self: center; }
/* A placeholder is drawn by the browser rather than as this element's own text,
   so the ellipsis has to be declared on the pseudo-element too. */
.cp-ask-input::placeholder { color: #94a3b8; text-overflow: ellipsis; }
.cp-send {
  flex: none; width: 40px; height: 40px; border-radius: 50%;
  border: none; cursor: pointer; background: #2563eb; color: #fff;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 1rem;
}
.cp-send:hover { background: #1d4ed8; }

/* The input carries a placeholder but no visible label, so the label is here
   for assistive technology only. */
.cp-sr-only {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ---------- sign-in: the same shell, a form where the ask bar sits ---------- */
.cp-auth-main {
  flex: 1; display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  padding: 0 20px 12vh; gap: 22px;
}
.cp-auth-card {
  width: 100%; max-width: 380px;
  display: flex; flex-direction: column; gap: 16px;
  padding: 24px;
  background: #fff; border: 1px solid #e2e8f0; border-radius: 16px;
  box-shadow: 0 12px 30px rgba(15, 23, 42, 0.08);
}
.cp-field { display: flex; flex-direction: column; gap: 6px; }
.cp-field span { font-size: 0.8rem; font-weight: 600; color: #334155; }
.cp-field input {
  font: inherit; font-size: 0.95rem; color: #0f172a;
  padding: 10px 12px; outline: none;
  background: #fff; border: 1px solid #cbd5e1; border-radius: 10px;
}
.cp-field input:focus {
  border-color: #2563eb; box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.12);
}
.cp-auth-error {
  margin: 0; padding: 9px 12px;
  font-size: 0.82rem; color: #991b1b;
  background: #fef2f2; border: 1px solid #fecaca; border-radius: 10px;
}
.cp-btn-block {
  width: 100%; text-align: center;
  padding: 11px 16px; font-size: 0.9rem;
}

/* ---------- the composer's `@` patient selector ---------- */
/* The dropdown positions against the bar, so the bar is the anchor. */
.cp-ask { position: relative; }

/* The chosen patient, as a pill at the head of the bar. A sibling of the input,
   not a child of it — an `<input>` holds text and nothing else, so the bar is the
   flex container that holds both. */
.patient-pill {
  flex: none; display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 6px 5px 12px;
  font-size: 0.85rem; font-weight: 600; color: #1d4ed8;
  background: #eff6ff; border: 1px solid #bfdbfe; border-radius: 999px;
  white-space: nowrap;
}
.patient-pill[hidden] { display: none; }
.patient-pill-clear {
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; padding: 0; cursor: pointer;
  font-size: 0.7rem; color: #1d4ed8;
  background: transparent; border: none; border-radius: 50%;
}
.patient-pill-clear:hover { background: #dbeafe; }

/* The command pill's rules were here. Removed with the pill itself (UX ruling
   2026-10-13): an armed command is shown by the typed `/command` left in the input,
   so nothing on the bar renders as a chip any more. */

/* Both dropdowns share one shape: anchored above the bar, full width of it. */
.cp-patient-list,
.cp-command-list {
  position: absolute; bottom: calc(100% + 8px); left: 0; right: 0; z-index: 30;
  margin: 0; padding: 6px; list-style: none;
  background: #fff; border: 1px solid #e2e8f0; border-radius: 14px;
  box-shadow: 0 12px 30px rgba(15, 23, 42, 0.12);
}
.cp-patient-list[hidden],
.cp-command-list[hidden] { display: none; }
.cp-patient {
  display: flex; align-items: baseline; gap: 10px;
  padding: 9px 12px; border-radius: 9px; cursor: pointer;
}
.cp-patient[aria-selected="true"] { background: #f1f5f9; }
.cp-patient-name { font-size: 0.9rem; color: #0f172a; }
.cp-patient-meta { font-size: 0.78rem; color: #64748b; }
.cp-patient-empty { padding: 10px 12px; font-size: 0.85rem; color: #64748b; }
.cp-command {
  display: flex; align-items: baseline; gap: 10px;
  padding: 9px 12px; border-radius: 9px; cursor: pointer;
}
.cp-command[aria-selected="true"] { background: #f1f5f9; }
.cp-command-name { flex: none; font-size: 0.85rem; font-weight: 600; color: #1d4ed8; }
.cp-command-desc {
  font-size: 0.82rem; color: #64748b;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ---------- the answer surface ---------- */
.cp-answer {
  flex: 1; min-height: 0; width: 100%; max-width: 860px;
  margin: 0 auto; padding: 8px 20px 32px;
  overflow-y: auto;
}
.cp-answer[hidden] { display: none; }

/* The agent's composed surface. Empty until a surface is mounted, so it
   contributes no space before an answer exists. */
.cp-canvas:empty { display: none; }
.cp-canvas { margin-bottom: 16px; }
/* ---- the conversation viewport ------------------------------------------------
   Three zones in a fixed-height column: the context bar, the feed, and the
   composer. Only the feed scrolls. The failure this replaces was a page that grew
   downward as turns were added, pushing the composer off the bottom and leaving
   the reader to scroll for the thing they type into. */
.cp-app-main { height: 100vh; display: flex; flex-direction: column; overflow: hidden; }
.cp-feed {
  flex: 1 1 auto; min-height: 0; overflow-y: auto; width: 100%;
  /* No vertical padding: a pinned heading sticks to the top of the scrollport, and
     padding here would leave a strip above it for the text to show through. The
     space above the first heading belongs to the heading. */
  padding: 0 32px;
}
.cp-ask { flex: 0 0 auto; }

/* The context bar: what the thread is about, and how long it will be kept. */
.cp-context {
  flex: 0 0 auto; display: flex; align-items: center; gap: 12px;
  /* Left inset matched to the brand above it, not 32px (2026-10-16). The ECC badge and
     the patient pill are the first thing on each of the two top rows, and they read as
     one column only if they begin at the same point: measured, the badge is at 285 and
     this row's first child was at 296, eleven pixels to its right. Both are now 21px
     from the pane's edge. The right inset is untouched — nothing on the right has an
     opposite number to line up with. */
  padding: 10px 32px 10px 21px; border-bottom: 1px solid #eceef1; flex-wrap: wrap;
}
.cp-context-pill {
  display: inline-flex; align-items: center; gap: 8px; background: #f3f4f6;
  border: 1px solid #e5e7eb; border-radius: 999px; padding: 4px 12px;
  font-size: 0.85rem; font-weight: 600; color: #1f2937;
}
.cp-context-hadm { font-weight: 400; color: #6b7280; }
.cp-context-state { font-size: 0.8rem; color: #6b7280; }

/* ---- the conversation: one column of turns -----------------------------------
   No card, no border, no number. A turn is a stretch of the column separated from
   the next by whitespace and a hairline, so twenty of them read as one document
   rather than as twenty boxes, and nothing has to be opened to be read. */
.cp-turn {
  width: 100%; max-width: 960px; margin: 0 auto;
  padding-bottom: 26px;
  border-bottom: 1px solid #f1f5f9;
}
.cp-turn:last-child { border-bottom: 0; }

/* The question, pinned to the head of the scroll area while its own answer passes
   under it. The next turn's question pushes it up and out, which is what makes the
   heading in view always the one belonging to the text beneath it — the job the
   navigator was doing, without a second control to keep in step with the first.

   The side margins are negative so the background reaches the edges of the scroll
   area rather than stopping at the text column: a heading that let the answer show
   past its left and right edges would read as text bleeding through. */
.cp-turn-head {
  position: sticky; top: 0; z-index: 10;
  display: flex; align-items: baseline; gap: 12px;
  margin: 0 -32px; padding: 16px 32px 10px;
  background: rgba(255, 255, 255, 0.92);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}
.cp-turn-title {
  flex: 1 1 auto; min-width: 0;
  margin: 0; font-size: 1rem; font-weight: 600; line-height: 1.45;
  color: #0f172a; letter-spacing: -0.005em;
}
.cp-turn-body { padding-top: 4px; }
.cp-turn-foot { padding-top: 12px; }
/* An empty part of a turn takes no space: a block is born with a canvas host and a
   prose element and neither has anything in it yet, so without this the gaps
   between them read as a turn that rendered blankly. */
.cp-answer-text:empty { display: none; }
.cp-canvas:empty { display: none; }

/* The draft, before the surface replaces it.

   Every metric here is the narrative's own (`NARRATIVE_STYLES` in
   a2ui_clinical_components.js), and the reason is that the draft and the settled answer
   are the same words. Laid out at the same size and the same leading, the handover
   between them changes a marker's border and nothing else. This element used to be 1.65
   leading against the narrative's 1.6, and unformatted, so the swap reflowed the whole
   answer at the moment the reader finished reading it.

   A shadow root cannot be styled from here and this cannot be styled from there, so the
   numbers are duplicated rather than shared — and `demo/test_frontend_stream.py` asserts
   that the two sets agree, which is the only thing that keeps a duplicate honest. */
.cp-answer-text { font-size: 1rem; line-height: 1.65; color: #0f172a; max-width: 68ch; }
.cp-answer-text > h1, .cp-answer-text > h2,
.cp-answer-text > h3, .cp-answer-text > h4 {
  font-size: 1.05rem; font-weight: 650; line-height: 1.4; color: #0f172a;
  margin: 1.5rem 0 0.35rem;
}
.cp-answer-text > :first-child { margin-top: 0; }
.cp-answer-text > p, .cp-answer-text > ul, .cp-answer-text > ol {
  margin: 0 0 0.9rem; text-wrap: pretty;
}

/* A block that has just finished arriving, settling into the place it will keep. It is
   appended once and never re-rendered, so this runs once per block and later text does
   not disturb the ones already read. */
.cp-draft-block { animation: cp-settle 200ms ease-out both; }

/* The block that has not finished arriving. `pre-wrap` because this is one block of
   markdown source: a list whose blank line has not arrived yet would otherwise run its
   items together on a single line. */
.cp-draft-tail { white-space: pre-wrap; }

/* A citation marker during the draft. Shaped like the component's own pill so the reader
   is not shown one thing and then another, and dashed because it is not yet a control:
   there is nothing to open until the answer settles. */
/* The same pill as the component's, softened the same way, and dashed because it is not
   yet a control. The settled marker swaps the dash for a solid hairline and nothing
   reflows, which is what keeps the handover from shifting a line of prose. */
.cp-cite {
  font-size: 0.72em; line-height: 1; vertical-align: super;
  margin-left: 1px; padding: 1px 5px;
  border: 1px dashed #cbd5e1; border-radius: 999px;
  background: #f1f5f9; color: #334155; opacity: 0.7;
  font-variant-numeric: tabular-nums; white-space: nowrap;
}

@keyframes cp-settle {
  from { opacity: 0; transform: translateY(3px); }
  to { opacity: 1; transform: none; }
}

/* The handover between the draft and the surface.

   One grid cell for both children, so they occupy the same place instead of stacking:
   the draft underneath at full opacity, the surface over it at zero, and then the two
   cross over in place. In normal flow the reader would be shown two copies of the answer
   one above the other for the length of the fade, which is the failure this replaces.

   The cell is the taller of the two — the surface, which carries the cards as well as
   the prose — and that is also the height the column takes once the draft is emptied and
   the grid is dropped, so the collapse at the end moves nothing. */
.cp-canvas > a2ui-surface {
  display: block;
  transition: opacity 180ms ease-out;
}
.cp-canvas > a2ui-surface.cp-entering { opacity: 0; }
.cp-answer.is-settling { display: grid; grid-template-columns: minmax(0, 1fr); }
.cp-answer.is-settling > * { grid-area: 1 / 1; align-self: start; }
.cp-answer.is-settling > .cp-answer-text { pointer-events: none; }
.cp-answer-text.cp-leaving { opacity: 0; transition: opacity 180ms ease-out; }

@media (prefers-reduced-motion: reduce) {
  .cp-draft-block, .cp-canvas > a2ui-surface { animation: none; }
  .cp-canvas > a2ui-surface, .cp-answer-text.cp-leaving { transition: none; }
}
.cp-answer-error {
  margin: 0; padding: 10px 14px; font-size: 0.88rem; color: #991b1b;
  background: #fef2f2; border: 1px solid #fecaca; border-radius: 10px;
}
/* A run that stopped after it had already put words on screen. The prose above it is
   kept — it arrived correctly, and replacing it with an apology takes back work the
   reader has already done — so this qualifies the text rather than standing in for it.
   A pill, not a banner: it says the answer is unfinished, which is one fact, and a
   full-width red box for one fact reads as a hazard alarm. */
.cp-answer-interrupted {
  display: inline-flex; align-items: center; gap: 6px;
  margin: 4px 0 0; padding: 4px 11px; border-radius: 999px;
  font-size: 0.78rem; font-weight: 500; color: #92400e;
  background: #fffbeb; border: 1px solid #fde68a;
}

/* The verification notice: a quiet pill beside the question rather than a banner over
   the answer. Muted slate, not amber — the previous full-width amber box read as a
   hazard alarm for what is a routine reconciliation against the record. `cursor: help`
   is the only affordance it needs, because the title carries the full account of what
   was removed. */
.cp-evidence {
  flex: none; display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 10px; border-radius: 999px;
  font-size: 0.75rem; font-weight: 500; color: #475569;
  background: #f1f5f9; border: 1px solid #e2e8f0;
  cursor: help;
  /* It arrives after the answer does, when the guardrails have finished with the text.
     Fading in says it is new; appearing whole under a line the reader has already
     started makes them look twice at what moved. */
  animation: cp-settle 180ms ease-out both;
}
.cp-evidence[hidden] { display: none; }

/* The scope pill: what the answer rested on. Quieter than the correction notice, because
   it is not news — it is the standing answer to "is this about my patient?" — but it is
   the one label that stops a claim about the literature being read as a chart finding. */
.cp-scope {
  flex: none; display: inline-flex; align-items: center;
  padding: 3px 10px; border-radius: 999px;
  font-size: 0.72rem; font-weight: 600; letter-spacing: 0.01em;
  color: #1e40af; background: #eff6ff; border: 1px solid #bfdbfe;
  animation: cp-settle 180ms ease-out both;
}
.cp-scope[hidden] { display: none; }

/* The foot of a turn: its references and its next questions.

   The gaps are the section rhythm, not decoration: 24px above the evidence block, 14px
   between its rows, and 24px below it before the follow-up card, so the three parts of
   the foot read as three parts rather than as one stack pressed together. */
.cp-turn-trail { display: flex; flex-direction: column; gap: 24px; margin-top: 24px; }

/* The references drawer, open by default and labelled in the editorial manner: the rows
   are part of the answer's evidence, and a reader checking a marker should not have to
   open a control first. The disclosure is kept — a reader who wants the answer alone can
   close it. */
.cp-references { font-size: 0.85rem; animation: cp-settle 200ms ease-out both; }
.cp-references[hidden] { display: none; }
.cp-references > summary {
  width: fit-content; padding: 4px 0 6px; cursor: pointer;
  font-size: 0.68rem; font-weight: 650; letter-spacing: 0.06em;
  text-transform: uppercase; color: #64748b; list-style: none;
}
.cp-references > summary::-webkit-details-marker { display: none; }
.cp-references > summary::before { content: '› '; color: #94a3b8; }
.cp-references[open] > summary::before { content: '⌄ '; }
.cp-reference-list {
  margin: 6px 0 0; padding: 0; list-style: none;
  display: flex; flex-direction: column; gap: 14px;
}
/* Each row is an invisible two-column grid of 28px and the rest: the number sits once, in
   the gutter, and the evidence hangs beside it. The grid draws no rules and no bullets,
   because these rows are evidence and a reader should see a list of passages rather than a
   list of controls.

   The number lives here and nowhere else. An earlier version carried `[1]` inside the row's
   own label beside a counter that rendered `1.`, so production showed `1. [1] Discharge
   note` — two numbers for one row, disagreeing about how to write it. */
.cp-reference-item {
  display: grid; grid-template-columns: 28px 1fr; align-items: start;
  padding-left: 0; border-left: 0;
}
.cp-reference-index {
  padding-top: 1px; color: #94a3b8; font-size: 0.8rem; line-height: 1.5;
  font-variant-numeric: tabular-nums;
}
.cp-reference-main { min-width: 0; }
/* The citation line under a published record: journal, year, authors, identifier. Set
   quieter than the title and allowed to wrap — it is long by nature and truncating it
   would leave the reader unable to cite the paper. */
.cp-reference-subtitle {
  margin-top: 3px; color: #64748b; font-size: 0.8rem; line-height: 1.45;
}
/* The header line is the section or the article, in the link accent, with a pill saying
   what kind of source it is: a discharge note is the patient's own record and a journal
   article is published evidence, and the reader weighs the second differently. The pill
   wraps under a long title rather than squeezing it into a column. */
.cp-reference-head {
  display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap;
  max-width: 100%; padding: 0; border: 0; background: none;
  font: inherit; font-weight: 600; color: #1d4ed8; text-align: left;
  text-decoration: none; cursor: pointer;
}
.cp-reference-title { min-width: 0; }
.cp-reference-head:hover .cp-reference-title { text-decoration: underline; }
.cp-reference-tag {
  flex: none; padding: 1px 8px; border: 1px solid #e2e8f0; border-radius: 999px;
  background: #f1f5f9; color: #64748b; font-size: 0.7rem; font-weight: 500;
  white-space: nowrap;
}
/* The opening passage is shown, not hidden behind a click, and clamped to two lines so a
   long chunk cannot push the rest of the evidence off the screen. Clicking the row still
   toggles the full text. */
.cp-reference-excerpt {
  margin: 4px 0 0; color: #475569; font-size: 0.88rem; line-height: 1.5;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  overflow: hidden;
}
.cp-reference-item.is-open .cp-reference-excerpt { -webkit-line-clamp: unset; }
/* The row a citation's "see all references" landed on.

   A smooth scroll ends somewhere, and this is how the reader can tell where: the same
   outline the prose marker wears when a drawer row points back at it, applied to the row
   the card sent them to. It clears itself after a moment (the page owns the timer), so the
   list is left as it was found. */
.cp-reference-item.is-target {
  outline: 2px solid #1f2937; outline-offset: 4px; border-radius: 6px;
}

/* The follow-up rows: one control per row, full width, hairline-separated, with the
   chevron saying what a click does. Disabled once one is taken — see `askFollowUp`.

   Framed as a card under an uppercase label, because the row is a block of the answer
   rather than a strip of chrome under it: unframed, three blue rows under a hairline read
   as a menu, and a reader does not know what they are a menu OF. */
.cp-follow-ups {
  display: flex; flex-direction: column;
  padding: 16px; border: 1px solid #e2e8f0; border-radius: 12px;
  background: #f8fafc;
  animation: cp-settle 220ms ease-out both;
}
.cp-follow-ups[hidden] { display: none; }
.cp-follow-ups::before {
  content: 'Follow-up questions';
  text-transform: uppercase; letter-spacing: 0.06em;
  font-size: 0.68rem; font-weight: 650; color: #64748b;
  margin-bottom: 8px;
}
.cp-follow-up {
  display: flex; align-items: center; gap: 12px; width: 100%;
  padding: 10px 12px; border: 0; border-top: 1px solid #e2e8f0;
  background: none; cursor: pointer; text-align: left;
  font: inherit; font-size: 0.92rem; color: #1d4ed8;
}
.cp-follow-up:hover { color: #1e3a8a; }
.cp-follow-up:disabled { color: #94a3b8; cursor: default; }
.cp-follow-up-text { flex: 1 1 auto; min-width: 0; }
.cp-follow-up-chevron { flex: none; color: #94a3b8; font-size: 1.05rem; line-height: 1; }

/* What the reader thought of a settled turn, and a copy of it.

   Icon-only with a tooltip, the way a chat transcript does it: the affordance is learned
   once and then costs nothing, where a labelled button would put three words of chrome
   under every answer. Outline glyphs in the same muted grey as the turn's other chrome,
   so the row reads as an affordance beside the answer rather than a reaction to it. */
.cp-turn-actions {
  display: flex; align-items: center; justify-content: flex-end;
  gap: 2px; margin-top: 12px;
}
/* `display: flex` above beats the user agent's `[hidden] { display: none }`, so the
   attribute the script sets to keep this strip hidden until the answer settles would
   otherwise do nothing at all — and the controls would sit beside the live status row,
   offering a rating for an answer that has not been written yet. */
.cp-turn-actions[hidden] { display: none; }

/* The turn's utility toolbar, opposite the title in the sticky header. `margin-left:
   auto` is what pins it to the right of the header's flex row: the title already grows,
   so the pills sit between the two and Export lands at the edge. */
.cp-turn-toolbar {
  display: flex; align-items: center; gap: 2px;
  margin-left: auto; flex: none;
}
.cp-turn-toolbar[hidden] { display: none; }
.cp-turn-action {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 28px; height: 28px; padding: 0 6px;
  border: 0; border-radius: 6px; background: none; cursor: pointer;
  font: inherit; font-size: 0.82rem; line-height: 1;
  color: #8b949e; transition: color 120ms ease, background 120ms ease;
}
.cp-turn-action:hover { color: #24292f; background: #f3f4f6; }
.cp-turn-action:focus-visible { outline: 2px solid #1f2937; outline-offset: 1px;
                                color: #24292f; }
/* The reader's own rating, held quietly. Not a badge and not a score shown back to them:
   it is a record of what they said, and it stays re-choosable because a reader who
   changes their mind is telling us something more useful than the first click was. */
.cp-turn-action.is-chosen { color: #1f2937; background: #eef1f5; }

/* ---------- application: the menu and the surface beside it ---------- */
/* The shell becomes a row: the menu takes a fixed column, the working surface
   takes the rest. `.cp` stays a column for the front door and the sign-in form,
   which have no menu to sit beside. */
/* The application owns the viewport: the menu and the canvas scroll within it
   rather than the page scrolling, which is what keeps the composer where it is
   put however long the answer runs. */
.cp-app { flex-direction: row; height: 100dvh; overflow: hidden; }

.cp-side {
  flex: none; width: 264px;
  display: flex; flex-direction: column;
  padding: 14px 12px;
  background: #f8fafc; border-right: 1px solid #e2e8f0;
  transition: width 150ms ease;
}
.cp-side-head {
  display: flex; justify-content: space-between; align-items: center;
  padding-bottom: 10px;
}
.cp-side-nav { display: flex; flex-direction: column; gap: 2px; }

.cp-nav-item {
  display: flex; align-items: center; gap: 11px;
  width: 100%; padding: 9px 10px;
  font: inherit; font-size: 0.86rem; text-align: left;
  color: #334155; background: transparent;
  border: none; border-radius: 9px;
}
.cp-nav-item i:first-child { width: 16px; text-align: center; color: #64748b; }
/* The four labels are placeholders and are rendered `disabled`. Keep the cursor
   from offering a click the element will not honour. */
.cp-nav-item[disabled] { cursor: default; }

/* ---- the thread list ---------------------------------------------------------
   One row per thread, and a thread is one patient. The row carries the name and
   nothing else: no first question, no turn count, no date. A reader looking for a
   patient is looking for a name, and everything beside it is read past. */
.cp-thread-search { padding: 0 2px 10px; }
.cp-thread-input {
  width: 100%; font: inherit; font-size: 0.86rem;
  padding: 7px 12px; border: 1px solid #e2e8f0; border-radius: 999px;
  background: #fff; color: #0f172a;
}
.cp-thread-input:focus {
  outline: none; border-color: #93c5fd; box-shadow: 0 0 0 3px #dbeafe;
}
.cp-thread-input::placeholder { color: #94a3b8; }

.cp-threads {
  display: flex; flex-direction: column; min-height: 0; flex: 1 1 auto;
  margin-top: 18px;
}
.cp-threads-label {
  margin: 0 0 6px; padding: 0 12px;
  font-size: 0.72rem; font-weight: 600; letter-spacing: 0.06em;
  text-transform: uppercase; color: #94a3b8;
}
.cp-thread-list {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-direction: column; gap: 2px;
  overflow-y: auto;
}
.cp-thread { position: relative; display: flex; align-items: center; gap: 2px; }
.cp-thread-open {
  display: flex; align-items: center; gap: 8px; flex: 1 1 auto; min-width: 0;
  padding: 8px 12px; border: 0; border-radius: 999px;
  font: inherit; font-size: 0.86rem; color: #334155;
  text-align: left; background: transparent; cursor: pointer;
}
.cp-thread-name {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cp-thread-pin { flex: 0 0 auto; font-size: 0.62rem; color: #94a3b8; }
.cp-thread-open:hover { background: #eef2f7; }
/* The thread on screen: bold, and carried on a pill. */
.cp-thread-open[aria-current="true"] {
  background: #e2e8f0; color: #0f172a; font-weight: 700;
}
.cp-threads-empty {
  margin: 0; padding: 6px 12px;
  font-size: 0.82rem; line-height: 1.45; color: #94a3b8;
}

/* The row's actions. Hidden until the row is hovered or the control is reached by
   keyboard: three dots on every row at rest is a column of dots, not a list of
   patients. */
.cp-thread-menu-wrap { display: flex; flex: 0 0 auto; }
.cp-thread-menu-btn {
  display: grid; place-items: center;
  width: 26px; height: 26px; border: 0; border-radius: 999px;
  background: transparent; color: #64748b; cursor: pointer;
  opacity: 0; transition: opacity 120ms ease-out;
}
.cp-thread:hover .cp-thread-menu-btn,
.cp-thread-menu-btn:focus-visible,
.cp-thread-menu-btn[aria-expanded="true"] { opacity: 1; }
.cp-thread-menu-btn:hover { background: #e2e8f0; color: #0f172a; }
/* Opacity is not enough on its own: a control that cannot be seen must not be able
   to be clicked by accident either. */
@media (hover: none) {
  .cp-thread-menu-btn { opacity: 1; }
}
/* Fixed to the viewport, not to the row. The list it belongs to is a scroll
   container, and a scroll container clips its absolutely positioned descendants —
   which is why this used to open downward and come out cut in half. Nothing here
   may be clipped or covered, so it is attached to the document instead and given
   the top of the stack. */
.cp-row-menu {
  position: fixed; z-index: 60;
  min-width: 172px; padding: 6px;
  display: flex; flex-direction: column; gap: 2px;
  background: #fff; border: 1px solid #e2e8f0; border-radius: 12px;
  box-shadow: 0 12px 30px rgba(15, 23, 42, 0.14);
}
.cp-row-menu[hidden] { display: none; }
.cp-row-menu-item {
  padding: 7px 10px; border: 0; border-radius: 8px;
  font: inherit; font-size: 0.85rem; color: #1f2937;
  text-align: left; background: transparent; cursor: pointer;
}
.cp-row-menu-item:hover { background: #f1f5f9; }
.cp-row-menu-danger { color: #b91c1c; }
.cp-row-menu-danger:hover { background: #fef2f2; }
.cp-row-menu-prompt {
  margin: 2px 2px 6px; font-size: 0.82rem; line-height: 1.4; color: #475569;
}

/* The identity sits at the foot of the menu, which is where the eye expects to
   find the account it is signed in as. It opens the account menu above it. */
.cp-side-foot { position: relative; margin-top: auto; padding-top: 10px; border-top: 1px solid #e2e8f0; }

.cp-user {
  display: flex; align-items: center; gap: 10px;
  width: 100%; padding: 8px;
  font: inherit; text-align: left; cursor: pointer;
  background: transparent; border: none; border-radius: 10px;
}
.cp-user:hover { background: #eef2f7; }
.cp-avatar {
  flex: none; width: 30px; height: 30px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 0.72rem; font-weight: 600; letter-spacing: 0.02em;
  color: #fff; background: #475569;
}
.cp-user-text { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.cp-user-name {
  font-size: 0.84rem; font-weight: 600; color: #0f172a;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cp-user-email {
  font-size: 0.74rem; color: #64748b;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cp-user-caret { font-size: 0.65rem; color: #94a3b8; }

/* Anchored to the right of the footer rather than above it, aligned to the bottom
   so it reads as an extension of the row. The extra 20px clears the sidebar's own
   padding and border, so the gap is measured from the sidebar's edge rather than
   from the text inside it. The minimum width keeps the menu legible when the
   sidebar is collapsed and the footer is only an avatar wide. */
.cp-account-menu {
  position: absolute; bottom: 0; left: calc(100% + 20px); z-index: 20;
  min-width: 248px; padding: 6px;
  display: flex; flex-direction: column; gap: 2px;
  font-size: 0.85rem;
  background: #fff; border: 1px solid #e2e8f0; border-radius: 12px;
  box-shadow: 0 12px 30px rgba(15, 23, 42, 0.12);
}
.cp-account-menu[hidden] { display: none; }
/* The account being signed in as: a readout, so the check says which one it is
   rather than the row being clickable. */
.cp-account-current { color: #64748b; }
.cp-account-current span {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cp-account-menu .cp-account-logout {
  margin-top: 4px; padding-top: 4px; border-top: 1px solid #e2e8f0;
}

/* The collapse control shows the direction it will move the menu in. Both arrows
   live in the button and one is hidden, so the swap needs no script. */
.cp-side-toggle-icon { width: 19px; height: 19px; display: block; }
.cp-icon-when-collapsed { display: none; }
.cp-app.is-collapsed .cp-icon-when-open { display: none; }
.cp-app.is-collapsed .cp-icon-when-collapsed { display: block; }

/* A disabled control must not look like a live one. */
.cp-icon-btn[disabled] { cursor: default; opacity: 0.45; }

/* Collapsed: the labels go and the icons stay, so the rail still says what the
   menu holds without spending the width on saying it.

   Scoped above the drawer breakpoint on purpose. A rail is the answer to a column
   that is too wide, and below 700px there is no column — the menu is an overlay —
   so the collapsed state is switched off wholesale across the breakpoint rather
   than overridden rule by rule at it. */
@media (min-width: 701px) {
  .cp-app.is-collapsed .cp-side { width: 64px; }
  .cp-app.is-collapsed .cp-side-head { justify-content: center; }
  .cp-app.is-collapsed .cp-side-search,
  .cp-app.is-collapsed .cp-thread-search,
  .cp-app.is-collapsed .cp-threads { display: none; }
  .cp-app.is-collapsed .cp-nav-item span,
  .cp-app.is-collapsed .cp-user-text,
  .cp-app.is-collapsed .cp-user-caret { display: none; }
  .cp-app.is-collapsed .cp-nav-item,
  .cp-app.is-collapsed .cp-user { justify-content: center; }
}

/* The drawer's scrim: in the document at every width, displayed only by the
   narrow-viewport rules below. */
.cp-scrim { display: none; }

.cp-app-main {
  flex: 1; min-width: 0; height: 100%; overflow: hidden;
  display: flex; flex-direction: column;
  padding-bottom: 0;
}
/* The console's column is fixed, in every state: the mark at the head, the
   composer at the foot, and the conversation taking whatever is between.

   The two auto margins that used to meet in the middle were written for a canvas
   with nothing else on it, and they were the only thing centring the mark. With a
   sidebar and a populated thread list beside it, a title floating mid-page reads as
   a stray heading in the middle of a document rather than as a welcome — and the
   composer, which is the one control this surface exists for, sat above the fold
   with empty space beneath it. Nothing here needs centring to look deliberate.

   Scoped to this column on purpose: the public front door asks the same question of
   its own layout rule above, and a bare `.cp-ask` margin would move its composer as
   well. */
.cp-app-main .cp-top {
  margin-top: 0; margin-bottom: 18px;
  align-items: stretch;
}
.cp-app-main .cp-ask { margin-top: auto; margin-bottom: 22px; }
/* `is-asking` is still set on the shell by the client when the canvas holds a
   conversation, and nothing in this stylesheet reads it any more: every rule it
   used to switch was a difference between an empty canvas and a full one, and this
   column no longer has two states to switch between. It is left in place as the
   hook for the one that is coming — a run in flight — rather than removed and
   re-added. */
/* The mark is app chrome here rather than a hero. It sits at the head of the
   conversation in every state, so it keeps one size: growing it until the first
   question and shrinking it after was a change in the page's geometry that
   answered to nothing the reader had done. The landing page still scales its own. */
.cp-app-main .cp-logo { width: 30px; height: 30px; }
.cp-app-main .cp-brand-name { font-size: 1.05rem; }

/* ---- narrow viewports ---------------------------------------------------------
   The sidebar and the conversation side by side need about 700px before the
   composer starts losing room to the sidebar. Below that the sidebar leaves the
   flow and becomes an overlay drawer: it is not shrunk to an icon rail, because
   64px of rail plus a working composer does not fit either, and it is not put away
   without a trace, because navigation that cannot be reached is not a layout
   decision but a missing one.

   The same control drives both states and it does not move: above 700px it
   collapses the column, below it slides the drawer, and it stays pinned to the
   top-left corner either way so the panel arrives behind the control that summoned
   it. That is why the drawer travels on `left` and not on `transform` — a
   transform would make this element the containing block for its own
   fixed-position button, and the button would ride off the screen with the panel. */
/* The middle band: the sidebar gives up its width before the conversation does. */
@media (max-width: 900px) {
  .cp-side { width: 200px; }
}

@media (max-width: 700px) {
  /* Out of the flex flow and past the left edge. The main column therefore has the
     full width, which is the point: the composer keeps the room. */
  .cp-side {
    position: fixed; top: 0; bottom: 0; left: -280px; width: 264px;
    z-index: 50; transition: left 180ms ease;
    box-shadow: 0 0 0 1px rgba(15, 23, 42, 0.06), 0 18px 40px rgba(15, 23, 42, 0.18);
  }
  .cp-app.is-drawer-open .cp-side { left: 0; }

  /* Pinned to the viewport, so it holds one place open and closed. */
  #cp-side-toggle { position: fixed; top: 14px; left: 12px; z-index: 60; }

  /* The toggle has left the flow, so space-between has nothing to push against and
     the magnifier would fall to the left edge with it. */
  .cp-side-head { justify-content: flex-end; }

  /* The first row of the main column now starts under the pinned control, so it
     steps aside rather than sitting beneath it. */
  .cp-top { padding-left: 54px; }

  /* Laid out at drawer width, revealed only while the drawer is open. */
  .cp-scrim {
    position: fixed; inset: 0; z-index: 40;
    background: rgba(15, 23, 42, 0.45);
  }
  .cp-app.is-drawer-open .cp-scrim { display: block; }

  .cp-feed { padding: 0 16px; }
  .cp-turn-head { margin: 0 -16px; padding: 14px 16px 10px; }
  .cp-context { padding: 10px 16px; }
  .cp-app-main .cp-ask { margin-bottom: 14px; }
}

/* The composer's floor. It is the one control on the page that has to stay usable
   at any width, so it wraps before it squeezes: the patient pill moves to its own
   line rather than the field collapsing to nothing beside it, which is what it did
   at 300px — nine pixels of input is not a narrow layout, it is a broken one. */
.cp-ask { flex-wrap: wrap; }
.cp-ask-input { min-width: 140px; }

/* ------------------------------------------------------------------
   Printing a turn (UX gap 1, 2026-11-02).

   Measured by printing `/demo/a2ui/` to PDF: one page, the answer clipped at the
   viewport's edge, the sidebar down its left side and the composer laid across the
   bottom of the text. The cause is the shell's own design — `.cp-app` is `100dvh` with
   `overflow: hidden` and `.cp-feed` is the only thing that scrolls — which is exactly
   right on screen and exactly wrong on paper, where there is no scrollport and whatever
   it holds back is simply gone.

   A printed turn is a document, so under `@media print` the shell stops being an
   application: the chrome is removed, every height and overflow clamp is released so the
   browser paginates the whole conversation, and the blocks that carry clinical meaning are
   kept from splitting across a page break.

   One thing CSS cannot do from here: the A2UI surface is drawn into shadow roots, so the
   component-level print rules live in the components' own stylesheets
   (`static/js/a2ui/shared.js`, `cited_narrative.js`, `comparative_risk_matrix.js`). This
   block owns the page around them.
   ------------------------------------------------------------------ */
@media print {
  /* ---- 1. Chrome that is an affordance, not a fact -----------------------------
     None of it survives the page: a sidebar cannot be opened on paper, a composer cannot
     be typed into, a rating control cannot be clicked. The turn's own content — the
     question, the answer, the tables, the references, the follow-up questions — is kept,
     because that is what a printed clinical note is. */
  .cp-side,
  .cp-head,
  .cp-top,
  .cp-context,
  .cp-ask,
  .cp-scrim,
  .cp-status,
  .cp-turn-actions,
  #cp-side-toggle,
  .cp-icon-btn,
  .cp-btn,
  .cp-menu {
    display: none !important;
  }

  /* ---- 2. Release the viewport clamps -----------------------------------------
     Every element from `html` down to the answer is told to size itself to its content.
     Without this the browser prints one viewport-height of the FIRST page and stops,
     which is the `1/1` page count that was reported. */
  html,
  body,
  .cp,
  .cp-app,
  .cp-app-main,
  .cp-feed,
  .cp-answer,
  .cp-turn,
  .cp-turn-body,
  .cp-turn-foot,
  .cp-turn-trail,
  .cp-references,
  .cp-references > ol {
    height: auto !important;
    max-height: none !important;
    overflow: visible !important;
    position: static !important;
    display: block !important;
    float: none !important;
  }

  /* The shell is a row on screen and a column on paper: the sidebar is gone and the
     surface takes the page width. */
  .cp-app { flex-direction: column !important; }

  /* The reading column keeps a measure, but a paper one: the page's own margins do the
     centring, and a 960px cap would leave a turn narrower than the page it prints on. */
  .cp-turn,
  .cp-answer,
  .cp-feed {
    max-width: none !important;
    margin: 0 !important;
    padding: 0 !important;
    width: auto !important;
  }

  /* A pinned question becomes an ordinary heading on its own line — sticky positioning
     and a backdrop blur have no meaning on a page, and the blur prints as a grey band. */
  .cp-turn-head {
    position: static !important;
    margin: 0 0 6pt !important;
    padding: 0 !important;
    background: none !important;
    -webkit-backdrop-filter: none !important;
    backdrop-filter: none !important;
    break-after: avoid;
    page-break-after: avoid;
  }

  /* ---- 3. The references, which are the bibliography of the page -----------------
     The drawer is a `<details>`: on screen a reader opens or closes it, and in print the
     state they left it in would decide whether the bibliography exists. It is forced open
     and its summary — a control — is removed, so the list always prints. Same reasoning
     for a note row's clamped passage: two lines is a screen affordance, the whole passage
     is the paper content, because there is nothing to click. */
  .cp-references {
    display: block !important;
    border-top: 1px solid #e2e8f0;
    margin-top: 10pt;
  }
  .cp-references > summary { display: none !important; }
  .cp-references[open] > * { display: block !important; }
  .cp-reference-list { display: block !important; }
  .cp-reference-excerpt,
  .cp-reference-item.is-open .cp-reference-excerpt {
    -webkit-line-clamp: unset !important;
    line-clamp: unset !important;
    display: block !important;
    overflow: visible !important;
  }
  .cp-reference-head { cursor: auto; }

  /* ---- 4. Blocks that must not be split ---------------------------------------- */
  .cp-reference-item,
  .cp-follow-up,
  .cp-turn-body > *,
  .cp-canvas > * {
    break-inside: avoid;
    page-break-inside: avoid;
  }

  /* The follow-up row asks the next question rather than answering this one, and a
     printed clinical note of this kind carries it. Kept deliberately. */
  .cp-follow-ups {
    display: block !important;
    break-inside: avoid;
    page-break-inside: avoid;
  }

  /* ---- 5. Type on paper --------------------------------------------------------
     Ink is denser than a screen, so body text is set a shade larger; links lose their
     colour so a printed answer survives a photocopy. `print-color-adjust` keeps a table's
     tinted baseline row from being dropped by an ink-saving default, which would make the
     patient's own row indistinguishable from the cohorts beside it. */
  body { font-size: 11pt; color: #000; background: #fff; }
  a { color: #000; text-decoration: none; }
  * { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
}

/* The page itself. Margins are stated here rather than left to the browser's default so
   a two-sided print has a usable gutter and the clinical table is not clipped by the
   page edge. */
@page {
  size: auto;
  margin: 14mm 12mm 16mm;
}
