/* ==========================================================================
   MedDex Experience — Lens-first premium clinical workspace
   ==========================================================================

   WHAT THIS FILE IS
   -----------------
   The visual and structural layer for the redesigned MedDex: a one-page,
   Lens-first workspace with a whitish "porcelain clinical" surface and Liquid
   Glass reserved strictly for floating navigation and controls.

   WHY IT IS A SEPARATE FILE
   -------------------------
   Every rule is scoped under `body.mdx`. meddex-experience.js only adds that
   class when the redesign is enabled, so:

     * nothing here can affect the classic UI,
     * `?classic=1` (or localStorage meddex.ui=classic) restores the exact
       previous appearance at runtime, with no deploy, and
     * deleting the two <script>/<link> tags removes the redesign entirely.

   The old stylesheets are still authoritative for everything inside a screen
   that this file does not deliberately restate. This is a re-skin plus a new
   shell, never a replacement, because the screens' markup and behaviour are
   owned by app.js / osce-ui.js / lens-spatial-ui.js and must keep working.

   LIQUID GLASS RULE
   -----------------
   Glass is a NAVIGATION material here, not a page material. It is applied to
   the rail, the MedDex Bar, floating controls and sheet chrome — things that
   float ABOVE content. Content surfaces stay opaque porcelain so clinical
   imagery and text are never read through a blur.
   ========================================================================== */

body.mdx {
  /* ---- Porcelain clinical palette ------------------------------------- */
  --mdx-canvas: #f4f6f9;
  --mdx-canvas-warm: #fbfaf7;
  --mdx-surface: #ffffff;
  --mdx-surface-2: #f7f9fc;
  --mdx-surface-sunken: #eef1f6;

  --mdx-ink: #0e1726;
  --mdx-ink-2: #33415a;
  --mdx-muted: #5f6c80;
  --mdx-faint: #8b97a8;

  --mdx-hair: rgba(14, 23, 38, 0.08);
  --mdx-hair-strong: rgba(14, 23, 38, 0.14);

  /* Brand. Blue is action, gold is identity/premium, and the clinical
     semantics keep their existing meanings so nothing is re-taught. */
  --mdx-blue: #1769ff;
  --mdx-blue-ink: #0b46b5;
  --mdx-blue-wash: rgba(23, 105, 255, 0.08);
  --mdx-gold: #c8a34a;
  --mdx-gold-wash: rgba(200, 163, 74, 0.12);
  --mdx-green: #0f9d6c;
  --mdx-red: #dc2626;
  --mdx-violet: #6d5ce7;

  /* ---- Liquid Glass ---------------------------------------------------- */
  --mdx-glass: linear-gradient(177deg, rgba(255, 255, 255, 0.82) 0%, rgba(255, 255, 255, 0.66) 52%, rgba(248, 250, 253, 0.72) 100%);
  --mdx-glass-edge: rgba(255, 255, 255, 0.78);
  --mdx-glass-blur: saturate(185%) blur(30px);
  --mdx-glass-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.95),
    inset 0 -1px 0 rgba(14, 23, 38, 0.05),
    0 2px 6px rgba(14, 23, 38, 0.05),
    0 16px 44px rgba(14, 23, 38, 0.12);
  --mdx-glass-shadow-lift:
    inset 0 1px 0 rgba(255, 255, 255, 0.95),
    0 4px 12px rgba(14, 23, 38, 0.07),
    0 28px 70px rgba(14, 23, 38, 0.18);

  /* ---- Elevation for opaque content ----------------------------------- */
  --mdx-lift-1: 0 1px 2px rgba(14, 23, 38, 0.04), 0 2px 10px rgba(14, 23, 38, 0.04);
  --mdx-lift-2: 0 2px 6px rgba(14, 23, 38, 0.05), 0 12px 34px rgba(14, 23, 38, 0.08);

  --mdx-r-sm: 12px;
  --mdx-r: 18px;
  --mdx-r-lg: 24px;
  --mdx-r-pill: 999px;

  --mdx-ease: cubic-bezier(0.22, 0.9, 0.24, 1);
  --mdx-ease-spring: cubic-bezier(0.34, 1.32, 0.44, 1);

  /* Layout budget the rest of the app reads so nothing hides behind the
     floating chrome. Updated live from JS as the bar morphs. */
  --mdx-bar-h: 74px;
  --mdx-rail-h: 64px;
  /* 0 on a phone, where the navigation is a bar at the foot and costs height
     rather than width. Replaced with the rail's measured right edge + gutter
     the moment it becomes a left column (see measureChrome). */
  --mdx-rail-inset: 0px;
  --mdx-safe-b: env(safe-area-inset-b, 0px);
  --mdx-bottom-budget: calc(var(--mdx-bar-h) + var(--mdx-rail-h) + 26px + env(safe-area-inset-bottom, 0px));

  color: var(--mdx-ink);
  background: var(--mdx-canvas);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* A quiet, expensive-looking ground. The classic build animates a sweeping
   grid and drifting particles across the whole viewport; that reads as
   "consumer app", and it repaints constantly on phones. */
body.mdx {
  background:
    radial-gradient(1200px 620px at 12% -8%, rgba(23, 105, 255, 0.055), transparent 62%),
    radial-gradient(980px 560px at 92% 2%, rgba(200, 163, 74, 0.06), transparent 58%),
    linear-gradient(180deg, #fbfcfe 0%, #f4f6f9 46%, #f6f4f0 100%);
  background-attachment: fixed;
}
body.mdx::before,
body.mdx::after {
  content: none !important;
  animation: none !important;
}

/* ==========================================================================
   1. Shell — what the redesign removes from view
   ========================================================================== */

/* The bottom navigation is the app's own element, restyled in place — so
   updateBottomNav() and the coach-marks keep working against the same nodes.
   Lens is not in it: Lens is a mode of the home surface, and listing it here
   too would make it ambiguous whether Lens is a page or a mode. */

/* The classic sticky topbar is replaced by the rail + bar. Its controls
   (theme, sound, profile, admin) are re-presented in the rail's overflow. */
body.mdx > .app-shell > .topbar,
body.mdx .app-shell > header.topbar { display: none !important; }

/* The marketing footer belongs on a dashboard, not in a workspace. It is
   kept for crawlers and reachable from Settings. */
body.mdx .app-shell > footer { display: none; }
body.mdx.mdx-show-footer .app-shell > footer {
  display: block;
  margin-top: 28px;
  padding-top: 20px;
  border-top: 1px solid var(--mdx-hair);
}

body.mdx .app-shell {
  width: min(1240px, calc(100% - 28px));
  padding: 14px 0 var(--mdx-bottom-budget);
}

/* Lens runs edge to edge: it is the workspace, not a page in a container. */
body.mdx.lens-immersive .app-shell {
  width: 100%;
  padding: 0;
}

/* ===========================================================================
   The rail is a column, not an overlay
   ---------------------------------------------------------------------------
   At >=1024px the navigation leaves the foot of the screen and becomes a fixed
   column at left:18px, 76px wide. Fixed means it takes NO space in the flow,
   so everything laid out against the full viewport ran underneath it. On Lens
   that was unmissable: the heading was drawn at x=22 with the rail covering
   18..94, so the title and the upload call-to-action sat behind navigation at
   every width from iPad landscape up.

   The fix is not a margin picked to look right. --mdx-rail-inset is the rail's
   measured right edge plus a deliberate gutter, so the workspace starts where
   the navigation actually ends. It is applied as padding on the BODY, which
   means .app-shell keeps `margin: 0 auto` and therefore centres inside the
   REMAINING area rather than against the whole screen — the difference the
   eye reads as "laid out for this space" instead of "pushed over".

   Fixed chrome positions against the viewport, not the padded body, so the
   bar and the mode switch are shifted by half the inset to stay centred on
   the same axis as the content they belong to.

   Phones are untouched: --mdx-rail-inset is 0 until the rail is a column.
   ========================================================================= */

body.mdx.mdx-rail-column {
  padding-left: var(--mdx-rail-inset);
  /* The film, the report sheet and the sticky chrome all read this. */
  --mdx-content-left: var(--mdx-rail-inset);
}

/* Lens is the priority: it is edge-to-edge by design, so without this the
   whole workspace — stage, intro, entry buttons — starts under the rail. */
body.mdx.mdx-rail-column.lens-immersive .app-shell {
  width: 100%;
  padding: 0;
}

/* Chrome that centres on the viewport re-centres on the workspace. */
body.mdx.mdx-rail-column .mdx-bar,
body.mdx.mdx-rail-column .mdx-switch,
body.mdx.mdx-rail-column #mdxModeSwitch {
  left: calc(50% + (var(--mdx-rail-inset) / 2));
}
body.mdx.mdx-rail-column .install-prompt {
  left: calc(50% + (var(--mdx-rail-inset) / 2));
}

/* The bar must also stay inside the workspace, not merely centred on it. */
body.mdx.mdx-rail-column .mdx-bar {
  /* 100% (not 100vw): both are the viewport for a fixed element, but 100vw
     ignores page zoom, so at 150% the bar was sized from the unzoomed width
     and ran off the right edge. */
  width: min(720px, calc(100% - var(--mdx-rail-inset) - 24px));
}

/* Lens is FIXED, so padding on the body cannot reach it.
   ---------------------------------------------------------------------------
   .lens-screen and .lens-v2 are position:fixed at left:0, which positions them
   against the viewport rather than the padded body — which is why the Lens
   workspace alone kept starting at x=0 with its heading at x=22, underneath a
   rail occupying 18..94, while every other screen had already moved across.
   The inset has to be applied to the fixed boxes themselves; everything inside
   them is laid out at left:0/width:100% of that box and follows. */
body.mdx.mdx-rail-column .lens-screen,
body.mdx.mdx-rail-column .lens-v2,
body.mdx.mdx-rail-column #lensScreen {
  left: var(--mdx-rail-inset);
  width: calc(100% - var(--mdx-rail-inset));
}

/* Screens fade in rather than snapping, which is most of the perceived
   "premium" at zero layout cost. */
body.mdx .screen.active {
  animation: mdxScreenIn 0.34s var(--mdx-ease) both;
}
@keyframes mdxScreenIn {
  from { opacity: 0; transform: translate3d(0, 8px, 0); }
  to   { opacity: 1; transform: none; }
}

/* ==========================================================================
   2. The MedDex Rail — compact, floating, morphing
   ==========================================================================
   Collapsed it is a single glass pill showing the MedDex mark and where you
   are. Expanded it morphs into the seven destinations. It is never a
   permanent bar: it hides itself while you scroll down or while the camera is
   live, and comes back on any upward intent.
   ========================================================================== */

.mdx-rail {
  position: fixed;
  z-index: 2520;
  left: 50%;
  bottom: calc(14px + env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 6px;
  border-radius: var(--mdx-r-pill);
  background: var(--mdx-glass);
  -webkit-backdrop-filter: var(--mdx-glass-blur);
  backdrop-filter: var(--mdx-glass-blur);
  border: 1px solid var(--mdx-glass-edge);
  box-shadow: var(--mdx-glass-shadow);
  transition:
    transform 0.42s var(--mdx-ease-spring),
    opacity 0.24s var(--mdx-ease),
    box-shadow 0.3s var(--mdx-ease),
    border-radius 0.42s var(--mdx-ease-spring);
  will-change: transform;
}

/* The specular sheen that makes glass read as glass rather than as a blur. */
.mdx-rail::after {
  content: "";
  position: absolute;
  inset: 1px 1px auto 1px;
  height: 46%;
  border-radius: inherit;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.55), rgba(255, 255, 255, 0));
  pointer-events: none;
}

.mdx-rail.is-hidden {
  transform: translateX(-50%) translateY(calc(100% + 30px));
  opacity: 0;
  pointer-events: none;
}

.mdx-rail-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  min-width: 46px;
  height: 46px;
  padding: 0 12px;
  border: 0;
  border-radius: var(--mdx-r-pill);
  background: transparent;
  color: var(--mdx-muted);
  font-size: 0.78rem;
  font-weight: 650;
  letter-spacing: -0.01em;
  white-space: nowrap;
  transition: color 0.2s var(--mdx-ease), background 0.28s var(--mdx-ease), transform 0.2s var(--mdx-ease);
  -webkit-tap-highlight-color: transparent;
}
.mdx-rail-btn svg { width: 21px; height: 21px; flex: none; }
.mdx-rail-btn:hover { color: var(--mdx-ink); background: rgba(14, 23, 38, 0.045); }
.mdx-rail-btn:active { transform: scale(0.94); }

.mdx-rail-btn .mdx-rail-label {
  max-width: 0;
  overflow: hidden;
  opacity: 0;
  transition: max-width 0.36s var(--mdx-ease), opacity 0.22s var(--mdx-ease);
}
.mdx-rail-btn.is-active {
  color: var(--mdx-ink);
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.96), rgba(255, 255, 255, 0.72));
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.9) inset,
    0 1px 3px rgba(14, 23, 38, 0.07),
    0 6px 18px rgba(14, 23, 38, 0.09);
}
.mdx-rail-btn.is-active .mdx-rail-label { max-width: 120px; opacity: 1; }
.mdx-rail-btn.is-active svg { color: var(--mdx-blue); }

/* The gold hairline under the active destination — the one place the brand
   accent appears in navigation, so it stays a signature rather than decor. */
.mdx-rail-btn.is-active::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: 5px;
  width: 16px;
  height: 2px;
  border-radius: 2px;
  transform: translateX(-50%);
  background: linear-gradient(90deg, transparent, var(--mdx-gold), transparent);
}

.mdx-rail-badge {
  position: absolute;
  top: 4px;
  right: 4px;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: 999px;
  background: var(--mdx-red);
  color: #fff;
  font-size: 0.6rem;
  font-weight: 800;
  line-height: 16px;
  text-align: center;
  box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.9);
}
.mdx-rail-badge[hidden] { display: none; }

/* -- collapsed / expanded morph ------------------------------------------ */
.mdx-rail[data-state="collapsed"] .mdx-rail-btn:not(.is-active):not(.mdx-rail-more) {
  max-width: 0;
  min-width: 0;
  padding: 0;
  opacity: 0;
  pointer-events: none;
  transform: scale(0.7);
}
.mdx-rail .mdx-rail-btn {
  max-width: 200px;
  transition:
    max-width 0.4s var(--mdx-ease-spring),
    min-width 0.4s var(--mdx-ease-spring),
    padding 0.4s var(--mdx-ease-spring),
    opacity 0.26s var(--mdx-ease),
    transform 0.4s var(--mdx-ease-spring),
    color 0.2s var(--mdx-ease),
    background 0.28s var(--mdx-ease);
}

.mdx-rail-more {
  color: var(--mdx-ink);
}
.mdx-rail-more svg { transition: transform 0.4s var(--mdx-ease-spring); }
.mdx-rail[data-state="expanded"] .mdx-rail-more svg { transform: rotate(45deg); }

.mdx-rail-sep {
  width: 1px;
  height: 22px;
  margin: 0 3px;
  background: var(--mdx-hair);
  flex: none;
}
.mdx-rail[data-state="collapsed"] .mdx-rail-sep { display: none; }

/* -- desktop: a vertical rail on the left edge --------------------------- */
@media (min-width: 1024px) {
  .mdx-rail {
    left: 18px;
    top: 50%;
    bottom: auto;
    transform: translateY(-50%);
    flex-direction: column;
    border-radius: 26px;
    padding: 8px;
  }
  .mdx-rail.is-hidden {
    transform: translateY(-50%) translateX(calc(-100% - 26px));
  }
  .mdx-rail[data-state="collapsed"] .mdx-rail-btn:not(.is-active):not(.mdx-rail-more) {
    max-width: 200px;
    min-width: 46px;
    padding: 0 12px;
    opacity: 1;
    pointer-events: auto;
    transform: none;
  }
  .mdx-rail .mdx-rail-btn { width: 46px; padding: 0; }
  .mdx-rail .mdx-rail-btn .mdx-rail-label { display: none; }
  .mdx-rail-sep { display: none !important; width: 22px; height: 1px; margin: 3px 0; }
  .mdx-rail-more { display: none !important; }
  .mdx-rail-btn.is-active::after { left: auto; right: 4px; bottom: 50%; width: 2px; height: 16px; transform: translateY(50%); background: linear-gradient(180deg, transparent, var(--mdx-gold), transparent); }
  /* Superseded by the rail-aware sizing further down this file; kept only so
     the rail block stays self-contained if that section is ever lifted out. */
  body.mdx .app-shell { width: min(1240px, calc(100% - 208px)); margin-left: auto; margin-right: auto; }
}

/* Desktop tooltip for the icon-only vertical rail. */
@media (min-width: 1024px) {
  .mdx-rail-btn::before {
    content: attr(data-tip);
    position: absolute;
    left: calc(100% + 12px);
    top: 50%;
    transform: translateY(-50%) translateX(-6px);
    padding: 6px 10px;
    border-radius: 9px;
    background: var(--mdx-ink);
    color: #fff;
    font-size: 0.74rem;
    font-weight: 600;
    white-space: nowrap;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.18s var(--mdx-ease), transform 0.18s var(--mdx-ease);
  }
  .mdx-rail-btn:hover::before { opacity: 1; transform: translateY(-50%) translateX(0); }
}

/* ==========================================================================
   3. The MedDex Bar — one universal, context-aware control
   ==========================================================================
   Upload/capture, Ask Baihaqi AI, patient chat and contextual actions are the
   same object in different states. It morphs; it is never four bars.
   ========================================================================== */

.mdx-bar {
  position: fixed;
  z-index: 2530;
  left: 50%;
  bottom: calc(14px + var(--mdx-rail-h) + 10px + env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%);
  width: min(720px, calc(100vw - 24px));
  display: flex;
  flex-direction: column;
  gap: 0;
  border-radius: 26px;
  background: var(--mdx-glass);
  -webkit-backdrop-filter: var(--mdx-glass-blur);
  backdrop-filter: var(--mdx-glass-blur);
  border: 1px solid var(--mdx-glass-edge);
  box-shadow: var(--mdx-glass-shadow-lift);
  transition:
    transform 0.42s var(--mdx-ease-spring),
    opacity 0.24s var(--mdx-ease),
    width 0.42s var(--mdx-ease-spring),
    border-radius 0.4s var(--mdx-ease-spring);
  overflow: hidden;
}
.mdx-bar::after {
  content: "";
  position: absolute;
  inset: 1px 1px auto 1px;
  height: 40%;
  border-radius: inherit;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0));
  pointer-events: none;
}
.mdx-bar.is-hidden {
  transform: translateX(-50%) translateY(calc(100% + 120px));
  opacity: 0;
  pointer-events: none;
}
.mdx-bar[hidden] { display: none; }

/* -- contextual chip strip (row above the composer) ---------------------- */
.mdx-bar-chips {
  display: flex;
  gap: 7px;
  padding: 9px 11px 3px;
  overflow-x: auto;
  scrollbar-width: none;
  -ms-overflow-style: none;
  position: relative;
  z-index: 1;
}
.mdx-bar-chips::-webkit-scrollbar { display: none; }
.mdx-bar-chips:empty { display: none; }

.mdx-chip {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 32px;
  padding: 0 12px;
  border-radius: var(--mdx-r-pill);
  border: 1px solid var(--mdx-hair);
  background: rgba(255, 255, 255, 0.86);
  color: var(--mdx-ink-2);
  font-size: 0.775rem;
  font-weight: 620;
  letter-spacing: -0.01em;
  white-space: nowrap;
  transition: transform 0.18s var(--mdx-ease), background 0.2s var(--mdx-ease), border-color 0.2s var(--mdx-ease), color 0.2s var(--mdx-ease);
}
.mdx-chip svg { width: 14px; height: 14px; flex: none; opacity: 0.75; }
.mdx-chip:hover { background: #fff; border-color: var(--mdx-hair-strong); color: var(--mdx-ink); }
.mdx-chip:active { transform: scale(0.95); }
.mdx-chip[aria-pressed="true"],
.mdx-chip.is-on {
  background: var(--mdx-blue-wash);
  border-color: rgba(23, 105, 255, 0.28);
  color: var(--mdx-blue-ink);
}
.mdx-chip[aria-pressed="true"] svg, .mdx-chip.is-on svg { opacity: 1; }
.mdx-chip.mdx-chip-accent {
  background: var(--mdx-gold-wash);
  border-color: rgba(200, 163, 74, 0.34);
  color: #8a6d1c;
}

/* -- composer row -------------------------------------------------------- */
.mdx-bar-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 9px 10px;
  position: relative;
  z-index: 1;
}

.mdx-bar-btn {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  width: 44px;
  height: 44px;
  border-radius: var(--mdx-r-pill);
  border: 1px solid var(--mdx-hair);
  background: rgba(255, 255, 255, 0.9);
  color: var(--mdx-ink-2);
  transition: transform 0.18s var(--mdx-ease), background 0.2s var(--mdx-ease), color 0.2s var(--mdx-ease), border-color 0.2s var(--mdx-ease);
}
.mdx-bar-btn svg { width: 20px; height: 20px; }
.mdx-bar-btn:hover { background: #fff; color: var(--mdx-ink); border-color: var(--mdx-hair-strong); }
.mdx-bar-btn:active { transform: scale(0.93); }
.mdx-bar-btn.is-wide { width: auto; padding: 0 15px; font-size: 0.82rem; font-weight: 650; }

.mdx-bar-field {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  align-items: center;
  height: 44px;
  padding: 0 4px 0 14px;
  border-radius: var(--mdx-r-pill);
  background: rgba(255, 255, 255, 0.92);
  border: 1px solid var(--mdx-hair);
  transition: border-color 0.2s var(--mdx-ease), box-shadow 0.2s var(--mdx-ease), background 0.2s var(--mdx-ease);
}
.mdx-bar-field:focus-within {
  background: #fff;
  border-color: rgba(23, 105, 255, 0.45);
  box-shadow: 0 0 0 4px rgba(23, 105, 255, 0.1);
}
.mdx-bar-input,
body.mdx input.mdx-bar-input[type="text"] {
  flex: 1 1 auto;
  min-width: 0;
  border: 0;
  outline: 0;
  /* Overrides body.mdx input[type="text"], which paints form fields white.
     The field around it already provides the surface. */
  background: transparent;
  color: var(--mdx-ink);
  font-size: 0.92rem;
  font-weight: 500;
  letter-spacing: -0.011em;
}
.mdx-bar-input::placeholder { color: var(--mdx-faint); font-weight: 500; }

.mdx-bar-send {
  flex: none;
  width: 36px;
  height: 36px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: var(--mdx-r-pill);
  background: linear-gradient(180deg, #2f7bff, var(--mdx-blue));
  color: #fff;
  box-shadow: 0 2px 8px rgba(23, 105, 255, 0.34);
  transition: transform 0.18s var(--mdx-ease), opacity 0.2s var(--mdx-ease), box-shadow 0.2s var(--mdx-ease);
}
.mdx-bar-send svg { width: 17px; height: 17px; }
.mdx-bar-send:disabled { opacity: 0.36; box-shadow: none; cursor: default; }
.mdx-bar-send:not(:disabled):hover { box-shadow: 0 4px 14px rgba(23, 105, 255, 0.42); }
.mdx-bar-send:not(:disabled):active { transform: scale(0.9); }

/* Voice is a neighbouring action, not a second composer mode. A black disc
   and four white waveform reeds keep it distinct from the blue Send action
   without borrowing phone or microphone metaphors. */
.mdx-bar-voice {
  position: relative;
  flex: none;
  width: 36px;
  height: 36px;
  display: inline-grid;
  place-items: center;
  padding: 0;
  overflow: visible;
  border-radius: 50%;
  border: 1px solid rgba(0, 0, 0, 0.96);
  background: #050505;
  color: #fff;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.16),
    0 3px 10px rgba(0,0,0,.2);
  transition: transform .2s var(--mdx-ease), box-shadow .25s var(--mdx-ease), background .25s var(--mdx-ease);
}
.mdx-bar-voice::after {
  content: none;
}
.mdx-bar-voice svg { position: relative; width: 18px; height: 18px; z-index: 1; }
.mdx-bar-voice:hover { background: #151515; box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 5px 15px rgba(0,0,0,.28); }
.mdx-bar-voice:active { transform: scale(.91); }
.mdx-bar-voice:focus-visible { outline: 2px solid #111; outline-offset: 3px; }

@media (max-width: 420px) {
  .mdx-bar-field { gap: 2px; padding-left: 12px; }
  .mdx-bar-voice, .mdx-bar-send { width: 34px; height: 34px; }
}

/* -- the install prompt clears the floating chrome ----------------------
   The classic layout put the install card 92px off the bottom, which cleared
   a 92px navigation bar. Under this shell the bottom chrome is the rail PLUS
   the MedDex Bar PLUS the trust line — around 265px — so that offset landed
   the card squarely on the composer, the send button, the mode switch and the
   Terms/Privacy links, all of which stopped responding while it was up
   (z-index 22000 beats the bar's 2530).

   --mdx-bottom-budget is the number the shell publishes for exactly this, and
   it is re-measured whenever the bar morphs, so this stays correct as the bar
   changes shape. */
body.mdx .install-prompt {
  bottom: calc(var(--mdx-bottom-budget) + var(--mdx-switch-h, 0px) + 12px);
}
/* The classic sheet re-states this offset at phone widths; restate the
   corrected one at the same breakpoint so it is not reverted there. */
@media (max-width: 560px) {
  body.mdx .install-prompt {
    bottom: calc(var(--mdx-bottom-budget) + var(--mdx-switch-h, 0px) + 12px);
  }
}

/* -- trust line ----------------------------------------------------------
   A footnote to the composer, not a warning banner: one quiet line, tiny but
   never below the readable floor. It is deliberately NOT --mdx-faint, which
   sits at about 2.8:1 on this glass and would make the sentence decorative.
   The tokens below clear 4.5:1 in both themes, and the links clear 7:1 so
   they read as links at 11px without needing a colour a user must hunt for. */
.mdx-bar-legal {
  margin: 0;
  padding: 0 14px 9px;
  position: relative;
  z-index: 1;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: center;
  gap: 0 5px;
  font-size: 0.68rem;
  line-height: 1.45;
  font-weight: 500;
  letter-spacing: -0.004em;
  text-align: center;
  color: var(--mdx-legal, #5d6b82);
  text-wrap: balance;
}
.mdx-bar-legal[hidden] { display: none; }
/* A slightly wider gap after the sentence than between the two links, so the
   links read as one cluster set apart from it rather than as a third clause. */
.mdx-bar-legal-text { margin-right: 4px; }
.mdx-bar-legal-item {
  white-space: nowrap;
  display: inline-flex;
  align-items: baseline;
  gap: 5px;
}
.mdx-bar-legal-dot { opacity: 0.55; }
.mdx-bar-legal-link {
  color: var(--mdx-legal-link, #33415a);
  font-weight: 600;
  text-decoration: underline;
  text-decoration-thickness: from-font;
  text-underline-offset: 0.18em;
  border-radius: 5px;
  /* The type stays 11px; the touch target does not. Padding plus an equal
     negative margin buys a comfortably tappable box without moving the
     baseline or opening a gap in the sentence. */
  padding: 7px 6px;
  margin: -7px -6px;
}
.mdx-bar-legal-link:hover { color: var(--mdx-blue); }
.mdx-bar-legal-link:focus-visible {
  outline: 2px solid var(--mdx-blue);
  outline-offset: 1px;
}

/* Very short viewports (a landscape phone, or an open keyboard) need the
   composer more than they need the footnote. */
@media (max-height: 460px) {
  .mdx-bar-legal { display: none; }
}

/* -- the shutter, when Lens is in capture context ------------------------ */
.mdx-shutter {
  flex: none;
  position: relative;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  border: 0;
  background: transparent;
  transition: transform 0.2s var(--mdx-ease-spring);
}
.mdx-shutter::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 2.5px solid rgba(14, 23, 38, 0.16);
  transition: border-color 0.24s var(--mdx-ease);
}
.mdx-shutter::after {
  content: "";
  position: absolute;
  inset: 6px;
  border-radius: 50%;
  background: linear-gradient(180deg, #ffffff, #eef2f8);
  box-shadow:
    inset 0 1px 0 #fff,
    0 2px 8px rgba(14, 23, 38, 0.16),
    0 0 0 1px rgba(14, 23, 38, 0.06);
  transition: transform 0.2s var(--mdx-ease-spring), background 0.24s var(--mdx-ease);
}
.mdx-shutter:hover::before { border-color: rgba(23, 105, 255, 0.4); }
.mdx-shutter:active::after { transform: scale(0.88); }
.mdx-shutter.is-busy::before {
  border-color: rgba(23, 105, 255, 0.24);
  border-top-color: var(--mdx-blue);
  animation: mdxSpin 0.85s linear infinite;
}
@keyframes mdxSpin { to { transform: rotate(360deg); } }

/* -- busy/thinking shimmer along the bar's top edge ---------------------- */
.mdx-bar.is-busy::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  z-index: 2;
  background: linear-gradient(90deg, transparent, var(--mdx-blue), var(--mdx-gold), transparent);
  background-size: 45% 100%;
  background-repeat: no-repeat;
  animation: mdxSweep 1.5s var(--mdx-ease) infinite;
}
@keyframes mdxSweep {
  0%   { background-position: -50% 0; }
  100% { background-position: 150% 0; }
}

/* ==========================================================================
   4. Tools sheet — where advanced capability lives
   ==========================================================================
   The primary screen stays simple by moving everything optional behind
   "+ Tools". This is a real sheet: focus-trapped, dismissible, scrollable.
   ========================================================================== */

.mdx-sheet-scrim {
  position: fixed;
  inset: 0;
  z-index: 2560;
  background: rgba(14, 23, 38, 0.28);
  -webkit-backdrop-filter: blur(3px);
  backdrop-filter: blur(3px);
  opacity: 0;
  transition: opacity 0.3s var(--mdx-ease);
}
.mdx-sheet-scrim.is-open { opacity: 1; }
.mdx-sheet-scrim[hidden] { display: none; }

.mdx-sheet {
  position: fixed;
  z-index: 2570;
  left: 50%;
  bottom: 0;
  transform: translateX(-50%) translateY(100%);
  width: min(660px, 100vw);
  max-height: min(78vh, 720px);
  display: flex;
  flex-direction: column;
  border-radius: 28px 28px 0 0;
  background: var(--mdx-glass);
  -webkit-backdrop-filter: var(--mdx-glass-blur);
  backdrop-filter: var(--mdx-glass-blur);
  border: 1px solid var(--mdx-glass-edge);
  border-bottom: 0;
  box-shadow: var(--mdx-glass-shadow-lift);
  transition: transform 0.44s var(--mdx-ease-spring);
  padding-bottom: env(safe-area-inset-bottom, 0px);
}
.mdx-sheet.is-open { transform: translateX(-50%) translateY(0); }
.mdx-sheet[hidden] { display: none; }

@media (min-width: 720px) {
  .mdx-sheet { bottom: 22px; border-radius: 28px; border-bottom: 1px solid var(--mdx-glass-edge); }
  .mdx-sheet { transform: translateX(-50%) translateY(calc(100% + 40px)); }
  .mdx-sheet.is-open { transform: translateX(-50%) translateY(0); }
}

.mdx-sheet-grab {
  width: 38px;
  height: 4px;
  margin: 9px auto 2px;
  border-radius: 3px;
  background: var(--mdx-hair-strong);
  flex: none;
}
.mdx-sheet-head {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 8px 20px 12px;
  flex: none;
}
.mdx-sheet-head h2 {
  margin: 0;
  font-size: 1.06rem;
  font-weight: 720;
  letter-spacing: -0.022em;
  color: var(--mdx-ink);
}
.mdx-sheet-head p {
  margin: 3px 0 0;
  font-size: 0.8rem;
  color: var(--mdx-muted);
  line-height: 1.45;
}
.mdx-sheet-x {
  margin-left: auto;
  flex: none;
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  border: 1px solid var(--mdx-hair);
  background: rgba(255, 255, 255, 0.9);
  color: var(--mdx-muted);
}
.mdx-sheet-x:hover { color: var(--mdx-ink); background: #fff; }

.mdx-sheet-body {
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: 0 14px 18px;
}

.mdx-tool-group + .mdx-tool-group { margin-top: 14px; }
.mdx-tool-group > h3 {
  margin: 0 0 8px 6px;
  font-size: 0.68rem;
  font-weight: 750;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--mdx-faint);
}
.mdx-tool-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(148px, 1fr));
  gap: 8px;
}
.mdx-tool {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px;
  min-height: 60px;
  text-align: left;
  border-radius: var(--mdx-r);
  border: 1px solid var(--mdx-hair);
  background: rgba(255, 255, 255, 0.88);
  color: var(--mdx-ink);
  transition: transform 0.18s var(--mdx-ease), background 0.2s var(--mdx-ease), border-color 0.2s var(--mdx-ease), box-shadow 0.2s var(--mdx-ease);
}
.mdx-tool:hover { background: #fff; border-color: rgba(23, 105, 255, 0.26); box-shadow: var(--mdx-lift-1); }
.mdx-tool:active { transform: scale(0.975); }
.mdx-tool[disabled], .mdx-tool[aria-disabled="true"] { opacity: 0.42; pointer-events: none; }
.mdx-tool-ic {
  flex: none;
  width: 34px;
  height: 34px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 11px;
  background: var(--mdx-blue-wash);
  color: var(--mdx-blue);
}
.mdx-tool-ic svg { width: 18px; height: 18px; }
.mdx-tool.is-accent .mdx-tool-ic { background: var(--mdx-gold-wash); color: #8a6d1c; }
.mdx-tool.is-danger .mdx-tool-ic { background: rgba(220, 38, 38, 0.1); color: var(--mdx-red); }
.mdx-tool-txt { min-width: 0; }
.mdx-tool-txt strong {
  display: block;
  font-size: 0.845rem;
  font-weight: 660;
  letter-spacing: -0.014em;
  line-height: 1.25;
}
.mdx-tool-txt small {
  display: block;
  margin-top: 2px;
  font-size: 0.715rem;
  color: var(--mdx-muted);
  line-height: 1.35;
}

/* ==========================================================================
   5. Lens — the workspace
   ========================================================================== */

/* The stage is a lightbox: a soft, near-white viewing surface. Radiographs
   are mostly dark, so they gain contrast against it rather than losing it,
   and the whole screen stops looking like a consumer camera app. */
body.mdx .lens-screen .lens-stage {
  background:
    radial-gradient(120% 90% at 50% 0%, #ffffff 0%, #f2f5f9 55%, #e9edf3 100%);
}
body.mdx .lens-screen .lens-scrim { display: none; }

body.mdx .lens-screen .lens-empty-state {
  background: transparent;
  color: var(--mdx-ink);
}
body.mdx .lens-screen .lens-empty-state strong {
  color: var(--mdx-ink);
  font-weight: 700;
  letter-spacing: -0.024em;
}
body.mdx .lens-screen .lens-empty-state span { color: var(--mdx-muted); }
body.mdx .lens-screen .lens-empty-state .lens-enable-camera {
  border-radius: var(--mdx-r-pill);
  border: 1px solid var(--mdx-hair);
  background: rgba(255, 255, 255, 0.92);
  color: var(--mdx-ink);
  box-shadow: var(--mdx-lift-1);
}

/* The classic capture bar and top bar are superseded by the MedDex Bar and
   the floating controls. They stay in the DOM: app.js binds the shutter,
   gallery input, flash and camera switch to those exact elements, and the
   MedDex Bar drives them by delegation. */
body.mdx .lens-screen .lens-capturebar { display: none !important; }
body.mdx .lens-screen .lens-topbar-v2 { display: none !important; }
body.mdx .lens-screen .lens-ai-orb-wrap { display: none !important; }

/* Floating glass controls, top-left and top-right of the stage. */
.mdx-lens-controls {
  position: fixed;
  z-index: 2500;
  top: calc(12px + env(safe-area-inset-top, 0px));
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 5px;
  border-radius: var(--mdx-r-pill);
  background: var(--mdx-glass);
  -webkit-backdrop-filter: var(--mdx-glass-blur);
  backdrop-filter: var(--mdx-glass-blur);
  border: 1px solid var(--mdx-glass-edge);
  box-shadow: var(--mdx-glass-shadow);
  transition: transform 0.36s var(--mdx-ease-spring), opacity 0.24s var(--mdx-ease);
}
.mdx-lens-controls[hidden] { display: none; }
.mdx-lens-controls.is-left { left: 12px; }
.mdx-lens-controls.is-right { right: 12px; }
.mdx-lens-controls.is-hidden { opacity: 0; transform: translateY(-16px); pointer-events: none; }
@media (min-width: 1024px) {
  .mdx-lens-controls.is-left { left: 92px; }
}
.mdx-lens-btn {
  width: 38px;
  height: 38px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--mdx-ink-2);
  transition: background 0.2s var(--mdx-ease), color 0.2s var(--mdx-ease), transform 0.18s var(--mdx-ease);
}
.mdx-lens-btn svg { width: 18px; height: 18px; }
.mdx-lens-btn:hover { background: rgba(14, 23, 38, 0.06); color: var(--mdx-ink); }
.mdx-lens-btn:active { transform: scale(0.9); }
.mdx-lens-btn[aria-pressed="true"] { background: var(--mdx-blue-wash); color: var(--mdx-blue); }

/* The modality pill floats with the controls instead of stacking bars. */
body.mdx .lens-screen .lens-modes-wrap {
  position: fixed;
  top: calc(60px + env(safe-area-inset-top, 0px));
  left: 50%;
  transform: translateX(-50%);
  z-index: 925;
  width: auto;
  max-width: min(560px, calc(100vw - 24px));
  padding: 0;
  background: none;
  border: 0;
}
body.mdx .lens-screen .lens-modality-pill {
  border-radius: var(--mdx-r-pill);
  background: var(--mdx-glass);
  -webkit-backdrop-filter: var(--mdx-glass-blur);
  backdrop-filter: var(--mdx-glass-blur);
  border: 1px solid var(--mdx-glass-edge);
  box-shadow: var(--mdx-glass-shadow);
  color: var(--mdx-ink);
  font-weight: 640;
}
body.mdx .lens-screen .lens-segment { display: none; }

/* The report sheet becomes a proper workspace panel: opaque porcelain for
   the reading surface, glass only for its floating header. */
body.mdx .lens-screen .lens-sheet .lens-sheet-panel {
  background: rgba(255, 255, 255, 0.97);
  -webkit-backdrop-filter: saturate(180%) blur(22px);
  backdrop-filter: saturate(180%) blur(22px);
  border: 1px solid var(--mdx-hair);
  border-bottom: 0;
  border-radius: 26px 26px 0 0;
  box-shadow: 0 -2px 10px rgba(14, 23, 38, 0.05), 0 -22px 60px rgba(14, 23, 38, 0.13);
  color: var(--mdx-ink);
}
body.mdx .lens-screen .lens-sheet .lens-sheet-head h3 {
  color: var(--mdx-ink);
  letter-spacing: -0.024em;
  font-weight: 720;
}
body.mdx .lens-screen .lens-sheet .eyebrow { color: var(--mdx-gold); letter-spacing: 0.1em; }
body.mdx .lens-screen .lens-answer { color: var(--mdx-ink-2); }
body.mdx .lens-screen .lens-safety {
  color: var(--mdx-muted);
  border-top: 1px solid var(--mdx-hair);
  padding-top: 10px;
}

/* The sheet itself now ends above the chrome (section 17), so its scroll area
   only needs ordinary breathing room at the bottom. */
body.mdx .lens-screen .lens-sheet .lens-sheet-scroll {
  padding-bottom: 18px;
}

/* Spatial layer chrome inherits the same glass language. */
body.mdx #lspRail {
  background: var(--mdx-glass) !important;
  -webkit-backdrop-filter: var(--mdx-glass-blur) !important;
  backdrop-filter: var(--mdx-glass-blur) !important;
  border: 1px solid var(--mdx-glass-edge) !important;
  box-shadow: var(--mdx-glass-shadow) !important;
}
body.mdx #lspSheet {
  background: rgba(255, 255, 255, 0.97) !important;
  -webkit-backdrop-filter: saturate(180%) blur(22px) !important;
  backdrop-filter: saturate(180%) blur(22px) !important;
  border-top: 1px solid var(--mdx-hair) !important;
}

/* ==========================================================================
   6. Content screens — porcelain re-skin
   ========================================================================== */

body.mdx .platform-page-head { padding-top: 8px; }
body.mdx .platform-page-head h2 {
  font-size: clamp(1.5rem, 4.4vw, 2rem);
  font-weight: 740;
  letter-spacing: -0.032em;
  color: var(--mdx-ink);
}
body.mdx .platform-page-head p { color: var(--mdx-muted); }
body.mdx .eyebrow {
  color: var(--mdx-gold);
  font-size: 0.66rem;
  font-weight: 760;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

/* One card treatment across every screen, so Deck, Battle, Library and
   Settings finally look like the same product. */
body.mdx .deck-card,
body.mdx .library-stat-grid > article,
body.mdx .redeem-panel,
body.mdx .resume-panel,
body.mdx .home2-continue,
body.mdx .home2-card,
body.mdx .practice-stat-grid > article,
body.mdx .clinical-profile-screen .profile-card,
body.mdx .battle-home .battle-mode-card {
  background: var(--mdx-surface);
  border: 1px solid var(--mdx-hair);
  border-radius: var(--mdx-r);
  box-shadow: var(--mdx-lift-1);
  transition: transform 0.22s var(--mdx-ease), box-shadow 0.24s var(--mdx-ease), border-color 0.22s var(--mdx-ease);
}
body.mdx .deck-card:hover,
body.mdx .home2-card:hover,
body.mdx .battle-home .battle-mode-card:hover {
  transform: translateY(-2px);
  box-shadow: var(--mdx-lift-2);
  border-color: rgba(23, 105, 255, 0.2);
}

body.mdx .primary-button {
  border-radius: var(--mdx-r-pill);
  background: linear-gradient(180deg, #2f7bff, var(--mdx-blue));
  border: 0;
  color: #fff;
  font-weight: 660;
  letter-spacing: -0.012em;
  box-shadow: 0 2px 8px rgba(23, 105, 255, 0.3);
  transition: transform 0.18s var(--mdx-ease), box-shadow 0.22s var(--mdx-ease);
}
body.mdx .primary-button:hover { box-shadow: 0 6px 20px rgba(23, 105, 255, 0.38); }
body.mdx .primary-button:active { transform: scale(0.975); }
body.mdx .ghost-button {
  border-radius: var(--mdx-r-pill);
  border: 1px solid var(--mdx-hair);
  background: rgba(255, 255, 255, 0.9);
  color: var(--mdx-ink-2);
  font-weight: 620;
}
body.mdx .ghost-button:hover { background: #fff; color: var(--mdx-ink); border-color: var(--mdx-hair-strong); }

body.mdx input[type="text"],
body.mdx input[type="email"],
body.mdx input[type="search"],
body.mdx input[type="number"],
body.mdx select,
body.mdx textarea {
  border-radius: var(--mdx-r-sm);
  border: 1px solid var(--mdx-hair);
  background: #fff;
  color: var(--mdx-ink);
}
body.mdx input:focus-visible,
body.mdx select:focus-visible,
body.mdx textarea:focus-visible {
  outline: 0;
  border-color: rgba(23, 105, 255, 0.45);
  box-shadow: 0 0 0 4px rgba(23, 105, 255, 0.1);
}

/* ==========================================================================
   7. Library — the one screen that gained sub-navigation
   ==========================================================================
   The classic dashboard (progress, XP, continue-learning) is not deleted by
   making Lens the home; it moves here, behind a segmented control, so every
   entry point that used to live on the home screen is still reachable.
   ========================================================================== */

.mdx-seg {
  display: inline-flex;
  gap: 3px;
  padding: 4px;
  margin: 0 0 16px;
  border-radius: var(--mdx-r-pill);
  background: var(--mdx-surface-sunken);
  border: 1px solid var(--mdx-hair);
}
.mdx-seg[hidden] { display: none; }
.mdx-seg-btn {
  padding: 8px 16px;
  border: 0;
  border-radius: var(--mdx-r-pill);
  background: transparent;
  color: var(--mdx-muted);
  font-size: 0.82rem;
  font-weight: 640;
  letter-spacing: -0.012em;
  transition: background 0.24s var(--mdx-ease), color 0.2s var(--mdx-ease), box-shadow 0.24s var(--mdx-ease);
}
.mdx-seg-btn[aria-selected="true"] {
  background: #fff;
  color: var(--mdx-ink);
  box-shadow: 0 1px 2px rgba(14, 23, 38, 0.06), 0 2px 8px rgba(14, 23, 38, 0.06);
}

/* ==========================================================================
   8. Toast — quiet confirmations, never a modal
   ========================================================================== */

.mdx-toast-host {
  position: fixed;
  z-index: 2580;
  left: 50%;
  transform: translateX(-50%);
  bottom: calc(var(--mdx-bottom-budget) + 8px);
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: center;
  pointer-events: none;
  width: min(520px, calc(100vw - 24px));
}
.mdx-toast {
  max-width: 100%;
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 11px 16px;
  border-radius: var(--mdx-r-pill);
  background: var(--mdx-glass);
  -webkit-backdrop-filter: var(--mdx-glass-blur);
  backdrop-filter: var(--mdx-glass-blur);
  border: 1px solid var(--mdx-glass-edge);
  box-shadow: var(--mdx-glass-shadow);
  color: var(--mdx-ink);
  font-size: 0.83rem;
  font-weight: 600;
  letter-spacing: -0.012em;
  animation: mdxToastIn 0.36s var(--mdx-ease-spring) both;
}
.mdx-toast.is-out { animation: mdxToastOut 0.26s var(--mdx-ease) both; }
.mdx-toast svg { width: 16px; height: 16px; flex: none; }
.mdx-toast.is-ok svg { color: var(--mdx-green); }
.mdx-toast.is-warn svg { color: var(--mdx-red); }
@keyframes mdxToastIn { from { opacity: 0; transform: translateY(14px) scale(0.96); } to { opacity: 1; transform: none; } }
@keyframes mdxToastOut { to { opacity: 0; transform: translateY(8px) scale(0.98); } }

/* ==========================================================================
   9. Accessibility, motion and dark mode
   ========================================================================== */

body.mdx :focus-visible {
  outline: 2px solid var(--mdx-blue);
  outline-offset: 2px;
  border-radius: 6px;
}

.mdx-sr {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

@media (prefers-reduced-motion: reduce) {
  body.mdx *,
  body.mdx *::before,
  body.mdx *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

/* Backdrop-filter is not universal. Without it, translucent glass turns into
   an unreadable smear over content, so those surfaces go solid instead. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .mdx-rail,
  .mdx-bar,
  .mdx-sheet,
  .mdx-toast,
  .mdx-lens-controls {
    background: rgba(255, 255, 255, 0.985);
  }
}

/* The existing dark mode stays a first-class option: the same structure,
   inverted materials. Glass keeps its role; only its tint changes. */
body.mdx.dark-mode {
  --mdx-canvas: #0a0f17;
  --mdx-surface: #121a26;
  --mdx-surface-2: #0f1620;
  --mdx-surface-sunken: #0c131c;
  --mdx-ink: #f2f6fb;
  --mdx-ink-2: #cbd6e5;
  --mdx-muted: #93a1b5;
  --mdx-faint: #6c7b90;
  --mdx-hair: rgba(226, 232, 240, 0.12);
  --mdx-hair-strong: rgba(226, 232, 240, 0.2);
  --mdx-glass: linear-gradient(177deg, rgba(26, 35, 49, 0.86) 0%, rgba(18, 26, 38, 0.78) 100%);
  --mdx-legal: #9aa8bd;
  --mdx-legal-link: #dbe4f0;
  --mdx-glass-edge: rgba(226, 232, 240, 0.14);
  --mdx-glass-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.07),
    0 16px 44px rgba(0, 0, 0, 0.5);
  --mdx-glass-shadow-lift:
    inset 0 1px 0 rgba(255, 255, 255, 0.07),
    0 28px 70px rgba(0, 0, 0, 0.6);
  --mdx-lift-1: 0 1px 2px rgba(0, 0, 0, 0.3), 0 2px 10px rgba(0, 0, 0, 0.26);
  --mdx-lift-2: 0 2px 6px rgba(0, 0, 0, 0.34), 0 12px 34px rgba(0, 0, 0, 0.4);
  background:
    radial-gradient(1200px 620px at 12% -8%, rgba(23, 105, 255, 0.1), transparent 62%),
    linear-gradient(180deg, #0b111a 0%, #0a0f17 60%, #0c1017 100%);
}
body.mdx.dark-mode .mdx-bar-field,
body.mdx.dark-mode .mdx-bar-btn,
body.mdx.dark-mode .mdx-chip,
body.mdx.dark-mode .mdx-tool {
  background: rgba(255, 255, 255, 0.06);
  color: var(--mdx-ink-2);
}
body.mdx.dark-mode .mdx-rail-btn.is-active {
  background: rgba(255, 255, 255, 0.1);
  box-shadow: none;
}
body.mdx.dark-mode .lens-screen .lens-stage {
  background: radial-gradient(120% 90% at 50% 0%, #131b26 0%, #0b111a 60%, #080d14 100%);
}
body.mdx.dark-mode .lens-screen .lens-sheet .lens-sheet-panel,
body.mdx.dark-mode #lspSheet {
  background: rgba(18, 26, 38, 0.97) !important;
}

/* ==========================================================================
   10. Small screens
   ========================================================================== */

@media (max-width: 400px) {
  .mdx-bar { width: calc(100vw - 16px); }
  .mdx-rail { gap: 2px; padding: 5px; }
  .mdx-rail-btn { min-width: 42px; height: 42px; padding: 0 9px; }
  .mdx-bar-btn { width: 40px; height: 40px; }
  .mdx-bar-field { height: 40px; }
  .mdx-shutter { width: 50px; height: 50px; }
}

/* Landscape phones have almost no vertical room; the floating chrome must
   not eat the workspace. */
@media (max-height: 480px) and (orientation: landscape) {
  /* Everything is shorter, nothing moves: the navigation is persistent and
     stays at the bottom, so the composer sits above it exactly as it does in
     portrait — just tighter. */
  body.mdx .bottom-nav.mdx-nav { height: 50px; }
  body.mdx .mdx-bar { bottom: calc(6px + var(--mdx-rail-h) + 6px + env(safe-area-inset-bottom, 0px)); }
  .mdx-switch { bottom: calc(var(--mdx-bar-h) + var(--mdx-rail-h) + 20px + env(safe-area-inset-bottom, 0px)); }
  .mdx-switch-btn { height: 30px; width: 88px; font-size: 0.78rem; }
}

/* ==========================================================================
   11. OSCE — the patient conversation moves into the universal bar
   ==========================================================================
   When a station is running, the MedDex Bar becomes the patient composer.
   The station's own inline form is hidden rather than removed: the bar
   submits through it, so scoring, evidence capture and the per-turn model
   call are the same code path as before. If the shell is disabled, the class
   is never applied and the inline composer returns.
   ========================================================================== */

body.mdx.mdx-osce-chat #osceAsk { display: none !important; }
body.mdx.mdx-osce-chat .osce-convo-hint { margin-bottom: 2px; }
body.mdx #osceRoot { padding-bottom: var(--mdx-bottom-budget); }

/* The OSCE chat log sizes itself to the viewport minus everything above it,
   on the assumption that the whole station fits on one screen. It does not
   have to any more: #osceRoot carries the floating chrome's budget as bottom
   padding, so the page can scroll the log clear of the bar. That buys the
   conversation more room than the classic layout had, not less — subtracting
   the bar's height on top of the old constant left a 180px log. */
body.mdx #osceRoot .osce-chat {
  height: clamp(240px, calc(100dvh - 560px), 480px);
}

/* Content screens must clear the floating chrome, whatever owns their
   scroll container. */
body.mdx .screen { scroll-padding-bottom: var(--mdx-bottom-budget); }
body.mdx .practice-screen,
body.mdx .cards-screen,
body.mdx .battle-home,
body.mdx .clinical-profile-screen,
body.mdx .home2 { padding-bottom: 12px; }

/* ==========================================================================
   12. Reconciling with the floating AI companion
   ==========================================================================
   The classic build has a permanently floating Baihaqi orb pinned above the
   bottom nav at z-index 13000. With a rail that has a Baihaqi AI destination
   and a bar whose field is literally "Ask Baihaqi AI", a third floating entry
   point is both redundant and the only thing that would sit on top of the
   MedDex Bar. The orb goes; the companion's tips and its chat surface stay,
   lifted clear of the floating chrome.
   ========================================================================== */

body.mdx .ai-floating-button,
body.mdx .baihaqi-quick-actions { display: none !important; }

body.mdx #aiCompanionContainer {
  bottom: calc(var(--mdx-bottom-budget) + 6px) !important;
  z-index: 2510 !important;
}
body.mdx #aiCompanionContainer.hidden { display: none !important; }

/* The chat card and the fullscreen surface own the screen when open, so they
   must clear the shell rather than sit under it. */
body.mdx #baihaqiChat { z-index: 2600 !important; }

/* The coach-mark spotlight points at nav targets that are now hidden. Keeping
   it above the shell means it can still highlight in-screen targets. */
body.mdx .ai-companion-container.is-guiding { z-index: 30000 !important; }

/* ==========================================================================
   13. The capture row
   ==========================================================================
   Getting an image in and asking a question are both primary on Lens, so
   they get a row each rather than fighting over one.
   ========================================================================== */

.mdx-bar-capture {
  justify-content: center;
  gap: 22px;
  padding: 2px 10px 11px;
}
.mdx-bar-capture:empty { display: none; }

/* The modality pill and the credits badge share the floating header slot.
   Unstyled, the badge rendered above the pill and collided with the floating
   controls; stacking them puts the pill first and demotes the badge to the
   quiet hint it is. */
body.mdx .lens-screen .lens-modes-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 7px;
}
body.mdx .lens-screen #lensUsageBadge {
  order: 2;
  margin: 0;
  padding: 5px 12px;
  max-width: min(320px, calc(100vw - 40px));
  border-radius: var(--mdx-r-pill);
  background: var(--mdx-glass);
  -webkit-backdrop-filter: var(--mdx-glass-blur);
  backdrop-filter: var(--mdx-glass-blur);
  border: 1px solid var(--mdx-glass-edge);
  box-shadow: var(--mdx-glass-shadow);
  color: var(--mdx-muted);
  font-size: 0.72rem;
  font-weight: 600;
  line-height: 1.35;
  text-align: center;
}
body.mdx .lens-screen .lens-modality-pill { order: 1; }

/* ==========================================================================
   14. The expanded rail
   ==========================================================================
   Seven destinations, a separator, a "+" and a text label do not fit across a
   375px phone — the first attempt overflowed both edges. Expanded, the rail
   drops its chrome and becomes seven equal icon+label columns sized off the
   viewport, so it fits from 320px up without ever scrolling.
   ========================================================================== */

.mdx-rail[data-state="expanded"] {
  gap: 2px;
  padding: 5px;
  border-radius: 24px;
}
.mdx-rail[data-state="expanded"] .mdx-rail-sep,
.mdx-rail[data-state="expanded"] .mdx-rail-more { display: none; }

.mdx-rail[data-state="expanded"] .mdx-rail-btn {
  flex-direction: column;
  gap: 1px;
  width: clamp(38px, 12.1vw, 46px);
  min-width: 0;
  max-width: none;
  height: 50px;
  padding: 0;
}
.mdx-rail[data-state="expanded"] .mdx-rail-btn svg { width: 19px; height: 19px; }
.mdx-rail[data-state="expanded"] .mdx-rail-label {
  max-width: none;
  opacity: 1;
  font-size: 0.545rem;
  font-weight: 680;
  letter-spacing: -0.015em;
  line-height: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  width: 100%;
  text-align: center;
}
/* The gold underline would collide with the label in this state. */
.mdx-rail[data-state="expanded"] .mdx-rail-btn.is-active::after { display: none; }
.mdx-rail[data-state="expanded"] .mdx-rail-btn.is-active {
  background: var(--mdx-blue-wash);
  box-shadow: none;
}
.mdx-rail[data-state="expanded"] .mdx-rail-badge { top: 2px; right: 2px; }

/* Desktop keeps the always-open vertical rail, so the expanded layout must
   not leak into it. */
@media (min-width: 1024px) {
  .mdx-rail[data-state="expanded"] .mdx-rail-btn {
    flex-direction: row;
    width: 46px;
    height: 46px;
  }
  .mdx-rail[data-state="expanded"] .mdx-rail-label { display: none; }
}

/* A horizontally scrolling chip strip has to say so. The trailing inset keeps
   the last chip from sitting flush against the glass edge, which is what made
   "Finish station" read as clipped rather than scrollable. */
.mdx-bar-chips { padding-right: 20px; scroll-padding-inline: 11px; }
.mdx-bar-chips::after {
  content: "";
  flex: none;
  width: 1px;
}

/* ==========================================================================
   15. Brand anchor
   ==========================================================================
   The classic topbar carried the wordmark and the shell hides it. On desktop
   the rail is the one persistent surface, so the monogram sits at its head —
   the only place in the navigation where the gold is used as a fill rather
   than as a hairline.
   ========================================================================== */

.mdx-rail-brand { display: none; }

@media (min-width: 1024px) {
  .mdx-rail-brand {
    display: flex;
    align-items: center;
    justify-content: center;
    order: -1;
    width: 46px;
    height: 34px;
    margin-bottom: 4px;
    padding-bottom: 6px;
    border-bottom: 1px solid var(--mdx-hair);
    font-size: 1.02rem;
    font-weight: 800;
    letter-spacing: -0.04em;
    background: linear-gradient(145deg, #e0bd63 0%, var(--mdx-gold) 48%, #a8811f 100%);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: var(--mdx-gold);
  }
}

/* ==========================================================================
   16. The progress hero
   ==========================================================================
   The dashboard hero is the one surviving element of the old visual language:
   a saturated blue-violet gradient card with white text. It now sits inside
   Library → Progress, surrounded by porcelain, where it read as a leftover
   from a different product. Same information, same markup, MedDex materials.
   ========================================================================== */

body.mdx .home2-hero {
  background:
    radial-gradient(120% 140% at 8% 0%, rgba(23, 105, 255, 0.09), transparent 58%),
    radial-gradient(110% 130% at 96% 6%, rgba(200, 163, 74, 0.13), transparent 55%),
    linear-gradient(168deg, #ffffff 0%, #fbfcfe 58%, #faf8f3 100%);
  border: 1px solid var(--mdx-hair);
  border-radius: var(--mdx-r-lg);
  box-shadow: var(--mdx-lift-1);
  color: var(--mdx-ink);
}
body.mdx .home2-hero-glow { display: none; }

body.mdx .home2-greeting { color: var(--mdx-muted); font-weight: 620; }
body.mdx .home2-motivation {
  color: var(--mdx-ink);
  font-weight: 740;
  letter-spacing: -0.03em;
}
body.mdx .home2-xp-head { color: var(--mdx-muted); }
body.mdx .home2-xp-head strong { color: var(--mdx-ink); }
body.mdx .home2-xp-track {
  background: var(--mdx-surface-sunken);
  border: 1px solid var(--mdx-hair);
}
body.mdx .home2-xp-fill {
  background: linear-gradient(90deg, var(--mdx-blue), #58a0ff 70%, var(--mdx-gold));
}
body.mdx .home2-chip {
  background: rgba(255, 255, 255, 0.86);
  border: 1px solid var(--mdx-hair);
  border-radius: var(--mdx-r-sm);
  box-shadow: none;
}
body.mdx .home2-chip span { color: var(--mdx-faint); }
body.mdx .home2-chip strong { color: var(--mdx-ink); }

/* The continue-learning card keeps its emphasis, in the new palette. */
body.mdx .home2-continue { border-left: 3px solid var(--mdx-gold); }
body.mdx .home2-continue-ic {
  background: var(--mdx-blue-wash);
  color: var(--mdx-blue);
}

body.mdx.dark-mode .home2-hero {
  background:
    radial-gradient(120% 140% at 8% 0%, rgba(23, 105, 255, 0.16), transparent 58%),
    linear-gradient(168deg, #16202e 0%, #121a26 100%);
}
body.mdx.dark-mode .home2-chip { background: rgba(255, 255, 255, 0.05); }

/* ==========================================================================
   17. Post-analysis layout — nothing overlaps
   ==========================================================================
   MEASURED DEFECT (mobile, 375x812, after a Lens read):

     report sheet panel  617 → 1348   (peek 617–812)
     MedDex Bar          630 →  734
     rail                744 →  798

   Of the report's 195px peek, 182px sat under the floating chrome: the sheet
   head, its grabber, the overlay-control row and the report actions were all
   unreachable, and the spatial rail was pressed against the bar's edge.

   The sheet is positioned by app.js in dvh snap points that know nothing
   about the shell. Rather than fight it, the shell reserves its own height at
   the bottom of the Lens screen and shifts all three snap points up by
   exactly that much, so the peek, the medium stop and the full stop keep
   their intended visible heights and every one of them clears the chrome.
   app.js reads the same number (window.__mdxExperience.bottomBudgetPx) when
   it drives a drag, so dragging and resting agree.
   ========================================================================== */

body.mdx .lens-v2 {
  --lens-sheet-panel-h: calc(90dvh - var(--mdx-bottom-budget));
  /* These MUST match LENS_SNAP_OFFSET_DVH in app.js. A drag is driven by the
     JS numbers and the resting position by these, so if they disagree the
     sheet jumps the moment a finger lifts. Medium is the working stop: half
     image, half the findings that matter. */
  /* No bottom-budget subtraction: see lensSnapOffsetPx in app.js. The chrome
     recedes at the collapsed and full stops, and the sheet's scroller already
     pads for it, so subtracting here reserved the same space twice and pushed
     every stop about twenty points low. */
  --lens-snap-collapsed: 74dvh;
  --lens-snap-medium: 50dvh;
  --lens-snap-full: 0px;
}
body.mdx .lens-v2 .lens-sheet {
  bottom: var(--mdx-bottom-budget);
  /* The panel is translated DOWN inside this container and, unclipped, kept
     painting past it — so the report still ran underneath the bar even after
     the container was lifted. Clipping to the container is also what makes
     each stop show exactly its intended height: collapsed 24dvh, medium
     55dvh, full the whole panel. */
  overflow: hidden;
  border-radius: 26px 26px 0 0;
}

/* The Spatial Intelligence rail and its detail sheet are positioned inside
   the Lens stage and likewise know nothing of the floating chrome.

   The rail controls what is drawn ON THE IMAGE, so it belongs above the
   report sheet's peek, not on top of its head — clearing only the bar put it
   at y=586, right across the sheet title. The collapsed peek is 24dvh by
   construction (panel 90dvh, collapsed stop 66dvh), so that is what it
   clears. Above the collapsed stop the sheet owns the lower screen and the
   rail steps aside rather than fighting it for space. */
body.mdx #lspRail {
  bottom: calc(var(--mdx-bottom-budget) + 24dvh + 10px) !important;
  padding-left: 10px !important;
  padding-right: 10px !important;
  transition: opacity 0.28s var(--mdx-ease), bottom 0.36s var(--mdx-ease);
}
body.mdx .lens-v2:has(.lens-sheet.hidden) #lspRail {
  bottom: calc(var(--mdx-bottom-budget) + 10px) !important;
}
body.mdx .lens-v2:has(.lens-sheet[data-snap="medium"]) #lspRail {
  opacity: 0;
  pointer-events: none;
}
body.mdx #lspSheet {
  bottom: var(--mdx-bottom-budget) !important;
  max-height: calc(100dvh - var(--mdx-bottom-budget) - 90px) !important;
  overflow-y: auto !important;
}

/* When the report is fully expanded the rail would sit on top of it; the
   sheet already carries the layer controls' meaning at that point. */
body.mdx .lens-v2:has(.lens-sheet[data-snap="full"]) #lspRail {
  opacity: 0;
  pointer-events: none;
}

/* ==========================================================================
   18. One control, one place
   ==========================================================================
   The redesign gave several Lens controls a second home. Each of these is the
   copy that is now redundant; the function itself is untouched and the shell
   still presses these exact elements.
   ========================================================================== */

/* Zoom / zoom out / rotate / fullscreen — the shell's floating glass group
   (#mdxLensRight) is the canonical one. This is the dark stack that appeared
   beside it on the right edge of the image. */
body.mdx .lens-screen .lens-viewer-controls { display: none !important; }

/* Anatomy · Pathology · Refine outlines · Compare original. Refine and
   Compare are MedDex Bar chips; both layer toggles live in + Tools →
   Spatial map. The row itself sat under the bar and was unreachable anyway. */
body.mdx .lens-screen .lens-overlay-controls { display: none !important; }

/* Save Image · Export PDF · Share — Export PDF is a bar chip, all three are
   in + Tools → Save & export. */
body.mdx .lens-screen #lensReportActions { display: none !important; }

/* Save to notes · Add to revision — both are in + Tools → Save & export. */
body.mdx .lens-screen .lens-sheet-head-actions { display: none !important; }

/* ==========================================================================
   19. Baihaqi AI — a layer over the page, not a page of its own
   ==========================================================================
   The classic surface is a full-screen dark console with its own composer,
   which is what made Baihaqi feel like a separate product. Here it is a
   warm-white Liquid Glass sheet that rises over whatever you were doing, with
   the page still visible and dimmed behind it, and with the MedDex Bar as its
   composer — the same bar, in another context.
   ========================================================================== */

body.mdx.mdx-ai-open::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 2505;
  background: rgba(20, 26, 36, 0.32);
  -webkit-backdrop-filter: blur(3px) saturate(115%);
  backdrop-filter: blur(3px) saturate(115%);
  animation: mdxFade 0.32s var(--mdx-ease) both;
  pointer-events: none;
}
@keyframes mdxFade { from { opacity: 0; } to { opacity: 1; } }

body.mdx .bfs {
  /* From full-screen console to bottom sheet. */
  inset: auto 0 var(--mdx-bottom-budget) 0 !important;
  left: 50% !important;
  right: auto !important;
  transform: translateX(-50%) translateY(14px) !important;
  width: min(720px, calc(100vw - 16px)) !important;
  height: min(72dvh, calc(100dvh - var(--mdx-bottom-budget) - 72px)) !important;
  z-index: 2510 !important;
  display: flex;
  flex-direction: column;
  border-radius: 28px !important;
  /* A reading surface, not a navigation surface: glass here is warm white and
     nearly opaque, because a long clinical answer read through a blurred
     radiograph is unreadable. The blur stays so it still belongs to the
     material family. */
  background: linear-gradient(178deg, rgba(255, 253, 250, 0.96) 0%, rgba(252, 253, 255, 0.94) 60%, rgba(250, 248, 243, 0.96) 100%) !important;
  -webkit-backdrop-filter: var(--mdx-glass-blur) !important;
  backdrop-filter: var(--mdx-glass-blur) !important;
  border: 1px solid var(--mdx-glass-edge) !important;
  box-shadow: var(--mdx-glass-shadow-lift) !important;
  color: var(--mdx-ink) !important;
  overflow: hidden;
  opacity: 0;
  transition: opacity 0.3s var(--mdx-ease), transform 0.42s var(--mdx-ease-spring);
}
body.mdx .bfs.active {
  opacity: 1 !important;
  transform: translateX(-50%) translateY(0) !important;
}

/* The dark decorative field belongs to the console, not to a glass sheet. */
body.mdx .bfs .bfs-bg { display: none !important; }

body.mdx .bfs .bfs-header {
  flex: 0 0 auto;
  padding: 12px 14px 10px;
  border-bottom: 1px solid var(--mdx-hair);
}
body.mdx .bfs .bfs-avatar {
  width: 40px;
  height: 40px;
  background: var(--mdx-blue-wash) !important;
  box-shadow: inset 0 0 0 1px rgba(23, 105, 255, 0.16) !important;
}
body.mdx .bfs .bfs-id strong { color: var(--mdx-ink) !important; font-size: 0.96rem; font-weight: 720; letter-spacing: -0.02em; }
body.mdx .bfs .bfs-id span { color: var(--mdx-muted) !important; font-weight: 600; }
body.mdx .bfs .bfs-icon-btn {
  background: rgba(255, 255, 255, 0.9) !important;
  border: 1px solid var(--mdx-hair);
  color: var(--mdx-muted) !important;
}
body.mdx .bfs .bfs-icon-btn:hover { color: var(--mdx-ink) !important; background: #fff !important; }

body.mdx .bfs .bfs-log {
  flex: 1 1 auto;
  min-height: 0;
  padding: 14px 14px 18px;
  overscroll-behavior: contain;
}
body.mdx .bfs .bfs-log .bchat-msg {
  font-size: 0.875rem;
  line-height: 1.55;
  border-radius: 18px;
}
body.mdx .bfs .bfs-log .bchat-user {
  background: linear-gradient(180deg, #2f7bff, var(--mdx-blue)) !important;
  color: #fff !important;
  font-weight: 560 !important;
  box-shadow: 0 2px 10px rgba(23, 105, 255, 0.26);
}
body.mdx .bfs .bfs-log .bchat-assistant {
  background: rgba(255, 255, 255, 0.92) !important;
  border: 1px solid var(--mdx-hair) !important;
  color: var(--mdx-ink-2) !important;
  -webkit-backdrop-filter: none !important;
  backdrop-filter: none !important;
}

/* One composer in the product. The sheet's own is retired; the MedDex Bar
   below it submits through this exact form, so history, voice, mascot state
   and the send path are all unchanged. */
body.mdx .bfs .bfs-composer { display: none !important; }

body.mdx.dark-mode .bfs {
  background: linear-gradient(178deg, rgba(22, 30, 42, 0.97), rgba(16, 23, 33, 0.96)) !important;
}
body.mdx.dark-mode .bfs .bfs-log .bchat-assistant {
  background: rgba(255, 255, 255, 0.07) !important;
  color: var(--mdx-ink-2) !important;
}

/* The context pill is a statement of fact, not an action. */
.mdx-chip-context {
  background: var(--mdx-gold-wash);
  border-color: rgba(200, 163, 74, 0.34);
  color: #8a6d1c;
  cursor: default;
  pointer-events: none;
}
.mdx-chip-context svg { opacity: 1; }

@media (min-width: 1024px) {
  body.mdx .bfs { left: calc(50% + 40px) !important; }
}

/* ==========================================================================
   20. The Lens result reads as one page
   ==========================================================================
   The report was a drag-snap sheet with its own inner scroll sitting over a
   fixed, non-scrolling stage. That is two scrollers and a gesture arbiter in
   the same column: on iOS the sheet's drag competes with the list's momentum,
   and the only way to see the report at all was to pull it over the image.

   On a result the screen becomes ONE document. The image is the first thing
   in it and keeps the top of the viewport; the report flows underneath and is
   reached by scrolling the page, like any other page. The snap transforms,
   the inner scroller and the drag handle are all switched off, so there is
   exactly one thing that scrolls and nothing to arbitrate.

   Capture mode is untouched — it stays the fixed, immersive viewfinder.
   ========================================================================== */

/* THE IMAGE IS THE WORKSPACE.
   ---------------------------------------------------------------------------
   This block used to turn the result into one long document: the stage became
   the first block of a scrolling page and the sheet joined the flow beneath
   it. Reading the report therefore scrolled the image off the top, and getting
   back to it meant scrolling up through the whole write-up. The analysis had
   become the page, and the film had become a header.

   The image is now a persistent canvas and the report is a sheet over it, with
   three stops the reader can drag between at any time. app.js already owned a
   full snap system — three points, velocity flicks, per-image memory — which
   this stylesheet had been overriding into inertness. It is switched back on
   rather than rebuilt. */
body.mdx.mdx-lens-result .lens-screen.lens-v2 {
  /* The screen itself no longer scrolls; the sheet's own scroller does. */
  overflow: hidden;
  display: block;
  position: relative;
}

/* The stage holds the full viewport behind the sheet, so the image is still
   there at every stop instead of being a band at the top of a document. */
body.mdx.mdx-lens-result .lens-v2 .lens-stage {
  position: absolute;
  inset: 0;
  width: 100%;
  height: auto;
  min-height: 0;
}

/* The sheet is back to being a sheet.
   ---------------------------------------------------------------------------
   POINTER-EVENTS ON THE CONTAINER IS THE BUG THAT KILLED THE VIEWER.
   .lens-sheet is a positioning box; the thing a reader can actually see and
   touch is .lens-sheet-panel inside it, which is 100dvh tall and translated
   DOWN to its snap stop. The container is not translated, so its hit box
   stays the full height of the screen — 362x844 measured. With
   pointer-events:auto and z-index 30 on the container, that invisible box sat
   over the image, the spatial layer and the viewer toolbar and swallowed every
   tap. Nothing below it could be clicked at all.

   The container is now transparent to pointers and the panel takes them, so
   the hit area matches what is actually drawn. */
body.mdx.mdx-lens-result .lens-v2 .lens-sheet {
  position: absolute;
  inset: auto 0 0 0;
  overflow: visible;
  pointer-events: none;
  z-index: 30;
}
body.mdx.mdx-lens-result .lens-v2 .lens-sheet-panel { pointer-events: auto; }
body.mdx.mdx-lens-result .lens-v2 .lens-sheet-panel {
  height: 100dvh;
  max-height: 100dvh;
  border-radius: 26px 26px 0 0;
  box-shadow: 0 -2px 10px rgba(14, 23, 38, 0.06), 0 -18px 44px rgba(14, 23, 38, 0.14);
  /* Snap transforms come from app.js; only the easing is stated here so a
     released drag and a programmatic snap settle identically. */
  transition: transform 0.42s var(--mdx-ease-spring);
}
body.mdx.mdx-lens-result .lens-v2 .lens-sheet-panel.is-dragging { transition: none; }
body.mdx.mdx-lens-result .lens-v2 .lens-sheet-scroll {
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  /* Contained, so reaching the top of the report hands the gesture back to the
     sheet instead of scrolling the page behind it. */
  overscroll-behavior-y: contain;
  max-height: calc(100dvh - 56px);
  padding-bottom: calc(var(--mdx-bottom-budget) + 24px);
}
/* The grabber is the affordance for all of the above; it comes back. */
body.mdx.mdx-lens-result .lens-v2 .lens-sheet-grabber {
  display: block;
  cursor: grab;
  touch-action: none;
}
body.mdx.mdx-lens-result .lens-v2 .lens-sheet-panel.is-dragging .lens-sheet-grabber { cursor: grabbing; }

/* At the collapsed stop the sheet is a lip over a full-bleed image, so the
   report surface must not wash the film out behind it. */
body.mdx.mdx-lens-result[data-lens-sheet="collapsed"] .lens-v2 .lens-sheet-panel {
  box-shadow: 0 -2px 10px rgba(14, 23, 38, 0.1), 0 -22px 50px rgba(14, 23, 38, 0.2);
}

/* Floating chrome that would sit over the image is pinned to the stage
   instead, so it scrolls away with the image rather than following the
   reader down the report. */
body.mdx.mdx-lens-result #lspRail {
  position: absolute !important;
  bottom: 12px !important;
  left: 10px !important;
  right: 10px !important;
}
body.mdx.mdx-lens-result #lspSheet {
  position: fixed !important;
  bottom: calc(var(--mdx-rail-h) + 26px + env(safe-area-inset-bottom, 0px)) !important;
}
/* The viewer controls belong to the image, so they travel with it. */
body.mdx.mdx-lens-result .mdx-lens-controls {
  position: absolute;
  top: 12px;
}
body.mdx.mdx-lens-result .mdx-lens-controls.is-left { left: 12px; }
body.mdx.mdx-lens-result .mdx-lens-controls.is-right { right: 12px; }
body.mdx.mdx-lens-result .lens-v2 .lens-modes-wrap {
  position: absolute;
  top: 62px;
}

/* ==========================================================================
   21. Result actions, in the flow
   ========================================================================== */

.mdx-actions {
  display: flex;
  gap: 8px;
  padding: 4px 20px 14px;
  margin: 0;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  scrollbar-width: none;
  -ms-overflow-style: none;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
}
.mdx-actions::-webkit-scrollbar { display: none; }
.mdx-actions .mdx-chip { scroll-snap-align: start; height: 36px; font-size: 0.8rem; }
.mdx-actions::after { content: ""; flex: none; width: 8px; }

/* The strip must look swipeable, not clipped: the last chip fades under a
   soft edge so there is visibly more to the right. */
body.mdx.mdx-lens-result .lens-sheet-panel { position: relative; }
.mdx-actions {
  -webkit-mask-image: linear-gradient(90deg, #000 0, #000 calc(100% - 26px), transparent 100%);
  mask-image: linear-gradient(90deg, #000 0, #000 calc(100% - 26px), transparent 100%);
}

/* ==========================================================================
   22. The Baihaqi mark
   ========================================================================== */

.mdx-ai-fab {
  position: fixed;
  z-index: 2515;
  right: 14px;
  bottom: calc(var(--mdx-rail-h) + 28px + env(safe-area-inset-bottom, 0px));
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 48px;
  padding: 0 16px 0 8px;
  border: 1px solid var(--mdx-glass-edge);
  border-radius: var(--mdx-r-pill);
  background: var(--mdx-glass);
  -webkit-backdrop-filter: var(--mdx-glass-blur);
  backdrop-filter: var(--mdx-glass-blur);
  box-shadow: var(--mdx-glass-shadow);
  color: var(--mdx-ink);
  font-size: 0.83rem;
  font-weight: 650;
  letter-spacing: -0.014em;
  animation: mdxFabIn 0.42s var(--mdx-ease-spring) both;
  transition: transform 0.2s var(--mdx-ease), box-shadow 0.24s var(--mdx-ease);
}
.mdx-ai-fab[hidden] { display: none; }
.mdx-ai-fab:hover { box-shadow: var(--mdx-glass-shadow-lift); }
.mdx-ai-fab:active { transform: scale(0.96); }
.mdx-ai-fab-ic {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  flex: none;
  border-radius: 50%;
  background: linear-gradient(180deg, rgba(23, 105, 255, 0.14), rgba(200, 163, 74, 0.14));
  color: var(--mdx-blue);
}
.mdx-ai-fab-ic svg { width: 18px; height: 18px; }
@keyframes mdxFabIn { from { opacity: 0; transform: translateY(12px) scale(0.9); } to { opacity: 1; transform: none; } }

@media (max-width: 360px) {
  .mdx-ai-fab-text { display: none; }
  .mdx-ai-fab { padding: 0 8px; }
}

/* ==========================================================================
   23. Teaching overlay
   ==========================================================================
   Dashed = built from AI-estimated landmarks. Solid = built from a boundary
   or a point the reader placed. The distinction is the whole point, so it is
   carried in the stroke and not only in the legend.
   ========================================================================== */

.mdx-teach-svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 8;
  opacity: 0;
  transition: opacity 0.3s var(--mdx-ease);
}
body.mdx-teach-on .mdx-teach-svg { opacity: 1; }

.mdxt-line { fill: none; stroke-width: 3; stroke-linecap: round; }
.mdxt-estimated { stroke: #e0a53a; stroke-dasharray: 12 9; }
.mdxt-verified { stroke: #1769ff; }
.mdxt-reference { opacity: 0.72; stroke-width: 2.4; }
.mdxt-axis { stroke-dasharray: 4 8; opacity: 0.85; }
.mdxt-measure { stroke-width: 4; }
.mdxt-arc { fill: none; stroke-width: 2.6; }
.mdxt-dot { stroke: #fff; stroke-width: 2; }
.mdxt-dot.mdxt-estimated { fill: #e0a53a; }
.mdxt-dot.mdxt-verified { fill: #1769ff; }
.mdxt-cap, .mdxt-readout {
  font: 700 26px Inter, system-ui, sans-serif;
  paint-order: stroke;
  stroke: rgba(255, 255, 255, 0.92);
  stroke-width: 6;
  stroke-linejoin: round;
}
.mdxt-cap.mdxt-estimated, .mdxt-readout.mdxt-estimated { fill: #8a6d1c; }
.mdxt-cap.mdxt-verified, .mdxt-readout.mdxt-verified { fill: var(--mdx-blue-ink); }

.mdx-teach-legend {
  margin: 0 0 16px;
  padding: 14px 16px;
  border: 1px solid var(--mdx-hair);
  border-radius: var(--mdx-r);
  background: var(--mdx-surface-2);
}
.mdx-teach-legend h4 {
  margin: 0 0 6px;
  font-size: 0.9rem;
  font-weight: 720;
  letter-spacing: -0.02em;
  color: var(--mdx-ink);
}
.mdx-teach-note { margin: 0 0 10px; font-size: 0.74rem; line-height: 1.5; color: var(--mdx-muted); }
.mdx-teach-legend ul { margin: 0; padding: 0; list-style: none; display: grid; gap: 9px; }
.mdx-teach-legend li {
  padding: 9px 11px;
  border-radius: var(--mdx-r-sm);
  border: 1px solid var(--mdx-hair);
  background: #fff;
}
.mdx-teach-legend li.is-missing { opacity: 0.72; border-style: dashed; background: transparent; }
.mdx-teach-legend strong { display: block; font-size: 0.83rem; font-weight: 680; color: var(--mdx-ink); }
.mdx-teach-legend strong em {
  font-style: normal;
  margin-left: 6px;
  padding: 1px 7px;
  border-radius: 999px;
  background: var(--mdx-blue-wash);
  color: var(--mdx-blue-ink);
  font-size: 0.76rem;
  font-weight: 750;
}
.mdx-teach-legend span { display: block; margin-top: 3px; font-size: 0.755rem; line-height: 1.5; color: var(--mdx-muted); }
.mdx-teach-legend b {
  display: inline-block;
  margin-top: 6px;
  font-size: 0.68rem;
  font-weight: 750;
  letter-spacing: 0.03em;
  text-transform: uppercase;
}
.mdx-teach-legend li.is-estimated b { color: #8a6d1c; }
.mdx-teach-legend li.is-verified b { color: var(--mdx-green); }
.mdx-teach-legend li.is-missing b { color: var(--mdx-faint); }

/* ==========================================================================
   24. The entry screen
   ========================================================================== */

body.mdx .mdx-home { padding: 0; }
.mdx-home-inner {
  min-height: calc(100dvh - var(--mdx-bottom-budget) - 40px);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 4px;
  max-width: 720px;
  margin: 0 auto;
  padding: 24px 4px;
}
.mdx-home-mark {
  margin: 0 0 auto;
  padding-top: 8px;
  font-size: 0.78rem;
  font-weight: 800;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  background: linear-gradient(145deg, #e0bd63, var(--mdx-gold) 52%, #a8811f);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: var(--mdx-gold);
}
.mdx-home-title {
  margin: 0;
  font-size: clamp(1.75rem, 7vw, 2.5rem);
  font-weight: 740;
  letter-spacing: -0.038em;
  line-height: 1.08;
  color: var(--mdx-ink);
}
.mdx-home-sub {
  margin: 8px 0 26px;
  font-size: 1rem;
  color: var(--mdx-muted);
  letter-spacing: -0.012em;
}
.mdx-home-choices {
  display: grid;
  gap: 12px;
  margin-bottom: auto;
}
@media (min-width: 720px) {
  .mdx-home-choices { grid-template-columns: 1fr 1fr; }
}
.mdx-home-choice {
  display: block;
  text-align: left;
  padding: 20px;
  border-radius: var(--mdx-r-lg);
  border: 1px solid var(--mdx-hair);
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.96), rgba(252, 253, 255, 0.9));
  -webkit-backdrop-filter: var(--mdx-glass-blur);
  backdrop-filter: var(--mdx-glass-blur);
  box-shadow: var(--mdx-lift-1);
  transition: transform 0.24s var(--mdx-ease), box-shadow 0.26s var(--mdx-ease), border-color 0.24s var(--mdx-ease);
}
.mdx-home-choice:hover {
  transform: translateY(-3px);
  box-shadow: var(--mdx-lift-2);
  border-color: rgba(23, 105, 255, 0.24);
}
.mdx-home-choice:active { transform: translateY(0) scale(0.99); }
.mdx-home-ic {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  border-radius: 15px;
  background: var(--mdx-blue-wash);
  color: var(--mdx-blue);
  margin-bottom: 14px;
}
.mdx-home-ic.is-ai { background: var(--mdx-gold-wash); color: #8a6d1c; }
.mdx-home-ic svg { width: 24px; height: 24px; }
.mdx-home-choice strong {
  display: block;
  font-size: 1.14rem;
  font-weight: 720;
  letter-spacing: -0.026em;
  color: var(--mdx-ink);
}
.mdx-home-choice small {
  display: block;
  margin-top: 6px;
  font-size: 0.845rem;
  line-height: 1.5;
  color: var(--mdx-muted);
}
.mdx-home-go {
  display: inline-block;
  margin-top: 14px;
  font-size: 0.8rem;
  font-weight: 680;
  color: var(--mdx-blue);
}
.mdx-home-choice:nth-child(2) .mdx-home-go { color: #8a6d1c; }

body.mdx.dark-mode .mdx-home-choice {
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.06), rgba(255, 255, 255, 0.03));
}
body.mdx.dark-mode .mdx-teach-legend li { background: rgba(255, 255, 255, 0.04); }

/* On the entry screen no destination is current, which left the collapsed
   rail as a bare "+". The monogram stands in as the anchor there. */
body.mdx[data-mdx-section="home"] .mdx-rail-brand {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  margin: 0 2px 0 0;
  padding: 0;
  border: 0;
  border-bottom: 0;
  font-size: 1rem;
  font-weight: 800;
  letter-spacing: -0.04em;
  background: linear-gradient(145deg, #e0bd63 0%, var(--mdx-gold) 48%, #a8811f 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}

/* ==========================================================================
   25. Home is one workspace
   ==========================================================================
   Chat and Lens are two modes of the same page, not two products. The
   switcher is the only chrome the entry needs; everything below it is the
   conversation, and choosing Lens transforms this page rather than leaving
   it.
   ========================================================================== */

body.mdx .mdx-home { padding: 0; }

.mdx-home-head {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 6px 2px 12px;
}
.mdx-home-mark {
  margin: 0;
  flex: none;
  font-size: 0.76rem;
  font-weight: 800;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  background: linear-gradient(145deg, #e0bd63, var(--mdx-gold) 52%, #a8811f);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: var(--mdx-gold);
}

.mdx-switch {
  margin-left: auto;
  display: inline-flex;
  gap: 3px;
  padding: 4px;
  border-radius: var(--mdx-r-pill);
  background: var(--mdx-glass);
  -webkit-backdrop-filter: var(--mdx-glass-blur);
  backdrop-filter: var(--mdx-glass-blur);
  border: 1px solid var(--mdx-glass-edge);
  box-shadow: var(--mdx-glass-shadow);
}
.mdx-switch-btn {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 36px;
  padding: 0 15px;
  border: 0;
  border-radius: var(--mdx-r-pill);
  background: transparent;
  color: var(--mdx-muted);
  font-size: 0.83rem;
  font-weight: 650;
  letter-spacing: -0.014em;
  transition: background 0.3s var(--mdx-ease-spring), color 0.22s var(--mdx-ease), box-shadow 0.3s var(--mdx-ease);
}
.mdx-switch-btn svg { width: 17px; height: 17px; }
/* The sliding thumb is the highlight; the button stays transparent so the
   label always sits ON the thumb rather than on a second opaque layer. */
.mdx-switch-btn[aria-selected="true"] {
  background: transparent;
  color: var(--mdx-ink);
  box-shadow: none;
}
.mdx-switch-btn[aria-selected="true"] svg { color: var(--mdx-blue); }
.mdx-switch-btn:not([aria-selected="true"]):hover { color: var(--mdx-ink); }

/* The conversation, docked. Same element as the overlay — moved, not copied —
   so it keeps its history, its send path and its listeners. */
.mdx-home-chat {
  min-height: calc(100dvh - var(--mdx-bottom-budget) - 96px);
  display: flex;
}
body.mdx.mdx-chat-home .bfs {
  position: relative !important;
  inset: auto !important;
  left: auto !important;
  right: auto !important;
  transform: none !important;
  width: 100% !important;
  height: auto !important;
  min-height: calc(100dvh - var(--mdx-bottom-budget) - 96px) !important;
  z-index: auto !important;
  opacity: 1 !important;
  border-radius: var(--mdx-r-lg) !important;
  box-shadow: var(--mdx-lift-1) !important;
}
/* A docked conversation is the page, so it needs no dialog chrome. */
body.mdx.mdx-chat-home .bfs .bfs-collapse,
body.mdx.mdx-chat-home .bfs .bfs-close { display: none !important; }
body.mdx.mdx-chat-home::before { content: none !important; }

/* ==========================================================================
   26. Activating Lens
   ==========================================================================
   Nothing to animate: Lens opens on the tap. The veil that used to cover the
   switch held the screen for about a second in front of a camera the user had
   already asked for, so it was removed along with its keyframes.
   ========================================================================== */

@media (prefers-reduced-motion: reduce) { .mdx-lens-veil { display: none !important; } }

/* ==========================================================================
   27. Adaptive contrast over the image
   ==========================================================================
   The chrome is sampled against the band of the image it actually sits on
   (see syncAdaptiveContrast). Over a dark field it becomes a dark, high-
   opacity glass with light type; over a bright field it stays warm-white and
   deepens its border and shadow instead. Both keep the Liquid Glass material
   — what changes is which side of the contrast it sits on.
   ========================================================================== */

body.mdx.mdx-lens-result {
  --mdx-glass-dark:
    linear-gradient(178deg, rgba(16, 22, 32, 0.82) 0%, rgba(12, 17, 26, 0.76) 100%);
  --mdx-glass-dark-edge: rgba(255, 255, 255, 0.18);
  --mdx-glass-dark-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.14),
    0 10px 30px rgba(0, 0, 0, 0.42);
}

/* --- the top band: viewer controls and the modality pill ----------------- */
body.mdx.mdx-lens-result.mdx-top-dark .mdx-lens-controls,
body.mdx.mdx-lens-result.mdx-top-dark .lens-screen .lens-modality-pill,
body.mdx.mdx-lens-result.mdx-top-dark .lens-screen #lensUsageBadge {
  background: var(--mdx-glass-dark);
  border-color: var(--mdx-glass-dark-edge);
  box-shadow: var(--mdx-glass-dark-shadow);
  color: #f4f8ff;
}
body.mdx.mdx-lens-result.mdx-top-dark .mdx-lens-btn { color: #dfe9f7; }
body.mdx.mdx-lens-result.mdx-top-dark .mdx-lens-btn:hover { background: rgba(255, 255, 255, 0.14); color: #fff; }
body.mdx.mdx-lens-result.mdx-top-dark .lens-screen #lensUsageBadge { color: rgba(226, 236, 250, 0.86); }

/* Over a bright film the warm white stays, but it has to stop floating: a
   firmer border and a real shadow are what separate it from the image. */
body.mdx.mdx-lens-result.mdx-top-light .mdx-lens-controls,
body.mdx.mdx-lens-result.mdx-top-light .lens-screen .lens-modality-pill {
  background: linear-gradient(178deg, rgba(255, 255, 255, 0.94), rgba(248, 250, 253, 0.9));
  border-color: rgba(14, 23, 38, 0.16);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.95),
    0 2px 6px rgba(14, 23, 38, 0.14),
    0 12px 30px rgba(14, 23, 38, 0.18);
}

/* --- the bottom band: the Spatial Intelligence rail ---------------------- */
body.mdx.mdx-lens-result.mdx-bot-dark #lspRail {
  background: var(--mdx-glass-dark) !important;
  border-color: var(--mdx-glass-dark-edge) !important;
  box-shadow: var(--mdx-glass-dark-shadow) !important;
}
body.mdx.mdx-lens-result.mdx-bot-dark #lspRail .lsp-chip {
  color: #e8f0fb;
  border-color: rgba(255, 255, 255, 0.2);
  background: rgba(255, 255, 255, 0.08);
}
body.mdx.mdx-lens-result.mdx-bot-dark #lspRail .lsp-chip[aria-pressed="true"] {
  background: rgba(120, 175, 255, 0.26);
  border-color: rgba(150, 195, 255, 0.5);
  color: #fff;
}
body.mdx.mdx-lens-result.mdx-bot-light #lspRail {
  background: linear-gradient(178deg, rgba(255, 255, 255, 0.95), rgba(247, 250, 253, 0.92)) !important;
  border-color: rgba(14, 23, 38, 0.16) !important;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.95),
    0 2px 6px rgba(14, 23, 38, 0.14),
    0 12px 30px rgba(14, 23, 38, 0.18) !important;
}

/* Overlay text sits directly on pixels and cannot rely on a panel at all, so
   it carries its own halo in both directions. */
body.mdx.mdx-lens-result .lens-screen .lens-annotation,
body.mdx.mdx-lens-result .lsp-label {
  text-shadow:
    0 1px 2px rgba(0, 0, 0, 0.55),
    0 0 10px rgba(0, 0, 0, 0.35);
}
body.mdx.mdx-lens-result .mdxt-cap,
body.mdx.mdx-lens-result .mdxt-readout { stroke-width: 7; }

/* The floating Baihaqi mark sits over the report, not the image, but it
   follows the same rule when the report has not scrolled up yet. */
body.mdx.mdx-lens-result.mdx-bot-dark .mdx-ai-fab {
  background: var(--mdx-glass-dark);
  border-color: var(--mdx-glass-dark-edge);
  box-shadow: var(--mdx-glass-dark-shadow);
  color: #f2f7ff;
}

/* ==========================================================================
   28. Clinical progression
   ========================================================================== */

.mdx-prog {
  margin: 0 0 18px;
  padding: 18px;
  border-radius: var(--mdx-r-lg);
  border: 1px solid var(--mdx-hair);
  background:
    radial-gradient(120% 130% at 100% 0%, rgba(200, 163, 74, 0.1), transparent 58%),
    linear-gradient(180deg, #ffffff, #fbfcfe);
  box-shadow: var(--mdx-lift-1);
}
.mdx-prog-head { display: flex; align-items: flex-start; gap: 14px; margin-top: 4px; }
.mdx-prog-head h3 {
  margin: 0;
  font-size: 1.35rem;
  font-weight: 740;
  letter-spacing: -0.03em;
  color: var(--mdx-ink);
}
.mdx-prog-head p { margin: 4px 0 0; font-size: 0.83rem; color: var(--mdx-muted); }
.mdx-prog-xp {
  margin-left: auto;
  flex: none;
  font-size: 1.5rem;
  font-weight: 780;
  letter-spacing: -0.035em;
  color: var(--mdx-ink);
  line-height: 1;
}
.mdx-prog-xp small {
  display: block;
  margin-top: 3px;
  font-size: 0.62rem;
  font-weight: 750;
  letter-spacing: 0.12em;
  color: var(--mdx-faint);
  text-align: right;
}
.mdx-prog-track {
  margin: 14px 0 4px;
  height: 9px;
  border-radius: 999px;
  background: var(--mdx-surface-sunken);
  border: 1px solid var(--mdx-hair);
  overflow: hidden;
}
.mdx-prog-track i {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--mdx-blue), #5fa0ff 62%, var(--mdx-gold));
  transition: width 0.8s var(--mdx-ease);
}
.mdx-prog-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 8px;
  margin: 16px 0 0;
}
.mdx-prog-stats div {
  padding: 10px 12px;
  border-radius: var(--mdx-r-sm);
  background: var(--mdx-surface-2);
  border: 1px solid var(--mdx-hair);
}
.mdx-prog-stats dt { font-size: 0.68rem; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--mdx-faint); }
.mdx-prog-stats dd { margin: 3px 0 0; font-size: 1.02rem; font-weight: 720; letter-spacing: -0.02em; color: var(--mdx-ink); }

.mdx-prog-ladder { margin-top: 14px; }
.mdx-prog-ladder summary {
  cursor: pointer;
  font-size: 0.8rem;
  font-weight: 660;
  color: var(--mdx-blue);
  list-style: none;
}
.mdx-prog-ladder summary::-webkit-details-marker { display: none; }
.mdx-prog-ladder ol { margin: 12px 0 0; padding: 0; list-style: none; display: grid; gap: 5px; counter-reset: rank; }
.mdx-prog-ladder li {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  border-radius: var(--mdx-r-sm);
  border: 1px solid var(--mdx-hair);
  font-size: 0.82rem;
  color: var(--mdx-muted);
}
.mdx-prog-ladder li b { margin-left: auto; font-weight: 700; color: var(--mdx-faint); font-size: 0.76rem; }
.mdx-prog-ladder li.is-done { color: var(--mdx-ink-2); border-color: rgba(15, 157, 108, 0.28); }
.mdx-prog-ladder li.is-done b { color: var(--mdx-green); }
.mdx-prog-ladder li.is-now {
  background: var(--mdx-blue-wash);
  border-color: rgba(23, 105, 255, 0.32);
  color: var(--mdx-ink);
  font-weight: 680;
}
.mdx-prog-ladder li.is-now b { color: var(--mdx-blue-ink); }
.mdx-prog-ladder > p { margin: 12px 0 0; font-size: 0.745rem; line-height: 1.55; color: var(--mdx-muted); }

body.mdx.dark-mode .mdx-prog { background: linear-gradient(180deg, #141d29, #111925); }
body.mdx.dark-mode .mdx-prog-stats div { background: rgba(255, 255, 255, 0.04); }

/* ==========================================================================
   29. Reaching a new rank
   ========================================================================== */

.mdx-rankup {
  position: fixed;
  z-index: 2750;
  left: 50%;
  top: calc(18px + env(safe-area-inset-top, 0px));
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 13px;
  padding: 13px 20px 13px 14px;
  border-radius: var(--mdx-r-pill);
  background: var(--mdx-glass);
  -webkit-backdrop-filter: var(--mdx-glass-blur);
  backdrop-filter: var(--mdx-glass-blur);
  border: 1px solid rgba(200, 163, 74, 0.42);
  box-shadow: var(--mdx-glass-shadow-lift), 0 0 0 1px rgba(200, 163, 74, 0.12);
  overflow: hidden;
  animation: mdxRankIn 0.62s var(--mdx-ease-spring) both;
}
.mdx-rankup.is-out { animation: mdxRankOut 0.5s var(--mdx-ease) both; }
@keyframes mdxRankIn { from { opacity: 0; transform: translateX(-50%) translateY(-22px) scale(0.94); } to { opacity: 1; transform: translateX(-50%); } }
@keyframes mdxRankOut { to { opacity: 0; transform: translateX(-50%) translateY(-14px); } }

.mdx-rankup-glow {
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, transparent, rgba(224, 189, 99, 0.32), transparent);
  transform: translateX(-100%);
  animation: mdxRankSweep 1.5s var(--mdx-ease) 0.25s 2;
  pointer-events: none;
}
@keyframes mdxRankSweep { to { transform: translateX(100%); } }

.mdx-rankup-ic {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  flex: none;
  border-radius: 50%;
  background: linear-gradient(150deg, #f0d798, var(--mdx-gold));
  color: #4a390c;
  box-shadow: 0 4px 14px rgba(200, 163, 74, 0.42);
}
.mdx-rankup-ic svg { width: 20px; height: 20px; }
.mdx-rankup-txt { position: relative; display: flex; flex-direction: column; line-height: 1.15; }
.mdx-rankup-txt small { font-size: 0.64rem; font-weight: 750; letter-spacing: 0.1em; text-transform: uppercase; color: var(--mdx-muted); }
.mdx-rankup-txt strong { font-size: 1.02rem; font-weight: 740; letter-spacing: -0.024em; color: var(--mdx-ink); }

@media (prefers-reduced-motion: reduce) { .mdx-rankup-glow { display: none; } }

/* ==========================================================================
   30. Landscape on a phone
   ==========================================================================
   In landscape the rail moves to the top-right corner to reclaim vertical
   space — which is exactly where the Lens viewer controls already were. On an
   iPhone 13 at 844x390 the two sat on top of each other.

   The rail's WIDTH changes as it expands, so clearing it horizontally would
   be a moving target; the viewer controls drop below it instead, which is
   stable at either rail state.
   ========================================================================== */

@media (max-height: 480px) and (orientation: landscape) {
  body.mdx .mdx-lens-controls.is-right {
    top: calc(8px + 54px + 10px + env(safe-area-inset-top, 0px));
  }
  body.mdx .lens-screen .lens-modes-wrap {
    top: calc(8px + env(safe-area-inset-top, 0px));
    left: 50%;
    transform: translateX(-50%) scale(0.94);
  }
  /* The result stage must not eat the whole short viewport, and has to leave
     the spatial rail clear of the floating Baihaqi mark below it. */
  body.mdx.mdx-lens-result .lens-v2 .lens-stage { height: 74dvh; }
}

/* ==========================================================================
   31. The MedDex intelligence surface
   ==========================================================================
   One intelligence, two ways to use it. The page is the canvas: no wrapper
   card, no bordered chat box, no card inside a card. Glass is reserved for
   the things you touch — the composer, the mode switch, the navigation and
   the Lens toolbars — and content is left clean.
   ========================================================================== */

/* ---- persistent navigation --------------------------------------------- */

body.mdx .bottom-nav.mdx-nav {
  position: fixed;
  left: 50%;
  bottom: calc(8px + env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%);
  z-index: 2520;
  display: flex;
  align-items: stretch;
  justify-content: space-between;
  gap: 2px;
  width: min(560px, calc(100vw - 16px));
  height: 58px;
  padding: 5px 4px;
  border-radius: var(--mdx-r-pill);
  background: var(--mdx-glass);
  -webkit-backdrop-filter: var(--mdx-glass-blur);
  backdrop-filter: var(--mdx-glass-blur);
  border: 1px solid var(--mdx-glass-edge);
  box-shadow: var(--mdx-glass-shadow);
  /* The classic sheet gives this a grid and a raised centre dock. */
  grid-template-columns: none;
}

body.mdx .bottom-nav.mdx-nav .mdx-nav-item {
  flex: 1 1 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  min-width: 0;
  height: auto;
  padding: 0;
  border: 0;
  border-radius: 16px;
  background: transparent;
  color: var(--mdx-faint);
  font-size: 0.53rem;
  font-weight: 660;
  letter-spacing: -0.022em;
  position: relative;
  overflow: hidden;
  transition: color 0.22s var(--mdx-ease), background 0.26s var(--mdx-ease);
  -webkit-tap-highlight-color: transparent;
}
body.mdx .bottom-nav.mdx-nav .mdx-nav-item svg {
  width: 20px;
  height: 20px;
  stroke-width: 1.7;
  flex: none;
}
body.mdx .bottom-nav.mdx-nav .mdx-nav-item span {
  line-height: 1;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
body.mdx .bottom-nav.mdx-nav .mdx-nav-item:hover { color: var(--mdx-ink-2); }
body.mdx .bottom-nav.mdx-nav .mdx-nav-item:active { transform: scale(0.94); }

/* Active Home — and any active product — takes the MedDex gold. Everything
   else stays a quiet neutral so the navigation never competes with the
   intelligence surface above it. */
body.mdx .bottom-nav.mdx-nav .mdx-nav-item.active {
  color: #8a6d1c;
  background: var(--mdx-gold-wash);
}
body.mdx .bottom-nav.mdx-nav .mdx-nav-item.active svg { stroke-width: 2; }

body.mdx .bottom-nav.mdx-nav .nav-notification-badge {
  position: absolute;
  top: 2px;
  right: calc(50% - 20px);
  min-width: 15px;
  height: 15px;
  padding: 0 4px;
  border-radius: 999px;
  background: var(--mdx-red);
  color: #fff;
  font-size: 0.56rem;
  font-weight: 800;
  line-height: 15px;
  text-align: center;
  box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.9);
}
body.mdx .bottom-nav.mdx-nav .nav-notification-badge.hidden { display: none; }

@media (min-width: 1024px) {
  body.mdx .bottom-nav.mdx-nav {
    left: 18px;
    top: 50%;
    bottom: auto;
    transform: translateY(-50%);
    flex-direction: column;
    width: 76px;
    height: auto;
    padding: 8px 6px;
    border-radius: 26px;
    gap: 4px;
  }
  body.mdx .bottom-nav.mdx-nav .mdx-nav-item { height: 58px; flex: none; }

  /* The content column and the navigation column.
     ------------------------------------------------------------------
     `margin-inline: auto` centred the shell without knowing the rail was
     there. Because the shell also had a max width, the centring margin sat at
     a constant 105px from 1024px right up to 1440px — and the rail ends at
     94px, so every laptop and iPad-landscape width had an 11px gutter between
     the navigation and the hero.

     The margin is now floored at the rail's own width plus a gutter that
     scales with the viewport, and still centres once the window is wide
     enough that centring gives more room than the floor does. No fixed
     offset, and nothing stretches to fill the space. */
  body.mdx {
    --mdx-nav-x: 18px;
    --mdx-nav-w: 76px;
    --mdx-nav-gutter: clamp(28px, 3.5vw, 64px);
    --mdx-nav-zone: calc(var(--mdx-nav-x) + var(--mdx-nav-w) + var(--mdx-nav-gutter));
    --mdx-shell-w: min(1240px, calc(100% - var(--mdx-nav-zone) - 32px));
  }
  body.mdx .app-shell {
    width: var(--mdx-shell-w);
    /* Whichever is further right: clear of the rail, or centred. */
    margin-left: max(var(--mdx-nav-zone), calc((100% - var(--mdx-shell-w)) / 2));
    margin-right: auto;
  }
}

/* ---- the mode switch ---------------------------------------------------- */

.mdx-switch {
  position: fixed;
  z-index: 2540;
  left: 50%;
  bottom: calc(var(--mdx-bar-h) + var(--mdx-rail-h) + 40px + env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%);
  display: inline-flex;
  padding: 4px;
  border-radius: var(--mdx-r-pill);
  background: var(--mdx-glass);
  -webkit-backdrop-filter: var(--mdx-glass-blur);
  backdrop-filter: var(--mdx-glass-blur);
  border: 1px solid var(--mdx-glass-edge);
  box-shadow: var(--mdx-glass-shadow);
  transition: transform 0.42s var(--mdx-ease-spring), opacity 0.24s var(--mdx-ease), background 0.4s var(--mdx-ease), border-color 0.4s var(--mdx-ease);
}
.mdx-switch[hidden] { display: none; }
.mdx-switch.is-hidden { opacity: 0; transform: translateX(-50%) translateY(14px); pointer-events: none; }

.mdx-switch-thumb {
  position: absolute;
  top: 4px;
  left: 4px;
  width: calc(33.333% - 4px);
  height: calc(100% - 8px);
  border-radius: var(--mdx-r-pill);
  background: #fff;
  box-shadow: 0 1px 2px rgba(14, 23, 38, 0.08), 0 3px 10px rgba(14, 23, 38, 0.1);
  transition: transform 0.42s var(--mdx-ease-spring), background 0.4s var(--mdx-ease);
}
.mdx-switch[data-mode="lens"] .mdx-switch-thumb { transform: translateX(100%); }
.mdx-switch[data-mode="spatial"] .mdx-switch-thumb { transform: translateX(200%); }

.mdx-switch-btn {
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  width: 104px;
  height: 36px;
  border: 0;
  border-radius: var(--mdx-r-pill);
  background: transparent;
  color: var(--mdx-muted);
  font-size: 0.83rem;
  font-weight: 650;
  letter-spacing: -0.014em;
  transition: color 0.24s var(--mdx-ease);
}
.mdx-switch-btn svg { width: 16px; height: 16px; }
.mdx-sphere-mark {
  position: relative;
  display: inline-block;
  width: 16px;
  height: 16px;
  flex: 0 0 16px;
  border-radius: 50%;
  background:
    radial-gradient(circle at 31% 28%, rgba(255,255,255,.96) 0 8%, rgba(255,255,255,0) 34%),
    radial-gradient(circle at 64% 68%, rgba(116,229,255,.62), rgba(116,229,255,0) 58%),
    radial-gradient(circle at 50% 50%, #6a5ad2 0 35%, #221d4d 72%, #0f1220 100%);
  box-shadow: inset 0 0 3px rgba(255,255,255,.62), 0 0 7px rgba(106,90,210,.28);
}
.mdx-sphere-mark::after {
  content: "";
  position: absolute;
  inset: 1px -2px;
  border: 1px solid currentColor;
  border-radius: 50%;
  opacity: .34;
  transform: rotate(-22deg) scaleY(.42);
}
.mdx-switch-btn[aria-selected="true"] .mdx-sphere-mark { box-shadow: inset 0 0 3px rgba(255,255,255,.7), 0 0 9px rgba(106,90,210,.52); }
.mdx-switch-btn[aria-selected="true"] { color: var(--mdx-ink); }
.mdx-switch-btn[aria-selected="true"] svg { color: var(--mdx-blue); }

/* ---- the open canvas ---------------------------------------------------- */

body.mdx .mdx-home { padding: 0; display: flex; flex-direction: column; }

/* ==========================================================================
   THE GLOBAL HEADER
   ==========================================================================
   Safe area → header → page content. On every route, in that order.

   It was in flow inside the Home screen, which meant two things: no other
   destination had it at all, and on a screen whose content is laid out in flow
   it appeared wherever the flow put it — at the bottom, after a long page.

   Fixed, at body level, one instance. `--mdx-topline-h` is published by the
   shell from the element's MEASURED height (the safe-area inset is part of it
   and varies by device and orientation), and the screens reserve exactly that
   much so nothing is covered and nothing double-counts it. */
.mdx-topline {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  /* Under the drawer (4200+) and the rail (2520), over every page surface. */
  z-index: 2400;
  display: flex;
  align-items: center;
  gap: 10px;
  box-sizing: border-box;
  padding: calc(env(safe-area-inset-top, 0px) + 10px)
           calc(env(safe-area-inset-right, 0px) + 16px)
           8px
           calc(env(safe-area-inset-left, 0px) + 16px);
  flex: none;
  /* Content scrolls UNDER it, so it needs a ground of its own or the words
     underneath show through the wordmark. Blur where it is supported, an
     opaque fallback where it is not. */
  background: color-mix(in srgb, var(--mdx-surface, #fbfcfe) 82%, transparent);
  backdrop-filter: saturate(1.6) blur(14px);
  -webkit-backdrop-filter: saturate(1.6) blur(14px);
  transition: background 0.3s var(--mdx-ease), border-color 0.3s var(--mdx-ease);
}
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .mdx-topline { background: var(--mdx-surface, #fbfcfe); }
}
body.mdx.dark-mode .mdx-topline,
body.mdx[data-theme="dark"] .mdx-topline {
  background: color-mix(in srgb, var(--mdx-surface, #0b1220) 84%, transparent);
}
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  body.mdx.dark-mode .mdx-topline,
  body.mdx[data-theme="dark"] .mdx-topline { background: var(--mdx-surface, #0b1220); }
}

/* The space it occupies, given back to the page. Applied to the scrolling
   screen rather than to <main>, because several screens are themselves fixed
   boxes and would otherwise reserve the height twice. */
body.mdx main { padding-top: var(--mdx-topline-h, 56px); }

/* LENS IS THE ONE EXCEPTION, and only to the GROUND — never to the position.
   The viewfinder is deliberately edge to edge, so padding it down would put a
   grey band above a live camera. The header keeps its place and loses its
   backdrop there; the existing `mdx-top-dark` / `mdx-top-light` logic already
   decides which way its ink has to go over the frame. What DOES move is Lens's
   own floating chrome, which was positioned from the safe area and would now
   sit under the header. */
body.mdx[data-mdx-section="lens"] .mdx-topline {
  background: transparent;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
body.mdx[data-mdx-section="lens"] .mdx-lens-controls {
  top: calc(var(--mdx-topline-h, 56px) + 8px);
}
body.mdx[data-mdx-section="lens"] .lens-screen .lens-modes-wrap {
  top: calc(var(--mdx-topline-h, 56px) + 54px);
}
body.mdx.mdx-top-dark .mdx-topline .mdx-topline-mark { color: rgba(226, 236, 250, 0.72); }
body.mdx.mdx-top-dark .mdx-topline .mdx-topline-btn { color: #dfe9f7; }
.mdx-topline-mark {
  display: inline-flex;
  align-items: baseline;
  gap: 7px;
  font-size: 0.7rem;
  font-weight: 750;
  letter-spacing: 0.2em;
  color: var(--mdx-faint);
}
.mdx-topline-mark b {
  font-size: 0.95rem;
  font-weight: 800;
  letter-spacing: -0.04em;
  background: linear-gradient(145deg, #e0bd63, var(--mdx-gold) 52%, #a8811f);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
.mdx-topline-btn {
  margin-left: auto;
  width: 34px;
  height: 34px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--mdx-faint);
  transition: color 0.2s var(--mdx-ease), background 0.2s var(--mdx-ease);
}
.mdx-topline-btn svg { width: 18px; height: 18px; }
.mdx-topline-btn:hover { color: var(--mdx-ink); background: rgba(14, 23, 38, 0.05); }

/* The conversation docks straight into the page. No card, no border, no
   second background — the document is the canvas. */
.mdx-canvas { flex: 1 1 auto; min-height: 0; display: flex; }
body.mdx.mdx-chat-home .bfs {
  position: relative !important;
  inset: auto !important;
  left: auto !important;
  right: auto !important;
  transform: none !important;
  width: 100% !important;
  height: auto !important;
  min-height: calc(100dvh - var(--mdx-bottom-budget) - 110px) !important;
  z-index: auto !important;
  opacity: 1 !important;
  border: 0 !important;
  border-radius: 0 !important;
  background: none !important;
  -webkit-backdrop-filter: none !important;
  backdrop-filter: none !important;
  box-shadow: none !important;
}
body.mdx.mdx-chat-home .bfs .bfs-header { display: none !important; }
body.mdx.mdx-chat-home .bfs .bfs-log { padding: 4px 0 8px !important; }
body.mdx.mdx-chat-home::before { content: none !important; }

/* Before there is a conversation, the log has one greeting bubble in it.
   The elegant empty state replaces it rather than sitting under it — and the
   docked surface has to give up its reserved height, or the empty state is
   pushed to the floor of a screen of blank space. */
body.mdx.mdx-chat-empty .bfs .bfs-log { display: none !important; }
body.mdx.mdx-chat-empty .bfs { min-height: 0 !important; }
body.mdx.mdx-chat-empty .mdx-canvas { flex: 0 0 auto; min-height: 0; }

.mdx-empty {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 0;
  /* Clears the composer, the mode switch above it and the navigation below,
     so the negative space reads as intentional rather than as something
     hiding underneath. */
  padding: 0 2px calc(var(--mdx-bottom-budget) + 54px);
  min-height: calc(100dvh - 120px);
  animation: mdxScreenIn 0.42s var(--mdx-ease) both;
}
.mdx-empty[hidden] { display: none; }
.mdx-empty-id {
  margin: 0;
  font-size: 1rem;
  font-weight: 720;
  letter-spacing: -0.024em;
  color: var(--mdx-ink);
}
.mdx-empty-sub {
  margin: 2px 0 0;
  font-size: 0.86rem;
  color: var(--mdx-muted);
}
.mdx-empty-ask {
  margin: 22px 0 0;
  font-size: clamp(1.55rem, 6.4vw, 2.15rem);
  font-weight: 700;
  letter-spacing: -0.038em;
  line-height: 1.14;
  color: var(--mdx-ink);
  max-width: 15ch;
}
.mdx-empty-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 22px; }
.mdx-empty-actions .mdx-chip { height: 36px; font-size: 0.82rem; }

.mdx-onboard { margin-top: 26px; }
.mdx-onboard[hidden] { display: none; }
.mdx-onboard-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 11px 16px;
  border-radius: var(--mdx-r-pill);
  border: 1px solid rgba(200, 163, 74, 0.4);
  background: var(--mdx-gold-wash);
  color: #8a6d1c;
  font-size: 0.83rem;
  font-weight: 660;
  transition: transform 0.18s var(--mdx-ease), background 0.2s var(--mdx-ease);
}
.mdx-onboard-btn svg { width: 15px; height: 15px; transform: rotate(180deg); }
.mdx-onboard-btn:hover { background: rgba(200, 163, 74, 0.18); }
.mdx-onboard-btn:active { transform: scale(0.97); }

/* ==========================================================================
   32. Lens — the diagnostic workstation
   ==========================================================================
   Chat is for thinking, Lens is for seeing. The surface keeps the same
   geometry — same composer, same switch, same navigation — and changes
   environment: the canvas goes dark so the medical content is the brightest
   thing on screen, which is how a reading room is lit and why radiographs are
   not read on white.
   ========================================================================== */

body.mdx[data-mdx-section="lens"] {
  --mdx-ink: #eef4fb;
  --mdx-ink-2: #c3d1e2;
  --mdx-muted: #8fa0b5;
  --mdx-faint: #6b7d93;
  /* The Lens workstation is dark even when the rest of the app is light, so
     the trust line needs its own pair here. Carrying the light-theme values
     into it put the sentence at 3.4:1 and the Terms/Privacy links at 1.8:1 —
     a legal line nobody could read is not a legal line. */
  --mdx-legal: #9aa8bd;
  --mdx-legal-link: #dbe4f0;
  --mdx-hair: rgba(226, 236, 250, 0.12);
  --mdx-hair-strong: rgba(226, 236, 250, 0.2);
  --mdx-glass: linear-gradient(178deg, rgba(24, 32, 45, 0.84) 0%, rgba(16, 22, 33, 0.78) 100%);
  --mdx-glass-edge: rgba(226, 236, 250, 0.16);
  --mdx-glass-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.08),
    0 14px 40px rgba(0, 0, 0, 0.5);
  --mdx-glass-shadow-lift:
    inset 0 1px 0 rgba(255, 255, 255, 0.08),
    0 26px 64px rgba(0, 0, 0, 0.6);
  background: radial-gradient(120% 90% at 50% 0%, #131a25 0%, #0a0f17 62%, #070a10 100%);
}

body.mdx[data-mdx-section="lens"] .lens-screen .lens-stage {
  background: radial-gradient(120% 90% at 50% 8%, #141c27 0%, #0a0f17 64%, #05080d 100%);
}
body.mdx[data-mdx-section="lens"] .mdx-switch-thumb { background: rgba(255, 255, 255, 0.14); }
body.mdx[data-mdx-section="lens"] .mdx-switch-btn[aria-selected="true"] { color: #f2f7ff; }
body.mdx[data-mdx-section="lens"] .mdx-switch-btn[aria-selected="true"] svg { color: #7db4ff; }
body.mdx[data-mdx-section="lens"] .mdx-bar-field,
body.mdx[data-mdx-section="lens"] .mdx-bar-btn,
body.mdx[data-mdx-section="lens"] .mdx-chip {
  background: rgba(255, 255, 255, 0.07);
  border-color: rgba(226, 236, 250, 0.16);
  color: var(--mdx-ink-2);
}
body.mdx[data-mdx-section="lens"] .mdx-bar-input { color: var(--mdx-ink); }
body.mdx[data-mdx-section="lens"] .mdx-bar-input::placeholder { color: var(--mdx-faint); }
body.mdx[data-mdx-section="lens"] .bottom-nav.mdx-nav .mdx-nav-item { color: var(--mdx-faint); }
body.mdx[data-mdx-section="lens"] .bottom-nav.mdx-nav .mdx-nav-item.active {
  color: #f0d798;
  background: rgba(200, 163, 74, 0.18);
}
body.mdx[data-mdx-section="lens"] .lens-screen .lens-empty-state,
body.mdx[data-mdx-section="lens"] .lens-screen .lens-reticle,
body.mdx[data-mdx-section="lens"] .lens-screen .lens-dropzone-hint { display: none !important; }

/* ---- the opening state -------------------------------------------------- */

.mdx-lens-intro {
  position: absolute;
  inset: 0;
  z-index: 5;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 0 22px calc(var(--mdx-bottom-budget) + 40px);
  animation: mdxScreenIn 0.5s var(--mdx-ease) both;
  pointer-events: none;
}
.mdx-lens-intro > * { pointer-events: auto; }
.mdx-lens-intro-id {
  margin: 0;
  font-size: 1rem;
  font-weight: 720;
  letter-spacing: -0.024em;
  color: #eef4fb;
}
.mdx-lens-intro-sub {
  margin: 2px 0 0;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: #7db4ff;
}
.mdx-lens-intro-ask {
  margin: 22px 0 0;
  max-width: 14ch;
  font-size: clamp(1.5rem, 6.2vw, 2.05rem);
  font-weight: 700;
  letter-spacing: -0.036em;
  line-height: 1.14;
  color: #f4f8fd;
}
.mdx-lens-intro-actions { display: flex; flex-wrap: wrap; gap: 9px; margin-top: 24px; }
.mdx-lens-intro-actions button {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 40px;
  padding: 0 16px;
  border-radius: var(--mdx-r-pill);
  border: 1px solid rgba(226, 236, 250, 0.2);
  background: rgba(255, 255, 255, 0.07);
  -webkit-backdrop-filter: blur(18px);
  backdrop-filter: blur(18px);
  color: #e6eefa;
  font-size: 0.83rem;
  font-weight: 640;
  transition: background 0.22s var(--mdx-ease), transform 0.18s var(--mdx-ease);
}
.mdx-lens-intro-actions button svg { width: 16px; height: 16px; }
.mdx-lens-intro-actions button:hover { background: rgba(255, 255, 255, 0.13); }
.mdx-lens-intro-actions button:active { transform: scale(0.96); }

/* ---- entry buttons in the composer's capture row ------------------------ */

.mdx-lens-entry {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  min-width: 60px;
  padding: 4px 8px;
  border: 0;
  border-radius: 14px;
  background: transparent;
  color: var(--mdx-muted);
  font-size: 0.66rem;
  font-weight: 640;
  transition: color 0.2s var(--mdx-ease), background 0.2s var(--mdx-ease);
}
.mdx-lens-entry svg { width: 20px; height: 20px; }
.mdx-lens-entry:hover { color: var(--mdx-ink); background: rgba(127, 160, 200, 0.12); }
.mdx-lens-entry:active { transform: scale(0.95); }

/* ---- the viewer toolbar, revealed with the content ---------------------- */

.mdx-lens-toolbar {
  position: absolute;
  left: 50%;
  bottom: 12px;
  transform: translateX(-50%);
  z-index: 9;
  display: flex;
  gap: 2px;
  max-width: calc(100% - 20px);
  padding: 4px;
  border-radius: var(--mdx-r-pill);
  background: linear-gradient(178deg, rgba(24, 32, 45, 0.88), rgba(16, 22, 33, 0.84));
  -webkit-backdrop-filter: var(--mdx-glass-blur);
  backdrop-filter: var(--mdx-glass-blur);
  border: 1px solid rgba(226, 236, 250, 0.18);
  box-shadow: 0 14px 40px rgba(0, 0, 0, 0.5);
  overflow-x: auto;
  scrollbar-width: none;
  animation: mdxToolbarIn 0.44s var(--mdx-ease-spring) both;
}
.mdx-lens-toolbar::-webkit-scrollbar { display: none; }
@keyframes mdxToolbarIn { from { opacity: 0; transform: translateX(-50%) translateY(10px); } to { opacity: 1; transform: translateX(-50%); } }

.mdx-lens-tool {
  flex: none;
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  min-width: 54px;
  padding: 6px 8px;
  border: 0;
  border-radius: 14px;
  background: transparent;
  color: #b9c8db;
  font-size: 0.62rem;
  font-weight: 640;
  transition: color 0.2s var(--mdx-ease), background 0.22s var(--mdx-ease);
}
.mdx-lens-tool svg { width: 17px; height: 17px; }
.mdx-lens-tool:hover { color: #fff; background: rgba(255, 255, 255, 0.09); }
.mdx-lens-tool:active { transform: scale(0.95); }
.mdx-lens-tool.is-on { color: #9cc6ff; background: rgba(125, 180, 255, 0.16); }

/* On a result the toolbar owns the bottom of the stage, so the spatial rail
   moves above it rather than sharing the line.

   This offset is published as a variable because the Baihaqi mark is placed
   directly above the rail and has to be derived from where the rail actually
   is. It used to be a second, independent number, and when this one moved to
   66px the mark stayed at 54px — i.e. it sat ON the rail and swallowed the
   taps meant for "Regions" and "Coverage". */
body.mdx.mdx-lens-result { --mdx-lsp-rail-b: 66px; }
body.mdx.mdx-lens-result #lspRail { bottom: var(--mdx-lsp-rail-b) !important; }

/* The report stays a light reading surface even in the dark workstation:
   long clinical text on a dark panel is not what a report is read on. */
body.mdx[data-mdx-section="lens"] .lens-screen .lens-sheet .lens-sheet-panel {
  background: #ffffff;
  color: #0e1726;
}
body.mdx[data-mdx-section="lens"] .lens-screen .lens-sheet .lens-sheet-head h3,
body.mdx[data-mdx-section="lens"] .lens-screen .lens-answer { color: #0e1726; }
body.mdx[data-mdx-section="lens"] .lens-screen .lens-safety { color: #5f6c80; }
body.mdx[data-mdx-section="lens"] .mdx-actions .mdx-chip {
  background: #fff;
  border-color: rgba(14, 23, 38, 0.1);
  color: #33415a;
}
body.mdx[data-mdx-section="lens"] .mdx-teach-legend { background: #f7f9fc; }
body.mdx[data-mdx-section="lens"] .mdx-teach-legend h4 { color: #0e1726; }
body.mdx[data-mdx-section="lens"] .mdx-teach-legend li { background: #fff; }
body.mdx[data-mdx-section="lens"] .mdx-teach-legend strong { color: #0e1726; }

/* The classic build hides all app chrome for "true full screen" Lens. Under
   the shell Lens is a MODE of the home surface rather than a separate
   immersive page, so the navigation stays — that is the whole point of taking
   Lens out of the navigation and putting it in the switch. */
body.mdx.lens-immersive .bottom-nav.mdx-nav { display: flex !important; }
@media (min-width: 1024px) {
  body.mdx.lens-immersive .bottom-nav.mdx-nav { display: flex !important; flex-direction: column; }
}

/* The classic sheet styles .bottom-nav-item span as a 25px gradient icon
   bubble, because that is what the span used to hold. Here the span is the
   text label, so it has to be reset to being text — otherwise every label is
   a grey circle with three clipped characters in it.

   Scoped away from the Profile avatar, which is the one span in this bar that
   IS meant to be a circle. Without the exclusion these !important resets
   flattened it to the size of its own initials. */
body.mdx .bottom-nav.mdx-nav .mdx-nav-item span:not(.mdx-nav-avatar) {
  width: auto !important;
  height: auto !important;
  min-width: 0 !important;
  padding: 0 !important;
  margin: 0 !important;
  border: 0 !important;
  border-radius: 0 !important;
  background: none !important;
  box-shadow: none !important;
  font-size: inherit !important;
  font-weight: inherit !important;
  line-height: 1;
  color: inherit;
  display: block;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* The specular sheen and the focus fill were both tuned for warm-white glass:
   a 50% white highlight and a #fff focus state read as "solid white panel"
   over the dark workstation. Both are re-pitched for the dark environment. */
body.mdx[data-mdx-section="lens"] .mdx-bar::after,
body.mdx[data-mdx-section="lens"] .bottom-nav.mdx-nav::after {
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.09), rgba(255, 255, 255, 0));
}
body.mdx[data-mdx-section="lens"] .mdx-bar-field:focus-within {
  background: rgba(255, 255, 255, 0.13);
  border-color: rgba(125, 180, 255, 0.6);
  box-shadow: 0 0 0 4px rgba(125, 180, 255, 0.16);
}
body.mdx[data-mdx-section="lens"] .mdx-switch-thumb {
  background: rgba(255, 255, 255, 0.16);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.18), 0 2px 8px rgba(0, 0, 0, 0.4);
}
body.mdx[data-mdx-section="lens"] .mdx-bar-send {
  background: linear-gradient(180deg, #4d92ff, #1769ff);
  box-shadow: 0 2px 10px rgba(23, 105, 255, 0.4);
}
body.mdx[data-mdx-section="lens"] .mdx-shutter::before { border-color: rgba(226, 236, 250, 0.3); }
body.mdx[data-mdx-section="lens"] .mdx-shutter::after {
  background: linear-gradient(180deg, #f2f6fc, #d9e3f0);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9), 0 2px 10px rgba(0, 0, 0, 0.5);
}

/* The spatial detail sheet stays in the DOM between selections and is only
   translated out of view, which leaves a white sliver at the edge of the dark
   workstation. It has nothing to show unless it is open. */
body.mdx #lspSheet:not(.open) { display: none !important; }

/* ==========================================================================
   33. Explanation ↔ image
   ==========================================================================
   A finding named in the report or in Baihaqi's reply is tappable, and
   tapping it selects that structure through the spatial layer's own hit
   test. It is styled as a quiet underline rather than a button: it is still
   prose, and every other word around it is too.
   ========================================================================== */

.mdx-imglink {
  display: inline;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  text-decoration: underline;
  text-decoration-style: dotted;
  text-decoration-thickness: 1.5px;
  text-underline-offset: 3px;
  text-decoration-color: rgba(23, 105, 255, 0.55);
  cursor: pointer;
  transition: background 0.18s var(--mdx-ease), text-decoration-color 0.18s var(--mdx-ease);
  border-radius: 4px;
}
.mdx-imglink:hover {
  background: var(--mdx-blue-wash);
  text-decoration-color: var(--mdx-blue);
}
.mdx-imglink:active { background: rgba(23, 105, 255, 0.16); }
body.mdx[data-mdx-section="lens"] .bfs .mdx-imglink { text-decoration-color: rgba(125, 180, 255, 0.7); }

/* Baihaqi IS the page on Home and the mark on a Lens result, so the floating
   companion apparatus has nothing left to do; its container was ghosting a
   mascot and a tip bubble behind the composer. */
body.mdx #aiCompanionContainer { display: none !important; }
body.mdx.mdx-guiding #aiCompanionContainer,
body.mdx #aiCompanionContainer.is-guiding { display: block !important; }

/* On a Lens result the composer stands down, so --mdx-bar-h collapses to 0
   and the mode switch drops to just above the navigation — straight onto the
   floating Baihaqi mark. The mark stacks above the switch instead. */
body.mdx.mdx-lens-result .mdx-ai-fab {
  bottom: calc(var(--mdx-rail-h) + 96px + env(safe-area-inset-bottom, 0px));
}

/* Landscape on a phone with a result loaded is genuinely over-subscribed: a
   289px stage already carries the viewer controls, the Spatial Intelligence
   rail and the viewer toolbar, with the switch, composer and navigation below
   it. There is no honest position left for the floating Baihaqi mark, so it
   stands down there — "Explain" in the result action strip and + Tools reach
   the same conversation, so nothing is lost but the shortcut. */
@media (max-height: 480px) and (orientation: landscape) {
  body.mdx.mdx-lens-result .mdx-ai-fab { display: none; }
}

/* ==========================================================================
   34. Lens: the idle hero is idle-only
   ==========================================================================
   "MedDex Lens · Spatial Intelligence · Scan, upload, or open a case" answers
   a question the user has already answered the moment they hand over an
   image. It was gated only on "is there a report yet", so it stayed on screen
   through capture and the whole analysis, on top of the image being read.

   The JS now renders it only when Lens is genuinely idle; these rules are the
   belt to that braces — anything capture-only is also switched off by state,
   so a late class change cannot flash the hero back over a scan.
   ========================================================================== */

body.mdx.mdx-lens-analyzing .mdx-lens-intro,
body.mdx.mdx-lens-result .mdx-lens-intro,
body.mdx .lens-screen.lens-has-image .mdx-lens-intro,
body.mdx .lens-screen.lens-analyzing .mdx-lens-intro { display: none !important; }

/* The framing reticle, the drop hint and the modality/credits header are all
   about choosing an image. Once one is being read they are noise over it. */
body.mdx.mdx-lens-analyzing .lens-screen .lens-reticle,
body.mdx.mdx-lens-analyzing .lens-screen .lens-dropzone-hint,
body.mdx.mdx-lens-analyzing .lens-screen #lensUsageBadge,
body.mdx .lens-screen.lens-has-image .lens-reticle,
body.mdx .lens-screen.lens-has-image .lens-dropzone-hint { display: none !important; }

/* Progress belongs where the shutter was. */
.mdx-lens-status {
  margin: 0;
  padding: 0 8px;
  max-width: 100%;
  font-size: 0.78rem;
  font-weight: 620;
  letter-spacing: -0.012em;
  color: var(--mdx-ink-2);
  text-align: center;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
body.mdx.mdx-lens-analyzing .mdx-bar-capture { gap: 12px; }


/* ===========================================================================
   35. Keyboard-safe composer
   ---------------------------------------------------------------------------
   On phones the software keyboard does not shrink the layout viewport, so a
   bar anchored to the bottom of the page ends up underneath it. --mdx-kb
   carries the measured overlap (see the visualViewport watcher in
   meddex-experience.js) and the composer rides on top of it.

   While the keyboard is up the bottom navigation and the safe-area inset are
   both behind it, so their reservations are dropped rather than added - that
   was the difference between "just above the keys" and "half a nav bar too
   high".
   ========================================================================= */

body.mdx { --mdx-kb: 0px; }

body.mdx.mdx-keyboard .mdx-bar {
  bottom: calc(var(--mdx-kb) + 10px);
  /* Following the keyboard's own easing keeps the field from lagging behind
     the keys as they slide up. */
  transition:
    bottom 0.18s var(--mdx-ease),
    transform 0.42s var(--mdx-ease-spring),
    opacity 0.24s var(--mdx-ease);
}

/* The composer must be reachable, so it never rides out on scroll while the
   keyboard is up. */
body.mdx.mdx-keyboard .mdx-bar.is-hidden {
  transform: translateX(-50%);
  opacity: 1;
  pointer-events: auto;
}

/* No room for the mode switch or the nav above an open keyboard, and both
   would only crowd the field being typed into. Keyed on FOCUS as well as on
   the measured keyboard, so a browser whose keyboard we fail to measure still
   gets the switch out of the composer's way. */
body.mdx.mdx-keyboard .mdx-switch,
body.mdx.mdx-composer-focus .mdx-switch { opacity: 0; pointer-events: none; }
/* translateX(-50%) is what CENTRES the bar (it is positioned at left:50%), so
   a transform that only names translateY silently un-centres it: the nav
   slides down AND 187px to the right, and lands half outside the viewport.
   Both hide transforms therefore restate the centring. */
body.mdx.mdx-keyboard .bottom-nav,
body.mdx.mdx-composer-focus .bottom-nav { transform: translateX(-50%) translateY(120%); }

/* A composer with the caret in it is never scrolled away, whatever the
   viewport reports. */
body.mdx.mdx-composer-focus .mdx-bar.is-hidden {
  transform: translateX(-50%);
  opacity: 1;
  pointer-events: auto;
}

/* The Baihaqi sheet is anchored to --mdx-bottom-budget and sized from 100dvh.
   Neither shrinks when the keyboard opens, so the sheet stayed put: its lower
   third went behind the keys, and the composer - which had correctly moved up
   - landed in the middle of the sheet, on top of the conversation. That is the
   "the text field disappears when I tap Ask Baihaqi AI" report.

   With the keyboard up the stack is, bottom to top: keys, composer, sheet. */
body.mdx.mdx-keyboard .bfs {
  bottom: calc(var(--mdx-kb) + var(--mdx-bar-h) + 24px) !important;
  height: max(
    180px,
    calc(100dvh - var(--mdx-kb) - var(--mdx-bar-h) - 96px - env(safe-area-inset-top, 0px))
  ) !important;
  transition: bottom 0.18s var(--mdx-ease), height 0.18s var(--mdx-ease), opacity 0.3s var(--mdx-ease);
}

/* Same reasoning for the compact chat bubble, which anchors to the bottom of
   the viewport in the contexts that still use it. */
body.mdx.mdx-keyboard .baihaqi-chat-panel,
body.mdx.mdx-keyboard .baihaqi-chat {
  bottom: calc(var(--mdx-kb) + 12px) !important;
}

/* Whatever the context, a composer the user is typing into is never scrolled
   away or faded out. mdx-bar covers Home Chat, Lens, Quiz and OSCE because the
   shell routes all four through it; these cover any surface that kept its own. */
body.mdx.mdx-keyboard .bfs-composer,
body.mdx.mdx-keyboard .baihaqi-chat-input,
body.mdx.mdx-keyboard #osceAsk {
  opacity: 1 !important;
  visibility: visible !important;
  transform: none !important;
}

/* ===========================================================================
   36. OSCE patient chat: the question box stays put
   ---------------------------------------------------------------------------
   Scrolling back through what the patient said must not take away the means
   to ask the next question. Inside the patient stage the composer is pinned
   for the whole encounter and only leaves when the stage does.
   ========================================================================= */

body.mdx.mdx-osce-chat .mdx-bar.is-hidden {
  transform: translateX(-50%);
  opacity: 1;
  pointer-events: auto;
}

/* ===========================================================================
   37. Lens readability — the report must be legible over any image
   ---------------------------------------------------------------------------
   Two different problems were being solved with one treatment. Chrome that
   floats OVER the image needs enough backdrop to survive a bright lung field
   or a black CT window; text INSIDE the report panel needs hierarchy, so the
   eye can find the finding, then its evidence, then its caveats, without
   reading every line.

   Glass is kept — this is still the same material — but over the image it is
   nearly opaque, because a clinical sentence read through a blurred radiograph
   is not readable at any font weight.
   ========================================================================= */

/* Anatomy labels sat at 0.72 alpha, which over a white lung field lightened to
   roughly 3:1 against their own text. */
body.mdx .lens-overlay-label.anatomical {
  background: rgba(9, 18, 36, 0.93) !important;
  color: #eaf4ff !important;
  border-color: rgba(160, 214, 255, 0.72) !important;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.45), 0 0 0 1px rgba(0, 0, 0, 0.25) !important;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.55);
  font-weight: 850;
}
body.mdx .lens-overlay-label.abnormal {
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
  box-shadow: 0 0 0 6px rgba(0, 0, 0, 0.18), 0 8px 22px rgba(0, 0, 0, 0.4) !important;
}

/* Slider and tool captions live directly on the image in Lens's dark
   workstation, where a mid-grey caption disappears against mid-grey tissue. */
body.mdx[data-mdx-section="lens"] .lens-slider-label,
body.mdx[data-mdx-section="lens"] .lens-tool-caption,
body.mdx[data-mdx-section="lens"] .lens-range-value {
  color: #f2f7ff !important;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.75);
  font-weight: 650;
}

/* ------------------------------------------------------- visual phenotype */

.lens-phenotype { margin: 10px 0 0; }
.lens-pheno-title,
.lens-conf-title,
.lens-measure-title {
  display: block;
  font-size: 0.68rem;
  font-weight: 800;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--mdx-muted, #5a6577);
  margin-bottom: 6px;
}
.lens-pheno-grid {
  display: grid;
  grid-template-columns: minmax(88px, auto) 1fr;
  gap: 4px 12px;
  margin: 0;
  padding: 9px 11px;
  border-radius: 12px;
  background: rgba(12, 35, 64, 0.045);
  border: 1px solid rgba(12, 35, 64, 0.09);
}
.lens-pheno-row { display: contents; }
.lens-pheno-grid dt {
  font-size: 0.72rem;
  font-weight: 700;
  /* Deliberately the quieter half of the pair: the axis name is scaffolding,
     the value is the finding. */
  color: #5d6a7d;
}
.lens-pheno-grid dd {
  margin: 0;
  font-size: 0.78rem;
  font-weight: 620;
  color: #10233d;
  line-height: 1.35;
}

/* ----------------------------------------------------- confidence by layer */

.lens-conf-layers { margin: 12px 0 0; }
.lens-conf-row { display: flex; flex-wrap: wrap; gap: 6px; }
.lens-conf-cell {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 6px 10px;
  border-radius: 10px;
  border: 1px solid transparent;
  min-width: 92px;
}
.lens-conf-key { font-size: 0.64rem; font-weight: 750; letter-spacing: 0.03em; opacity: 0.78; }
.lens-conf-grade { font-size: 0.76rem; font-weight: 800; text-transform: capitalize; }
/* Three states, distinguishable by more than hue: the fill weight and the
   border change too, so this still reads without colour vision. */
.lens-conf-high { background: rgba(16, 122, 87, 0.12); border-color: rgba(16, 122, 87, 0.34); color: #0a5c41; }
.lens-conf-moderate { background: rgba(166, 108, 10, 0.12); border-color: rgba(166, 108, 10, 0.32); color: #7a4f06; }
.lens-conf-low { background: rgba(158, 45, 45, 0.11); border-color: rgba(158, 45, 45, 0.3); color: #8a2b2b; }
em.lens-conf-grade { padding: 2px 8px; border-radius: 999px; font-size: 0.68rem; font-style: normal; margin-left: 8px; }

/* ------------------------------------------------------------ measurements */

.lens-measurements { margin: 12px 0 0; }
.lens-measure-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.lens-measure-row {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 2px 10px;
  padding: 8px 11px;
  border-radius: 12px;
  background: rgba(12, 35, 64, 0.045);
  border: 1px solid rgba(12, 35, 64, 0.09);
}
.lens-measure-name { font-size: 0.78rem; font-weight: 700; color: #10233d; }
.lens-measure-value {
  font-size: 0.86rem;
  font-weight: 850;
  color: #0b2d52;
  font-variant-numeric: tabular-nums;
}
.lens-measure-basis {
  grid-column: 1 / -1;
  font-size: 0.68rem;
  line-height: 1.4;
  color: #5d6a7d;
}
/* An uncalibrated value is marked on its face, not only in the footnote: this
   is the difference between a measurement and a proportion. */
.lens-measure-row.is-uncalibrated {
  background: rgba(166, 108, 10, 0.07);
  border-color: rgba(166, 108, 10, 0.26);
}
.lens-measure-row.is-uncalibrated .lens-measure-value { color: #7a4f06; }

/* --------------------------------------------------------- reasoning chain */

.lens-reasoning { display: flex; flex-direction: column; gap: 12px; }
.lens-reason-step { position: relative; padding-left: 14px; }
.lens-reason-step::before {
  content: "";
  position: absolute;
  left: 0; top: 4px; bottom: 4px;
  width: 3px;
  border-radius: 3px;
  background: linear-gradient(180deg, rgba(22, 119, 255, 0.55), rgba(22, 119, 255, 0.12));
}
.lens-reason-tag {
  display: inline-block;
  font-size: 0.64rem;
  font-weight: 850;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: #2a5fa8;
  margin-bottom: 4px;
}
.lens-reason-chain {
  margin: 0;
  font-size: 0.8rem;
  line-height: 1.5;
  color: #24344b;
  font-weight: 560;
}
.lens-reason-favored {
  margin: 0;
  font-size: 0.98rem;
  font-weight: 800;
  letter-spacing: -0.01em;
  color: #0b1f38;
  line-height: 1.35;
}
.lens-reason-why { margin: 4px 0 0; font-size: 0.78rem; line-height: 1.5; color: #45536a; }

.lens-dd-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.lens-dd-item {
  padding: 9px 11px;
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.72);
  border: 1px solid rgba(12, 35, 64, 0.1);
}
.lens-dd-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.lens-dd-head strong { font-size: 0.84rem; font-weight: 780; color: #0b1f38; }
.lens-dd-likelihood {
  flex-shrink: 0;
  font-style: normal;
  font-size: 0.64rem;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 2px 8px;
  border-radius: 999px;
}
.lens-dd-likely .lens-dd-likelihood { background: rgba(16, 122, 87, 0.14); color: #0a5c41; }
.lens-dd-possible .lens-dd-likelihood { background: rgba(22, 119, 255, 0.13); color: #1a4f9c; }
.lens-dd-less_likely .lens-dd-likelihood { background: rgba(166, 108, 10, 0.14); color: #7a4f06; }
.lens-dd-unlikely .lens-dd-likelihood { background: rgba(90, 101, 119, 0.14); color: #4b5769; }
.lens-dd-for, .lens-dd-against { margin: 5px 0 0; font-size: 0.74rem; line-height: 1.45; color: #3a4759; }
.lens-dd-for span, .lens-dd-against span {
  display: inline-block;
  font-weight: 800;
  font-size: 0.62rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  margin-right: 6px;
}
.lens-dd-for span { color: #0a5c41; }
.lens-dd-against span { color: #8a2b2b; }

/* Lens runs its report on a dark workstation ground; every colour above is
   restated for it rather than left to inherit into illegibility. */
body.mdx[data-mdx-section="lens"] .lens-pheno-grid,
body.mdx[data-mdx-section="lens"] .lens-measure-row {
  background: rgba(255, 255, 255, 0.07);
  border-color: rgba(170, 210, 255, 0.2);
}
body.mdx[data-mdx-section="lens"] .lens-pheno-grid dt,
body.mdx[data-mdx-section="lens"] .lens-measure-basis,
body.mdx[data-mdx-section="lens"] .lens-reason-why { color: #b9cbe4; }
body.mdx[data-mdx-section="lens"] .lens-pheno-grid dd,
body.mdx[data-mdx-section="lens"] .lens-measure-name,
body.mdx[data-mdx-section="lens"] .lens-measure-value,
body.mdx[data-mdx-section="lens"] .lens-reason-chain,
body.mdx[data-mdx-section="lens"] .lens-reason-favored,
body.mdx[data-mdx-section="lens"] .lens-dd-head strong { color: #f2f7ff; }
body.mdx[data-mdx-section="lens"] .lens-dd-item {
  background: rgba(255, 255, 255, 0.06);
  border-color: rgba(170, 210, 255, 0.2);
}
body.mdx[data-mdx-section="lens"] .lens-dd-for,
body.mdx[data-mdx-section="lens"] .lens-dd-against { color: #cfe0f5; }
body.mdx[data-mdx-section="lens"] .lens-reason-tag { color: #7fc4ff; }
body.mdx[data-mdx-section="lens"] .lens-pheno-title,
body.mdx[data-mdx-section="lens"] .lens-conf-title,
body.mdx[data-mdx-section="lens"] .lens-measure-title { color: #a9c0dc; }
body.mdx[data-mdx-section="lens"] .lens-conf-high { background: rgba(52, 211, 153, 0.16); border-color: rgba(52, 211, 153, 0.4); color: #6ee7b7; }
body.mdx[data-mdx-section="lens"] .lens-conf-moderate { background: rgba(251, 191, 36, 0.16); border-color: rgba(251, 191, 36, 0.4); color: #fcd34d; }
body.mdx[data-mdx-section="lens"] .lens-conf-low { background: rgba(248, 113, 113, 0.16); border-color: rgba(248, 113, 113, 0.4); color: #fca5a5; }
body.mdx[data-mdx-section="lens"] .lens-dd-for span { color: #6ee7b7; }
body.mdx[data-mdx-section="lens"] .lens-dd-against span { color: #fca5a5; }
body.mdx[data-mdx-section="lens"] .lens-measure-row.is-uncalibrated {
  background: rgba(251, 191, 36, 0.1);
  border-color: rgba(251, 191, 36, 0.34);
}
body.mdx[data-mdx-section="lens"] .lens-measure-row.is-uncalibrated .lens-measure-value { color: #fcd34d; }

/* ===========================================================================
   38. Clinical result cards are opaque
   ---------------------------------------------------------------------------
   The finding cards were rgba(2, 6, 23, 0.4) — a 40% translucent panel sitting
   directly on the radiograph. Over a bright lung field the card lightened,
   the image showed through the text, and the badges (which shared one flex
   row with the finding name) crowded it from the side.

   Glass is a chrome material. It is right for a floating bar that must not
   hide the image behind it, and wrong for the sentence a student reads a
   diagnosis off. So the chrome keeps its glass and the clinical cards stop
   being translucent altogether: an opaque near-white surface whose appearance
   does not depend on what is behind it.
   ========================================================================= */

body.mdx .lens-abnormal-item {
  /* Opaque, not tinted: the card reads identically over black CT and over a
     white lung field. */
  background: #fbfcfe;
  border: 1px solid rgba(12, 35, 64, 0.14);
  border-left: 4px solid var(--lens-sev);
  border-radius: 14px;
  box-shadow: 0 1px 2px rgba(9, 22, 44, 0.06), 0 6px 18px rgba(9, 22, 44, 0.1);
  overflow: hidden;
}

/* Name on its own line, badges underneath it. A badge is metadata about the
   finding and must never sit where it can crowd the finding's own name. */
body.mdx .lens-abnormal-btn {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 7px;
  padding: 12px 14px;
  background: none;
  color: #0b1f38;
}
body.mdx .lens-finding-name {
  display: flex;
  align-items: baseline;
  gap: 9px;
  min-width: 0;
}
body.mdx .lens-abnormal-btn strong {
  /* The single most important string on the screen. */
  font-size: 1rem;
  font-weight: 780;
  line-height: 1.3;
  letter-spacing: -0.01em;
  color: #0b1f38;
  white-space: normal;
  overflow-wrap: anywhere;
}
body.mdx .lens-finding-name .lens-sev-dot {
  align-self: center;
  flex: 0 0 auto;
}
body.mdx .lens-finding-badges {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  min-width: 0;
}

/* Badges: quiet, legible, and clearly a tier below the name. Each carries its
   own solid fill so none of them depends on the surface underneath. */
body.mdx .lens-finding-badges .lens-tier-tag,
body.mdx .lens-finding-badges .lens-sev-tag {
  font-size: 0.63rem;
  font-weight: 800;
  letter-spacing: 0.045em;
  text-transform: uppercase;
  border-radius: 999px;
  padding: 3px 8px;
  white-space: nowrap;
}
body.mdx .lens-finding-badges .lens-tier-tag { border: 1px solid transparent; }
body.mdx .lens-tier-confirmed { background: rgba(16, 122, 87, 0.13); color: #0a5c41; border-color: rgba(16, 122, 87, 0.3) !important; }
body.mdx .lens-tier-highly_likely { background: rgba(22, 119, 255, 0.12); color: #1a4f9c; border-color: rgba(22, 119, 255, 0.3) !important; }
body.mdx .lens-tier-probable { background: rgba(166, 108, 10, 0.14); color: #7a4f06; border-color: rgba(166, 108, 10, 0.32) !important; }
body.mdx .lens-tier-uncertain,
body.mdx .lens-tier-low-confidence { background: rgba(90, 101, 119, 0.13); color: #47536a; border-color: rgba(90, 101, 119, 0.3) !important; }
body.mdx .lens-class-observation { background: rgba(90, 101, 119, 0.1); color: #46536a; border-color: rgba(90, 101, 119, 0.26) !important; }
body.mdx .lens-class-imaging_sign { background: rgba(109, 74, 168, 0.12); color: #55348c; border-color: rgba(109, 74, 168, 0.3) !important; }
body.mdx .lens-class-diagnosis { background: rgba(22, 119, 255, 0.12); color: #1a4f9c; border-color: rgba(22, 119, 255, 0.3) !important; }
body.mdx .lens-finding-badges .lens-sev-tag {
  background: color-mix(in srgb, var(--lens-sev) 20%, #fff);
  color: color-mix(in srgb, var(--lens-sev) 72%, #101b2c);
  border: 1px solid color-mix(in srgb, var(--lens-sev) 42%, transparent);
}
body.mdx .lens-finding-badges .lens-why {
  margin-left: auto;
  font-size: 0.68rem;
  font-weight: 750;
  color: #1a4f9c;
  background: rgba(22, 119, 255, 0.1);
  border-radius: 999px;
  padding: 3px 10px;
}
body.mdx .lens-finding-badges .lens-noloc {
  font-size: 0.58rem;
  font-weight: 800;
  letter-spacing: 0.04em;
  color: #6a5304;
  background: rgba(166, 108, 10, 0.12);
  border-radius: 6px;
  padding: 3px 7px;
}

/* The body of the card: description, location, measurements, reasoning. */
body.mdx .lens-abnormal-explain {
  padding: 0 14px 13px;
  font-size: 0.82rem;
  line-height: 1.55;
  color: #24344b;
  border-top: 1px solid rgba(12, 35, 64, 0.08);
  padding-top: 11px;
  margin-top: 2px;
}
body.mdx .lens-abnormal-explain p { margin: 0 0 8px; }
body.mdx .lens-abnormal-explain p:last-child { margin-bottom: 0; }
/* Each paragraph leads with its own label; make that label the anchor the eye
   scans down, and the prose the thing it stops on. */
body.mdx .lens-abnormal-explain p > strong {
  display: block;
  font-size: 0.64rem;
  font-weight: 800;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: #5d6a7d;
  margin-bottom: 2px;
}
body.mdx .lens-observation { color: #10233d; font-weight: 560; }

/* The same treatment for the other result lists, which share the surface. */
body.mdx .lens-uncertain-list > li,
body.mdx .lens-low-confidence-list > li {
  background: #fbfcfe;
  border: 1px solid rgba(12, 35, 64, 0.14);
  color: #24344b;
  border-radius: 12px;
}
body.mdx .lens-uncertain-list > li strong { color: #0b1f38; }

/* The report groups the cards sit in stop being translucent too, so a card is
   never read through two layers of the image at once. */
body.mdx[data-mdx-section="lens"] .lens-report-group,
body.mdx[data-mdx-section="lens"] .lens-report-section {
  background: rgba(252, 253, 255, 0.97);
  border-color: rgba(12, 35, 64, 0.12);
}

/* The blocks added with the finding-first work were written for the dark
   workstation ground. On an opaque light card they take the light palette. */
body.mdx[data-mdx-section="lens"] .lens-abnormal-item .lens-pheno-grid,
body.mdx[data-mdx-section="lens"] .lens-abnormal-item .lens-measure-row {
  background: rgba(12, 35, 64, 0.045);
  border-color: rgba(12, 35, 64, 0.1);
}
body.mdx[data-mdx-section="lens"] .lens-abnormal-item .lens-pheno-grid dt,
body.mdx[data-mdx-section="lens"] .lens-abnormal-item .lens-measure-basis { color: #5d6a7d; }
body.mdx[data-mdx-section="lens"] .lens-abnormal-item .lens-pheno-grid dd,
body.mdx[data-mdx-section="lens"] .lens-abnormal-item .lens-measure-name,
body.mdx[data-mdx-section="lens"] .lens-abnormal-item .lens-measure-value { color: #10233d; }
body.mdx[data-mdx-section="lens"] .lens-abnormal-item .lens-pheno-title,
body.mdx[data-mdx-section="lens"] .lens-abnormal-item .lens-conf-title,
body.mdx[data-mdx-section="lens"] .lens-abnormal-item .lens-measure-title { color: #5d6a7d; }
body.mdx[data-mdx-section="lens"] .lens-abnormal-item .lens-conf-high { background: rgba(16, 122, 87, 0.12); border-color: rgba(16, 122, 87, 0.34); color: #0a5c41; }
body.mdx[data-mdx-section="lens"] .lens-abnormal-item .lens-conf-moderate { background: rgba(166, 108, 10, 0.12); border-color: rgba(166, 108, 10, 0.32); color: #7a4f06; }
body.mdx[data-mdx-section="lens"] .lens-abnormal-item .lens-conf-low { background: rgba(158, 45, 45, 0.11); border-color: rgba(158, 45, 45, 0.3); color: #8a2b2b; }
body.mdx[data-mdx-section="lens"] .lens-abnormal-item .lens-measure-row.is-uncalibrated {
  background: rgba(166, 108, 10, 0.07);
  border-color: rgba(166, 108, 10, 0.26);
}
body.mdx[data-mdx-section="lens"] .lens-abnormal-item .lens-measure-row.is-uncalibrated .lens-measure-value { color: #7a4f06; }

/* Overlay labels ON the image get a solid backing rather than a tint: they are
   the one piece of text that genuinely cannot control what is behind it. */
body.mdx .lens-overlay-label.anatomical {
  background: #0b1526 !important;
  color: #f2f8ff !important;
  border-color: rgba(190, 226, 255, 0.55) !important;
  text-shadow: none;
}
body.mdx .lens-overlay-label.abnormal {
  background: color-mix(in srgb, var(--lens-sev, #ff9f0a) 88%, #0b1526) !important;
  color: #fff !important;
  border-color: #fff !important;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
}


/* ===========================================================================
   39. The Baihaqi mark never floats over the report
   ---------------------------------------------------------------------------
   The mark is anchored to the navigation. On a Lens result the report sheet
   rises over the lower half of the screen, so that anchor put the mark inside
   the report's own content area — on top of the clinical text, and touching
   the action strip as soon as the finding cards grew a line.

   In result mode it is anchored to the SHEET instead: --mdx-sheet-top is the
   measured top edge of the results panel, so the mark sits over the image
   above it whatever the report contains. No pixel offset to re-tune when the
   cards change shape.
   ========================================================================= */

body.mdx.mdx-lens-result .mdx-ai-fab {
  /* Pinned into the stage (see dockAiFab), directly above the spatial rail
     that occupies the stage's own foot. Both belong to the image, so both
     scroll away together when the reader moves down to the report.

     Cleared from the rail's OWN offset plus the rail's measured height, so
     the mark keeps its 12px gap wherever the rail is put. */
  position: absolute;
  right: 12px;
  bottom: calc(var(--mdx-lsp-rail-b, 12px) + var(--mdx-lsp-rail-h, 34px) + 12px);
}

/* In cramped phone landscape the stage is short enough that the mark would
   crowd the image itself. Baihaqi stays reachable from Explain in the action
   strip. */
@media (orientation: landscape) and (max-height: 560px) {
  body.mdx.mdx-lens-result .mdx-ai-fab { display: none; }
}

/* ===========================================================================
   40. Baihaqi answers — built to be scanned, not read
   ---------------------------------------------------------------------------
   The answer is now real block markup (see formatAiAnswer), so the spacing can
   come from the stylesheet instead of from stacked <br>s. The rhythm is what
   does the work here: a student on a ward should be able to find the
   management line without reading the definition.

   Two rules make that happen. Space BETWEEN blocks is larger than space WITHIN
   a block, so groups separate at a glance. And a heading binds to what follows
   it — bigger margin above than below — so it reads as a lid on its section
   rather than as a line floating between two.
   ========================================================================= */

.bchat-msg .ai-heading,
.ai-message .ai-heading {
  /* Bound to the section beneath it. */
  margin: 16px 0 6px;
  line-height: 1.3;
  letter-spacing: -0.005em;
  font-weight: 800;
}
.bchat-msg > .ai-heading:first-child,
.ai-message > .ai-heading:first-child { margin-top: 0; }
.bchat-msg .ai-heading-4,
.ai-message .ai-heading-4 {
  /* Has to be visibly bigger than the body, not a rounding error above it:
     0.9rem against a 0.88rem bubble was a 0.4px difference on a phone. */
  font-size: 1.02rem;
}
.bchat-msg .ai-heading-5,
.ai-message .ai-heading-5 {
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  opacity: 0.92;
}

.bchat-msg p,
.ai-message p {
  margin: 0 0 10px;
  /* Loose enough that a wrapped clinical sentence does not look like one
     block of grey. */
  line-height: 1.6;
}
.bchat-msg p:last-child,
.ai-message p:last-child { margin-bottom: 0; }

/* The one-line summary: read it and stop, or carry on. */
.bchat-msg .ai-lede,
.ai-message .ai-lede {
  font-size: 0.92rem;
  font-weight: 620;
  line-height: 1.5;
  margin-bottom: 12px;
}

.bchat-msg .ai-list,
.ai-message .ai-list {
  margin: 0 0 12px;
  padding-left: 20px;
  display: flex;
  flex-direction: column;
  /* Within a group: tighter than the gap between groups. */
  gap: 5px;
}
.bchat-msg .ai-list:last-child,
.ai-message .ai-list:last-child { margin-bottom: 0; }
.bchat-msg .ai-list li,
.ai-message .ai-list li {
  line-height: 1.55;
  /* A wrapped bullet hangs under its own text, not under the marker. */
  padding-left: 2px;
}
.bchat-msg ul.ai-list,
.ai-message ul.ai-list { list-style: disc; }
.bchat-msg ol.ai-list,
.ai-message ol.ai-list { list-style: decimal; }
.bchat-msg .ai-list li::marker,
.ai-message .ai-list li::marker { font-weight: 700; opacity: 0.55; }

/* A heading straight after a list still needs its air. */
.bchat-msg .ai-list + .ai-heading,
.ai-message .ai-list + .ai-heading { margin-top: 18px; }

/* Bubbles carrying a structured answer get room to breathe. A wall of text in
   a tight bubble is unreadable however well it is marked up. */
body.mdx .bfs-log .bchat-assistant,
body.mdx .baihaqi-chat-log .bchat-assistant {
  padding: 13px 15px;
  max-width: 94%;
}

/* Contrast. The assistant bubble is a near-opaque light surface and the text
   on it is near-black; the answer must not depend on the blur behind it. */
body.mdx .bfs-log .bchat-assistant {
  background: rgba(255, 255, 255, 0.96) !important;
  border-color: rgba(12, 35, 64, 0.12) !important;
  color: #16233a !important;
}
body.mdx .bfs-log .bchat-assistant .ai-heading { color: #0b1f38; }
body.mdx .bfs-log .bchat-assistant .ai-heading-5 { color: #33507d; }
body.mdx .bfs-log .bchat-assistant .ai-em,
body.mdx .bfs-log .bchat-assistant strong { color: #0b1f38; font-weight: 800; }
body.mdx .bfs-log .bchat-assistant .ai-clinical-label { color: #1a4f9c; font-weight: 850; }
body.mdx .bfs-log .bchat-assistant .ai-code {
  background: rgba(12, 35, 64, 0.07);
  color: #10233d;
  border-radius: 5px;
  padding: 1px 5px;
  font-size: 0.92em;
}

body.mdx.dark-mode .bfs-log .bchat-assistant {
  background: rgba(16, 28, 48, 0.96) !important;
  border-color: rgba(150, 210, 255, 0.2) !important;
  color: #e7f0fb !important;
}
body.mdx.dark-mode .bfs-log .bchat-assistant .ai-heading { color: #f2f8ff; }
body.mdx.dark-mode .bfs-log .bchat-assistant .ai-heading-5 { color: #a8c8ee; }
body.mdx.dark-mode .bfs-log .bchat-assistant .ai-em,
body.mdx.dark-mode .bfs-log .bchat-assistant strong { color: #ffffff; }
body.mdx.dark-mode .bfs-log .bchat-assistant .ai-clinical-label { color: #7fc4ff; }
body.mdx.dark-mode .bfs-log .bchat-assistant .ai-code {
  background: rgba(255, 255, 255, 0.1);
  color: #e7f0fb;
}

/* Phones: slightly larger body text and a touch more line height, because
   this is where the answer is actually read. */
@media (max-width: 520px) {
  body.mdx .bfs-log .bchat-msg { font-size: 0.9rem; }
  body.mdx .bfs-log .bchat-assistant p,
  body.mdx .bfs-log .bchat-assistant .ai-list li { line-height: 1.62; }
  body.mdx .bfs-log .bchat-assistant { max-width: 96%; }
}

/* Long words - drug names, eponyms, URLs - wrap instead of forcing the bubble
   wider than the screen. */
.bchat-msg .ai-list li,
.bchat-msg p,
.ai-message .ai-list li,
.ai-message p { overflow-wrap: anywhere; }

/* ===========================================================================
   41. "More detail" chips
   ---------------------------------------------------------------------------
   Baihaqi answers only what was asked. When it has deliberately left something
   out, the choice to expand belongs to the student, so it appears as a small
   row of taps rather than as more prose. Quiet by design: this is an offer,
   not part of the answer.
   ========================================================================= */

.bchat-more {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin: -2px 0 2px;
  padding: 0 2px;
  align-self: flex-start;
  max-width: 96%;
}
.bchat-more-label {
  font-size: 0.64rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #6b7889;
  margin-right: 2px;
}
.bchat-more-chip {
  font: inherit;
  font-size: 0.74rem;
  font-weight: 650;
  line-height: 1;
  color: #1a4f9c;
  background: rgba(22, 119, 255, 0.09);
  border: 1px solid rgba(22, 119, 255, 0.26);
  border-radius: 999px;
  /* Comfortably tappable without looking like a primary action. */
  padding: 7px 12px;
  cursor: pointer;
  transition: background 140ms ease, transform 140ms ease;
}
.bchat-more-chip:hover { background: rgba(22, 119, 255, 0.16); }
.bchat-more-chip:active { transform: scale(0.96); }

body.mdx.dark-mode .bchat-more-label { color: #9db0c9; }
body.mdx.dark-mode .bchat-more-chip {
  color: #9ecbff;
  background: rgba(126, 190, 255, 0.13);
  border-color: rgba(126, 190, 255, 0.3);
}

/* ===========================================================================
   42. Answer typography — sized for reading on a phone
   ---------------------------------------------------------------------------
   The bubble was set at 0.88rem (about 14px), which is fine for chat and too
   small for a clinical answer being revised from. Body text is now 16-17px on
   a phone with a 1.55 line height, and the vertical rhythm is explicit rather
   than inherited: roughly 14px between the items inside a section and 24px
   between one section and the next, so the gap itself tells the reader where
   a section ends.
   ========================================================================= */

/* Matching the specificity of `body.mdx .bfs .bfs-log .bchat-msg`, which sets
   0.875rem for chat and would otherwise keep a clinical answer at 14px. */
body.mdx .bfs .bfs-log .bchat-assistant,
body.mdx .bfs-log .bchat-assistant,
body.mdx .ai-answer-card {
  font-size: 1rem;
  line-height: 1.55;
}

.bchat-msg .ai-heading-3,
.ai-message .ai-heading-3,
.ai-answer-card .ai-heading-3 {
  /* Relative to the bubble, not to the root: the body text grows on a phone
     and the heading has to stay ahead of it. */
  font-size: 1.18em;
  font-weight: 800;
  /* Between-section space lives above the heading that opens the section. */
  margin: 24px 0 8px;
  line-height: 1.3;
}
.bchat-msg .ai-heading-4,
.ai-message .ai-heading-4,
.ai-answer-card .ai-heading-4 {
  /* A sub-heading under an h3. It reads as subordinate through weight, case
     and tracking rather than by being smaller than the body text. */
  font-size: 0.88em;
  font-weight: 850;
  margin: 20px 0 7px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  line-height: 1.35;
  opacity: 0.9;
}
.bchat-msg > .ai-heading:first-child,
.ai-answer-card > .ai-heading:first-child { margin-top: 0; }

.bchat-msg p,
.ai-answer-card p {
  margin: 0 0 14px;
  line-height: 1.55;
}
.bchat-msg .ai-lede,
.ai-answer-card .ai-lede {
  font-size: 1.04rem;
  font-weight: 620;
  line-height: 1.5;
  margin-bottom: 16px;
}
.bchat-msg .ai-list,
.ai-answer-card .ai-list {
  margin: 0 0 14px;
  padding-left: 22px;
  gap: 8px;
}
.bchat-msg .ai-list li,
.ai-answer-card .ai-list li { line-height: 1.5; }
.bchat-msg .ai-list + .ai-heading,
.ai-answer-card .ai-list + .ai-heading { margin-top: 24px; }

/* The structured card in the main AI chat is the same material as the sheet:
   an opaque reading surface, not glass over an image. */
.ai-answer-card {
  background: #fbfcfe;
  border: 1px solid rgba(12, 35, 64, 0.12);
  border-radius: 16px;
  padding: 15px 16px;
  color: #16233a;
}
.ai-answer-card .ai-heading { color: #0b1f38; }
.ai-answer-card .ai-em, .ai-answer-card strong { color: #0b1f38; font-weight: 800; }
body.mdx.dark-mode .ai-answer-card {
  background: rgba(16, 28, 48, 0.96);
  border-color: rgba(150, 210, 255, 0.2);
  color: #e7f0fb;
}
body.mdx.dark-mode .ai-answer-card .ai-heading,
body.mdx.dark-mode .ai-answer-card .ai-em,
body.mdx.dark-mode .ai-answer-card strong { color: #f2f8ff; }

/* "More detail" in the main chat, matching the sheet's chips. */
.ai-more-detail {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  margin-top: 16px; padding-top: 13px;
  border-top: 1px solid rgba(12, 35, 64, 0.09);
}
.ai-more-label {
  font-size: 0.66rem; font-weight: 800; letter-spacing: 0.06em;
  text-transform: uppercase; color: #6b7889; margin-right: 2px;
}
.ai-more-chip {
  font: inherit; font-size: 0.8rem; font-weight: 650; line-height: 1;
  color: #1a4f9c; background: rgba(22, 119, 255, 0.09);
  border: 1px solid rgba(22, 119, 255, 0.26); border-radius: 999px;
  padding: 8px 13px; cursor: pointer;
}
.ai-more-chip:active { transform: scale(0.96); }
body.mdx.dark-mode .ai-more-label { color: #9db0c9; }
body.mdx.dark-mode .ai-more-chip {
  color: #9ecbff; background: rgba(126, 190, 255, 0.13); border-color: rgba(126, 190, 255, 0.3);
}

@media (max-width: 520px) {
  /* 17px: the top of the requested range, because this is the surface the
     answer is actually revised from. */
  body.mdx .bfs .bfs-log .bchat-assistant,
  body.mdx .bfs-log .bchat-assistant,
  body.mdx .ai-answer-card { font-size: 1.06rem; line-height: 1.55; }
}

/* ===========================================================================
   43. Profile in the navigation
   ---------------------------------------------------------------------------
   The last slot is the account, not a settings page, so it shows who is signed
   in. It occupies exactly the box the icon did, so the six slots stay evenly
   spaced whether the user has a photo or not.
   ========================================================================= */

/* The avatar is a COMPONENT, not a nav decoration.
   ---------------------------------------------------------------------------
   All of this used to be scoped to `body.mdx .bottom-nav .mdx-nav-item`, so
   the identical markup mounted in the Home header inherited none of it: no
   circle, no clipping, and object-fit defaulting to `fill`. A non-square
   account photo therefore rendered as a stretched square escaping its button —
   the "large green square" in the report. The shape now travels with the
   class, and the places that mount it only choose a size. */
.mdx-nav-avatar {
  box-sizing: border-box;
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  aspect-ratio: 1 / 1;          /* 1:1 enforced, not assumed */
  border-radius: 50%;
  overflow: hidden;             /* nothing paints outside the circle */
  background: linear-gradient(135deg, rgba(22, 119, 255, 0.16), rgba(34, 193, 238, 0.16));
  border: 1px solid rgba(12, 35, 64, 0.16);
  color: #1a4f9c;
  font-weight: 850;
  line-height: 1;
}
.mdx-nav-avatar img,
.mdx-nav-avatar svg {
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;            /* crop to fill, never distort to fit */
  border-radius: 50%;
}
.mdx-nav-avatar.has-image {
  background: rgba(12, 35, 64, 0.06);
  border-color: rgba(12, 35, 64, 0.14);
}
/* The signed-out glyph is inset so it reads as an icon in a circle rather than
   a photo cropped to one. */
.mdx-nav-avatar svg { padding: 20%; opacity: 0.7; }

body.mdx .bottom-nav.mdx-nav .mdx-nav-item .mdx-nav-avatar {
  /* !important to clear the classic sheet's `.bottom-nav-item span` bubble,
     which is itself sized in px and would otherwise win here. */
  /* border-box so the 1px ring is inside the 22px, not added to it. */
  box-sizing: border-box;
  width: 22px !important;
  height: 22px !important;
  min-width: 22px !important;
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  border-radius: 50%;
  overflow: hidden;
  /* Initials fallback: a clean monogram, not an anonymous silhouette. */
  background: linear-gradient(135deg, rgba(22, 119, 255, 0.16), rgba(34, 193, 238, 0.16));
  border: 1px solid rgba(12, 35, 64, 0.16);
  color: #1a4f9c;
  font-size: 0.6rem;
  font-weight: 850;
  letter-spacing: 0.01em;
  line-height: 1;
}
body.mdx .bottom-nav.mdx-nav .mdx-nav-item .mdx-nav-avatar.has-image {
  background: rgba(12, 35, 64, 0.06);
  border-color: rgba(12, 35, 64, 0.14);
}
body.mdx .bottom-nav.mdx-nav .mdx-nav-item .mdx-nav-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* The active slot rings the photo the way it underlines the other icons. */
body.mdx .bottom-nav.mdx-nav .mdx-nav-item.active .mdx-nav-avatar {
  border-color: var(--mdx-gold, #c9a227);
  box-shadow: 0 0 0 1.5px rgba(201, 162, 39, 0.35);
}
body.mdx.dark-mode .bottom-nav.mdx-nav .mdx-nav-item .mdx-nav-avatar {
  border-color: rgba(160, 210, 255, 0.28);
  color: #9ecbff;
}

/* ===========================================================================
   44. Answer body copy is normal weight
   ---------------------------------------------------------------------------
   The AI message block sets a heavy weight for its own labels and card titles,
   and answer paragraphs inherited it — so a whole reply rendered semi-bold and
   the bold-for-emphasis carried no meaning at all. Weight is now stated
   explicitly for body copy, and emphasis is the only thing that raises it.
   ========================================================================= */

.ai-answer-card,
.ai-answer-card p,
.ai-answer-card li,
.bchat-msg.bchat-assistant,
.bchat-msg.bchat-assistant p,
.bchat-msg.bchat-assistant li {
  font-weight: 400;
}
/* The lede is the one-line summary, and emphasis is emphasis. */
.ai-answer-card .ai-lede,
.bchat-msg.bchat-assistant .ai-lede { font-weight: 600; }
.ai-answer-card strong,
.ai-answer-card .ai-em,
.bchat-msg.bchat-assistant strong,
.bchat-msg.bchat-assistant .ai-em { font-weight: 700; }
.ai-answer-card .ai-heading,
.bchat-msg.bchat-assistant .ai-heading { font-weight: 800; }

/* ===========================================================================
   45. The way in, on Home
   ---------------------------------------------------------------------------
   A signed-out visitor needs a route to an account; a signed-in one needs
   their account. Both live in the same top-right slot so the header keeps its
   shape either way.

   Quiet on purpose. Home exists for Chat and Lens, and a filled button up here
   would pull against the one thing the page is asking you to do.
   ========================================================================= */

body.mdx .mdx-topline-end {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-left: auto;
}
body.mdx .mdx-topline-auth {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 32px;
  padding: 0 13px;
  border-radius: 999px;
  font: inherit;
  font-size: 0.78rem;
  font-weight: 650;
  letter-spacing: -0.005em;
  color: var(--mdx-ink-2, #45536a);
  background: transparent;
  border: 1px solid var(--mdx-hair-strong, rgba(12, 35, 64, 0.16));
  cursor: pointer;
  transition: background 160ms var(--mdx-ease), color 160ms var(--mdx-ease), border-color 160ms var(--mdx-ease);
  -webkit-tap-highlight-color: transparent;
}
body.mdx .mdx-topline-auth[hidden] { display: none; }
body.mdx .mdx-topline-auth.is-signed-out:hover {
  color: var(--mdx-ink, #0b1f38);
  background: rgba(12, 35, 64, 0.04);
  border-color: var(--mdx-hair-strong, rgba(12, 35, 64, 0.24));
}
body.mdx .mdx-topline-auth:active { transform: scale(0.96); }

/* Signed in it is just the avatar: no pill, no label, same footprint. */
/* A circular avatar button in EVERY state, so the header keeps its geometry
   when someone signs in: signed out it is a generic person, signed in it is
   the account photo or their initials. */
body.mdx .mdx-topline-auth.is-avatar {
  width: 38px;
  height: 38px;
  padding: 0;
  border: 0;
  background: transparent;
  border-radius: 50%;
}
body.mdx .mdx-topline-auth .mdx-nav-avatar {
  width: 36px;
  height: 36px;
  min-width: 36px;
  font-size: 0.78rem;
  /* MedDex chrome: a hairline and a soft lift, not a hard shadow. */
  box-shadow: 0 1px 2px rgba(9, 22, 44, 0.06), 0 2px 8px rgba(9, 22, 44, 0.08);
}
body.mdx .mdx-topline-auth:hover .mdx-nav-avatar { border-color: rgba(12, 35, 64, 0.28); }
body.mdx.dark-mode .mdx-topline-auth .mdx-nav-avatar {
  border-color: rgba(160, 210, 255, 0.3);
  color: #9ecbff;
}
body.mdx.dark-mode .mdx-topline-auth {
  color: #b9cbe4;
  border-color: rgba(160, 210, 255, 0.24);
}
body.mdx.dark-mode .mdx-topline-auth.is-signed-out:hover {
  color: #f2f8ff;
  background: rgba(255, 255, 255, 0.06);
}

/* ===========================================================================
   46. The selected spatial object, in the report
   ---------------------------------------------------------------------------
   A finding is one object drawn three ways: an annotation on the image, a chip
   in the rail, and a card in the report. When the image selects it, the card
   has to say so — otherwise the reader taps a lesion and the report gives no
   sign of having heard.

   Deliberately a marker, not a colour wash: the card is clinical text and must
   stay as readable selected as unselected.
   ========================================================================= */

body.mdx .lens-abnormal-item.is-spatial-selected {
  border-color: rgba(34, 193, 238, 0.55);
  box-shadow: 0 0 0 1px rgba(34, 193, 238, 0.35), 0 6px 20px rgba(9, 22, 44, 0.12);
}
body.mdx .lens-abnormal-item.is-spatial-selected .lens-abnormal-btn strong { color: #0a4f6d; }
/* The severity rail on the left doubles as the selection indicator, so nothing
   new has to be drawn into an already busy card. */
body.mdx .lens-abnormal-item.is-spatial-selected { border-left-color: #22c1ee; }

@media (prefers-reduced-motion: no-preference) {
  body.mdx .lens-abnormal-item.is-spatial-selected { transition: border-color 220ms ease, box-shadow 220ms ease; }
}

/* ===========================================================================
   47. Lens is a workspace, so the app furniture recedes
   ---------------------------------------------------------------------------
   The bottom navigation and the Chat/Lens switch are right for Home and wrong
   over a radiograph: at the collapsed stop they sit on the image, and at the
   full stop they sit on the report. Rather than hiding them outright — which
   strands the reader in Lens — they follow the sheet.

   collapsed  the reader is looking at the IMAGE: nav goes, so nothing floats
              over the film
   medium     the working stop: nav stays, this is normal navigation territory
   full       the reader has committed to the report: nav goes again so the
              text runs to the bottom of the screen

   Restored the moment the sheet comes back to medium or Lens is left.
   ========================================================================= */

body.mdx.mdx-lens-result[data-lens-sheet="collapsed"] .bottom-nav.mdx-nav,
body.mdx.mdx-lens-result[data-lens-sheet="full"] .bottom-nav.mdx-nav {
  /* Centring restated — see the note on the keyboard hide above. */
  transform: translateX(-50%) translateY(130%);
  pointer-events: none;
}
body.mdx.mdx-lens-result[data-lens-sheet="collapsed"] .mdx-switch,
body.mdx.mdx-lens-result[data-lens-sheet="full"] .mdx-switch {
  opacity: 0;
  pointer-events: none;
}
body.mdx.mdx-lens-result .bottom-nav.mdx-nav,
body.mdx.mdx-lens-result .mdx-switch {
  transition: transform 0.42s var(--mdx-ease-spring), opacity 0.28s var(--mdx-ease);
}
/* On a desktop the navigation is a side column, not a bar over the image, so
   it never needs to get out of the way. */
@media (min-width: 1024px) {
  body.mdx.mdx-lens-result[data-lens-sheet="collapsed"] .bottom-nav.mdx-nav,
  body.mdx.mdx-lens-result[data-lens-sheet="full"] .bottom-nav.mdx-nav {
    transform: translateY(-50%);
    pointer-events: auto;
  }
}

/* ===========================================================================
   48. The report is a reading surface, not glass
   ---------------------------------------------------------------------------
   The analysis panel was translucent over the image, which left the text
   sitting at roughly the contrast of a disabled control. Translucency is kept
   for chrome that floats OVER the film — where seeing through it is the point
   — and dropped for the report, where readability is.

   Three distinct levels, so the eye can tell surface from card from selection:
     ground   the sheet itself
     card     a finding or section raised off it
     selected the spatial object currently in play
   ========================================================================= */

/* ---------------------------------------------------------------------------
   The report is ONE white surface, not boxes on a grey tray.
   ---------------------------------------------------------------------------
   The panel used to be #f7f9fc with white cards sitting on it, and each
   collapsible group drew its own rounded, bordered container inside that —
   so a single finding was read through three nested surfaces. Grey behind
   white behind white is a lot of visual weight for a document whose job is to
   be read, and it made the accents that DO carry meaning (severity, selection)
   compete with borders that carry none.

   The rule now: one white sheet, and structure expressed as 1px rules and
   space. Colour is reserved for things that mean something — severity, the
   selected finding, MedDex blue and gold. Only the finding cards keep a
   surface of their own, because a finding IS a discrete object.

   Applied to the section, not to a modality, so every Lens result reads the
   same whatever was uploaded.
   ------------------------------------------------------------------------ */

body.mdx.mdx-lens-result .lens-v2 .lens-sheet-panel {
  background: #ffffff !important;
  -webkit-backdrop-filter: none !important;
  backdrop-filter: none !important;
  border-top: 1px solid rgba(12, 35, 64, 0.12) !important;
  color: #24344b;
}
/* The content areas are the same white as the sheet; they are separated by
   rules and spacing rather than by their own tinted containers. */
body.mdx.mdx-lens-result .lens-sheet-panel .lens-report-group,
body.mdx.mdx-lens-result .lens-sheet-panel .lens-report-section {
  background: #ffffff;
  border: 0;
  color: #24344b;
}
body.mdx.mdx-lens-result .lens-sheet-panel h3,
body.mdx.mdx-lens-result .lens-sheet-panel h4,
body.mdx.mdx-lens-result .lens-sheet-panel strong { color: #0b1f38; }
body.mdx.mdx-lens-result .lens-sheet-panel .lens-sheet-head {
  background: #ffffff;
  border-bottom: 1px solid rgba(12, 35, 64, 0.1);
}
body.mdx.mdx-lens-result .lens-sheet-panel .lens-sheet-scroll,
body.mdx.mdx-lens-result .lens-sheet-panel .lens-answer,
body.mdx.mdx-lens-result .lens-sheet-panel .lens-report { background: transparent; }

/* A group is a heading with a rule above it, not a card. */
body.mdx.mdx-lens-result .lens-sheet-panel .lens-group {
  background: transparent;
  border: 0;
  border-top: 1px solid rgba(12, 35, 64, 0.09);
  border-radius: 0;
  margin: 0;
  overflow: visible;
}
body.mdx.mdx-lens-result .lens-sheet-panel .lens-group:first-of-type { border-top: 0; }
body.mdx.mdx-lens-result .lens-sheet-panel .lens-group > summary {
  padding: 16px 2px 12px;
  color: #0b1f38;
  font-size: 0.95rem;
  font-weight: 760;
  letter-spacing: -0.011em;
}
body.mdx.mdx-lens-result .lens-sheet-panel .lens-group-body { padding: 0 2px 14px; }
body.mdx.mdx-lens-result .lens-sheet-panel .lens-group-chev {
  border-right-color: rgba(12, 35, 64, 0.4);
  border-bottom-color: rgba(12, 35, 64, 0.4);
}
/* The count badge is information, not decoration: quiet unless it is zero-less
   and worth reading. */
body.mdx.mdx-lens-result .lens-sheet-panel .lens-group-badge {
  background: rgba(12, 35, 64, 0.06);
  color: #3b4a61;
  font-weight: 700;
}
body.mdx.mdx-lens-result .lens-sheet-panel .lens-group[open] > summary .lens-group-badge {
  background: rgba(23, 105, 255, 0.1);
  color: #1156c9;
}

/* Sections inside a group separate with space, and a rule only when they
   genuinely follow one another. */
body.mdx.mdx-lens-result .lens-sheet-panel .lens-rep-section {
  border-top: 1px solid rgba(12, 35, 64, 0.07);
  padding-top: 14px;
  margin-top: 14px;
}
body.mdx.mdx-lens-result .lens-sheet-panel .lens-rep-section:first-child {
  border-top: 0;
  padding-top: 0;
  margin-top: 0;
}
/* Section label: secondary, so the finding names below it stay primary. */
body.mdx.mdx-lens-result .lens-sheet-panel .lens-rep-h {
  color: #5d6a7d;
  font-size: 0.7rem;
  font-weight: 750;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  margin: 0 0 9px;
}
body.mdx.mdx-lens-result .lens-sheet-panel .lens-answer p,
body.mdx.mdx-lens-result .lens-sheet-panel .lens-group-body p { color: #33415a; }

/* The hero is the top of the hierarchy: modality, then the one-line read. */
body.mdx.mdx-lens-result .lens-sheet-panel .lens-hero {
  background: transparent;
  border: 0;
  border-bottom: 1px solid rgba(12, 35, 64, 0.09);
  padding: 0 0 16px;
  margin: 0 0 4px;
}
body.mdx.mdx-lens-result .lens-sheet-panel .lens-hero-type strong {
  font-size: 0.74rem;
  font-weight: 780;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: #5d6a7d;
}
body.mdx.mdx-lens-result .lens-sheet-panel .lens-hero-impression {
  color: #0b1f38;
  font-size: 1.02rem;
  font-weight: 640;
  line-height: 1.4;
  letter-spacing: -0.012em;
}
body.mdx.mdx-lens-result .lens-sheet-panel .lens-hero-quality { color: #5d6a7d; }
body.mdx.mdx-lens-result .lens-sheet-panel .lens-conf-label { color: #5d6a7d; }
body.mdx.mdx-lens-result .lens-sheet-panel .lens-conf-num { color: #0b1f38; }
body.mdx.mdx-lens-result .lens-sheet-panel .lens-conf-track { stroke: rgba(12, 35, 64, 0.12); }

/* Secondary prose stays grey; nothing in the report is grey-on-grey. */
body.mdx.mdx-lens-result .lens-sheet-panel .lens-normal-note,
body.mdx.mdx-lens-result .lens-sheet-panel .lens-safety { color: #5d6a7d; }
body.mdx.mdx-lens-result .lens-sheet-panel .lens-normal-list li,
body.mdx.mdx-lens-result .lens-sheet-panel .lens-normal-btn {
  background: #ffffff;
  color: #24344b;
}
body.mdx.mdx-lens-result .lens-sheet-panel .lens-normal-btn strong { color: #0b1f38; }
body.mdx.mdx-lens-result .lens-sheet-panel .lens-normal-btn span { color: #5d6a7d; }
body.mdx.mdx-lens-result .lens-sheet-panel .lens-normal-list li {
  border-bottom: 1px solid rgba(12, 35, 64, 0.07);
}
body.mdx.mdx-lens-result .lens-sheet-panel .lens-normal-list li:last-child { border-bottom: 0; }

/* The three components that were still wearing the dark theme on a white
   sheet. Each was invisible as a defect in the dark build and obvious the
   moment the sheet turned white. */

/* A finding card is a discrete object, so it keeps a surface — but the surface
   is white, and its identity comes from the severity edge and a hairline. */
body.mdx.mdx-lens-result .lens-sheet-panel .lens-abnormal-item {
  background: #ffffff;
  border: 1px solid rgba(12, 35, 64, 0.1);
  border-left: 4px solid var(--lens-sev);
  box-shadow: 0 1px 2px rgba(9, 22, 44, 0.05);
}

/* Jump chips: a dark slate pill with white text, on white. They also clipped
   the finding's name to an ellipsis, which is the one string on the chip
   worth reading, so they wrap instead of truncating. */
/* The label sat BESIDE the track and took about 150px of a 390px screen, so
   a chip wide enough to hold a real finding name was wider than the track it
   lived in and was clipped mid-word. Stacking the label above the strip gives
   the names the full width of the sheet. */
body.mdx.mdx-lens-result .lens-sheet-panel .lens-jump {
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 6px;
}
body.mdx.mdx-lens-result .lens-sheet-panel .lens-jump-label {
  flex: 1 0 100%;
  color: #5d6a7d;
}
body.mdx.mdx-lens-result .lens-sheet-panel .lens-jump-chip {
  background: color-mix(in srgb, var(--lens-sev) 10%, #ffffff);
  border-color: color-mix(in srgb, var(--lens-sev) 42%, transparent);
  color: #0b1f38;
  /* Bounded by the TRACK, not by the viewport, so it can never be wider than
     the box that scrolls it. */
  max-width: 100%;
  padding: 9px 13px;
  text-align: left;
}
body.mdx.mdx-lens-result .lens-sheet-panel .lens-jump-chip .lens-jump-text {
  overflow: visible;
  text-overflow: clip;
  white-space: normal;
  line-height: 1.28;
  /* A flex child will not shrink below its content width without this, so the
     name wrapped onto a second line while the first line still ran out past
     the pill's edge. */
  min-width: 0;
  overflow-wrap: anywhere;
}
/* The count is a badge, not the last character of the word: the markup is
   `Key findings<b>1</b>`, and with <b> unstyled it read "KEY FINDINGS1". */
body.mdx.mdx-lens-result .lens-sheet-panel .lens-jump-label b {
  display: inline-grid;
  place-items: center;
  min-width: 18px;
  height: 18px;
  margin-left: 6px;
  padding: 0 5px;
  border-radius: 999px;
  background: rgba(12, 35, 64, 0.07);
  color: #3b4a61;
  font-size: 0.66rem;
  font-weight: 750;
  vertical-align: middle;
}
body.mdx.mdx-lens-result .lens-sheet-panel .lens-jump-chip:hover {
  background: color-mix(in srgb, var(--lens-sev) 20%, #ffffff);
}

/* The overlay colour key was a filled slate panel — the single heaviest grey
   box left in the report, and it explains the image rather than carrying a
   finding, so it should be the quietest thing on the page. */
body.mdx.mdx-lens-result .lens-sheet-panel .lens-legend {
  background: transparent;
  border: 0;
  border-top: 1px solid rgba(12, 35, 64, 0.07);
  border-bottom: 1px solid rgba(12, 35, 64, 0.07);
  border-radius: 0;
  padding: 10px 2px;
  margin: 12px 0;
}
body.mdx.mdx-lens-result .lens-sheet-panel .lens-legend-item { color: #5d6a7d; }

body.mdx.mdx-lens-result .lens-sheet-grabber i,
body.mdx.mdx-lens-result .lens-sheet-grabber span {
  background: rgba(12, 35, 64, 0.28) !important;
}
body.mdx.dark-mode.mdx-lens-result .lens-v2 .lens-sheet-panel {
  background: #0e1726 !important;
  border-top-color: rgba(150, 210, 255, 0.2) !important;
  color: #e7f0fb;
}
body.mdx.dark-mode.mdx-lens-result .lens-sheet-panel .lens-report-group,
body.mdx.dark-mode.mdx-lens-result .lens-sheet-panel .lens-report-section {
  background: rgba(255, 255, 255, 0.05);
  border-color: rgba(150, 210, 255, 0.18);
  color: #cfe0f5;
}
body.mdx.dark-mode.mdx-lens-result .lens-sheet-panel h3,
body.mdx.dark-mode.mdx-lens-result .lens-sheet-panel h4,
body.mdx.dark-mode.mdx-lens-result .lens-sheet-panel strong { color: #f2f8ff; }

/* ===========================================================================
   49. One primary result action, not four
   ---------------------------------------------------------------------------
   Export, Compare, Explain and MCQs were four identical chips directly under
   the title, which gave a finished read four equally loud invitations before
   the reader had even looked at it. Export is the one that ends a read, so it
   carries the weight; the rest stay available and quiet, and everything else
   is already behind More.
   ========================================================================= */

body.mdx .mdx-actions .mdx-chip.is-primary {
  background: linear-gradient(135deg, #22c1ee, #1677ff);
  border-color: transparent;
  color: #fff;
  font-weight: 700;
  box-shadow: 0 2px 8px rgba(22, 119, 255, 0.28);
}
body.mdx .mdx-actions .mdx-chip.is-primary svg { color: #fff; }
body.mdx .mdx-actions .mdx-chip.is-primary:hover { filter: brightness(1.05); }
/* The secondary chips lose their fill so the row reads as one action plus a
   set of options, rather than a wall of buttons. */
body.mdx .mdx-actions .mdx-chip:not(.is-primary) {
  background: transparent;
  border-color: rgba(12, 35, 64, 0.16);
  color: var(--mdx-ink-2, #45536a);
  font-weight: 600;
}
body.mdx .mdx-actions .mdx-chip:not(.is-primary)[aria-pressed="true"] {
  background: rgba(22, 119, 255, 0.1);
  border-color: rgba(22, 119, 255, 0.3);
  color: #1a4f9c;
}
body.mdx.dark-mode .mdx-actions .mdx-chip:not(.is-primary) {
  border-color: rgba(160, 210, 255, 0.24);
  color: #b9cbe4;
}

/* ===========================================================================
   50. Spatial transitions
   ---------------------------------------------------------------------------
   The point of every movement here is that the reader never loses their place
   on the film. Nothing slides in from off-screen and nothing cross-fades a
   whole page; things grow, settle and dim in place, so the relationship
   between a card, its annotation and the anatomy under it stays legible while
   it changes.
   ========================================================================= */

/* Card -> annotation. The card lifts fractionally as the ring fires on the
   image, which ties the two events together without moving either. */
body.mdx .lens-abnormal-item.is-spatial-selected {
  transform: translateY(-1px);
}

/* Annotation -> card. The card it belongs to arrives rather than appearing. */
@media (prefers-reduced-motion: no-preference) {
  body.mdx .lens-abnormal-item .lens-abnormal-explain:not(.hidden) {
    animation: mdxExplainIn 260ms cubic-bezier(0.22, 0.61, 0.36, 1) both;
  }
  @keyframes mdxExplainIn {
    from { opacity: 0; transform: translateY(-4px); }
    to { opacity: 1; transform: none; }
  }
}

/* Anatomy layer on. The overlays fade into position instead of snapping, so
   the reader can see WHERE they landed relative to the pathology. */
body.mdx #lensSpatialLayer .lsp-pin,
body.mdx #lensSpatialLayer .lsp-shape {
  transition: opacity 240ms var(--mdx-ease), stroke-opacity 240ms var(--mdx-ease);
}
@media (prefers-reduced-motion: no-preference) {
  body.mdx #lensSpatialLayer .lsp-pin { animation: mdxPinIn 260ms cubic-bezier(0.22, 0.61, 0.36, 1) both; }
  @keyframes mdxPinIn {
    from { opacity: 0; transform: scale(0.7); }
    to { opacity: 1; transform: none; }
  }
  /* A nudged pin must keep its offset while it arrives, or it animates to the
     wrong place and then jumps. */
  body.mdx #lensSpatialLayer .lsp-pin.nudged { animation: mdxPinInNudged 260ms cubic-bezier(0.22, 0.61, 0.36, 1) both; }
  @keyframes mdxPinInNudged {
    from { opacity: 0; transform: translate(var(--lsp-nudge-x, 0), var(--lsp-nudge-y, 0)) scale(0.7); }
    to { opacity: 1; transform: translate(var(--lsp-nudge-x, 0), var(--lsp-nudge-y, 0)); }
  }
}

/* Unrelated marks dim rather than disappear while one object is selected:
   the reader keeps the whole picture and is only told where to look. */
body.mdx.mdx-lens-result #lensSpatialLayer.has-selection .lsp-pin:not(.sel) { opacity: 0.38; }
body.mdx.mdx-lens-result #lensSpatialLayer.has-selection .lsp-shape:not(.sel) { opacity: 0.3; }

/* Sheet dragged down -> the image expands into the room it leaves. Driven by
   the stop rather than by the drag, so it settles with the sheet. */
body.mdx.mdx-lens-result .lens-v2 .lens-stage {
  transition: filter 0.42s var(--mdx-ease);
}
body.mdx.mdx-lens-result[data-lens-sheet="full"] .lens-v2 .lens-stage {
  /* Behind a full report the film recedes rather than vanishing, so the
     spatial context is still there when the sheet comes back down. */
  filter: saturate(0.9) brightness(0.82);
}

/* ===========================================================================
   51. Image chrome sits above the sheet, not under it
   ---------------------------------------------------------------------------
   The spatial rail and the Baihaqi mark are pinned to the bottom of the stage
   because they belong to the image. Now that the stage spans the full viewport
   behind the sheet, "the bottom of the stage" is the bottom of the SCREEN —
   underneath the report. They landed on top of the action strip.

   The stage's visible box is therefore clipped to the exposed image at each
   stop, so anything pinned to its foot lands just above the sheet's edge and
   moves with it.
   ========================================================================= */

body.mdx.mdx-lens-result[data-lens-sheet="collapsed"] .lens-v2 .lens-stage {
  height: var(--lens-snap-collapsed);
  bottom: auto;
}
body.mdx.mdx-lens-result[data-lens-sheet="medium"] .lens-v2 .lens-stage {
  height: var(--lens-snap-medium);
  bottom: auto;
}
/* At the full stop the report owns the screen. The film stays behind it for
   continuity, but its chrome would be buried, so it stands down. */
body.mdx.mdx-lens-result[data-lens-sheet="full"] .lens-v2 .lens-stage {
  height: 100dvh;
  bottom: auto;
}
body.mdx.mdx-lens-result[data-lens-sheet="full"] #lspRail,
body.mdx.mdx-lens-result[data-lens-sheet="full"] .mdx-ai-fab,
body.mdx.mdx-lens-result[data-lens-sheet="full"] .mdx-lens-controls {
  opacity: 0;
  pointer-events: none;
}
body.mdx.mdx-lens-result #lspRail,
body.mdx.mdx-lens-result .mdx-ai-fab,
body.mdx.mdx-lens-result .mdx-lens-controls {
  transition: opacity 0.28s var(--mdx-ease);
}
/* The stage follows the sheet rather than jumping to the next stop. */
body.mdx.mdx-lens-result .lens-v2 .lens-stage {
  transition: height 0.42s var(--mdx-ease-spring), filter 0.42s var(--mdx-ease);
}

/* An active viewer mode reads as pressed, so Pan and Measure are visibly a
   pair of states rather than two buttons that both look idle. */
body.mdx .mdx-lens-tool.is-active {
  background: rgba(34, 193, 238, 0.9);
  border-color: transparent;
  color: #04263a;
}
body.mdx .mdx-lens-tool.is-active svg { color: #04263a; }

/* Display state that belongs to the VIEW, never to the analysis. Inverting or
   mirroring changes how the film renders; the findings are unchanged, and
   Reset clears all of it. */
body.mdx.mdx-lens-inverted #lensResultImage { filter: invert(1) contrast(1) brightness(1); }
body.mdx.mdx-lens-mirrored #lensResultImage,
body.mdx.mdx-lens-mirrored #lensSpatialLayer,
body.mdx.mdx-lens-mirrored #lensOverlayLayer { transform: scaleX(-1); }
/* The labels must not read backwards inside a mirrored frame. */
body.mdx.mdx-lens-mirrored #lensSpatialLayer .lsp-pin,
body.mdx.mdx-lens-mirrored #lensSpatialLayer .lsp-legend,
body.mdx.mdx-lens-mirrored #lensOverlayLayer .lens-overlay-label { transform: scaleX(-1) translate(50%, -50%); }
body.mdx.mdx-lens-mirrored #lensSpatialLayer .lsp-legend { transform: scaleX(-1); }
/* A mirrored film says so, permanently, because left now looks like right. */
body.mdx.mdx-lens-mirrored .lens-stage::after {
  content: "MIRRORED · laterality does not apply";
  position: absolute; left: 50%; top: 10px; transform: translateX(-50%);
  padding: 4px 12px; border-radius: 999px;
  background: #7a1d1d; color: #fff;
  font: 800 10px/1 system-ui, -apple-system, "Segoe UI", sans-serif;
  letter-spacing: 0.06em; z-index: 40; pointer-events: none;
}
body.mdx.mdx-lens-annotations-off #lensSpatialLayer,
body.mdx.mdx-lens-annotations-off #lensOverlayLayer { opacity: 0; pointer-events: none; }
body.mdx #lensSpatialLayer, body.mdx #lensOverlayLayer {
  opacity: var(--mdx-annotation-opacity, 1);
  transition: opacity 200ms var(--mdx-ease);
}

/* ===========================================================================
   52. Nothing floats over the viewer's own controls
   ---------------------------------------------------------------------------
   The PWA install nudge sits at z-index 22000 and occupies the bottom of the
   screen — exactly where the Lens viewer toolbar lives. Measured with
   elementFromPoint, a tap aimed at Pan, W/L, Measure, Reset or More landed on
   the install prompt instead, so none of them could be pressed at all.

   Asking someone to install the app while they are reading a radiograph is
   the wrong moment anyway. It is deferred for the duration of the read and
   comes back when they leave.
   ========================================================================= */

body.mdx.mdx-lens-result #installPrompt,
body.mdx[data-mdx-section="lens"] #installPrompt {
  display: none !important;
}

/* The camera surface is not part of a finished read.
   Measured with elementFromPoint, #lensVideo was still receiving taps over the
   lower part of the stage after analysis, so part of the image could not be
   interrogated at all. It is retired for the duration of the result. */
body.mdx.mdx-lens-result #lensVideo,
body.mdx.mdx-lens-result .lens-camera-surface {
  display: none !important;
  pointer-events: none !important;
}

/* ==========================================================================
   Tool call-to-action
   ==========================================================================
   A Connected Apps result ends in a place to go. It used to end in the URL
   itself — a hundred characters of Canva design id and tracking parameters
   printed into the transcript — because nothing in the answer formatter
   rendered markdown links. Now the destination is a button and the address is
   never shown. */

.bchat-msg .ai-cta {
  display: inline-flex;
  align-items: center;
  gap: 0.45em;
  margin: 0.55rem 0 0.15rem;
  padding: 0.62rem 1.05rem;
  border-radius: 999px;
  background: var(--mdx-accent, #1769ff);
  color: #fff;
  font-weight: 650;
  font-size: 0.94rem;
  line-height: 1.2;
  text-decoration: none;
  box-shadow: 0 1px 2px rgba(16, 24, 40, 0.10), 0 8px 22px -10px rgba(23, 105, 255, 0.65);
  transition: transform 0.16s ease, box-shadow 0.24s ease, background 0.24s ease;
}
.bchat-msg .ai-cta:hover {
  background: color-mix(in srgb, var(--mdx-accent, #1769ff) 88%, #000);
  box-shadow: 0 2px 4px rgba(16, 24, 40, 0.12), 0 14px 30px -12px rgba(23, 105, 255, 0.75);
}
.bchat-msg .ai-cta:active { transform: translateY(1px); }
.bchat-msg .ai-cta:focus-visible { outline: 2px solid var(--mdx-accent, #1769ff); outline-offset: 3px; }
.bchat-msg .ai-cta span { transition: transform 0.2s ease; }
.bchat-msg .ai-cta:hover span { transform: translateX(2px); }

.bchat-msg .ai-link {
  color: var(--mdx-accent, #1769ff);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 0.18em;
  text-decoration-thickness: 0.08em;
}
.bchat-msg .ai-link:hover { text-decoration-thickness: 0.14em; }

/* On the dark full-screen log the accent has to lift off a near-black ground
   rather than sit on white. */
.bfs-log .bchat-assistant .ai-cta { background: #2f80ff; color: #fff; }
.bfs-log .bchat-assistant .ai-link { color: #7fb4ff; }

/* ==========================================================================
   14. The chat composer
   ==========================================================================
   ONE RECTANGLE, NOT A ROW OF OBJECTS.

   The pill it replaces was a 44px field with a send button inside it and a
   separate round Tools button floating beside it: three surfaces arguing about
   which one you were meant to press, and a text field about 140px wide on a
   phone. This is a single rounded rectangle with the question on its own line
   and its controls beneath — the field gets the whole width, the controls get
   real hit areas, and everything the message is carrying (a picture, a search
   mode, what is left of today's image allowance) is inside the same object
   rather than floating above it.

   TWO NON-NEGOTIABLES, both of which were real defects:

     * 16px text. Below 16px, iOS Safari zooms the page on focus and never
       zooms back, after which every fixed element is being positioned in units
       that no longer match the screen. Every reported "the composer jumps"
       trail ends here.
     * The surface grows to a ceiling and then scrolls INSIDE itself. A long
       question must never be able to push the send button off the screen.
   ========================================================================== */

.mdx-composer {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 12px 12px 10px;
  border-radius: 22px;
  background: var(--mdx-composer-surface, rgba(255, 255, 255, 0.96));
  border: 1px solid var(--mdx-composer-edge, rgba(14, 23, 38, 0.09));
  box-shadow: var(--mdx-composer-shadow, inset 0 1px 0 rgba(255, 255, 255, 0.9));
  transition: border-color 0.22s var(--mdx-ease), box-shadow 0.22s var(--mdx-ease), background 0.22s var(--mdx-ease);
}
/* A focus state, not a browser focus ring: the surface lifts and its edge
   warms. A 2px blue outline around a 22px rectangle is the one thing that
   would make this read as a form field again. */
.mdx-composer:focus-within {
  border-color: var(--mdx-composer-edge-focus, rgba(23, 105, 255, 0.34));
  box-shadow: var(--mdx-composer-shadow-focus, inset 0 1px 0 rgba(255, 255, 255, 0.95), 0 0 0 3px rgba(23, 105, 255, 0.08));
}

/* `display` on a rule beats the user agent's `[hidden] { display: none }`, so
   the media strip, the search pill and the note would all be permanently
   visible without this. They are hidden by property, not by class. */
.mdx-composer [hidden] { display: none !important; }

.mdx-composer-text { display: flex; min-width: 0; }

/* Scroll chaining is what makes a keyboard-open page bounce: flicking the
   conversation past its end hands the gesture to the document, which rubber
   bands the whole fixed layout including the composer. Contain it, in the two
   places that scroll. */
body.mdx #bfsLog,
body.mdx .baihaqi-chat-log,
.mdx-composer-input { overscroll-behavior: contain; }
body.mdx.mdx-keyboard { overscroll-behavior-y: none; }

.mdx-composer-input,
body.mdx textarea.mdx-composer-input {
  flex: 1 1 auto;
  min-width: 0;
  width: 100%;
  margin: 0;
  padding: 2px 4px;
  border: 0;
  outline: 0;
  resize: none;
  background: transparent;
  color: var(--mdx-ink);
  font-family: inherit;
  /* NOT a rem: a user's root font size must not be able to take this under
     the 16px iOS zoom threshold. */
  font-size: 16px;
  line-height: 1.45;
  font-weight: 500;
  letter-spacing: -0.011em;
  max-height: calc(1.45em * 6);
  overflow-y: hidden;
  -webkit-appearance: none;
  appearance: none;
}
.mdx-composer-input::placeholder { color: var(--mdx-faint); font-weight: 500; }
.mdx-composer-input::-webkit-scrollbar { width: 0; }
/* The app paints every form field with a border and a blue focus ring. Inside
   this surface both are wrong: the RECTANGLE is the field, and a second
   outlined box inside it is the "browser-style focus ring" this composer
   exists to get rid of. Specific enough to beat both the generic rule in
   styles.css and body.mdx's own. */
body.mdx textarea.mdx-composer-input,
body.mdx textarea.mdx-composer-input:focus,
body.mdx textarea.mdx-composer-input:focus-visible {
  border: 0;
  outline: 0;
  background: transparent;
  box-shadow: none;
  border-radius: 0;
}

.mdx-composer-tools {
  display: flex;
  align-items: center;
  gap: 6px;
}
.mdx-composer-gap { flex: 1 1 auto; }

.mdx-composer-btn {
  flex: none;
  display: inline-grid;
  place-items: center;
  width: 34px;
  height: 34px;
  padding: 0;
  border: 1px solid transparent;
  border-radius: 12px;
  background: transparent;
  color: var(--mdx-muted);
  transition: background 0.18s var(--mdx-ease), color 0.18s var(--mdx-ease), transform 0.16s var(--mdx-ease);
}
.mdx-composer-btn svg { width: 19px; height: 19px; }
.mdx-composer-btn:hover { background: var(--mdx-composer-hover, rgba(14, 23, 38, 0.05)); color: var(--mdx-ink); }
.mdx-composer-btn:active { transform: scale(0.92); }

.mdx-composer-mode {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  height: 28px;
  padding: 0 10px;
  border-radius: var(--mdx-r-pill);
  border: 1px solid rgba(23, 105, 255, 0.28);
  background: var(--mdx-blue-wash);
  color: var(--mdx-blue-ink);
  font-size: 0.74rem;
  font-weight: 650;
  letter-spacing: -0.005em;
}
.mdx-composer-mode svg { width: 13px; height: 13px; }
.mdx-composer-mode:active { transform: scale(0.95); }

.mdx-composer-send {
  flex: none;
  display: inline-grid;
  place-items: center;
  width: 34px;
  height: 34px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: linear-gradient(180deg, #2f7bff, var(--mdx-blue));
  color: #fff;
  box-shadow: 0 2px 8px rgba(23, 105, 255, 0.34);
  transition: transform 0.18s var(--mdx-ease), opacity 0.2s var(--mdx-ease), box-shadow 0.2s var(--mdx-ease);
}
.mdx-composer-send svg { width: 16px; height: 16px; }
.mdx-composer-send:disabled { opacity: 0.3; box-shadow: none; cursor: default; }
.mdx-composer-send:not(:disabled):hover { box-shadow: 0 4px 14px rgba(23, 105, 255, 0.42); }
.mdx-composer-send:not(:disabled):active { transform: scale(0.9); }

.mdx-composer-voice {
  position: relative;
  flex: none;
  width: 34px;
  height: 34px;
  display: inline-grid;
  place-items: center;
  padding: 0;
  border-radius: 50%;
  border: 1px solid rgba(0, 0, 0, 0.96);
  background: #050505;
  color: #fff;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .16), 0 3px 10px rgba(0, 0, 0, .2);
  transition: transform .2s var(--mdx-ease), box-shadow .25s var(--mdx-ease), background .25s var(--mdx-ease);
}
.mdx-composer-voice svg { width: 17px; height: 17px; }
.mdx-composer-voice:hover { background: #151515; }
.mdx-composer-voice:active { transform: scale(.91); }

/* -- what the message is carrying --------------------------------------- */
.mdx-composer-media {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  padding-bottom: 2px;
}
.mdx-composer-thumb {
  position: relative;
  width: 62px;
  height: 62px;
  border-radius: 14px;
  overflow: hidden;
  border: 1px solid var(--mdx-hair);
  background: var(--mdx-surface-sunken, rgba(14, 23, 38, 0.05));
}
.mdx-composer-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.mdx-composer-thumb-x {
  position: absolute;
  top: 3px;
  right: 3px;
  width: 20px;
  height: 20px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgba(8, 12, 20, 0.72);
  color: #fff;
  backdrop-filter: blur(6px);
}
.mdx-composer-thumb-x svg { width: 12px; height: 12px; }

.mdx-composer-note {
  margin: 0;
  padding: 0 2px;
  font-size: 0.72rem;
  line-height: 1.4;
  font-weight: 550;
  color: var(--mdx-muted);
}

@media (max-width: 420px) {
  .mdx-composer { padding: 11px 10px 9px; border-radius: 20px; }
  .mdx-composer-btn, .mdx-composer-send, .mdx-composer-voice { width: 33px; height: 33px; }
}

/* -- the bar around it --------------------------------------------------
   The composer is now the bar's whole content on the chat surfaces, so the
   bar stops adding padding of its own around it. Two nested rounded
   rectangles with 9px between them read as a frame; one does not. */
.mdx-bar-row:has(> .mdx-composer) { padding: 6px 6px; gap: 6px; }

/* ==========================================================================
   15. Dark composer separation
   ==========================================================================
   The reported problem: in dark mode the composer disappeared into the page.
   It is the same three surfaces it always was — background, conversation,
   composer — and in dark mode they were within a couple of percent of each
   other in luminance, so nothing separated them.

   The fix is luminance, not a border. Each surface steps up from the one
   behind it, and the composer additionally carries a one-pixel top highlight
   — the light-catching edge a raised object has — so it reads as sitting ON
   the page rather than being cut out of it. No harsh outline, and no focus
   ring: the edge warms and the lift increases instead.
   ========================================================================== */
body.mdx.dark-mode {
  --mdx-composer-surface: #1c2634;
  --mdx-composer-edge: rgba(226, 232, 240, 0.13);
  --mdx-composer-edge-focus: rgba(120, 165, 255, 0.42);
  --mdx-composer-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.09),
    0 6px 20px rgba(0, 0, 0, 0.34);
  --mdx-composer-shadow-focus:
    inset 0 1px 0 rgba(255, 255, 255, 0.13),
    0 0 0 3px rgba(88, 140, 255, 0.14),
    0 10px 28px rgba(0, 0, 0, 0.42);
  --mdx-composer-hover: rgba(255, 255, 255, 0.08);
}
/* The bar behind it steps DOWN so the composer can step up out of it. */
body.mdx.dark-mode .mdx-bar {
  background: linear-gradient(177deg, rgba(19, 26, 37, 0.94) 0%, rgba(14, 20, 30, 0.92) 100%);
  border-color: rgba(226, 232, 240, 0.1);
}
body.mdx.dark-mode .mdx-bar::after { background: linear-gradient(180deg, rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0)); }
body.mdx.dark-mode .mdx-composer-input { color: #f4f7fb; }
/* Placeholder, icons and the note all clear 4.5:1 on #1c2634. The send button
   keeps its blue, which clears it comfortably against white. */
body.mdx.dark-mode .mdx-composer-input::placeholder { color: #8798ac; }
body.mdx.dark-mode .mdx-composer-btn { color: #a9b8cb; }
body.mdx.dark-mode .mdx-composer-btn:hover { color: #f4f7fb; }
body.mdx.dark-mode .mdx-composer-note { color: #9aabc0; }
body.mdx.dark-mode .mdx-composer-mode {
  background: rgba(88, 140, 255, 0.18);
  border-color: rgba(120, 165, 255, 0.34);
  color: #cfdeff;
}
body.mdx.dark-mode .mdx-composer-thumb { background: rgba(255, 255, 255, 0.05); border-color: rgba(226, 232, 240, 0.14); }

/* ==========================================================================
   16. The conversation: actions, images, references, thinking
   ========================================================================== */

/* -- the immediate thinking state ---------------------------------------
   A small sphere and one word, on the frame the message is sent. It is not a
   spinner: the orb is the same material the big Sphere is made of, moving,
   and the word says what is actually being done with THIS question. */
.bchat-status {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 4px 2px;
  animation: bchatStatusIn 240ms cubic-bezier(0.22, 0.61, 0.36, 1) both;
}
/* THE SPHERE, SMALL, IN THE TRANSCRIPT.
   This host is filled by the same MedDexSphere component used on Home. The
   CSS fallback keeps the status useful if WebGL is unavailable. */
.bchat-status-orb {
  width: 26px;
  height: 26px;
  display: block;
  flex: 0 0 30px;
  border-radius: 50%;
  background:
    radial-gradient(42% 42% at 33% 34%, rgba(214, 200, 255, 0.95), rgba(214, 200, 255, 0) 70%),
    radial-gradient(40% 40% at 68% 62%, rgba(178, 158, 255, 0.85), rgba(178, 158, 255, 0) 72%),
    radial-gradient(58% 58% at 50% 50%, rgba(24, 20, 54, 0.55), rgba(24, 20, 54, 0) 74%),
    conic-gradient(from 210deg, #b9a6ff, #efeaff, #8f7ce8, #d7ccff, #b9a6ff);
  box-shadow:
    inset 0 0 6px rgba(255, 255, 255, 0.55),
    0 0 0 1px rgba(150, 128, 240, 0.22),
    0 0 14px rgba(139, 116, 232, 0.45);
  animation: bchatStatusSpin 5.2s linear infinite, bchatStatusBreathe 2.6s ease-in-out infinite;
}
.bchat-status-orb.is-sphere-host {
  width: 30px;
  height: 30px;
  background: transparent;
  box-shadow: none;
  animation: none;
  overflow: visible;
}
.bchat-status-orb.is-sphere-host .mdxs {
  --mdxs-inline: 30px;
  width: 30px;
  min-width: 30px;
  height: 30px;
  pointer-events: none;
}
.bchat-status-orb.is-sphere-host .mdxs-core { pointer-events: none; }
.bchat-status-orb.is-sphere-host .mdxs-think,
.bchat-status-orb.is-sphere-host .mdxs-label { display: none !important; }
.bchat-status-text {
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  color: var(--mdx-muted, #526174);
  transition: opacity .18s ease, transform .18s ease;
}
.bchat-status-text.is-changing { opacity: .45; transform: translateY(2px); }
@keyframes bchatStatusIn { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
@keyframes bchatStatusSpin { to { transform: rotate(360deg); } }
@keyframes bchatStatusBreathe {
  0%, 100% { box-shadow: inset 0 0 6px rgba(255,255,255,0.55), 0 0 0 1px rgba(150,128,240,0.22), 0 0 14px rgba(139,116,232,0.45); }
  50%      { box-shadow: inset 0 0 9px rgba(255,255,255,0.7),  0 0 0 3px rgba(150,128,240,0.12), 0 0 22px rgba(139,116,232,0.6); }
}
@media (prefers-reduced-motion: reduce) {
  .bchat-status-orb { animation: none; }
  .bchat-status { animation: none; }
}

/* -- message actions -----------------------------------------------------
   Small, quiet, and only on a finished message. On a pointer device they
   fade in on hover; on touch, where there is no hover, they are simply there
   at low contrast — an action you cannot discover is not an action. */
.bchat-acts {
  display: flex;
  gap: 2px;
  margin-top: 6px;
  opacity: 0.5;
  transition: opacity 0.2s ease;
}
.bchat-msg:hover .bchat-acts,
.bchat-acts:focus-within { opacity: 1; }
.bchat-act {
  display: inline-grid;
  place-items: center;
  width: 26px;
  height: 26px;
  padding: 0;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: currentColor;
  cursor: pointer;
  transition: background 0.16s ease, transform 0.14s ease;
}
.bchat-act svg { width: 14px; height: 14px; }
.bchat-act:hover { background: rgba(127, 145, 175, 0.16); }
.bchat-act:active { transform: scale(0.9); }
.bchat-act.is-done { color: #17a673; }
@media (hover: none) {
  .bchat-acts { opacity: 0.62; }
}
/* On the blue user bubble the icons are white on saturated blue, where 0.5
   opacity is not a subtle control, it is an invisible one. */
.bchat-user .bchat-acts { opacity: 0.72; }
.bchat-user:hover .bchat-acts { opacity: 1; }
.bchat-user .bchat-act:hover { background: rgba(255, 255, 255, 0.22); }

/* -- images in the conversation ----------------------------------------- */
.bchat-images {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 8px;
}
.bchat-image {
  margin: 0;
  border-radius: 14px;
  overflow: hidden;
  max-width: 220px;
  line-height: 0;
  background: rgba(127, 145, 175, 0.12);
}
.bchat-image img {
  display: block;
  width: 100%;
  height: auto;
  max-height: 260px;
  object-fit: cover;
  cursor: zoom-in;
}
/* Expanded in place, so the answer discussing the picture stays visible
   beside it. */
.bchat-image.is-open { max-width: 100%; }
.bchat-image.is-open img { max-height: none; object-fit: contain; cursor: zoom-out; }

/* -- references ---------------------------------------------------------- */
.bchat-sources {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-top: 10px;
  padding-top: 9px;
  border-top: 1px solid rgba(127, 145, 175, 0.2);
}
.bchat-sources-label {
  font-size: 0.68rem;
  font-weight: 750;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  opacity: 0.6;
}
.bchat-source {
  display: flex;
  align-items: baseline;
  gap: 7px;
  font-size: 0.78rem;
  line-height: 1.4;
  text-decoration: none;
  color: inherit;
}
.bchat-source b {
  flex: none;
  min-width: 16px;
  height: 16px;
  display: inline-grid;
  place-items: center;
  border-radius: 5px;
  background: rgba(23, 105, 255, 0.14);
  color: var(--mdx-blue-ink, #1769ff);
  font-size: 0.64rem;
  font-weight: 800;
}
.bchat-source span { text-decoration: underline; text-underline-offset: 2px; opacity: 0.86; }
.bchat-source:hover span { opacity: 1; }

/* -- inline citations ----------------------------------------------------
   The number sits against the phrase it belongs to, at the size a footnote
   marker should be: findable, and not competing with the sentence. Tapping it
   takes the eye to the source underneath. */
.ai-cite {
  display: inline-block;
  min-width: 15px;
  margin: 0 1px 0 2px;
  padding: 0 3px;
  border-radius: 5px;
  background: rgba(23, 105, 255, 0.13);
  color: var(--mdx-blue-ink, #1769ff);
  font-size: 0.62em;
  font-weight: 800;
  line-height: 1.5;
  text-align: center;
  vertical-align: super;
  cursor: pointer;
  transition: background 0.16s ease;
}
.ai-cite:hover { background: rgba(23, 105, 255, 0.24); }
.ai-cite:focus-visible { outline: 2px solid var(--mdx-blue, #1769ff); outline-offset: 1px; }
body.mdx.dark-mode .ai-cite { background: rgba(120, 165, 255, 0.2); color: #cfdeff; }

.bchat-source i {
  display: block;
  font-style: normal;
  font-size: 0.86em;
  font-weight: 600;
  opacity: 0.62;
  text-decoration: none;
}
.bchat-source span { display: block; }
/* Where the eye is sent when a citation is followed. */
.bchat-source.is-cited b {
  background: var(--mdx-blue, #1769ff);
  color: #fff;
  transform: scale(1.12);
}
.bchat-source b { transition: background 0.2s ease, color 0.2s ease, transform 0.2s ease; }

/* -- the + menu ----------------------------------------------------------
   Two items, opening upward out of the composer, because the composer is at
   the foot of the screen and anything that opens downward from it opens into
   the keyboard. */
.mdx-plus-menu {
  /* Fixed and portalled to the body: `.mdx-bar` is overflow:hidden and would
     otherwise clip this away completely. Above the bar's own z-index, because
     it belongs to the bar's control. */
  position: fixed;
  top: 0;
  left: 0;
  z-index: 2600;
  min-width: 244px;
  max-width: calc(100vw - 40px);
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 6px;
  border-radius: 18px;
  background: var(--mdx-composer-surface, #fff);
  border: 1px solid var(--mdx-composer-edge, rgba(14, 23, 38, 0.09));
  box-shadow: var(--mdx-lift-2, 0 2px 6px rgba(14,23,38,.06), 0 18px 44px rgba(14,23,38,.14));
  animation: mdxPlusIn 160ms cubic-bezier(0.22, 0.9, 0.24, 1) both;
}
@keyframes mdxPlusIn { from { opacity: 0; transform: translateY(6px) scale(0.98); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .mdx-plus-menu { animation: none; } }

.mdx-plus-item {
  display: flex;
  align-items: center;
  gap: 11px;
  width: 100%;
  padding: 9px 10px;
  border: 0;
  border-radius: 13px;
  background: transparent;
  color: var(--mdx-ink);
  text-align: left;
  transition: background 0.16s ease;
}
.mdx-plus-item:hover, .mdx-plus-item:focus-visible { background: var(--mdx-composer-hover, rgba(14, 23, 38, 0.05)); outline: 0; }
.mdx-plus-ic { flex: none; display: grid; place-items: center; width: 32px; height: 32px; border-radius: 10px; background: var(--mdx-blue-wash, rgba(23,105,255,.08)); color: var(--mdx-blue-ink, #1769ff); }
.mdx-plus-ic svg { width: 17px; height: 17px; }
.mdx-plus-txt { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.mdx-plus-txt strong { font-size: 0.86rem; font-weight: 650; letter-spacing: -0.01em; }
.mdx-plus-txt small { font-size: 0.72rem; font-weight: 500; color: var(--mdx-muted); }
.mdx-plus-tick { flex: none; color: var(--mdx-blue-ink, #1769ff); }
.mdx-plus-tick svg { width: 16px; height: 16px; }
.mdx-plus-item.is-on .mdx-plus-ic { background: var(--mdx-blue, #1769ff); color: #fff; }
body.mdx.dark-mode .mdx-plus-menu { background: #202b3a; border-color: rgba(226,232,240,.14); }
body.mdx.dark-mode .mdx-plus-ic { background: rgba(120,165,255,.18); color: #cfdeff; }

/* -- references: short form and APA on the same list --------------------- */
.bchat-sources-head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 2px;
}
.bchat-sources-head .bchat-sources-label { flex: 1 1 auto; }
.bchat-sources-apa {
  flex: none;
  padding: 2px 7px;
  border: 1px solid rgba(127, 145, 175, 0.3);
  border-radius: 7px;
  background: transparent;
  color: inherit;
  font-size: 0.64rem;
  font-weight: 750;
  letter-spacing: 0.04em;
  opacity: 0.72;
  cursor: pointer;
  transition: background 0.16s ease, opacity 0.16s ease, border-color 0.16s ease;
}
.bchat-sources-apa:hover { opacity: 1; background: rgba(127, 145, 175, 0.14); }
.bchat-sources-apa.is-on {
  opacity: 1;
  background: var(--mdx-blue-wash, rgba(23, 105, 255, 0.1));
  border-color: rgba(23, 105, 255, 0.3);
  color: var(--mdx-blue-ink, #1769ff);
}
.bchat-sources-list { display: flex; flex-direction: column; gap: 4px; }
/* An APA entry is a full reference, so it gets room to wrap and stops
   pretending to be a link title. */
.bchat-sources-list.is-apa .bchat-source { align-items: flex-start; }
.bchat-sources-list.is-apa .bchat-source span { text-decoration: none; opacity: 1; line-height: 1.5; }
.bchat-sources-list.is-apa .bchat-source i { display: none; }

/* -- the model selector --------------------------------------------------
   A word, not an icon. "Local" and "Pro" mean something; a cloud glyph beside
   a sparkle does not. It sits at the quiet end of the control row and only
   raises its voice when it is on Local, which is the state worth noticing. */
.mdx-composer-model {
  flex: none;
  height: 26px;
  padding: 0 9px;
  border: 1px solid transparent;
  border-radius: var(--mdx-r-pill);
  background: transparent;
  color: var(--mdx-muted);
  font-size: 0.72rem;
  font-weight: 650;
  letter-spacing: -0.004em;
  white-space: nowrap;
  transition: background 0.18s var(--mdx-ease), color 0.18s var(--mdx-ease), border-color 0.18s var(--mdx-ease);
}
.mdx-composer-model:hover { background: var(--mdx-composer-hover, rgba(14, 23, 38, 0.05)); color: var(--mdx-ink); }
.mdx-composer-model.is-local {
  color: #1f7a52;
  border-color: rgba(31, 122, 82, 0.28);
  background: rgba(31, 122, 82, 0.09);
}
.mdx-composer-model[hidden] { display: none; }
body.mdx.dark-mode .mdx-composer-model { color: #9aabc0; }
body.mdx.dark-mode .mdx-composer-model:hover { color: #f4f7fb; }
body.mdx.dark-mode .mdx-composer-model.is-local { color: #7fd8ab; border-color: rgba(127, 216, 171, 0.3); background: rgba(127, 216, 171, 0.14); }
.mdx-model-menu { min-width: 268px; }

/* ==========================================================================
   Comparison tables
   ==========================================================================
   "Compare HFrEF and HFpEF" is one of the most common things anybody asks a
   medical tutor, and the answer is a table. The rule that makes one survive a
   375 px phone is that IT SCROLLS INSIDE ITS OWN BOX: columns keep a readable
   minimum width and the overflow is taken by the wrapper, so a five-column
   comparison neither crushes every cell to one word nor pushes the page
   sideways. `overscroll-behavior-x: contain` stops the swipe that scrolls the
   table from also dragging the conversation.
   ========================================================================== */
.ai-table-wrap {
  max-width: 100%;
  margin: 10px 0;
  overflow-x: auto;
  overflow-y: hidden;
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
  border: 1px solid rgba(127, 145, 175, 0.24);
  border-radius: 12px;
  /* A hint that there is more to the right, without a scrollbar on iOS. */
  background:
    linear-gradient(90deg, var(--mdx-surface, #fff) 30%, rgba(255, 255, 255, 0)) left / 26px 100% no-repeat,
    linear-gradient(270deg, var(--mdx-surface, #fff) 30%, rgba(255, 255, 255, 0)) right / 26px 100% no-repeat,
    radial-gradient(farthest-side at 0 50%, rgba(14, 23, 38, 0.13), transparent) left / 12px 100% no-repeat,
    radial-gradient(farthest-side at 100% 50%, rgba(14, 23, 38, 0.13), transparent) right / 12px 100% no-repeat;
  background-attachment: local, local, scroll, scroll;
}
.ai-table-wrap:focus-visible { outline: 2px solid var(--mdx-blue, #1769ff); outline-offset: 2px; }
.ai-table-wrap::-webkit-scrollbar { height: 6px; }
.ai-table-wrap::-webkit-scrollbar-thumb { background: rgba(127, 145, 175, 0.4); border-radius: 3px; }

.ai-table {
  border-collapse: collapse;
  width: 100%;
  /* Wider than the bubble when it needs to be — that is what the wrapper's
     scroll is for. Below this, cells wrap to two words a line and the table
     stops being readable. */
  min-width: max-content;
  font-size: 0.84rem;
  line-height: 1.45;
}
.ai-table th,
.ai-table td {
  padding: 8px 11px;
  border-bottom: 1px solid rgba(127, 145, 175, 0.18);
  border-right: 1px solid rgba(127, 145, 175, 0.12);
  vertical-align: top;
  /* Readable, and never so wide that one cell owns the screen. */
  min-width: 96px;
  max-width: 260px;
  white-space: normal;
  word-break: break-word;
}
.ai-table th:last-child, .ai-table td:last-child { border-right: 0; }
.ai-table tbody tr:last-child td { border-bottom: 0; }
.ai-table th {
  position: sticky;
  top: 0;
  background: var(--mdx-surface-2, #f4f7fb);
  font-weight: 700;
  text-align: left;
  letter-spacing: -0.005em;
}
.ai-table tbody tr:nth-child(even) td { background: rgba(127, 145, 175, 0.045); }
/* The first column is the row label in almost every comparison, so it earns
   a little more weight and stays with its row while the rest scrolls. */
.ai-table td:first-child { font-weight: 620; }

body.mdx.dark-mode .ai-table-wrap {
  border-color: rgba(226, 232, 240, 0.16);
  background:
    linear-gradient(90deg, #1c2634 30%, rgba(28, 38, 52, 0)) left / 26px 100% no-repeat,
    linear-gradient(270deg, #1c2634 30%, rgba(28, 38, 52, 0)) right / 26px 100% no-repeat,
    radial-gradient(farthest-side at 0 50%, rgba(0, 0, 0, 0.4), transparent) left / 12px 100% no-repeat,
    radial-gradient(farthest-side at 100% 50%, rgba(0, 0, 0, 0.4), transparent) right / 12px 100% no-repeat;
  background-attachment: local, local, scroll, scroll;
}
body.mdx.dark-mode .ai-table th { background: #202b3a; }
body.mdx.dark-mode .ai-table th,
body.mdx.dark-mode .ai-table td { border-color: rgba(226, 232, 240, 0.12); }
body.mdx.dark-mode .ai-table tbody tr:nth-child(even) td { background: rgba(255, 255, 255, 0.035); }

/* The bubble must never be what overflows: the table's wrapper owns the
   scroll, and the message stays inside the conversation column. */
.bchat-msg .ai-table-wrap { max-width: 100%; }
.bchat-assistant { max-width: 88%; overflow-wrap: anywhere; }

/* A search that ran and found nothing, said plainly under the answer it
   affects, with another go where another go would help. Compact on purpose:
   this is a footnote about the answer, not a second answer. */
.bchat-search-miss {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 4px 8px;
  margin-top: 10px;
  padding-top: 9px;
  border-top: 1px solid rgba(127, 145, 175, 0.2);
  font-size: 12px;
  line-height: 1.45;
  color: var(--mdx-ink-soft, #6b7280);
}
.bchat-search-miss-text { flex: 1 1 220px; }
.bchat-search-retry {
  flex: 0 0 auto;
  appearance: none;
  border: 1px solid rgba(127, 145, 175, 0.34);
  background: transparent;
  border-radius: 999px;
  padding: 3px 10px;
  font: inherit;
  font-weight: 600;
  color: inherit;
  cursor: pointer;
}
.bchat-search-retry:hover:not(:disabled) { background: rgba(127, 145, 175, 0.12); }
.bchat-search-retry:disabled { opacity: 0.55; cursor: default; }

/* ---------------------------------------------------------------- Local AI
   The most consequential choice in the app used to be a grey system alert
   with a URL in it. This is the same decision, in MedDex's own voice, and it
   can say things confirm() cannot — like how much room the device has. */
.mdx-localsheet-scrim {
  position: fixed;
  inset: 0;
  z-index: 9000;
  background: rgba(16, 20, 34, 0.34);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  opacity: 0;
  transition: opacity 0.24s ease;
}
.mdx-localsheet-scrim.is-in { opacity: 1; }
.mdx-localsheet {
  position: fixed;
  left: 50%;
  bottom: 0;
  z-index: 9001;
  width: min(520px, calc(100vw - 20px));
  transform: translate(-50%, 14px);
  margin-bottom: max(10px, env(safe-area-inset-bottom));
  padding: 10px 22px 20px;
  border-radius: 26px;
  background: var(--mdx-card, #fff);
  box-shadow: 0 -2px 60px rgba(19, 26, 48, 0.22), 0 1px 0 rgba(255, 255, 255, 0.7) inset;
  opacity: 0;
  transition: transform 0.32s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.24s ease;
}
.mdx-localsheet.is-in { transform: translate(-50%, 0); opacity: 1; }
.mdx-localsheet-grip {
  width: 38px;
  height: 4px;
  margin: 0 auto 14px;
  border-radius: 999px;
  background: rgba(127, 145, 175, 0.30);
}
.mdx-local-head { display: flex; align-items: flex-start; gap: 13px; }
.mdx-local-ic {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  border-radius: 13px;
  background: rgba(59, 106, 255, 0.10);
  color: #3b6aff;
}
.mdx-local-ic svg { width: 21px; height: 21px; }
.mdx-local-head h2 { margin: 1px 0 2px; font-size: 18px; font-weight: 700; letter-spacing: -0.01em; }
.mdx-local-sub { margin: 0; font-size: 13px; color: var(--mdx-ink-soft, #6b7280); }
.mdx-local-points { margin: 16px 0 0; padding: 0; list-style: none; display: grid; gap: 10px; }
.mdx-local-points li {
  position: relative;
  padding-left: 18px;
  font-size: 13.5px;
  line-height: 1.45;
  color: var(--mdx-ink-soft, #6b7280);
}
.mdx-local-points li::before {
  content: "";
  position: absolute;
  left: 3px;
  top: 8px;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: rgba(59, 106, 255, 0.55);
}
.mdx-local-points strong { color: var(--mdx-ink, #131a30); font-weight: 650; }
.mdx-local-room, .mdx-local-warn {
  margin: 14px 0 0;
  font-size: 12.5px;
  color: var(--mdx-ink-soft, #6b7280);
}
.mdx-local-warn { color: #b0561f; font-weight: 600; }
.mdx-local-actions { display: flex; gap: 10px; margin-top: 18px; }
.mdx-local-actions button {
  flex: 1 1 0;
  appearance: none;
  border: 0;
  border-radius: 14px;
  padding: 13px 14px;
  font: inherit;
  font-size: 15px;
  font-weight: 650;
  cursor: pointer;
}
.mdx-local-no { background: rgba(127, 145, 175, 0.12); color: var(--mdx-ink, #131a30); }
.mdx-local-go { background: #3b6aff; color: #fff; }
.mdx-local-go:disabled { opacity: 0.42; cursor: default; }
.mdx-local-no:hover { background: rgba(127, 145, 175, 0.18); }

@media (prefers-color-scheme: dark) {
  .mdx-localsheet { background: #171b28; box-shadow: 0 -2px 60px rgba(0, 0, 0, 0.55); }
  .mdx-local-ic { background: rgba(120, 156, 255, 0.16); color: #8fb0ff; }
  .mdx-local-no { background: rgba(255, 255, 255, 0.09); color: #eef1f8; }
}

/* ===========================================================================
   53. The answer is the page, not a card
   ---------------------------------------------------------------------------
   A QUESTION IS A REMARK. AN ANSWER IS A DOCUMENT.

   What someone typed is short, personal and addressed to MedDex, so it keeps
   its bubble: it should read as a thing that was said. What comes back is not
   a reply in a thread — it is headings, lists, tables, citations and
   references, often several screens of it. Putting that inside a rounded
   rectangle with its own background did three things, all of them bad:

     * it drew a box around the only content on the screen, so the container
       competed with the thing it contained;
     * it measured every line against an edge at 88–94% of a width the reader
       cannot see, which is what made long answers feel cramped on a phone and
       stranded on a desktop;
     * it stacked card on card until the transcript read as a social feed
       rather than as a page you are reading.

   So the answer gives up its container completely and is set directly on the
   conversation canvas, one comfortable measure wide, with the typography doing
   all of the structural work.

   NOTHING ELSE MOVES. The question keeps its bubble. The composer keeps
   floating. The Sphere still opens its gutter beside a streaming answer and
   still arrives as glass. Citations, references, Spatial Intelligence, AR,
   copy, share and retry are all where they were and all still work — they
   simply sit on the page now instead of inside a box.
   ========================================================================= */

/* ONE MEASURE FOR THE WHOLE CONVERSATION.
   720px is not a taste: it is the composer's own width (`.mdx-bar`), so the
   question, the answer and the field they were typed into share one axis all
   the way down the screen. On a phone the column is narrower than the cap and
   this changes nothing, which is the point — the phone was already right. The
   overlay sheet is 720px wide already, so only its rhythm changes. */
body.mdx.mdx-chat-home .bfs .bfs-log {
  width: 100%;
  max-width: 720px;
  margin-inline: auto;
}
/* A document breathes between turns. 10px was bubble spacing. */
body.mdx .bfs .bfs-log { gap: 16px; }

/* THE ANSWER ITSELF — no ground, no edge, no lift, and the full width of the
   column rather than a fraction of it. */
body.mdx #bfsLog .bchat-msg.bchat-assistant:not(.bchat-tool):not(.bchat-typing),
body.mdx .baihaqi-chat-log .bchat-msg.bchat-assistant:not(.bchat-tool):not(.bchat-typing) {
  align-self: stretch;
  width: 100%;
  max-width: 100%;
  padding: 2px 0 6px;
  background: none !important;
  border: 0 !important;
  box-shadow: none !important;
  -webkit-backdrop-filter: none !important;
  backdrop-filter: none !important;
  /* Kept deliberately, and invisible with nothing painted behind it: the
     Sphere's arrival overlay inherits this radius, and a full-bleed rectangle
     of glass is not the animation that was designed. */
  border-radius: 20px;
}

/* THE SPHERE'S GUTTER, RE-ASSERTED.
   `body.mdx.mdx-sphere-inline #bfsLog .bchat-msg.is-streaming` opens 46px on
   the left so the inline Sphere sits beside the sentence being written rather
   than under it. The rule above is more specific than that one, so the gutter
   is restated here rather than lost to a selector accident. */
body.mdx.mdx-sphere-inline #bfsLog .bchat-msg.bchat-assistant.is-streaming {
  padding-left: 46px;
}

/* A CONTAINER THAT IS NOT THERE CANNOT GLOW.
   The streaming state was a soft box-shadow around the card's edge; with no
   card that is a halo around nothing. The Sphere sitting in the gutter beside
   the sentence being written is the indicator, and it is a better one. */
body.mdx #bfsLog .bchat-msg.bchat-assistant.is-streaming {
  animation: none !important;
  box-shadow: none !important;
}

/* The controls belong to the answer, so they line up with its first character
   — which is now the edge of the column — and they earn a little more room
   than they had inside a padded card. */
body.mdx #bfsLog .bchat-msg.bchat-assistant > .bchat-acts,
body.mdx .baihaqi-chat-log .bchat-msg.bchat-assistant > .bchat-acts {
  margin-top: 10px;
  gap: 4px;
}
/* On the page rather than on a card, the resting state has to carry itself:
   there is no surface behind it doing half the work. */
body.mdx #bfsLog .bchat-msg.bchat-assistant > .bchat-acts { opacity: 0.62; }
body.mdx #bfsLog .bchat-msg.bchat-assistant:hover > .bchat-acts,
body.mdx #bfsLog .bchat-msg.bchat-assistant > .bchat-acts:focus-within { opacity: 1; }
body.mdx #bfsLog .bchat-msg.bchat-assistant .bchat-act { color: var(--mdx-muted); }
body.mdx #bfsLog .bchat-msg.bchat-assistant .bchat-act:hover { color: var(--mdx-ink); }
body.mdx #bfsLog .bchat-msg.bchat-assistant .bchat-act.is-done { color: #17a673; }

/* References and the search footnote were divided from the answer by a hair
   inside the card. Edge to edge, the same hair reads as a rule under the
   document — which is what it always meant. */
body.mdx #bfsLog .bchat-msg.bchat-assistant > .bchat-sources,
body.mdx #bfsLog .bchat-msg.bchat-assistant > .bchat-search-miss {
  margin-top: 16px;
  padding-top: 13px;
}

/* Spatial Intelligence and AR sit on the same left edge as the answer they
   belong to. They were already siblings of the message; with the card gone
   there is no inset left to match, only the column. */
body.mdx #bfsLog .mdx-si-row { margin: 2px 0 6px; padding-left: 0; }

/* Phones: the answer runs to the app-shell's own gutter, which is the
   comfortable margin — never to the glass edge of the screen. */
@media (max-width: 520px) {
  body.mdx .bfs .bfs-log { gap: 14px; }
  body.mdx #bfsLog .bchat-msg.bchat-assistant:not(.bchat-tool):not(.bchat-typing) { padding-bottom: 8px; }
}

/* ===========================================================================
   54. A picture MedDex made
   ---------------------------------------------------------------------------
   It is the answer, not an attachment to one, so it gets the full width of the
   column and its own controls underneath — the same quiet row the rest of the
   conversation uses, at a size that suits three labelled actions rather than
   three icons.
   ========================================================================= */
.bchat-made {
  margin: 0 0 10px;
  border-radius: 18px;
  overflow: hidden;
  background: rgba(127, 145, 175, 0.10);
  line-height: 0;
}
.bchat-made img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1 / 1;
  object-fit: cover;
}
.bchat-made-acts {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 8px;
  padding: 8px 10px 2px;
  line-height: 1.4;
}
.bchat-made-act {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 30px;
  padding: 0 11px 0 9px;
  border: 1px solid rgba(127, 145, 175, 0.28);
  border-radius: 999px;
  background: transparent;
  color: inherit;
  font: inherit;
  font-size: 0.76rem;
  font-weight: 620;
  cursor: pointer;
  transition: background 0.16s ease, border-color 0.16s ease, transform 0.14s ease;
  -webkit-tap-highlight-color: transparent;
}
.bchat-made-act svg { width: 14px; height: 14px; flex: none; }
.bchat-made-act:hover:not(:disabled) { background: rgba(127, 145, 175, 0.14); border-color: rgba(127, 145, 175, 0.42); }
.bchat-made-act:active:not(:disabled) { transform: scale(0.96); }
.bchat-made-act:disabled { opacity: 0.5; cursor: default; }

/* What is left, said once and quietly. A limit nobody can see feels arbitrary;
   a limit shouted about feels mean. */
.bchat-quota {
  margin: 10px 0 0;
  font-size: 0.74rem;
  font-weight: 600;
  color: var(--mdx-muted, #7c8a9c);
}
body.mdx.dark-mode .bchat-made { background: rgba(255, 255, 255, 0.06); }
body.mdx.dark-mode .bchat-made-act { border-color: rgba(226, 232, 240, 0.2); }

/* A picture still coming back from the device store, and one whose bytes are
   on a different device. Both are states the reader should recognise without
   reading anything. */
.bchat-made.is-loading { aspect-ratio: 1 / 1; }
.bchat-made-skeleton {
  width: 100%;
  aspect-ratio: 1 / 1;
  background: linear-gradient(100deg,
    rgba(127, 145, 175, 0.10) 30%,
    rgba(127, 145, 175, 0.20) 50%,
    rgba(127, 145, 175, 0.10) 70%) 0 0 / 300% 100%;
  animation: bchatMadeShimmer 1.5s linear infinite;
}
@keyframes bchatMadeShimmer { to { background-position: -300% 0; } }
@media (prefers-reduced-motion: reduce) { .bchat-made-skeleton { animation: none; } }

.bchat-made.is-missing { background: rgba(127, 145, 175, 0.08); line-height: 1.45; }
.bchat-made-missing {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 18px 16px 4px;
  font-size: 0.82rem;
}
.bchat-made-missing strong { font-weight: 660; }
.bchat-made-missing span { color: var(--mdx-muted, #7c8a9c); overflow-wrap: anywhere; }

/* Tapped once, it fills the column instead of being cropped square. */
.bchat-made.is-open img { aspect-ratio: auto; object-fit: contain; cursor: zoom-out; }
.bchat-made img { cursor: zoom-in; }

/* ===========================================================================
   55. The header signs you in, and the sphere stands alone
   ---------------------------------------------------------------------------
   Two removals and one addition, all in the service of the same thing: the
   home screen is a sphere and a question, and everything else on it was
   competing with those two.
   ========================================================================= */

/* LOG IN, AS A WORD.
   The signed-out state used to be a generic head-and-shoulders glyph in a grey
   ring, which says "an account exists here" to somebody who has one and
   nothing at all to somebody who does not. Solid rather than outlined, because
   it is the only thing on this header anybody is being asked to press. */
body.mdx .mdx-topline-auth.is-login {
  height: 34px;
  padding: 0 15px;
  gap: 0;
  color: #fff;
  font-weight: 660;
  font-size: 0.8rem;
  letter-spacing: -0.012em;
  background: linear-gradient(180deg, #2f7bff, var(--mdx-blue, #1769ff));
  border-color: transparent;
  box-shadow: 0 1px 2px rgba(23, 105, 255, 0.24), 0 6px 18px rgba(23, 105, 255, 0.22);
}
body.mdx .mdx-topline-auth.is-login:hover {
  background: linear-gradient(180deg, #4189ff, #2274ff);
  box-shadow: 0 1px 2px rgba(23, 105, 255, 0.28), 0 8px 22px rgba(23, 105, 255, 0.28);
}
body.mdx .mdx-topline-auth.is-login:active { transform: scale(0.965); }
body.mdx .mdx-topline-auth.is-login:focus-visible {
  outline: 2px solid var(--mdx-blue, #1769ff);
  outline-offset: 2px;
}
body.mdx.dark-mode .mdx-topline-auth.is-login {
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 8px 22px rgba(23, 105, 255, 0.26);
}

/* A HEADER WITH ONE CONTROL ON THE RIGHT.
   The History icon has gone; without this the remaining button inherits a gap
   meant for two and floats away from the edge. */
body.mdx .mdx-topline-end { display: inline-flex; align-items: center; gap: 8px; margin-left: auto; }

/* THE SPHERE, CENTRED ON NOTHING BUT ITSELF.
   The orbit ring reserved room on all four sides for labels that no longer
   exist, so the sphere sat high and the question sat low with a band of
   nothing between them. The empty state closes that gap and gives the pair a
   little more air above, which is what makes the arrangement read as composed
   rather than as something with its middle removed. */
body.mdx .mdx-empty { gap: 0; }
body.mdx .mdx-empty-ask { margin-top: 14px; }
body.mdx.mdx-sphere-home .mdxs-home { margin-bottom: 0; }
body.mdx.mdx-sphere-home .mdxs-hint { margin-top: 2px; }

/* Nothing to expand into, so the core stops behaving like an expander. */
body.mdx .mdxs-orbit:empty { display: none !important; }

/* ============================================================ 56. layering
   THE INSTALL BANNER IS NOT A DIALOG AND MUST NOT SIT OVER ONE.
   It is fixed at z-index 22000 in styles.css, which put it above the tools
   sheet (2570), the model sheet and the auth modal. On a phone it landed
   squarely over four rows of the tools sheet — "MedDex home", "My profile",
   "Certificates" and "Achievements" — and swallowed every tap aimed at them.
   A promotional banner loses to anything the person deliberately opened. */
body.mdx.mdx-sheet-open .install-prompt,
body.mdx.mdx-modal-open .install-prompt {
  opacity: 0;
  pointer-events: none;
  transform: translate(-50%, 12px);
  transition: opacity 0.2s ease, transform 0.2s ease;
}

/* ================================================ 57. the docked sidebar
   PHONE IS UNCHANGED. Everything below is inside a min-width query, so the
   drawer, the rail and the hero on a phone are exactly what they were.

   Above it, the SAME drawer panel stops overlaying and becomes furniture:
   the scrim goes, the panel sits in the layout, and the app shell is inset by
   its width so the content uses the REMAINING viewport rather than centring
   underneath it. That last part is the difference between a sidebar and a
   sidebar-shaped thing sitting on top of a centred page. */
@media (min-width: 1024px) {
  body.mdx.mdx-docked {
    --mdx-side-w: 288px;
  }
  body.mdx.mdx-docked.mdx-docked-narrow {
    --mdx-side-w: 76px;
  }

  body.mdx.mdx-docked #mdxDrawer,
  body.mdx.mdx-docked .mdx-drawer {
    position: fixed;
    inset: 0 auto 0 0;
    width: var(--mdx-side-w);
    z-index: 2400;
    pointer-events: auto;
    transition: width 0.22s var(--mdx-ease, ease);
  }
  /* No scrim, ever, when it is furniture. */
  body.mdx.mdx-docked .mdx-drawer-scrim { display: none !important; }

  body.mdx.mdx-docked .mdx-drawer-panel {
    position: static;
    transform: none !important;
    width: var(--mdx-side-w);
    max-width: var(--mdx-side-w);
    height: 100%;
    border-radius: 0;
    border-right: 1px solid var(--mdx-hairline, rgba(18, 24, 40, 0.08));
    box-shadow: none;
    transition: width 0.22s var(--mdx-ease, ease);
  }

  /* THE CONTENT AREA IS WHAT IS LEFT, AND IT REALLY STARTS THERE.
     Padding would have inset the content while leaving the box at x=0, so
     anything centred inside it still centred against the whole window — a
     sidebar-shaped thing sitting on top of a centred page. A margin moves the
     box, and then `justify-content: center` inside means what it says. */
  body.mdx.mdx-docked {
    /* The rail is hidden when docked, so the space it reserved is not owed.
       Leaving it set is how the shell ended up inset TWICE. */
    --mdx-rail-inset: 0px;
  }
  /* ONE element carries the offset. Applying it to `.app-shell` AND to the
     `main` inside it added 288 twice and pushed the hero half a sidebar past
     the middle of its own region. */
  body.mdx.mdx-docked .app-shell {
    margin-left: var(--mdx-side-w);
    width: calc(100% - var(--mdx-side-w));
    max-width: calc(100% - var(--mdx-side-w));
    transition: margin-left 0.22s var(--mdx-ease, ease), width 0.22s var(--mdx-ease, ease);
  }

  /* The Sphere layer is `position: relative` INSIDE the shell, so it is
     already inside the content region and needs nothing. Setting `left` on it
     shifted it a further sidebar's width and was itself the sideways scroll. */
  body.mdx.mdx-docked .mdx-topline {
    padding-left: calc(var(--mdx-side-w) + 12px);
  }
  /* Fixed furniture is positioned from the same edge, so it centres in the
     content region rather than in the window. */
  body.mdx.mdx-docked .mdx-bar,
  body.mdx.mdx-docked .mdx-switch,
  body.mdx.mdx-docked #mdxModeSwitch,
  body.mdx.mdx-docked .install-prompt {
    left: calc(50% + var(--mdx-side-w) / 2);
  }

  /* The floating rail is the phone's navigation. Docked, the sidebar IS the
     navigation, and two of them is one too many. */
  /* The bottom navigation becomes a floating column on wide screens
     (`.mdx-nav` / `.mdx-rail-column`). Docked, the sidebar carries those same
     destinations, so the column is a second copy of the navigation painted on
     top of the first. */
  body.mdx.mdx-docked .mdx-rail,
  body.mdx.mdx-docked .mdx-nav,
  body.mdx.mdx-docked [data-bottom-nav],
  body.mdx.mdx-docked .bottom-nav { display: none !important; }
  body.mdx.mdx-docked .mdx-topline-menu[aria-hidden="true"] { display: none; }

  body.mdx.mdx-docked .mdx-drawer-close { display: none; }
  .mdx-drawer-collapse { display: none; }
  body.mdx.mdx-docked .mdx-drawer-collapse {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: 9px;
    border: 0;
    background: transparent;
    color: var(--mdx-muted, #7c8a9c);
    cursor: pointer;
  }
  body.mdx.mdx-docked .mdx-drawer-collapse:hover { background: rgba(18, 24, 40, 0.05); }
  body.mdx.mdx-docked .mdx-drawer-collapse svg { width: 19px; height: 19px; }

  /* Collapsed: icons only, and nothing that would wrap into two lines. */
  body.mdx.mdx-docked-narrow .mdx-drawer-mark span,
  body.mdx.mdx-docked-narrow .mdx-drawer-sechead,
  body.mdx.mdx-docked-narrow .mdx-drawer-recent,
  body.mdx.mdx-docked-narrow .mdx-drawer-item-text,
  body.mdx.mdx-docked-narrow .mdx-drawer-new span,
  body.mdx.mdx-docked-narrow .mdx-drawer-account-text { display: none; }
  body.mdx.mdx-docked-narrow .mdx-drawer-item,
  body.mdx.mdx-docked-narrow .mdx-drawer-new { justify-content: center; padding-left: 0; padding-right: 0; }
}

/* ============================================ 58. the hero fits the screen
   THE INSTALL BANNER WAS PAINTED OVER THE HEADLINE. It is fixed at z-index
   22000 and anchored above the bottom navigation, which on a phone clears the
   composer and on anything wider lands squarely across "What can I help you
   understand?". A promotional banner does not get to cover the one sentence
   the screen exists to ask. While the empty hero is showing it stands down;
   once there is a conversation to come back to, it can ask again. */
body.mdx.mdx-chat-empty .install-prompt {
  opacity: 0;
  pointer-events: none;
  visibility: hidden;
}

/* The hero as a column that FITS, at any height. Every gap is proportional to
   the viewport rather than fixed, so the same stack works at 768 tall and at
   1080 without a breakpoint for each — which is what "do not hardcode
   coordinates for one screen size" means in practice. */
@media (min-width: 720px) {
  body.mdx .mdx-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: clamp(6px, 1.4vh, 18px);
    padding-inline: clamp(16px, 4vw, 48px);
    /* Never taller than the room between the header and the composer. */
    max-height: calc(100dvh - var(--mdx-top-h, 64px) - var(--mdx-bar-h, 150px));
  }
  body.mdx .mdx-empty-ask {
    margin-top: clamp(8px, 1.6vh, 22px);
    font-size: clamp(1.5rem, 2.6vw, 2.3rem);
    line-height: 1.16;
    max-width: min(18ch, 100%);
    text-wrap: balance;
    /* The whole sentence, always. It used to be clipped to one line's worth
       of a box sized for a phone. */
    overflow: visible;
  }
  /* The sphere takes the room that is left, and no more. */
  body.mdx .mdxs-stage {
    width: clamp(180px, min(34vh, 30vw), 340px);
    height: clamp(180px, min(34vh, 30vw), 340px);
    max-height: 38vh;
  }
}

/* Wide monitors: the conversation must not become a single line of text
   stretched across two feet of glass. */
@media (min-width: 1024px) {
  body.mdx .mdx-bar { max-width: min(760px, calc(100vw - var(--mdx-side-w, 0px) - 96px)); }
  body.mdx #bfsLog { max-width: 820px; margin-inline: auto; }
}

/* Keep the last line of a long answer above the floating composer on phones;
   scroll-padding also covers touch momentum and programmatic reveal. */
body.mdx #bfsLog,
body.mdx .baihaqi-chat-log { scroll-padding-bottom: calc(28px + env(safe-area-inset-bottom, 0px)); }
@media (max-width: 620px) {
  body.mdx .bfs .bfs-log { padding-bottom: calc(30px + env(safe-area-inset-bottom, 0px)); }
}
