/* ORAD Reading Station — shell layout.
   Shared components (pills, findings rows, differential rows, chat thread,
   composer) come from chat.css; this file owns the three-zone station, the lens
   switcher, the dockable Report (tabs ⇄ stacked panes), the resizable/collapsible
   rails, and the native Map lens. */

*{box-sizing:border-box}
body{margin:0;background:var(--bg);color:var(--ink);font-family:var(--font-body)}

/* visually-hidden live region for screen-reader announcements */
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}

/* brief self-dismissing notice (storage-full save failure, etc.) */
.toast{position:fixed;left:50%;bottom:22px;transform:translateX(-50%);z-index:70;max-width:min(460px,calc(100vw - 32px));background:var(--ink);color:var(--paper);border:1px solid var(--danger);border-left:3px solid var(--danger);border-radius:10px;padding:11px 14px;font-size:12.5px;line-height:1.45;box-shadow:var(--shadow-2)}
.toast.hidden{display:none}
.update-note{position:fixed;left:50%;bottom:22px;transform:translateX(-50%);z-index:71;display:flex;align-items:center;gap:8px;max-width:calc(100vw - 32px);background:var(--paper);color:var(--ink);border:1px solid var(--rule);border-left:3px solid var(--ox);border-radius:10px;padding:7px 8px 7px 14px;font-size:13px;line-height:1.4;box-shadow:var(--shadow-2)}
.update-note[hidden]{display:none}
.update-note button{font:inherit;font-size:12.5px;border-radius:var(--r-sm);padding:5px 11px;cursor:pointer;white-space:nowrap}
.update-go{background:var(--ox);color:var(--on-ox);border:1px solid var(--ox);font-weight:600}
.update-later{background:none;color:var(--muted);border:1px solid transparent}
.update-later:hover{color:var(--ink)}

/* ── station grid: sidebar · rz · stage · rz · report ───────────────────────── */
.station{
  --sb-w:216px; --sb-mini:60px; --rpt-w:384px; --rzl-w:6px; --rzr-w:6px;
  display:grid;grid-template-columns:var(--sb-w) var(--rzl-w) minmax(0,1fr) var(--rzr-w) var(--rpt-w);
  height:100dvh;min-height:520px;
}
/* pin every child to its track — a display:none rail must never shift the rest
   left into the wrong (possibly 0px) track via auto-placement */
.station .sidebar{grid-column:1}
.station #rzLeft{grid-column:2}
.station .stage{grid-column:3}
.station #rzRight{grid-column:4}
.station .report{grid-column:5}
/* collapsed sidebar → a slim, always-visible icon rail (never a floating chevron);
   the one toggle in the sidebar header expands it back */
.station.sb-collapsed{--sb-w:var(--sb-mini);--rzl-w:0px}
.station.sb-collapsed #rzLeft{pointer-events:none;opacity:0}
.station.rpt-hidden{--rpt-w:0px;--rzr-w:0px}
.station.rpt-hidden .report{display:none}
.station.rpt-hidden #rzRight{pointer-events:none;opacity:0}
/* Classic carries its own differential + inline atlas → the Report dock is redundant
   there; hide it lens-side (case state persists in the store). Same for the chat
   landing, which is a full-width entry with no results yet. */
.station.lens-classic,.station.lens-atlas,.station.chat-landing{--rpt-w:0px;--rzr-w:0px}
.station.lens-classic .report,.station.lens-atlas .report,.station.chat-landing .report{display:none}
.station.lens-classic #rzRight,.station.lens-atlas #rzRight,.station.chat-landing #rzRight{pointer-events:none;opacity:0}
/* The chat landing keeps only the mobile menu in its minimal header. Help lives in
   the sidebar footer, where it remains available across lenses. */
.station.chat-landing .stage-head{border-bottom:0;background:none}
.station.chat-landing .stage-head > *{display:none}
.station.chat-landing .stage-head > #sbOpen,
.station.chat-landing .stage-head > .mgap{display:block}
.station.stage-full{--sb-w:0px;--rpt-w:0px;--rzl-w:0px;--rzr-w:0px}
.station.stage-full .sidebar,.station.stage-full .report{display:none}
.station.stage-full .rail-rz{pointer-events:none;opacity:0}


/* The Report sheet shares the sidebar drawer's backdrop. shared/theme/sidebar.css
   owns .rail-scrim and the sb-shown case; the report's own trigger is app-only. */
.station.rpt-shown .rail-scrim{display:block}

/* drag handles between rails and stage */
.rail-rz{cursor:col-resize;background:transparent;position:relative;z-index:5}
.rail-rz::after{content:"";position:absolute;inset:0 2px;background:var(--rule);opacity:0;transition:opacity .12s}
.rail-rz:hover::after,.rail-rz.dragging::after{opacity:1;background:var(--ox)}


/* The case list's look lives in shared/theme/sidebar.css: the site's rail shows it too. */
.cs-rename{width:100%;font-family:var(--font-body);font-size:12.5px;color:var(--ink);background:var(--bg);border:1px solid var(--ox);border-radius:5px;padding:4px 6px;outline:none}

/* ── CENTER: the stage ──────────────────────────────────────────────────────── */
.stage{display:flex;flex-direction:column;overflow:hidden;background:var(--bg);min-width:0}
.stage-head{height:52px;flex:none;display:flex;align-items:center;gap:10px;padding:0 10px;border-bottom:1px solid var(--rule);background:linear-gradient(180deg,rgba(127,127,127,.03),transparent)}
.railbtn{font-size:14px;line-height:1;color:var(--muted);background:transparent;border:1px solid var(--rule);border-radius:7px;padding:6px 9px;cursor:pointer;flex:none}
.railbtn:hover{color:var(--ink);border-color:var(--ox)}
.railbtn.off{color:var(--faint);border-style:dashed}
/* current-lens label in the minimal stage header (the tabs moved to the sidebar) */
.stage-lens{font-family:var(--font-mono);font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--ox)}
.stage-lens:empty{display:none}

.stage-body{flex:1;min-height:0;position:relative;overflow:hidden}
.lens{position:absolute;inset:0;display:flex;flex-direction:column;overflow:hidden}
.lens.hidden{display:none}
#lensChat .chat{flex:1;min-height:0}

/* ── Chat landing: an OpenEvidence-style entry when the conversation is empty ──── */
#chatLanding{display:none}
.chat.landing #thread{display:none}
.chat.landing #chatLanding{display:block;flex:1;min-height:0;overflow-y:auto}
.chat.landing .composer{border-top:0;padding:0}

.cl-hero{min-height:82vh;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:18px;padding:6vh 24px 3vh;text-align:center}
.cl-mark{font-family:var(--font-display);font-weight:700;font-size:clamp(46px,9vw,86px);letter-spacing:-.03em;line-height:1;color:var(--ink)}
.cl-mark b{color:var(--ox)}
.cl-thesis{margin:0;color:var(--muted);font-size:clamp(15px,2vw,19px);line-height:1.4}
.cl-slot{width:100%;max-width:680px;margin-top:6px}
#landingSlot .composer-inner{border:1px solid var(--rule);border-radius:14px;background:var(--paper);padding:12px 14px;box-shadow:var(--shadow-3)}
#landingSlot .composer-inner:focus-within{border-color:var(--ox)}
/* landing starters: a compact centered pill row (overrides the big shared .starter-card
   cards from chat.css) — one clean Martian Mono line each, wraps if the capability-gated
   literature chip appears as a 4th */
.cl-starters{width:100%;max-width:660px;display:flex;flex-wrap:wrap;justify-content:center;gap:8px;margin-top:6px}
.cl-starters .starter-card{position:relative;display:inline-flex;align-items:center;gap:8px;padding:8px 15px;border:1px solid var(--rule);border-radius:999px;background:var(--paper);cursor:pointer}
.cl-starters .starter-card::before{display:none}
.cl-starters .starter-card:hover,.cl-starters .starter-card:focus-visible{border-color:var(--ox);background:var(--ox-soft);outline:none}
.cl-starters .sc-glyph{width:auto;height:auto;margin:0;border:0;background:transparent;font-size:12px;color:var(--ox)}
.cl-starters .sc-title{font-family:var(--font-mono);font-weight:500;font-size:11px;letter-spacing:.03em;color:var(--muted);line-height:1}
.cl-starters .starter-card:hover .sc-title,.cl-starters .starter-card:focus-visible .sc-title{color:var(--ink)}
.cl-cue{font-family:var(--font-mono);font-size:9.5px;letter-spacing:.08em;text-transform:uppercase;color:var(--faint);margin-top:6px}

.cl-more{max-width:760px;margin:0 auto;padding:8px 24px 64px;display:flex;flex-direction:column;gap:34px}
.cl-block{min-width:0}
.cl-h{font-family:var(--font-mono);font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:var(--ox);margin-bottom:13px}
.cl-cards{display:grid;grid-template-columns:1fr 1fr 1fr;gap:10px}
.cl-refs{grid-template-columns:1fr 1fr}
.ex-card{display:flex;flex-direction:column;gap:5px;text-align:left;padding:13px 15px;border:1px solid var(--rule);border-radius:11px;background:var(--paper);cursor:pointer;min-width:0;text-decoration:none}
.ex-card:hover{border-color:var(--ox);background:var(--ox-soft)}
/* Category index: the root's crawlable route into the 194 lesion pages. Quiet by
   design — it is wayfinding at the bottom of the landing, not a call to action. */
.cl-cats{display:flex;flex-wrap:wrap;gap:7px}
.cl-cats a{padding:6px 11px;border:1px solid var(--rule);border-radius:999px;background:var(--paper);color:var(--muted);font-size:11.5px;text-decoration:none}
.cl-cats a:hover{border-color:var(--ox);color:var(--ink);background:var(--ox-soft)}
.ex-t{font-family:var(--font-display);font-size:13.5px;font-weight:600;color:var(--ink)}
.ex-s{font-size:11.5px;color:var(--muted);line-height:1.42}
.cl-how{margin:0;padding-left:20px;display:flex;flex-direction:column;gap:9px;color:var(--muted);font-size:13.5px;line-height:1.5}
.cl-how b{color:var(--ink);font-weight:600}
.cl-disc{margin:14px 0 0;font-family:var(--font-mono);font-size:10px;letter-spacing:.03em;color:var(--faint)}
.cl-about{text-align:center;padding-top:4px}
.cl-about a{font-family:var(--font-mono);font-size:10px;letter-spacing:.06em;text-transform:uppercase;color:var(--muted);text-decoration:none}
.cl-about a:hover{color:var(--ox)}
@media(max-width:620px){
  .cl-hero{min-height:76vh;padding-top:8vh}
  .cl-cards,.cl-refs{grid-template-columns:1fr}
}

/* Classic lens — a normal center-stage lens (the sidebar stays docked beside it):
   findings rail left (clinical over radiographic), differential + lesion-profile
   boxes right. The original tool's shape, minus the image kit. */
.classic-wrap{--cl-side-w:380px;flex:1;min-height:0;display:grid;grid-template-columns:minmax(0,1fr) 6px minmax(0,var(--cl-side-w));grid-template-rows:minmax(0,1fr)}
.classic-center{min-width:0;min-height:0;overflow:hidden;display:flex;flex-direction:column;background:var(--paper)}
.classic-center>[hidden],#classicLesion[hidden]{display:none}
.classic-findings{flex:1;overflow-y:auto;background:var(--paper);padding-bottom:4px;min-width:0;min-height:0;container-type:inline-size;container-name:findings}
/* The findings form is a table in all but markup: every label sits in one column and
   every row's chips start at the same edge, so the eye runs straight down the answers.
   Its headings are the loud part (Jason, 2026-10-02: "make the headers more visible like
   we did before", and say Radiographic before Location): each panel opens on a solid ink
   bar, and each radiographic section on a tinted band with an accent edge, numbered by
   its step in the search pattern. Both are opaque, so the sticky bar never shows rows
   scrolling through it. A gutter beside the rows was tried and dropped the same day: it
   spent a whole column on a few words. The full question is the row's tooltip and
   accessible name (app-shell.js frow). The dock's Report pane keeps its own
   label-above-chips layout from chat.css. */
.cl-sec{position:sticky;top:0;z-index:2;font-family:var(--font-display);font-size:13px;font-weight:700;line-height:1.2;letter-spacing:.01em;color:var(--paper);background:var(--ink);padding:9px 16px 9px 18px}
/* 156px holds the longest label that carries a "multiple" cue ("Tooth relation", 87px, +
   6px gap + the 54px cue) on one line with room to spare. At 148px, with the old
   "Relation to teeth" label, the cue wrapped under the label (Jason, 2026-10-19). */
.classic-findings{--fs-lab:156px}
.classic-findings .fsec{display:flex;flex-direction:column;min-width:0}
.classic-findings .fsec-h{display:flex;align-items:baseline;gap:10px;padding:7px 16px 7px 15px;background:var(--ox-soft);border-left:3px solid var(--ox);min-width:0}
.classic-findings .fsec-t{display:flex;align-items:baseline;gap:7px;font-family:var(--font-display);font-size:13.5px;font-weight:700;line-height:1.25;color:var(--ink)}
.classic-findings .fsec-n{flex:none;color:var(--ox);font-variant-numeric:tabular-nums}
.classic-findings .fsec-c{font-size:11px;line-height:1.3;color:var(--muted);font-variant-numeric:tabular-nums}
.classic-findings .fsec-rows{display:flex;flex-direction:column;gap:1px;padding:6px 16px 8px 12px;min-width:0}
.classic-findings .frow{display:grid;grid-template-columns:var(--fs-lab) minmax(0,1fr);align-items:start;column-gap:12px;padding:2px 6px;border-radius:0 8px 8px 0;min-width:0;max-width:100%}
.classic-findings .frow .lab{margin:0;padding-top:4px;display:flex;flex-wrap:wrap;align-items:center;gap:2px 6px;font-size:13px;font-weight:600;line-height:1.3;color:var(--ink);cursor:help;min-width:0}
.classic-findings .frow.empty .lab{color:var(--muted)}
.classic-findings .frow .vals{display:flex;flex-wrap:wrap;gap:5px;min-width:0}
/* Chips are buttons here. An answered chip is the one solid element on the form, so a
   glance down the column reads as the case (Jason, 2026-10-02). Film proposals keep their
   dashed provenance styles from chat.css. */
/* manipulation: tapping a chip twice to undo it must toggle it, not trigger iPhone
   Safari's double-tap zoom (Bill, 2026-10-02: "deselect, then click Y or N again") */
.classic-findings .opt{font:inherit;font-size:12.5px;line-height:1.2;margin:0;padding:4px 11px;text-align:center;touch-action:manipulation}
.classic-findings .opt.clin,.classic-findings .opt.you{background:var(--ox);border-color:var(--ox);color:var(--on-ox)}
.classic-findings .opt.clin:hover,.classic-findings .opt.you:hover{border-color:var(--ink);color:var(--on-ox)}
.classic-findings .opt:focus-visible{outline:2px solid var(--ox);outline-offset:2px}
/* A narrow form (a phone, or a wide differential column) sets a label above its chips. */
@container findings (max-width:430px){
  .classic-findings .frow{grid-template-columns:minmax(0,1fr);row-gap:4px;padding:4px 6px}
  .classic-findings .frow .lab{padding-top:0}
}
.cl-rz{border-left:1px solid var(--rule)}
.cl-rz:focus-visible{outline:2px solid var(--ox);outline-offset:-2px}
.classic-side{overflow-y:auto;min-width:0;min-height:0;padding:12px;display:flex;flex-direction:column;gap:12px;background:var(--bg)}
.cl-box{border:1px solid var(--rule);border-radius:12px;background:var(--paper);overflow:hidden;flex:none}
.cl-box-h{font-family:var(--font-display);font-size:13px;font-weight:700;line-height:1.3;color:var(--ink);padding:10px 14px;border-bottom:1px solid var(--rule)}
.cl-box-b{min-height:56px}
/* The reader: the article in the center, in place of the findings form. Only the body
   scrolls; the head (Back, n of N) and foot (Previous / Next) are pinned outside it. The
   article holds the atlas prose measure (86ch = 760px at 14px, plus the 16px .cl-pad
   inset), and the outline joins it once the center has room for both. */
#classicLesion{flex:1;display:flex;flex-direction:column;min-height:0;container-type:inline-size;container-name:reader}
.cl-profile-mid{flex:1;min-height:0;display:flex}
.cl-profile-body{flex:1;min-width:0;min-height:0;overflow-y:auto;scroll-behavior:auto}
.cl-profile-body>.cl-pad{max-width:792px;margin-inline:auto}
.cl-profile-toc{display:none}
@container reader (min-width:1000px){.cl-profile-toc:not([hidden]){display:block;flex:none;width:220px;overflow-y:auto;border-right:1px solid var(--rule);padding:18px 12px 28px}}
.cl-profile-toc .spine-link.on{color:var(--ink);background:var(--ox-soft)}
.cl-profile-head,.cl-profile-foot{flex:none;display:flex;align-items:center;gap:10px;padding:6px 14px;background:var(--bg);font-family:var(--font-mono);font-size:10.5px;letter-spacing:.04em;text-transform:uppercase;min-width:0}
.cl-profile-head[hidden],.cl-profile-foot[hidden]{display:none}
.cl-profile-head{border-bottom:1px solid var(--rule)}
.cl-profile-foot{border-top:1px solid var(--rule);justify-content:space-between}
.cl-profile-back{background:none;border:0;padding:4px 2px;margin:0;font:inherit;letter-spacing:inherit;text-transform:inherit;color:var(--ox);cursor:pointer}
.cl-profile-back:hover{color:var(--ink)}
.cl-profile-pos{margin-left:auto;color:var(--faint)}
.cl-profile-step{display:flex;flex-direction:column;gap:2px;flex:0 1 48%;min-width:0;background:var(--paper);border:1px solid var(--rule);border-radius:var(--r-sm);padding:5px 10px;text-align:left;cursor:pointer;color:var(--ink);font:inherit;letter-spacing:inherit;text-transform:inherit}
.cl-profile-step.next{text-align:right;align-items:flex-end;margin-left:auto}
.cl-profile-step:hover:not(:disabled){border-color:var(--ox);color:var(--ox)}
.cl-profile-step:disabled{opacity:.45;cursor:default}
.cps-k{font-size:9px;letter-spacing:.08em;color:var(--faint)}
.cps-n{font-family:var(--font-body);font-size:11.5px;letter-spacing:0;text-transform:none;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* differential rows: the open action is a real button (rank + name), so keyboard users
   get one tab stop to open and one to set aside; the rows' own rings replace any
   outline on the focus-target column */
.lrow-open{flex:1;min-width:0;display:flex;align-items:center;gap:9px;background:none;border:0;padding:0;margin:0;font:inherit;color:inherit;text-align:left;cursor:pointer}
.lrow-open:focus-visible,.cl-profile-back:focus-visible,.cl-profile-step:focus-visible,.fit-row:focus-visible{outline:2px solid var(--ox);outline-offset:2px;border-radius:4px}
#classicDiff:focus{outline:none}
/* the row opens the lesion's Atlas article; the rail's book glyph says so where the eye is */
.lrow-atlas{flex:none;color:var(--ox);opacity:0;transition:opacity .12s}
.lrow:hover .lrow-atlas,.lrow-open:focus-visible .lrow-atlas,.lrow.sel .lrow-atlas{opacity:1}
@media(prefers-reduced-motion:reduce){.lrow-atlas{transition:none}}
.fit-row{display:grid;grid-template-columns:minmax(72px,30%) minmax(0,1fr) auto;align-items:center;column-gap:10px;width:100%;padding:6px 14px;border:0;border-top:1px solid var(--rule);background:transparent;font:inherit;font-size:12px;line-height:1.3;color:var(--ink);text-align:left;cursor:pointer}
.fit-row:first-child{border-top:0}
.fit-row:hover{background:var(--ox-soft)}
.fit-k{color:var(--muted)}
/* the answer gets the room the band word used to take: two lines before it clips */
.fit-v{min-width:0;overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow-wrap:anywhere}
.fit-b{display:inline-flex;align-items:center;font-size:11px;color:var(--muted);white-space:nowrap}
.fit-row.weak .fit-b{color:var(--danger);font-weight:600}
.fit-row.weak .atlas-seg.on{background:var(--danger)}
/* One key for every meter in the table, in place of a word on each row. */
.fit-legend{display:flex;flex-wrap:wrap;gap:5px 14px;padding:9px 14px 10px;border-top:1px solid var(--rule);background:var(--bg);font-size:11px;line-height:1.3;color:var(--muted)}
.fl-i{display:inline-flex;align-items:center;gap:6px;white-space:nowrap}
.fit-legend .atlas-meter{gap:2px}
.fit-legend .atlas-seg{width:7px;height:6px}
.frow.flash{animation:frowflash 1.2s ease-out}
@keyframes frowflash{from{background:var(--ox-soft)}to{background:transparent}}
@media(prefers-reduced-motion:reduce){.frow.flash{animation:none;background:var(--ox-soft)}}
.cl-pad{padding:12px 16px 16px}

/* Browse uses the shared catalogue's own search/category controls. The article
   outline returns only when reading, so no extra catalogue rail competes with it. */
#lensAtlas.catalogue-mode .atlas-layout{grid-template-columns:minmax(0,1fr)}
#lensAtlas.catalogue-mode .atlas-spine{display:none}

/* Atlas lens */
.atlas-head{flex:none;display:flex;align-items:center;gap:9px;padding:10px 18px;border-bottom:1px solid var(--rule);background:linear-gradient(180deg,rgba(127,127,127,.03),transparent)}
/* brief "no lesion matches" feedback for an atlas search that hits nothing */
.atlas-nomatch{font-family:var(--font-mono);font-size:10px;color:var(--danger);opacity:0;pointer-events:none;transition:opacity .15s;white-space:nowrap}
.atlas-nomatch.show{opacity:1}
.atlas-search-ic{flex:none;color:var(--faint);font-size:12px}
.atlas-search-input{flex:1;min-width:0;max-width:420px;font-family:var(--font-body);font-size:13px;color:var(--ink);background:var(--bg);border:1px solid var(--rule);border-radius:var(--r-sm);padding:8px 11px;outline:none}
.atlas-search-input:focus{border-color:var(--ox)}
.atlas-search-input::placeholder{color:var(--faint)}
.atlas-scroll{overflow-y:auto;padding:22px 26px 40px;min-width:0}

/* Atlas layout: a navigation spine beside the scrolling article. container-type lets the
   spine collapse to a tick minimap when the COLUMN (not the viewport) gets narrow — so it
   adapts to the sidebar/report widths, the ChatGPT-style compact nav the brief asked for. */
.atlas-layout{flex:1;min-height:0;display:grid;grid-template-columns:minmax(188px,224px) minmax(0,1fr);container-type:inline-size;container-name:atlas;overflow:hidden}
.atlas-spine{overflow-y:auto;border-right:1px solid var(--rule);background:linear-gradient(180deg,rgba(127,127,127,.03),transparent);padding:18px 14px 28px;scrollbar-width:thin}
.atlas-browse-btn{display:flex;align-items:center;gap:9px;width:100%;padding:9px 10px;border:1px solid var(--rule);border-radius:var(--r-sm);background:var(--paper);color:var(--ink);font-family:var(--font-mono);font-size:10px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;cursor:pointer}
.atlas-browse-btn:hover{border-color:var(--ox)}
.atlas-browse-btn.on{border-color:var(--ox);background:var(--ox-soft)}
.atlas-browse-btn .abx-ic{color:var(--ox);font-size:12px;flex:none}
.spine-outline{margin-top:22px}
.spine-label{margin:0 0 8px;font-family:var(--font-mono);font-size:9px;font-weight:600;letter-spacing:.16em;text-transform:uppercase;color:var(--faint)}
.spine-nav{display:grid;gap:1px}
.spine-link{position:relative;display:flex;align-items:center;gap:8px;padding:6px 7px 6px 6px;color:var(--muted);font-family:var(--font-body);font-size:12.5px;line-height:1.3;text-decoration:none;border-radius:6px;cursor:pointer}
.spine-link .spine-tick{flex:none;width:4px;height:4px;border-radius:50%;background:var(--rule)}
.spine-link .spine-txt{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* Category jumps (browse mode) wrap instead of truncating: "Malignant tumors, non-odontogenic"
   and "Malignant odontogenic tumors" both ellipsised to the same first three words in a
   224px spine, so the list was unreadable exactly where it is meant to disambiguate. Article
   section titles are short and keep the one-line ellipsis. */
.spine-browse .spine-link{align-items:flex-start}
.spine-browse .spine-link .spine-tick{margin-top:6px}
.spine-browse .spine-link .spine-txt{white-space:normal;overflow:visible;text-overflow:clip}
.spine-link .spine-n{margin-left:auto;flex:none;font-family:var(--font-mono);font-size:9px;color:var(--faint)}
.spine-link:hover{color:var(--ink)}
.spine-link.on{color:var(--ink);background:linear-gradient(90deg,var(--ox-soft),transparent)}
.spine-link.on .spine-tick{background:var(--ox);box-shadow:0 0 0 3px var(--ox-soft)}

/* Named gap on the fallback profile: why this is not the full article. */
.atlas-gap{margin:10px 0 14px;padding:9px 12px;border-left:2px solid var(--rule);font-size:12px;line-height:1.5;color:var(--muted)}

/* narrow column → the tick minimap: hide labels, keep the ticks, native title = hover
   tooltip. The browse button becomes an icon. */
@container atlas (max-width:560px){
  .atlas-layout{grid-template-columns:48px minmax(0,1fr)}
  .atlas-spine{padding:14px 0;display:flex;flex-direction:column;align-items:center;gap:2px}
  .atlas-browse-btn{width:36px;justify-content:center;padding:8px 0}
  .atlas-browse-btn .abx-lbl{display:none}
  .spine-outline{margin-top:14px;width:100%}
  .spine-label{display:none}
  .spine-nav{gap:4px;justify-items:center}
  .spine-link{width:28px;justify-content:center;padding:6px 0}
  .spine-link .spine-txt,.spine-link .spine-n{display:none}
  .spine-link .spine-tick{width:16px;height:3px;border-radius:2px}
  .spine-link.on{background:transparent}
  .spine-link.on .spine-tick{box-shadow:none}
}

/* ── Map lens: the constellation (a true image well → --plate) ──────────────── */
.map-controls{flex:none;display:flex;align-items:center;flex-wrap:wrap;gap:8px;min-height:42px;padding:5px 12px;border-bottom:1px solid var(--rule);background:var(--paper)}
.map-controls .prevtoggle{flex:none;padding:5px 8px;font-family:var(--font-mono);font-size:9px;letter-spacing:.04em;text-transform:uppercase}
.map-score-status{flex:1 1 100%;padding:0 2px 3px;color:var(--muted);font-size:11px}
.map-set-aside{min-width:0;max-width:48%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:5px 9px;border:1px solid var(--rule);border-radius:6px;background:var(--paper);color:var(--ink);font:inherit;font-size:11px;cursor:pointer}
.map-set-aside:hover,.map-restore summary:hover{color:var(--ox);border-color:var(--ox)}
.map-restore{position:relative;flex:none;margin-left:auto;font-family:var(--font-mono);font-size:10px;color:var(--muted)}
.map-restore summary{cursor:pointer;padding:5px 8px;border:1px solid var(--rule);border-radius:6px;list-style:none}
.map-restore summary::-webkit-details-marker{display:none}
.map-restore-list{position:absolute;top:calc(100% + 5px);right:0;z-index:8;width:min(290px,75vw);max-height:45vh;overflow-y:auto;padding:6px;background:var(--paper);border:1px solid var(--rule);border-radius:8px;box-shadow:var(--shadow-2)}
.map-restore-row{display:flex;align-items:center;gap:8px;padding:4px;border-bottom:1px solid var(--rule)}
.map-restore-row:last-child{border-bottom:0}
.map-restore-name{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--ink);font:12px var(--font-body)}
.map-restore-row button{flex:none;padding:4px 7px;border:1px solid var(--rule);border-radius:5px;background:var(--paper);color:var(--ox);font:10px var(--font-mono);cursor:pointer}
.maplens{flex:1;position:relative;overflow:hidden;background:linear-gradient(180deg,var(--paper),var(--bg));container:maplens/inline-size}
.maplens svg{position:absolute;inset:0;width:100%;height:100%;cursor:grab;touch-action:none}
.maplens svg.grabbing{cursor:grabbing}
.maplens .edge{stroke:var(--ox);fill:none;stroke-opacity:0;pointer-events:none;transition:stroke-opacity .22s ease}
.maplens .edge.faint{stroke:var(--rule);stroke-opacity:.15}
.maplens .node{cursor:pointer}
.maplens .node.gone{opacity:0;pointer-events:none}
/* fill-opacity and stroke-opacity, never opacity: Chromium composites each opacity-transitioning
   svg element into a layer of its own (docs/solutions/ui-bugs/map-click-flash-chromium-svg-opacity-compositing.md).
   `filter` was transitioned here too, and selecting a lesion restyles ~250
   nodes in a single tick: filters on SVG children cannot be composited, so every frame of
   that .4s re-rasterized the entire canvas, on top of the 540ms camera tween. The
   grayscale/saturate change now snaps, which is invisible against a simultaneous fade. */
.maplens .dot{transition:fill-opacity .4s ease,stroke-opacity .4s ease}
/* ONE dim treatment (issue #32: dimmed must read as dim whatever the hue): fade AND
   desaturate, by mixing the star's own colour (--c, set by lib/mapview.js) toward grey.
   A fill, not a CSS filter: a filter on ~200 SVG circles re-rasterizes each one on every
   frame of a camera tween. Visibility order: live > off-profile > selection-dimmed >
   ruled out, with or without a lesion open. Ruled-out used to be a flat grey at
   .35!important, which beat the .12 of a selection-dimmed star, so with a lesion open the
   ghosts were the BRIGHTEST stars on the sky. A ruled star (.12) also stays under an
   off-profile dimmed one (.72 x .18 = .13). Same rules as the site's /map (map.astro). */
/* Off-profile (a soft finding is atypical): a long shot, kept; a hollow ring marks it. */
.maplens .node.off:not(.sel){opacity:.72}
.maplens .node.off:not(.sel) .dot{stroke:var(--faint);stroke-width:.6;stroke-dasharray:1.6 1.4;fill:color-mix(in oklab,var(--c) 55%,var(--faint))}
/* Not one of the open lesion's look-alikes */
.maplens .node.dimc .dot{fill-opacity:.18;stroke-opacity:.18;fill:color-mix(in oklab,var(--c) 35%,var(--faint))}
/* Ruled out by a picked sign: the faintest ghost, kept on the sky (and still
   reachable through the differential) so nothing silently vanishes. */
.maplens .node.ruled{pointer-events:none}
.maplens .node.ruled .dot{fill:color-mix(in oklab,var(--c) 15%,var(--faint));stroke:var(--muted);stroke-width:.6;fill-opacity:.12!important;stroke-opacity:.12!important}
.maplens .node.ruled.dimc .dot{fill-opacity:.09!important;stroke-opacity:.09!important}
.maplens .node.ruled .halo{opacity:0!important}
.maplens .halo{opacity:0}
.maplens .lbl{fill-opacity:0;stroke-opacity:0;pointer-events:none;transition:fill-opacity .2s,stroke-opacity .2s}
.maplens .lbl.show{fill-opacity:1;stroke-opacity:1}
.maplens .lbl.show.clash{fill-opacity:0;stroke-opacity:0;pointer-events:none}
.maplens .nlabel{font-family:var(--font-mono);fill:var(--ink)}
/* A name is a tag on its star, tinted in the star's colour (--c, lib/mapview.js tagPath). */
.maplens .nlabel-bg{fill:color-mix(in oklab,var(--c) 13%,var(--paper));stroke:color-mix(in oklab,var(--c) 45%,var(--paper));stroke-width:1}
.maplens .lbl.lm .nlabel{fill:var(--muted)}
/* the % after a name in its tag (mapview setPct): compact, bold, tabular figures */
.maplens .npct{font-size:.85em;font-weight:700;font-variant-numeric:tabular-nums}
/* Keyboard focus uses the public map's accent stroke; SVG outlines are unreliable. */
.maplens .node:focus{outline:none}
.maplens .node.dimc .halo{opacity:0!important}
.maplens .node.sel .dot{stroke:var(--ox);stroke-width:2}
.maplens .node:focus-visible .dot{stroke:var(--ox);stroke-width:3}
.map-toolbar{position:absolute;top:12px;right:12px;display:flex;flex-direction:column;gap:5px;z-index:5}
.map-toolbar button{width:32px;height:32px;font-family:var(--font-mono);font-size:14px;color:var(--ink);background:var(--paper);border:1px solid var(--rule);border-radius:7px;cursor:pointer}
.map-toolbar button.fit{font-size:11px;letter-spacing:0}
.map-toolbar button:hover{color:var(--ox);border-color:var(--ox)}
.map-caption{position:absolute;left:12px;bottom:10px;max-width:calc(100% - 150px);font-family:var(--font-mono);font-size:9.5px;color:var(--muted);z-index:4;background:color-mix(in srgb,var(--paper) 88%,transparent);border-radius:6px;padding:5px 9px}
.map-caption b{color:var(--ink)}
.map-caption a{color:var(--ox)}
.map-loading{position:absolute;inset:0;display:grid;place-items:center;color:var(--muted);font-family:var(--font-mono);font-size:11px;z-index:6;background:var(--bg);text-align:center;padding:0 18px}
.map-loading.hidden{display:none}
/* retry affordance shown when the map payload fails to load (releases the init latch) */
.map-retry{font-family:var(--font-mono);font-size:11px;color:var(--ink);background:transparent;border:1px solid var(--ox);border-radius:6px;padding:4px 10px;margin:0 2px;cursor:pointer}
.map-retry:hover{background:var(--ox-soft)}

/* Ruled-out / rare-match readout: how the current findings reshaped the map */
.map-ruled{position:absolute;left:12px;bottom:44px;z-index:4;max-width:min(340px,calc(100% - 24px));font-family:var(--font-mono);font-size:9.5px;line-height:1.5;color:var(--muted);background:color-mix(in srgb,var(--paper) 92%,transparent);border:1px solid var(--rule);border-left:2px solid var(--ox);border-radius:6px;padding:6px 10px}
.map-ruled[hidden]{display:none}
.map-ruled b{color:var(--ink)}
.map-ruled .fade{color:var(--faint)}
.map-ruled .fade b{color:var(--green)}

/* Category key — a corner button that opens a compact swatch list (built from the
   payload). Each row toggles that category's visibility on the map. */
.map-legend{position:absolute;right:12px;bottom:10px;z-index:5;display:flex;flex-direction:column;align-items:flex-end;gap:6px}
.map-legend-btn{font-family:var(--font-mono);font-size:9px;letter-spacing:.06em;text-transform:uppercase;color:var(--ink);background:color-mix(in srgb,var(--paper) 92%,transparent);border:1px solid var(--rule);border-radius:6px;padding:6px 10px;cursor:pointer}
.map-legend-btn:hover{color:var(--ox);border-color:var(--ox)}
.map-legend.open .map-legend-btn{color:var(--ox);border-color:var(--ox)}
.map-legend-panel{width:230px;max-height:min(46vh,320px);overflow-y:auto;background:color-mix(in srgb,var(--paper) 94%,transparent);border:1px solid var(--rule);border-radius:9px;padding:6px;display:flex;flex-direction:column;gap:1px;box-shadow:var(--shadow-2)}
.map-legend-panel[hidden]{display:none}
.map-legend-panel button{display:flex;align-items:center;gap:8px;background:none;border:0;border-radius:5px;padding:5px 7px;cursor:pointer;text-align:left;width:100%}
.map-legend-panel button:hover{background:var(--ox-soft)}
.map-legend-panel button[aria-pressed="false"]{opacity:.4}
.map-legend-panel button[aria-pressed="false"] .ml-sw{filter:grayscale(1)}
.map-legend-panel .ml-sw{width:9px;height:9px;border-radius:50%;flex:none}
/* The panel sits on the light stage like everything else, so its text follows the page
   tokens (it once carried fixed light values because the stage was always dark). */
.map-legend-panel .ml-nm{flex:1;font-family:var(--font-body);font-size:11px;color:var(--ink);line-height:1.25;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.map-legend-panel .ml-ct{font-family:var(--font-mono);font-size:11px;color:var(--faint)}

/* the fly-in lesion card (ported from map.astro, tool-scoped) */
.lmap-atlas{position:absolute;top:12px;left:12px;width:300px;max-width:calc(100% - 24px);max-height:calc(100% - 24px);overflow-y:auto;background:var(--paper);border:1px solid var(--rule);border-radius:var(--r-lg);padding:14px 15px;transform:translateX(-14px);opacity:0;pointer-events:none;transition:opacity .26s ease,transform .26s ease;z-index:6;box-shadow:var(--shadow-1)}
.lmap-atlas.on{transform:none;opacity:1;pointer-events:auto}
/* The previous lesion's content, dissolving over the new one on a hop (lib/mapview.js). */
.lmap-atlas .ac-ghost{position:absolute;top:0;left:0;right:0;padding:inherit;overflow:hidden;background:var(--paper);pointer-events:none;z-index:1}
.lmap-atlas .x{position:absolute;top:10px;right:12px;background:none;border:0;color:var(--faint);font-size:15px;cursor:pointer;line-height:1}
.lmap-atlas .x:hover{color:var(--ink)}
.lmap-atlas .ac-cat{font-family:var(--font-mono);font-size:10px;letter-spacing:.06em;text-transform:uppercase}
.lmap-atlas .ac-name{font-family:var(--font-mono);font-size:15px;font-weight:600;letter-spacing:0;color:var(--ink);margin:3px 0 2px;line-height:1.24}
.lmap-atlas .ac-name:focus{outline:none}.lmap-atlas .ac-name:focus-visible{outline:2px solid var(--ox);outline-offset:2px;border-radius:3px}
.lmap-atlas .ac-prev{font-family:var(--font-mono);font-size:10px;color:var(--faint);margin-bottom:11px}
.lmap-atlas .ac-prev b{color:var(--ox)}
.lmap-atlas .ac-ov{font-size:12px;line-height:1.5;color:var(--muted);margin:0 0 12px;padding-bottom:11px;border-bottom:1px solid var(--rule)}
.lmap-atlas .ac-ov .ac-citation{display:inline-block;margin-left:1px;color:var(--ox);font-family:var(--font-mono);font-size:max(.66em,11px);line-height:1;vertical-align:super}
.lmap-atlas .sig-row{display:grid;grid-template-columns:80px 1fr auto;align-items:center;gap:8px;margin-bottom:6px}
.lmap-atlas .sig-k{font-family:var(--font-mono);font-size:11px;color:var(--faint);text-transform:uppercase}
.lmap-atlas .sig-k.gate{color:var(--danger)}
.lmap-atlas .sig-v{font-size:11px;color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.lmap-atlas .sig-m{display:flex;gap:2px}
.lmap-atlas .sig-m i{width:7px;height:7px;border-radius:2px;background:var(--bg);border:1px solid var(--rule)}
.lmap-atlas .sig-m i.on{background:var(--ox);border-color:var(--ox)}
.lmap-atlas .ac-dh{font-family:var(--font-mono);font-size:11px;letter-spacing:.02em;text-transform:uppercase;color:var(--faint);margin:9px 0 6px;padding-top:9px;border-top:1px solid var(--rule)}
.lmap-atlas .ac-diff button{display:flex;align-items:center;gap:7px;background:transparent;border:0;color:var(--muted);font-family:var(--font-body);font-size:11.5px;cursor:pointer;padding:2px 0;text-align:left;width:100%}
.lmap-atlas .ac-diff button:hover{color:var(--ox)}
.lmap-atlas .ac-diff .dd{width:7px;height:7px;border-radius:50%;flex:none}
.lmap-atlas .ac-diff .ds{margin-left:auto;flex:none;font-family:var(--font-mono);font-size:10.5px;color:var(--faint)}
.lmap-atlas .ac-diff .ds.b0{color:var(--ox);font-weight:600}.lmap-atlas .ac-diff .ds.b1{color:var(--muted)}
.lmap-atlas .ac-open{display:block;margin-top:9px;font-family:var(--font-mono);font-size:10.5px;color:var(--bg);background:var(--ox);border-radius:5px;padding:7px 12px;text-decoration:none;text-align:center;border:0;width:100%;cursor:pointer}
.lmap-atlas .ac-open:hover{filter:brightness(1.08)}
/* Narrow Map lens: the card becomes a bottom sheet, as on the site's /map (map.astro).
   As a 300px side card it covered a 375px phone, the open star was squeezed into a ~90px
   strip beside it and the look-alikes sat underneath. focusCamera (lib/mapview.js) sees a
   card wider than 70% of the stage and below its top, and frames the star with its
   look-alikes in the band above the sheet. */
@container maplens (max-width:640px){
  .maplens .lmap-atlas{top:auto;left:0;right:0;bottom:0;width:auto;max-width:none;max-height:52%;border-width:1px 0 0;border-radius:14px 14px 0 0;transform:translateY(16px);padding-bottom:18px}
  .maplens .lmap-atlas.on{transform:none}
}

/* ── RIGHT: the Report dock ─────────────────────────────────────────────────── */
.report{position:relative;background:var(--paper);border-left:1px solid var(--rule);display:flex;flex-direction:column;overflow:hidden;min-width:0}
/* the Report's collapse button overlaps the empty right of the tab strip so it
   costs no vertical space; nudge the tab strip clear of it */
#zoneTopHead{padding-right:40px}
.dockzone{display:flex;flex-direction:column;min-height:80px;overflow:hidden}
.dockzone.hidden{display:none}
#zoneTop{flex:var(--dock-top,1) 1 0}
#zoneBottom{flex:var(--dock-bot,1) 1 0;border-top:0}
.zone-head{flex:none;display:flex;align-items:stretch;gap:0;border-bottom:1px solid var(--rule);background:linear-gradient(180deg,rgba(127,127,127,.04),transparent);min-height:37px}
.ztab{position:relative;display:inline-flex;align-items:center;gap:7px;font-family:var(--font-mono);font-size:10px;letter-spacing:.04em;color:var(--muted);background:transparent;border:0;border-right:1px solid var(--rule);padding:0 12px;cursor:pointer;white-space:nowrap}
.ztab:hover{color:var(--ink)}
.ztab.on{color:var(--ink);box-shadow:inset 0 -2px 0 var(--ox)}
.ztab .tab-ct{font-size:8.5px;color:var(--faint)}
.ztab.on .tab-ct{color:var(--ox)}
.ztab-act{font-size:11px;line-height:1;color:var(--faint);background:transparent;border:0;padding:2px 3px;cursor:pointer;border-radius:4px}
.ztab-act:hover{color:var(--ox);background:var(--ox-soft)}
.zone-body{flex:1;overflow-y:auto;min-height:0}
.dock-split{flex:none;height:6px;cursor:row-resize;background:var(--bg);border-top:1px solid var(--rule);border-bottom:1px solid var(--rule);position:relative}
.dock-split::after{content:"";position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:34px;height:2px;border-radius:2px;background:var(--rule)}
.dock-split:hover::after,.dock-split.dragging::after{background:var(--ox)}
.dock-split.hidden{display:none}

/* Map's report is only Classic's findings form, moved in from the Classic lens. */
#mapCol{flex:1 1 0;min-height:0;min-width:0;display:flex;flex-direction:column;overflow-y:auto;scrollbar-gutter:stable}
#mapCol[hidden]{display:none}
.report.map-col-on .dockzone,.report.map-col-on .dock-split{display:none}
/* The report slot owns scrolling while the same form node moves between lenses. */
#mapCol .classic-findings{overflow:visible}

/* findings pane: progress bar tops the pane */
.pane-prog{padding:10px 14px 0}
.pane-prog .prog{margin-top:0}
.rpt-meta{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:9px 14px 4px;font-family:var(--font-mono);font-size:9px;color:var(--faint)}
/* the differential's own prevalence toggle — smaller than the composer's, same states (chat.css .prevtoggle) */
.prevmini{font-size:9px;padding:2px 8px;line-height:1.4}
.rpt-empty{padding:22px 16px;color:var(--faint);font-size:12px;line-height:1.5}

/* chat "differential updated" nudge — wraps so the lead lesion is never squeezed
   out on a narrow stage (the lead name gets its own line before it would ellipsis) */
.diffnudge{max-width:720px;margin:0 auto 16px;display:flex;flex-wrap:wrap;align-items:center;gap:8px 11px;border:1px solid var(--rule);border-left:2px solid var(--ox);background:var(--ox-soft);border-radius:9px;padding:10px 13px}
.diffnudge .dn-k{font-family:var(--font-mono);font-size:9px;letter-spacing:.08em;text-transform:uppercase;color:var(--ox);flex:none}
.diffnudge .dn-lead{font-size:13px;color:var(--ink);flex:1 1 150px;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.diffnudge .dn-lead b{color:var(--ink)}
.diffnudge .dn-band{font-family:var(--font-mono);font-size:10px;color:var(--ox);flex:none}
.diffnudge button{font-family:var(--font-mono);font-size:9.5px;letter-spacing:.04em;text-transform:uppercase;color:var(--muted);background:transparent;border:1px solid var(--rule);border-radius:6px;padding:5px 9px;cursor:pointer;flex:none;margin-left:auto}
.diffnudge button:hover{color:var(--ink);border-color:var(--ox)}

/* ── atlas profile (Atlas lens) ─────────────────────────────────────────────── */
.atlas-wrap{max-width:760px;margin:0 auto}
.atlas-dh{font-family:var(--font-display);font-size:20px;color:var(--ink)}
.atlas-dlinks{display:flex;flex-wrap:wrap;gap:8px;margin:9px 0 4px}
.dlink{font-family:var(--font-mono);font-size:10px;letter-spacing:.04em;color:var(--ox);text-decoration:none;border:1px solid var(--rule);border-radius:6px;padding:5px 9px}
.dlink:hover{border-color:var(--ox)}
.atlas-k{font-family:var(--font-mono);font-size:9px;letter-spacing:.1em;text-transform:uppercase;color:var(--faint);margin:18px 0 8px}
.atlas-grp{font-family:var(--font-mono);font-size:9px;letter-spacing:.08em;text-transform:uppercase;color:var(--muted);margin:14px 0 6px}
.atlas-row{border-top:1px solid var(--rule);padding:9px 0}
.atlas-lab{font-size:12.5px;color:var(--ink);margin-bottom:6px}
.atlas-opt{display:grid;grid-template-columns:1fr 90px 84px;align-items:center;gap:10px;padding:3px 0}
.atlas-opt .al{font-size:12px;color:var(--muted)}
.atlas-meter{display:inline-flex;gap:3px}
.atlas-seg{width:14px;height:8px;border-radius:2px;background:var(--rule)}
.atlas-seg.on{background:var(--ox)}
.atlas-opt .ab{font-family:var(--font-mono);font-size:10px;color:var(--faint);text-align:right}
.atlas-ref{font-size:12px;color:var(--muted);line-height:1.6;border-left:2px solid var(--rule);padding-left:12px}
.atlas-loading,.atlas-empty{color:var(--faint);font-size:12px;padding:20px 0}

/* published wiki article in the Atlas lens — leads over the band profile */
.wiki{margin-top:4px}
.wiki-byline{font-family:var(--font-mono);font-size:9px;letter-spacing:.06em;text-transform:uppercase;color:var(--faint);margin:2px 0 16px}
.wiki-sec{margin:0 0 18px}
.wiki-h{font-family:var(--font-display);font-size:15px;color:var(--ink);margin:0 0 7px;font-weight:600}
.wiki-body{font-size:14px;line-height:1.62;color:var(--ink)}
.wiki-body p{margin:0 0 10px}
.wiki-body ul,.wiki-body ol{margin:0 0 10px;padding-left:20px}
.wiki-body li{margin:3px 0}
.wiki-body b,.wiki-body strong{color:var(--ink);font-weight:600}
.wiki-body a{color:var(--ox);text-decoration:none;border-bottom:1px dotted var(--ox)}
.wiki-body a:hover{border-bottom-style:solid}
.wiki-body h2,.wiki-body h3,.wiki-body h4{font-family:var(--font-display);font-size:13px;color:var(--ink);margin:14px 0 6px}
.wiki-refs{margin-top:6px}
.atlas-data{margin-top:20px;border-top:1px solid var(--rule);padding-top:14px}
.atlas-data > .srcs-sum{margin-bottom:2px}
.atlas-data-body{margin-top:6px}

/* ── Image assist modal (ported from the classic tool, re-themed) ───────────── */
.imgmodal{position:fixed;inset:0;z-index:60;display:flex;align-items:center;justify-content:center;padding:20px;background:color-mix(in srgb,var(--ink) 55%,transparent)}
.imgmodal.hidden{display:none}
.imgmodal-box{width:min(560px,100%);max-height:calc(100vh - 40px);display:flex;flex-direction:column;background:var(--paper);border:1px solid var(--rule);border-radius:var(--r-lg);overflow:hidden;box-shadow:var(--shadow-3)}
.imgmodal-head{display:flex;align-items:flex-start;gap:12px;padding:15px 17px;border-bottom:1px solid var(--rule)}
.imgmodal-k{font-family:var(--font-mono);font-size:9px;letter-spacing:.14em;text-transform:uppercase;color:var(--ox)}
.imgmodal-head h2{font-family:var(--font-display);font-size:17px;font-weight:600;color:var(--ink);margin:3px 0 0}
.imgmodal-x{margin-left:auto;background:transparent;border:1px solid var(--rule);border-radius:7px;color:var(--muted);font-size:16px;line-height:1;width:28px;height:28px;cursor:pointer;flex:none}
.imgmodal-x:hover{color:var(--ink);border-color:var(--ox)}
.imgmodal-body{padding:16px 17px;overflow-y:auto;flex:1}
.imgdz{border:1.5px dashed var(--rule);border-radius:12px;padding:26px 18px;display:flex;flex-direction:column;align-items:center;gap:6px;text-align:center;cursor:pointer;transition:border-color .15s,background-color .15s}
.imgdz:hover{border-color:var(--faint)}
.imgdz.drag{border-color:var(--ox);background:var(--ox-soft)}
.imgdz-ic{font-size:22px;color:var(--ox)}
.imgdz b{font-size:13px;color:var(--ink)}
.imgdz span{font-size:11.5px;color:var(--faint);max-width:38ch;line-height:1.5}
.imgpick{margin-top:8px;font-family:var(--font-display);font-weight:600;font-size:12.5px;color:var(--on-ox);background:var(--ox);border:0;border-radius:8px;padding:8px 15px;cursor:pointer}
.imgpick:hover{filter:brightness(1.06)}
.imgcrop.hidden{display:none}
.imgcrop-frame{position:relative;width:fit-content;max-width:100%;margin:0 auto;border-radius:10px;overflow:hidden;background:var(--plate)}
.imgcrop-frame img{display:block;max-width:100%;max-height:46vh;user-select:none;-webkit-user-drag:none}
.imgcrop-frame canvas{position:absolute;inset:0;width:100%;height:100%;touch-action:none;cursor:crosshair}
.imgcrop-actions{display:flex;align-items:center;gap:10px;margin-top:9px}
.imgcrop-size{font-family:var(--font-mono);font-size:10px;color:var(--faint)}
.linkbtn{background:transparent;border:0;color:var(--blue);font-family:var(--font-mono);font-size:10px;letter-spacing:.04em;text-transform:uppercase;cursor:pointer;padding:2px 4px}
.linkbtn:hover{color:var(--ink)}
.imgrow{display:flex;align-items:center;gap:10px;margin-top:12px}
.imglabel{font-family:var(--font-mono);font-size:9px;letter-spacing:.1em;text-transform:uppercase;color:var(--faint);flex:none}
.imgseg{display:inline-flex;border:1px solid var(--rule);border-radius:8px;overflow:hidden;background:var(--bg)}
.imgseg button{background:transparent;border:0;color:var(--muted);font-family:var(--font-mono);font-size:10px;letter-spacing:.04em;padding:6px 11px;cursor:pointer}
.imgseg button.on{background:var(--ox);color:var(--on-ox);font-weight:600}
.imgnotes{width:100%;margin-top:11px;min-height:52px;max-height:120px;resize:vertical;background:var(--bg);border:1px solid var(--rule);border-radius:9px;padding:9px 11px;color:var(--ink);font-family:var(--font-body);font-size:12.5px;outline:none}
.imgnotes:focus{border-color:var(--ox)}
.imgnotes::placeholder{color:var(--faint)}
.imgdisc{margin:13px 0 0;font-size:11px;line-height:1.5;color:var(--faint)}
.imgmodal-foot{display:flex;align-items:center;gap:10px;padding:12px 17px;border-top:1px solid var(--rule);background:linear-gradient(180deg,rgba(127,127,127,.03),transparent)}
/* First-open introduction — reuses the imgmodal dialog scaffold, prose-sized. */
.intro-box{width:min(520px,100%)}
.intro-body p{margin:0 0 12px;font-size:13px;line-height:1.65;color:var(--muted)}
.intro-body p b,.intro-list b{color:var(--ink)}
.intro-list{margin:0 0 12px;padding-left:18px;display:flex;flex-direction:column;gap:6px}
.intro-list li{font-size:12.5px;line-height:1.55;color:var(--muted)}
.intro-credit{font-size:10.5px;color:var(--muted)}
.intro-soon{font-family:var(--font-mono);font-size:10.5px;letter-spacing:.03em;color:var(--faint)}
.intro-moved{margin:0 0 .8rem;padding:.55rem .8rem;border-left:2px solid var(--ox);background:var(--ox-soft);color:var(--ink)}
.intro-body .imgdisc a,.intro-body .intro-credit a{color:var(--blue)}
/* orad.org-only "What's new" under the move notice. Tighter than the prose below it so the
   dialog stays phone-sized; the rule beneath separates it from the standing introduction.
   [hidden] is restated because the shell ships no global reset and this is a block. */
.intro-new{margin:0 0 14px;padding:0 0 12px;border-bottom:1px solid var(--rule)}
.intro-new[hidden]{display:none}
.intro-body .intro-new-k{margin:0 0 6px;font-family:var(--font-mono);font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--ox)}
.intro-new-list{margin:0 0 8px;padding-left:18px;display:flex;flex-direction:column;gap:3px}
.intro-new-list li{font-size:12px;line-height:1.5;color:var(--muted)}
.intro-new-more{font-family:var(--font-mono);font-size:10.5px;letter-spacing:.03em;color:var(--blue);text-decoration:none}
.intro-new-more:hover{text-decoration:underline}
.imgstatus{font-family:var(--font-mono);font-size:10px;color:var(--faint)}
.imganalyze:disabled{opacity:.45;cursor:default}

/* Guest AI quota: the sign-in gate atop the composer (shown on the edge Worker's 429),
   plus a small running remaining-count chip in the composer tools. */
.ai-gate{display:flex;flex-wrap:wrap;align-items:center;gap:9px 14px;margin:0 0 9px;padding:10px 13px;border:1px solid var(--ox);border-radius:11px;background:var(--ox-soft)}
.ai-gate.hidden{display:none}
.ai-gate-body{flex:1;min-width:210px;font-size:12.5px;line-height:1.45;color:var(--ink)}
.ai-gate-body strong{color:var(--ink);font-weight:600}
.ai-gate-body span{color:var(--muted)}
.ai-gate-actions{display:flex;align-items:center;gap:8px;flex:none}
.ai-gate-signup{font-family:var(--font-mono);font-size:10px;letter-spacing:.04em;text-transform:uppercase;font-weight:600;color:var(--bg);background:var(--ox);border-radius:6px;padding:7px 12px;text-decoration:none}
.ai-gate-signup[hidden]{display:none}
.ai-gate-signup:hover{filter:brightness(1.06)}
.ai-gate-classic{font-family:var(--font-mono);font-size:10px;letter-spacing:.04em;text-transform:uppercase;color:var(--muted);background:transparent;border:1px solid var(--rule);border-radius:6px;padding:7px 12px;cursor:pointer}
.ai-gate-classic:hover{color:var(--ink);border-color:var(--ox)}
.ai-quota{font-family:var(--font-mono);font-size:9px;letter-spacing:.03em;color:var(--faint);white-space:nowrap}
.ai-quota[hidden]{display:none}

@media(max-width:1240px){.station{--rpt-w:344px}}

/* ── mobile: the stage is the page; the sidebar and Report slide in as off-canvas
      drawers — the ☰ in the stage header opens the sidebar, ◨ opens the Report ── */
@media(max-width:960px){
  .station{grid-template-columns:0 0 minmax(0,1fr) 0 0}
  .rail-rz{display:none!important}
  /* the fixed rails leave the grid flow, so the stage would auto-place into the
     first (0px) track — pin it to the fluid one */
  .stage{grid-column:3}
  /* the sidebar's own drawer rules live in shared/theme/sidebar.css */
  @media(prefers-reduced-motion:reduce){.station .report{transition:none}}
  .station .report{position:fixed;top:0;bottom:0;right:0;width:min(400px,94vw);z-index:40;transform:translateX(102%);transition:transform .2s ease;box-shadow:var(--shadow-3);border-left:1px solid var(--rule);display:flex;padding-top:env(safe-area-inset-top)}
  .station.rpt-shown .report{transform:none}
  .atlas-scroll{padding:16px 14px 40px}
  /* atlas: stack the spine as a horizontal sticky strip above the article (like the
     public site) — overrides the desktop container-query tick rail on a phone */
  .atlas-layout{display:flex;flex-direction:column}
  .atlas-spine{flex:none;display:flex;flex-direction:row;align-items:center;gap:10px;border-right:0;border-bottom:1px solid var(--rule);padding:8px 12px;overflow-x:auto}
  /* The way back to the lesion list keeps its words on a phone (R2, CP0 sweep F2): a bare
     ☰ here sat right under the sidebar's own ☰, and its name lived only in a tooltip that
     touch screens never show. The site's lesion pages show "☰ Browse Atlas" at 390px too. */
  .atlas-spine .atlas-browse-btn{width:auto;flex:none;padding:8px 10px}
  .atlas-spine .atlas-browse-btn .abx-lbl{display:inline;white-space:nowrap}
  .atlas-spine .spine-outline{margin-top:0;flex:1;min-width:0}
  .atlas-spine .spine-label{display:none}
  .atlas-spine .spine-nav{display:flex;gap:3px;overflow-x:auto;scrollbar-width:none}
  .atlas-spine .spine-nav::-webkit-scrollbar{display:none}
  .atlas-spine .spine-link{width:auto;padding:6px 9px;white-space:nowrap}
  .atlas-spine .spine-link .spine-txt{display:inline}
  .atlas-spine .spine-link .spine-tick{display:none}
  /* classic: one scrolling column — findings first, then the result boxes */
  .classic-wrap{display:block;overflow-y:auto}
  .classic-findings{overflow:visible;border-bottom:1px solid var(--rule)}
  #classicLesion{border-bottom:1px solid var(--rule)}
  .cl-profile-body{overflow:visible}
  .cl-profile-head{position:sticky;top:0;z-index:3}
  /* the form's own narrow layout is the @container findings fold, not the viewport */
  .classic-side{overflow:visible;padding:14px 12px 32px}
  .thread{padding:18px 14px 10px}
  .stage-head{gap:7px;padding:0 8px}
  /* keep the minimal header (with the ☰ drawer toggle) on the mobile landing. The
     desktop rule above already keeps the bar and thins it to ☰ + "?", so this only
     has to restore the flex row itself. */
  .station.chat-landing .stage-head{display:flex}
  .cl-more{padding-bottom:40px}
  /* Map: keep the bottom overlays clear of one another on a narrow stage */
  .map-legend{bottom:8px}
  .map-legend-panel{width:min(230px,72vw)}
  .map-ruled{bottom:52px}
  .map-caption{max-width:calc(100% - 128px);bottom:8px;font-size:9px}
}

@media(prefers-reduced-motion:reduce){.maplens .node,.lmap-atlas,.maplens .lbl,.maplens .edge,.maplens .dot{transition:none}}
