/* demo.css — the in-browser Tomoid interface simulation.
   The chrome carries the APPLICATION palette (extracted verbatim from
   src/Mediray.App/Themes/Tokens.xaml), scoped under .demo-app so it never
   mixes with the surrounding site (teal / IBM Plex). Just as a screenshot
   would carry the app's own colours, the demo does. Fonts: Jost for UI,
   Consolas for numerics — same split as the app (Tokens.xaml §fonts). */

/* ============ section wrapper (site side) ============ */
.demo {
  margin: 0 auto;
  max-width: 1060px;
  padding: 8px 24px 64px;
}
.demo-head { margin-bottom: 22px; }
.demo-head h2 {
  margin: 10px 0 0;
  font-size: clamp(22px, 3.4vw, 28px);
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--text-primary);
}
.demo-head .sub {
  margin-top: 10px;
  font-size: 15px;
  line-height: 1.55;
  color: var(--text-secondary);
  max-width: 52ch;
}

/* horizontal-scroll shell: wide app chrome scrolls inside itself on small
   screens; the page body never scrolls sideways (Э5 turns this into a
   stacked-column mobile layout). */
.demo-shell { overflow-x: auto; overflow-y: hidden; }

/* The site's own focus ring (teaser.css: 2px solid var(--accent) = #00C49A) must
   NOT leak into the app chrome — that colour does not exist in the application
   palette, and the app draws no ring around a lone viewport at all. Keyboard
   focus still gets a visible indicator, in the app's cyan and inset so it never
   reads as the "active viewport" border (which the app shows only on 2+ cells). */
.demo-app :focus { outline: none; }
.demo-app :focus-visible { outline: none; }
.demo-app .tb-btn:focus-visible,
.demo-app .tb-chev:focus-visible,
.demo-app .tb-cap:focus-visible,
.demo-app .wl-row:focus-visible { box-shadow: inset 0 0 0 2px rgba(38, 198, 218, 0.7); }
/* The viewport gets NO ring of its own — the app never outlines a lone viewport,
   and any border there reads as "active viewport". Keyboard focus is instead
   shown on the shell, i.e. outside the app window, where it cannot be mistaken
   for chrome. */
.demo-viewport:focus, .demo-viewport:focus-visible { outline: none; box-shadow: none; }
/* ...and the shell ring is gated on ARRIVING BY TAB (html[data-kbnav], set in
   demo.js). Without that gate every keystroke inside the viewport re-triggers
   :focus-visible, so picking a W/L preset with 0-9 made a cyan ring flash
   around the whole demo — which reads as a bug, not as an affordance. */
html[data-kbnav] .demo-shell:has(.demo-viewport:focus-visible) {
  outline: 2px solid rgba(38, 198, 218, 0.6);
  outline-offset: 3px;
}
/* engines without :has() would otherwise leave the viewport with no focus
   indicator at all — fall back to an inset ring on the viewport itself */
@supports not selector(a:has(a)) {
  html[data-kbnav] .demo-viewport:focus-visible { box-shadow: inset 0 0 0 2px rgba(38, 198, 218, 0.6); }
}

/* ============ the app window ============ */
.demo-app {
  /* --- application design tokens (Tokens.xaml) --- */
  --app-s0: #121212;  --app-s1: #1E1E1E;  --app-s2: #252526;  --app-s3: #2D2D30;
  --app-hover: #333337;  --app-pressed: #0E0E0F;
  --app-border: #2F2F33;  --app-border-med: #3F3F46;
  --app-text: #F1F1F1;  --app-text2: #B0B0B5;  --app-text3: #6E6E72;
  --app-accent: #26C6DA;  --app-accent-h: #4DD0E1;  --app-accent-p: #00ACC1;
  --app-amber: #F1C674;  --app-amber-dim: rgba(241, 198, 116, 0.6);
  --app-white: #FFFFFF;  --app-sel: rgba(38, 198, 218, 0.20);  --app-gold: #EFD469;
  --app-viewport: #000000;  --app-sidebar: #151518;  --app-logo: #E0E0E0;
  --f-app: 'Jost', var(--f-sans);
  --f-num: 'Consolas', ui-monospace, monospace;   /* app: ConsolasFont, no Plex fallback */
  -webkit-font-smoothing: auto;                   /* undo the site's antialiased body */

  position: relative;
  min-width: 760px;
  background: var(--app-s0);
  /* WindowChrome CornerRadius=0 and no visible window border (MainWindow.xaml) */
  overflow: hidden;
  color: var(--app-text);
  font-family: var(--f-app);
  user-select: none;
}

/* ============ toolbar (MainWindow.xaml, 49 px, Surface2) ============ */
.demo-toolbar {
  height: 49px;              /* app caption/toolbar height */
  background: var(--app-s2);
  display: flex;
  align-items: center;   /* the app's toolbar Border has no bottom edge */
}
.tb-logo {
  width: 178px;              /* = series-panel column width (app) */
  box-sizing: border-box;
  padding-left: 29px;        /* MainWindow.xaml logo padding */
  font-family: var(--f-app);
  font-size: 26px;
  font-weight: 700;
  color: var(--app-logo);
  flex: none;            /* app sets no tracking on the logo */
}
.tb-group { display: flex; align-items: center; }
.tb-sep {
  width: 1px;
  height: 24px;
  background: var(--app-border);
  margin: 0 6px;
  flex: none;
}
.tb-spacer { flex: 1 1 auto; }
.tb-btn {
  width: 38px;
  height: 39px;
  margin: 0 2px;
  border: 0;
  background: transparent;
  border-radius: 4px;
  color: var(--app-text2);       /* icon inactive = TextSecondary */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  flex: none;
  position: relative;
  padding: 0;
  transition: background 0.1s;
}
.tb-btn:hover { background: var(--app-hover); }        /* #333337 */
.tb-btn:active { background: var(--app-pressed); }     /* #0E0E0F */
.tb-btn svg { width: 20px; height: 20px; display: block; }
/* active tool: icon stays gray like every other (the app shows the binding via
   the coloured stripe below, NOT a cyan icon) */
/* the labels button is a ToggleButton: while the overlays are hidden it stays
   visibly checked (#333337 + brighter icon), like every toggle in the app */
.tb-btn.is-toggled { background: var(--app-hover); color: var(--app-text); }
.tb-btn.gear { margin-right: 8px; }
/* split-button chevron */
.tb-split { display: inline-flex; align-items: center; margin: 0 2px; }
.tb-split .tb-btn { margin: 0; }
.tb-chev {
  width: 16px; height: 39px;
  border: 0; background: transparent; cursor: pointer;
  color: var(--app-text2);
  display: inline-flex; align-items: center; justify-content: center;
  padding: 0; flex: none;
  border-radius: 4px;
  position: relative;
  transition: background 0.1s;
}
/* the app's chevron is 16px wide; stretch the HIT area to the 24px WCAG floor
   without touching the visual */
.tb-chev::after { content: ""; position: absolute; top: 0; bottom: 0; left: -4px; right: -4px; }
/* the chevron is a ToggleButton in the app: it hovers and presses like any
   other, and stays lit while its popup is open (SharedControls.xaml) */
.tb-chev:hover { background: var(--app-hover); }
.tb-chev:active { background: var(--app-pressed); }
.tb-chev.is-open { background: var(--app-hover); color: var(--app-text); }
.tb-chev svg { width: 6px; height: 3px; }   /* app Path is 6x3, not 8x5 */
/* the annotations split-button uses a FILLED triangle in #888888, unlike the
   outlined chevron everywhere else (SplitButton.xaml) */
.tb-chev.tri svg { width: 8px; height: 4px; color: #888888; }
/* cine and sync keep the default ToolbarIconButton margin, so their groups are
   62 px wide with a 2 px gap before the chevron (MainWindow.xaml) */
.tb-split.wide .tb-btn { margin: 0 2px; }
/* mouse-binding stripes (ToolButton.xaml): cyan LMB / magenta MMB / yellow RMB */
.tb-stripes {
  position: absolute;
  bottom: 3px; left: 50%; transform: translateX(-50%);
  display: flex; gap: 2px;
  pointer-events: none;
}
.tb-stripes .st { width: 6px; height: 3px; border-radius: 1px; display: none; }
.tb-stripes .st-c { background: #26C6DA; }
.tb-stripes .st-m { background: #FF6B9D; }
.tb-stripes .st-y { background: var(--app-amber); }
.tb-btn.is-active .st-c { display: block; }   /* cyan follows the active (LMB) tool */
.tb-btn.has-m .st-m { display: block; }        /* MMB = pan */
.tb-btn.has-y .st-y { display: block; }        /* RMB = zoom */

/* window caption buttons (min / max / close): 46x32, top-aligned in the 49px bar */
.tb-caps { align-self: flex-start; display: flex; flex: none; }
.tb-cap {
  width: 46px; height: 32px;
  border: 0; background: transparent;
  color: var(--app-text2);
  display: inline-flex; align-items: center; justify-content: center;
  cursor: default; padding: 0;
}
.tb-cap svg { width: 10px; height: 10px; display: block; }
.tb-cap:hover { background: var(--app-hover); }
.tb-cap:active { background: var(--app-pressed); }
.tb-cap-close:hover { background: #E81123; color: #fff; }
.tb-cap-close:active { background: #C50E1F; color: #fff; }

/* ============ body: series panel + viewer area ============ */
.demo-body { display: flex; height: 480px; }

/* --- series panel (178 px, #151518) --- */
.demo-series {
  width: 178px;
  flex: none;
  background: var(--app-sidebar);
  /* the app's ListBox has Padding=0 — the capsule spans the full column */
  overflow-y: auto;
}
.series-capsule {
  background: var(--app-s1);
  border-radius: 6px;      /* SharedControls.xaml capsule radius */
  overflow: hidden;
  margin-bottom: 10px;     /* every capsule, including the last (app) */
}
.series-header {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 8px;        /* app Padding="8,6" = 8 horizontal, 6 vertical */
  cursor: pointer;
}
.series-header .chev { width: 14px; color: #888888; font-size: 10px; text-align: center; flex: none; }
/* A flex item will not shrink below its content unless told to, and without
   that the ellipsis on .st-name never fires — the name pushes the capsule wide
   instead of being clipped. This lived in a style attribute until the site's
   own CSP (style-src 'self') started refusing to apply it. */
.series-header .st-text { min-width: 0; }
.series-header .st-name {
  font-family: var(--f-app); font-size: 11px; font-weight: 700;
  color: #DDDDDD; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.series-header .st-sub { font-family: var(--f-app); font-size: 10px; color: #888888; }
.series-items {
  border-top: 1px solid var(--app-border);
  padding: 0 0 10px;       /* app has no side padding: the thumb centres itself */
}
.series-thumb {
  margin-top: 10px;
  /* app stacks the caption straight under the frame, no gap */
  display: flex; flex-direction: column; align-items: center;
  cursor: pointer;
  /* it is a <button> for keyboard reach — strip the UA chrome, keep the look */
  width: 100%; padding: 0; border: 0; background: none; font: inherit; color: inherit;
}
/* the app's ListBoxItem has no hover trigger at all — selection only */
.series-thumb:focus-visible .thumb-frame { box-shadow: 0 0 0 2px rgba(38, 198, 218, 0.7); }
.series-thumb .thumb-frame {
  position: relative;
  box-sizing: content-box;  /* app: Image 140x100 + 1px border outside = 142x102 */
  width: 140px; height: 100px;
  background: #000;
  border: 1px solid transparent;
  border-radius: 5px;
  overflow: hidden;
}
.series-thumb.is-sel .thumb-frame { border-color: rgba(38, 198, 218, 0.5); }  /* #8026C6DA */
.series-thumb canvas { width: 100%; height: 100%; display: block; object-fit: cover; }
.thumb-badge {
  position: absolute; right: 2px; bottom: 2px;
  background: #000; border-radius: 5px; padding: 1px 4px;
  font-family: var(--f-app); font-size: 9px; font-weight: 700; color: #fff;
}
.series-thumb .thumb-name {
  font-family: var(--f-app); font-size: 10px; color: #fff;
  max-width: 140px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* --- viewer area (#151518; the app's cell carries Margin=2 + Padding=2 +
   BorderThickness=2, so the gutter around the black cell reads as ~4 px) --- */
.demo-viewarea {
  flex: 1 1 auto;
  background: var(--app-sidebar);
  padding: 4px;
  display: grid;
  gap: 4px;
  grid-template-columns: 1fr;   /* Э2 switches to 1+3 MPR grid */
  min-width: 0;
}
.demo-viewport {
  position: relative;
  background: var(--app-viewport);
  overflow: hidden;
  border: 1px solid transparent;
  border-radius: 5px;           /* SplitGridControl cell CornerRadius=5 */
  min-width: 0;
}
/* no active-viewport border in the demo (single viewport; user request) */
.demo-viewport canvas.vp-canvas {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  display: block;                /* fit/zoom/pan handled in JS draw() */
}
/* per-tool cursor cues (Э1) */
/* touch drags belong to the viewport (slices / W-L), not to page scroll */
.demo-viewport { cursor: crosshair; touch-action: none; }
.demo-viewport.tool-pan { cursor: grab; }
.demo-viewport.tool-pan:active { cursor: grabbing; }
.demo-viewport.tool-zoom { cursor: zoom-in; }
.demo-viewport.tool-stack { cursor: ns-resize; }
.demo-viewport.tool-select { cursor: default; }
/* overlays wrapper — labels toggle fades the whole group */
.vp-overlays { position: absolute; inset: 0; pointer-events: none; transition: opacity 0.15s; }

/* ============ viewport overlays (ViewportInfoOverlay.xaml grammar) ============
   White = emphasis (name/desc/modality/series/Value HU); amber = values;
   amber@60% = labels/metadata. Black halo (drop shadow, blur 2) keeps text
   readable on any image content. Jost for labels, Consolas for numerics. */
.ov {
  position: absolute;
  pointer-events: none;
  font-family: var(--f-app);
  font-size: 14px;
  color: var(--app-amber);
  text-shadow: 0 0 2px #000;   /* app: one DropShadow, ShadowDepth=0, Blur=2 */
  /* the app spaces rows with Margin="0,0,0,2" rather than leading, so rows sit
     tighter and the last one carries no trailing gap */
  line-height: 1.15;
}
.ov > * + * { margin-top: 2px; }
/* only the bottom panels are width-capped in the app (MaxWidth = half), and
   overflow is trimmed with an ellipsis instead of wrapping */
.ov-bl, .ov-br { max-width: 50%; }
.ov-bl > *, .ov-br > * { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* pairs are printed with two spaces in the app ("WC: 40  WW: 350") — HTML would
   collapse them to one */
.ov .num { font-family: var(--f-num); white-space: pre; }
.ov .white { color: var(--app-white); }
.ov .dim { color: var(--app-amber-dim); }
.ov .lbl { color: var(--app-amber-dim); }   /* dim label + amber value, per app */
.ov .semib { font-weight: 600; }
.ov .s12 { font-size: 12px; }
.ov-tl { top: 10px; left: 10px; }
.ov-tr { top: 10px; right: 16px; text-align: right; }
.ov-bl { bottom: 10px; left: 10px; }
.ov-br { bottom: 10px; right: 16px; text-align: right; }
.ov-tr .mpr-badge { color: var(--app-gold); font-family: var(--f-num); font-weight: 600; }
/* orientation markers R/L/A/P at edge centres (Jost 14 bold) */
.ov-orient {
  position: absolute;
  font-family: var(--f-app); font-size: 14px; font-weight: 700;
  color: var(--app-amber);
  text-shadow: 0 0 2px #000;
  pointer-events: none;
}
.ov-orient.top { top: 10px; left: 50%; transform: translateX(-50%); }   /* app Margin="0,10,0,0" */
.ov-orient.bottom { bottom: 10px; left: 50%; transform: translateX(-50%); }
.ov-orient.left { left: 10px; top: 50%; transform: translateY(-50%); }
.ov-orient.right { right: 16px; top: 50%; transform: translateY(-50%); }

/* cine HUD — the app prints "Cine: N.N FPS" above the bottom-right block while
   playing (ViewportControl.xaml, Margin="0,0,12,28") */
.vp-cine-hud {
  position: absolute; right: 12px; bottom: 28px;
  font-family: var(--f-app); font-size: 12px;
  color: var(--app-gold);
  text-shadow: 0 0 2px #000;
  pointer-events: none;
}

/* ============ caption under the app ============ */
.demo-meta {
  margin-top: 12px;
  display: flex;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}
.demo-meta span {
  font-family: var(--f-mono);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--text-dim);
}

/* ============ hero -> demo scroll link ============ */
.hero-demolink {
  margin-top: 14px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--f-mono);
  font-size: 12px;
  letter-spacing: 0.03em;
  color: var(--text-secondary);
  /* underline: these sit next to same-tone static text (.price-scope,
     .fineprint) — colour alone doesn't mark them as links (WCAG 1.4.1) */
  text-decoration: underline;
  text-underline-offset: 3px;
}
.hero-demolink:hover { color: var(--accent); }
.hero-demolink .arr { transition: transform 0.15s; }
.hero-demolink:hover .arr { transform: translateY(2px); }

/* ============ slice rail (right edge, like the app) ============ */
/* slice bar — copied from the app's ViewportSliceBar (App.xaml): 14px hit lane,
   a 4px thumb #5A5A60 r2 (hover/drag #8A8A92), and the dark track (#1B1B1C =
   SliderTrackBrush) revealed only on hover. */
.vp-rail {
  position: absolute; top: 8px; right: 2px; bottom: 8px;   /* app Margin="0,8,2,8" */
  width: 14px;
  cursor: ns-resize;
}
.vp-rail::after {
  content: ""; position: absolute; top: 0; bottom: 0; right: 0;
  width: 4px; border-radius: 3px; background: transparent;
  transition: background 0.12s, width 0.12s;
}
/* the app animates the rail 4 -> 12 px on hover (App.xaml ViewportSliceBar) */
.vp-rail:hover::after { background: #1B1B1C; width: 12px; }
.vp-rail-thumb {
  position: absolute; right: 0; z-index: 1;
  width: 4px;           /* height set in px by syncOverlays: ~20% of the lane, min 44 */
  background: #5A5A60;
  border-radius: 2px;
  transition: width 0.12s;
}
.vp-rail:hover .vp-rail-thumb { background: #8A8A92; width: 12px; }

/* scrollbars — the app's DarkScrollBar (SharedControls.xaml): 9px slim, track
   Surface1, thumb BorderMedium r4 (hover #5A5A60), no arrow buttons. */
.demo-series { scrollbar-width: thin; scrollbar-color: var(--app-border-med) var(--app-s1); }
.demo-series::-webkit-scrollbar { width: 9px; }
.demo-series::-webkit-scrollbar-track { background: var(--app-s1); border-radius: 4px; }
.demo-series::-webkit-scrollbar-thumb { background: var(--app-border-med); border-radius: 4px; }
.demo-series::-webkit-scrollbar-thumb:hover { background: #5A5A60; }
.demo-series::-webkit-scrollbar-button { display: none; height: 0; width: 0; }

/* ============ honest "in the app" hint ============ */
.demo-hint {
  position: absolute; left: 50%; bottom: 16px; transform: translateX(-50%) translateY(6px);
  padding: 7px 14px;
  background: rgba(14,14,15,0.9);
  border: 1px solid var(--app-border-med);
  border-radius: 4px;
  font-family: var(--f-app); font-size: 12.5px; color: var(--app-text);
  pointer-events: none; opacity: 0;
  transition: opacity 0.18s, transform 0.18s;
}
.demo-hint.show { opacity: 1; transform: translateX(-50%) translateY(0); }

/* ============ W/L preset popup ============ */
.wl-popup {
  position: absolute; z-index: 20;
  min-width: 240px;                  /* app popup MinWidth=240 */
  background: var(--app-s3);
  border: 1px solid var(--app-border-med);
  border-radius: 3px;
  padding: 4px;                      /* the app's popup casts no shadow */
}
.wl-row {
  display: flex; align-items: center; gap: 10px;
  width: 100%;
  height: 28px; padding: 0 8px;
  border: 0; background: transparent; border-radius: 3px;
  color: #CCCCCC; font-family: var(--f-app); font-size: 12px;
  cursor: pointer; text-align: left;
}
.wl-row:hover { background: #2A2A2E; }   /* app popup hover, not toolbar hover */
/* lifted from --app-text3 #6E6E72: 11px text on the popup fails WCAG at
   2.7:1 — the one deliberate departure from the Tokens.xaml replica */
.wl-row .slot { font-family: var(--f-num); color: #8E8E93; font-size: 11px; width: 10px; flex: none; }
.wl-row .nm { flex: 1 1 auto; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.wl-row .num { font-family: var(--f-num); color: var(--app-text2); font-size: 11px; flex: none; }

/* ============ split view (layout button): 1 + "Drop series here" ============ */
.demo-viewarea.is-split { grid-template-columns: 1fr 1fr; }
.vp-drop { display: flex; align-items: center; justify-content: center; cursor: default; }
/* #6E6E72 on the black viewport is 4.14:1 — lifted to clear the 4.5:1 floor */
.drop-text { font-family: var(--f-app); font-size: 13px; color: #7A7A7E; }
/* Was a style attribute on the noscript paragraph. Moved here so the CSP can
   refuse inline styles outright instead of allowing them for one padding. */
.noscript-pad { padding: 24px; }

/* ============ bottom status bar (app main window) ============ */
.demo-statusbar {
  height: 25px;                    /* app: Height=24 + 1 px top border */
  background: var(--app-s0);       /* Surface0 #121212 — blends with the window */
  border-top: 1px solid var(--app-border);
  display: flex; align-items: center;
  padding: 0;
  font-family: var(--f-app); font-size: 11px;
  color: var(--app-text2);
}
/* patient cell is 178 px wide so its right edge lands on the sidebar/viewport
   seam, then a 1 px divider, exactly like the app's status bar */
.demo-statusbar .sb-patient {
  width: 178px; flex: none; box-sizing: border-box;
  padding: 0 6px 0 12px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.demo-statusbar .sb-sep {
  width: 1px; align-self: stretch; flex: none;
  margin: 4px 8px;
  background: var(--app-border-med);
}

/* ============ MPR window (demo-mpr.js) — the app opens MPR as its own window:
   "MPR" logo + its own toolbar + captions, no series panel; one large Axial
   pane left, Coronal / Sagittal stacked right; gold dashed crosshairs. ====== */
.demo-viewarea { position: relative; }
.demo-mpr {
  position: absolute; inset: 0; z-index: 30;
  background: var(--app-s0);
  display: flex; flex-direction: column;
}
.mpr-logo {
  padding: 0 24px 0 16px;
  font-family: var(--f-app); font-size: 26px; font-weight: 700;
  color: var(--app-logo); flex: none; letter-spacing: 0.01em;
}
.mpr-toolbar { flex: none; }
.mpr-body { position: relative; flex: 1 1 auto; min-height: 0; background: var(--app-sidebar); }
.mpr-canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.mpr-pane { position: absolute; cursor: crosshair; touch-action: none; }
.pane-axial { left: 0; top: 0; width: calc(59% - 1px); height: 100%; }
.pane-coronal { left: calc(59% + 1px); top: 0; width: calc(41% - 1px); height: calc(50% - 1px); }
.pane-sagittal { left: calc(59% + 1px); top: calc(50% + 1px); width: calc(41% - 1px); height: calc(50% - 1px); }
.mpr-label {
  position: absolute; top: 8px; left: 10px;
  font-family: var(--f-app); font-size: 13px;
  color: var(--app-text); text-shadow: 0 0 2px #000, 0 0 2px #000;
  pointer-events: none;
}
.mpr-o {
  position: absolute; font-family: var(--f-app); font-size: 12px;
  color: var(--app-text); text-shadow: 0 0 2px #000, 0 0 2px #000; pointer-events: none;
}
.mpr-o.t { top: 6px; left: 50%; transform: translateX(-50%); }
.mpr-o.b { bottom: 6px; left: 50%; transform: translateX(-50%); }
.mpr-o.l { left: 8px; top: 50%; transform: translateY(-50%); }
.mpr-o.r { right: 8px; top: 50%; transform: translateY(-50%); }
.mpr-pos {
  position: absolute; right: 10px; bottom: 6px;
  font-family: var(--f-num); font-size: 12px;
  color: var(--app-amber); text-shadow: 0 0 2px #000, 0 0 2px #000;
  pointer-events: none;
}
.mpr-pos .lbl { color: var(--app-amber-dim); }
.mpr-val {
  position: absolute; left: 10px; bottom: 6px;
  font-family: var(--f-num); font-size: 13px; font-weight: 600;
  color: #fff; text-shadow: 0 0 2px #000, 0 0 2px #000;
  pointer-events: none;
}

/* ============ responsive ============ */
/* Э5 mobile: the app window can't keep its 760 px desktop chrome on a phone.
   The toolbar scrolls horizontally (it is clipped in the app too), and the
   series panel becomes a strip UNDER the viewport — the image keeps the width,
   which is what the visitor came for. Everything stays operable: no control is
   hidden on mobile, so §6's "if it is visible it works" still holds. */
@media (max-width: 720px) {
  .demo-app { min-width: 0; }
  .demo-toolbar { overflow-x: auto; overflow-y: hidden; scrollbar-width: none; }
  .demo-toolbar::-webkit-scrollbar { display: none; }
  .demo-body { height: 430px; flex-direction: column-reverse; }
  .demo-series {
    width: auto; height: 96px; flex: none;
    overflow-x: auto; overflow-y: hidden;
    padding: 6px;
  }
  .series-capsule { display: flex; align-items: center; height: 100%; }
  .series-header { display: none; }          /* patient line already in the overlay + status bar */
  .series-items { display: flex; gap: 8px; border-top: 0; padding: 0 2px; }
  .series-thumb { margin-top: 0; width: auto; flex: none; }
  .series-thumb .thumb-frame { width: 104px; height: 60px; }
  .series-thumb .thumb-name { max-width: 104px; font-size: 9px; }
}
