/* ==========================================================================
   MedDex Sphere — the signature interaction object
   ==========================================================================

   WHAT THIS FILE IS
   -----------------
   The chrome around the sphere: the stage it lives in, the orbit of actions,
   the finding labels and the explanation panel. The GLASS itself is drawn by
   meddex-sphere.js into a canvas — nothing here paints the sphere except the
   fallback, which is the whole point of the fallback.

   WHY THE SELECTORS ARE NOT SCOPED TO body.mdx
   --------------------------------------------
   Every class here is prefixed `mdxs-`, which exists nowhere else in MedDex,
   so the component can be dropped into any screen without inheriting a shell.
   Only the rules that place it inside the redesigned home are scoped, at the
   bottom of this file, because those ARE shell decisions.

   MATERIAL RULE
   -------------
   The sphere is the only lit object. Everything around it — actions, labels,
   the panel — is quiet porcelain and hairlines, so the eye goes to the glass
   and not to the furniture. If two things on this screen glow, neither does.
   ========================================================================== */

.mdxs {
  --mdxs-stage: 300px;
  --mdxs-ink: var(--mdx-ink, #0e1726);
  --mdxs-muted: var(--mdx-muted, #5f6c80);
  --mdxs-faint: var(--mdx-faint, #8b97a8);
  --mdxs-hair: var(--mdx-hair, rgba(14, 23, 38, 0.08));
  --mdxs-surface: var(--mdx-surface, #ffffff);
  --mdxs-blue: var(--mdx-blue, #1769ff);
  --mdxs-gold: var(--mdx-gold, #c8a34a);
  --mdxs-ease: var(--mdx-ease, cubic-bezier(0.22, 0.9, 0.24, 1));
  --mdxs-spring: var(--mdx-ease-spring, cubic-bezier(0.34, 1.32, 0.44, 1));

  position: relative;
  display: block;
  width: 100%;
  height: var(--mdxs-h, 400px);
  isolation: isolate;
  /* The sphere handles its own gestures; the browser must not decide that a
     drag across the glass was a page scroll before the component sees it. */
  touch-action: pan-y;
  -webkit-tap-highlight-color: transparent;
  contain: layout style;
}

.mdxs[hidden] { display: none; }

/* ---- the two canvases ---------------------------------------------------
   Instruments span the whole component so a leader line can leave the glass
   and reach a label. Material spans only the stage, at a capped resolution. */

.mdxs-instruments,
.mdxs-material {
  position: absolute;
  display: block;
  pointer-events: none;
}
.mdxs-instruments { inset: 0; width: 100%; height: 100%; z-index: 2; }
.mdxs-material { inset: 0; width: 100%; height: 100%; z-index: 1; }

/* The geometry layer. It lives inside the stage, so it is exactly the glass
   square and shares its camera; it is empty and transparent until a scene
   mounts a renderer on it, and it fades in rather than appearing, because the
   droplets underneath it are already on their way to the same surface. */
.mdxs-scene {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 1;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.5s var(--mdxs-ease);
}
.mdxs[data-scene="1"] .mdxs-scene { opacity: 1; }
.mdxs[data-particle-story="1"] .mdxs-material { opacity: 0.12; transition: opacity 0.7s ease; }
.mdxs[data-particle-story="1"] .mdxs-instruments { opacity: 0.18; }
@media (prefers-reduced-motion: reduce) { .mdxs-scene { transition-duration: 0.001s; } }

.mdxs-stage {
  position: absolute;
  left: 50%;
  top: 50%;
  width: var(--mdxs-stage);
  height: var(--mdxs-stage);
  transform: translate(-50%, -50%);
  z-index: 1;
}

/* ---- the core control ---------------------------------------------------
   A real button covering exactly the glass. Border-radius clips hit testing,
   so the corners of the square stay part of the page. */

.mdxs-core {
  position: absolute;
  /* The hit target is the GLASS, not the canvas box. --mdxs-inset is published
     by the renderer from the same camera the shader uses, so the two can never
     drift apart. */
  inset: var(--mdxs-inset, 11.5%);
  z-index: 3;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: inherit;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  touch-action: none;
  /* Matched to the radius spring in the renderer, so the target and the glass
     recede together rather than one chasing the other. */
  transform: scale(var(--mdxs-scale, 1));
  transition: transform 0.46s var(--mdxs-spring);
}
.mdxs.is-dragging .mdxs-core { cursor: grabbing; }

/* The ring is a FOCUS indicator and nothing else. It used to appear on hover
   and while the orbit was open, where a 1px hairline sitting just outside a
   soft-edged sphere read as a stray dotted circle rather than an affordance —
   the sphere's own rim brightening says "this is live" far better. */
.mdxs-core-ring {
  position: absolute;
  inset: -8px;
  border-radius: 50%;
  border: 2px solid transparent;
  opacity: 0;
  transform: scale(0.97);
  transition: opacity 0.2s var(--mdxs-ease), transform 0.2s var(--mdxs-ease);
  pointer-events: none;
}

.mdxs-core:focus { outline: none; }
.mdxs-core:focus-visible .mdxs-core-ring {
  opacity: 1;
  transform: scale(1);
  border-color: var(--mdxs-blue);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--mdxs-blue) 16%, transparent);
}

/* ---- the fallback sphere ------------------------------------------------
   Drawn before the renderer boots and kept permanently where neither WebGL
   nor a 2D canvas is available. It is a real sphere, not a grey box: the
   component must never look broken, only quieter. */

.mdxs-stage::after {
  content: "";
  position: absolute;
  inset: var(--mdxs-inset, 11.5%);
  transform: scale(var(--mdxs-scale, 1));
  border-radius: 50%;
  opacity: 0;
  transition: opacity 0.5s var(--mdxs-ease);
  pointer-events: none;
  background:
    radial-gradient(circle at 34% 28%, rgba(255, 255, 255, 0.95), rgba(255, 255, 255, 0) 46%),
    radial-gradient(circle at 62% 74%, color-mix(in srgb, var(--mdxs-blue) 26%, transparent), transparent 58%),
    radial-gradient(circle at 50% 50%, rgba(255, 255, 255, 0.5), color-mix(in srgb, var(--mdxs-blue) 12%, #eef3fb) 72%);
  box-shadow:
    inset 0 1px 2px rgba(255, 255, 255, 0.9),
    inset 0 -10px 26px color-mix(in srgb, var(--mdxs-blue) 14%, transparent),
    0 18px 48px rgba(14, 23, 38, 0.12);
}
.mdxs:not(.is-ready) .mdxs-stage::after,
.mdxs[data-tier="static"] .mdxs-stage::after { opacity: 1; }

/* ==========================================================================
   SphereOrbit — actions held around the intelligence
   ========================================================================== */

.mdxs-orbit {
  position: absolute;
  inset: 0;
  z-index: 4;
  pointer-events: none;
}
.mdxs-orbit[hidden] { display: none; }

.mdxs-action {
  position: absolute;
  left: var(--mdxs-cx, 50%);
  top: var(--mdxs-cy, 50%);
  width: 68px;
  height: 68px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  color: var(--mdxs-ink);
  cursor: pointer;
  pointer-events: auto;
  overflow: visible;
  /* Closed, the actions are folded into the middle of the glass. Opening is
     the sphere handing them out, not a menu unfolding next to it. */
  transform:
    translate(-50%, -50%)
    translate(calc(var(--mdxs-x, 0px) * 0.12), calc(var(--mdxs-y, 0px) * 0.12))
    scale(0.5);
  opacity: 0;
  transition:
    transform 0.46s var(--mdxs-spring),
    opacity 0.24s var(--mdxs-ease);
}
.mdxs-orbit.is-open .mdxs-action {
  transform: translate(-50%, -50%) translate(var(--mdxs-x, 0px), var(--mdxs-y, 0px)) scale(1);
  opacity: 1;
  transition-delay: calc(var(--mdxs-i, 0) * 28ms);
}

.mdxs-action-ring {
  position: absolute;
  inset: 5px;
  border-radius: 50%;
  background: var(--mdx-glass, linear-gradient(177deg, rgba(255, 255, 255, 0.86), rgba(255, 255, 255, 0.7)));
  -webkit-backdrop-filter: var(--mdx-glass-blur, saturate(180%) blur(24px));
  backdrop-filter: var(--mdx-glass-blur, saturate(180%) blur(24px));
  border: 1px solid var(--mdx-glass-edge, rgba(255, 255, 255, 0.8));
  box-shadow: var(--mdx-glass-shadow, 0 2px 6px rgba(14, 23, 38, 0.06), 0 14px 34px rgba(14, 23, 38, 0.12));
  transition: transform 0.22s var(--mdxs-ease), box-shadow 0.22s var(--mdxs-ease);
}
.mdxs-action:hover .mdxs-action-ring { transform: scale(1.06); }
.mdxs-action:active .mdxs-action-ring { transform: scale(0.95); }
.mdxs-action:focus-visible .mdxs-action-ring {
  border-color: var(--mdxs-blue);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--mdxs-blue) 22%, transparent);
}
.mdxs-action:focus { outline: none; }

.mdxs-action-glyph {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  color: var(--mdxs-ink);
}
.mdxs-action-glyph svg { width: 100%; height: 100%; }

/* The label sits under the disc rather than inside it, so the target stays a
   comfortable circle and the word stays readable at 0.66rem. */
.mdxs-action-label {
  position: absolute;
  top: calc(100% + 5px);
  left: 50%;
  transform: translateX(-50%);
  font-size: 0.66rem;
  font-weight: 640;
  letter-spacing: -0.008em;
  color: var(--mdxs-muted);
  white-space: nowrap;
  pointer-events: none;
}

/* Too narrow for a ring: the actions become a plain row under the glass.
   They are the same buttons in the same order — only the geometry gives up. */
.mdxs-orbit.is-rail {
  inset: auto 0 0 0;
  display: flex;
  gap: 6px;
  justify-content: center;
  flex-wrap: wrap;
  padding: 0 4px 2px;
}
.mdxs-orbit.is-rail .mdxs-action {
  position: static;
  width: 60px;
  height: 60px;
  transform: scale(0.6);
}
.mdxs-orbit.is-rail.is-open .mdxs-action { transform: scale(1); }
.mdxs-orbit.is-rail .mdxs-action-label { position: static; transform: none; margin-top: 2px; }
.mdxs-orbit.is-rail .mdxs-action { flex-direction: column; }
.mdxs-orbit.is-rail .mdxs-action-ring { inset: 0 5px 18px; }

/* ==========================================================================
   SpatialNode — findings held beside the thing they describe
   ========================================================================== */

.mdxs-nodes {
  position: absolute;
  inset: 0;
  z-index: 5;
  pointer-events: none;
}
.mdxs-nodes[hidden] { display: none; }

.mdxs-node {
  position: absolute;
  left: 0;
  top: 0;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  max-width: var(--mdxs-node-max, 200px);
  padding: 7px 12px 7px 10px;
  border: 1px solid var(--mdxs-hair);
  border-radius: 999px;
  background: var(--mdxs-surface);
  box-shadow: var(--mdx-lift-1, 0 1px 2px rgba(14, 23, 38, 0.05), 0 6px 18px rgba(14, 23, 38, 0.06));
  color: var(--mdxs-ink);
  font: inherit;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: -0.012em;
  text-align: left;
  cursor: pointer;
  pointer-events: auto;
  transform:
    translate(var(--mdxs-x, 0px), var(--mdxs-y, 0px))
    translate(var(--mdxs-side, 0%), -50%)
    scale(0.86);
  opacity: 0;
  transition:
    opacity 0.34s var(--mdxs-ease),
    box-shadow 0.24s var(--mdxs-ease),
    border-color 0.24s var(--mdxs-ease),
    transform 0.44s var(--mdxs-spring);
}
.mdxs-node.is-in {
  opacity: 1;
  transform: translate(var(--mdxs-x, 0px), var(--mdxs-y, 0px)) translate(var(--mdxs-side, 0%), -50%) scale(1);
  transition-delay: var(--mdxs-delay, 0s);
}
.mdxs-node:hover { border-color: var(--mdx-hair-strong, rgba(14, 23, 38, 0.16)); }
.mdxs-node:focus { outline: none; }
.mdxs-node:focus-visible {
  border-color: var(--mdxs-blue);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--mdxs-blue) 20%, transparent);
}
.mdxs-node.is-selected {
  border-color: color-mix(in srgb, var(--mdxs-blue) 46%, transparent);
  box-shadow: var(--mdx-lift-2, 0 2px 6px rgba(14, 23, 38, 0.06), 0 14px 34px rgba(14, 23, 38, 0.12));
}

/* When one finding is chosen the others recede rather than vanish: the set is
   still there, it is just no longer what is being read. */
.mdxs-nodes.has-selection .mdxs-node:not(.is-selected) { opacity: 0.52; }

.mdxs-node-dot {
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--mdxs-blue);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--mdxs-blue) 14%, transparent);
}
.mdxs-node[data-tone="caution"] .mdxs-node-dot {
  background: var(--mdxs-gold);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--mdxs-gold) 18%, transparent);
}
/* "No pneumothorax" is a finding too, and a quiet one. A negative must never
   wear the same dot as something that needs attention. */
.mdxs-node[data-tone="absent"] {
  color: var(--mdxs-muted);
  font-weight: 560;
}
.mdxs-node[data-tone="absent"] .mdxs-node-dot {
  background: transparent;
  border: 1px solid var(--mdx-hair-strong, rgba(14, 23, 38, 0.2));
  box-shadow: none;
}

.mdxs-node-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.mdxs-node-meta {
  flex: none;
  color: var(--mdxs-faint);
  font-size: 0.7rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* Findings stay spatial, but never become a ring of heavy pills around the
   subject. In the dark studio they use translucent optical glass; on the
   light home page they belong to the page and remain visually subordinate to
   the Sphere. */
.mdxs[data-dark="1"] .mdxs-node {
  gap: 6px;
  padding: 6px 10px 6px 9px;
  background: rgba(12, 23, 39, 0.66);
  border-color: rgba(153, 196, 255, 0.16);
  box-shadow: 0 5px 18px rgba(0, 5, 18, 0.16);
  -webkit-backdrop-filter: saturate(135%) blur(14px);
  backdrop-filter: saturate(135%) blur(14px);
}

body.mdx:not(.dark-mode).mdx-sphere-home .mdxs[data-dark="1"] .mdxs-node {
  background: rgba(255, 255, 255, 0.84);
  border-color: rgba(47, 80, 126, 0.14);
  color: #25354b;
  box-shadow: 0 5px 18px rgba(18, 42, 74, 0.09);
}

body.mdx:not(.dark-mode).mdx-sphere-home .mdxs[data-dark="1"] .mdxs-node-meta {
  color: #718097;
}

/* Narrow: one scrollable rail beneath the glass. The leader lines still run
   from the anatomy down to each chip, so the spatial reading survives. */
.mdxs-nodes.is-rail {
  inset: auto 0 0 0;
  display: flex;
  gap: 7px;
  padding: 4px 14px 6px;
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  pointer-events: auto;
}
.mdxs-nodes.is-rail::-webkit-scrollbar { display: none; }
.mdxs-nodes.is-rail .mdxs-node {
  position: static;
  flex: 0 0 auto;
  max-width: 62vw;
  transform: translateY(10px) scale(0.94);
}
.mdxs-nodes.is-rail .mdxs-node.is-in { transform: none; }

/* ==========================================================================
   The explanation panel
   ========================================================================== */

.mdxs-detail {
  position: absolute;
  left: 50%;
  bottom: 0;
  z-index: 6;
  width: min(460px, 100%);
  max-height: 70%;
  overflow-y: auto;
  padding: 14px 16px 16px;
  border: 1px solid var(--mdxs-hair);
  border-radius: var(--mdx-r, 18px);
  background: var(--mdxs-surface);
  box-shadow: var(--mdx-lift-2, 0 2px 6px rgba(14, 23, 38, 0.06), 0 18px 44px rgba(14, 23, 38, 0.14));
  transform: translateX(-50%);
  animation: mdxsPanelIn 0.34s var(--mdxs-ease) both;
  -webkit-overflow-scrolling: touch;
}
.mdxs-detail[hidden] { display: none; }

@media (min-width: 900px) {
  .mdxs-detail {
    left: 0;
    transform: none;
    width: min(420px, 44%);
    max-height: 76%;
    animation-name: mdxsPanelInLeft;
  }
  @keyframes mdxsPanelInLeft {
    from { opacity: 0; transform: translateY(10px); }
    to { opacity: 1; transform: translateY(0); }
  }
}

@keyframes mdxsPanelIn {
  from { opacity: 0; transform: translateX(-50%) translateY(10px); }
  to { opacity: 1; transform: translateX(-50%) translateY(0); }
}

.mdxs-detail-head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 10px;
}
.mdxs-detail-title {
  flex: 1 1 auto;
  font-size: 0.95rem;
  font-weight: 700;
  letter-spacing: -0.022em;
  color: var(--mdxs-ink);
}
.mdxs-detail-close {
  flex: none;
  width: 30px;
  height: 30px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--mdxs-faint);
  cursor: pointer;
}
.mdxs-detail-close svg { width: 15px; height: 15px; }
.mdxs-detail-close:hover { color: var(--mdxs-ink); background: rgba(14, 23, 38, 0.05); }

.mdxs-detail-row { padding: 9px 0; border-top: 1px solid var(--mdxs-hair); }
.mdxs-detail-row:first-of-type { border-top: 0; padding-top: 0; }
.mdxs-detail-row dt {
  margin: 0 0 3px;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--mdxs-faint);
}
.mdxs-detail-row dd {
  margin: 0;
  font-size: 0.86rem;
  line-height: 1.5;
  color: var(--mdx-ink-2, #33415a);
}

.mdxs-detail-note {
  margin: 12px 0 0;
  padding-top: 10px;
  border-top: 1px solid var(--mdxs-hair);
  font-size: 0.72rem;
  line-height: 1.45;
  color: var(--mdxs-faint);
}

/* ==========================================================================
   Caption, hint and the live region
   ========================================================================== */

.mdxs-caption {
  position: absolute;
  left: 0;
  right: 0;
  top: var(--mdxs-cy, 50%);
  margin: 0;
  transform: translateY(calc(var(--mdxs-r, 116px) + 18px));
  text-align: center;
  font-size: 0.72rem;
  font-weight: 640;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--mdxs-faint);
  pointer-events: none;
  z-index: 3;
  transition: color 0.4s var(--mdxs-ease);
  /* A caption used to be one word ("HEART"). Semantix writes the model's own
     clause under the glass, so it has to be able to run to two lines and stop
     at the stage's edge instead of running off the page. */
  max-width: min(30rem, 88%);
  margin-inline: auto;
  line-height: 1.45;
  text-wrap: balance;
  overflow-wrap: anywhere;
}
.mdxs[data-state="analysing"] .mdxs-caption,
.mdxs[data-state="thinking"] .mdxs-caption { color: var(--mdxs-muted); }
.mdxs[data-state="caution"] .mdxs-caption { color: color-mix(in srgb, var(--mdxs-gold) 78%, var(--mdxs-ink)); }
/* The caption is a label for the glass; with actions on screen it would just
   be a third thing competing for the same space. */
.mdxs.is-expanded .mdxs-caption { opacity: 0; }

.mdxs-hint {
  position: absolute;
  left: var(--mdxs-cx, 50%);
  top: var(--mdxs-cy, 50%);
  transform: translate(-50%, calc(var(--mdxs-r, 116px) + 44px));
  margin: 0;
  padding: 6px 12px;
  border: 1px solid var(--mdxs-hair);
  border-radius: 999px;
  background: var(--mdxs-surface);
  box-shadow: var(--mdx-lift-1, 0 1px 2px rgba(14, 23, 38, 0.05), 0 6px 18px rgba(14, 23, 38, 0.06));
  font-size: 0.72rem;
  font-weight: 600;
  color: var(--mdxs-muted);
  white-space: nowrap;
  pointer-events: none;
  z-index: 3;
  animation: mdxsHintIn 0.5s var(--mdxs-ease) both;
}
.mdxs-hint[hidden] { display: none; }
.mdxs-hint.is-out { opacity: 0; transition: opacity 0.4s var(--mdxs-ease); }
@keyframes mdxsHintIn { from { opacity: 0; transform: translate(-50%, calc(var(--mdxs-r, 116px) + 52px)); } }

.mdxs-live {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* The image in flight, from wherever it was to inside the glass. */
.mdxs-ghost {
  position: fixed;
  z-index: 9999;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  border-radius: 14px;
  box-shadow: 0 18px 46px rgba(14, 23, 38, 0.22);
  pointer-events: none;
  will-change: transform, opacity;
}

/* ==========================================================================
   Dark surfaces
   ========================================================================== */

.mdxs[data-dark="1"] {
  --mdxs-ink: #f2f6fb;
  --mdxs-muted: #a9b9cf;
  --mdxs-faint: #7f92ac;
  --mdxs-hair: rgba(226, 232, 240, 0.14);
  --mdxs-surface: rgba(14, 23, 36, 0.88);
  --mdx-glass: linear-gradient(177deg, rgba(27, 39, 57, 0.82), rgba(10, 18, 31, 0.76));
  --mdx-glass-edge: rgba(214, 231, 255, 0.17);
  --mdx-glass-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08), 0 16px 40px rgba(0, 5, 18, 0.42);
  --mdx-lift-1: 0 2px 5px rgba(0, 4, 16, 0.24), 0 10px 28px rgba(0, 5, 20, 0.3);
  --mdx-lift-2: 0 3px 8px rgba(0, 4, 16, 0.3), 0 18px 42px rgba(0, 5, 20, 0.38);
}
.mdxs[data-dark="1"] .mdxs-detail-close:hover { background: rgba(255, 255, 255, 0.08); }
.mdxs[data-dark="1"] .mdxs-stage::after {
  background:
    radial-gradient(circle at 34% 28%, rgba(255, 255, 255, 0.30), rgba(255, 255, 255, 0) 44%),
    radial-gradient(circle at 62% 74%, color-mix(in srgb, var(--mdxs-blue) 42%, transparent), transparent 60%),
    radial-gradient(circle at 50% 50%, rgba(120, 160, 220, 0.16), rgba(12, 20, 32, 0.9) 74%);
  box-shadow:
    inset 0 1px 2px rgba(255, 255, 255, 0.14),
    0 18px 48px rgba(0, 0, 0, 0.5);
}

/* ==========================================================================
   Reduced motion
   ==========================================================================
   The renderer already stops animating on its own. What is left here is the
   chrome: transitions become instant, nothing staggers, and the orbit appears
   rather than unfolding. The INFORMATION is identical.
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  .mdxs-action,
  .mdxs-node,
  .mdxs-core-ring,
  .mdxs-detail,
  .mdxs-caption {
    transition-duration: 0.001s !important;
    transition-delay: 0s !important;
    animation-duration: 0.001s !important;
  }
  .mdxs-orbit.is-open .mdxs-action { transition-delay: 0s; }
  .mdxs-hint { animation: none; }
}

/* Windows high contrast / forced colours: the glass cannot survive a forced
   palette, so the component falls back to structure — an outlined circle and
   ordinary buttons that all still work. */
@media (forced-colors: active) {
  .mdxs-material, .mdxs-instruments { display: none; }
  .mdxs-stage::after {
    opacity: 1;
    background: none;
    border: 2px solid CanvasText;
    box-shadow: none;
  }
  .mdxs-action-ring { background: Canvas; border: 1px solid CanvasText; }
  .mdxs-node { border: 1px solid CanvasText; }
}

/* ==========================================================================
   Placement inside the redesigned MedDex home
   ==========================================================================
   These are the only shell-aware rules in the file. The sphere replaces
   nothing: it sits above the empty-state type, and the moment there is a
   conversation to read, the host removes it.
   ========================================================================== */

body.mdx .mdx-empty { position: relative; }

body.mdx .mdxs-home {
  /* The hero is the one thing on this screen that is allowed to be big. */
  --mdxs-h: clamp(268px, 43vh, 420px);
  margin: 0 0 6px;
  /* The empty state is a centred flex column, which shrink-wraps its children.
     A percentage-width canvas inside a shrink-wrapped box measures zero, and a
     sphere with no width has nowhere to put its orbit — every action lands on
     the same pixel. The stretch is not cosmetic. */
  width: 100%;
  align-self: stretch;
  flex: none;
}

/* ==========================================================================
   Sphere Voice — the Home intelligence becomes the room
   ========================================================================== */
.mdxs-voice-environment,
.mdxs-voice-exit { opacity: 0; pointer-events: none; }

.mdxs-voice-environment {
  position: fixed;
  inset: 0;
  z-index: -1;
  background:
    radial-gradient(circle at 50% 47%, rgba(75, 56, 202, .24), transparent 28%),
    radial-gradient(circle at 50% 52%, rgba(28, 102, 226, .15), transparent 47%),
    radial-gradient(circle at 50% 120%, rgba(63, 49, 153, .2), transparent 50%),
    linear-gradient(165deg, #060812 0%, #02040b 55%, #080916 100%);
  transition: opacity .52s var(--mdxs-ease);
}
.mdxs-voice-environment::before,
.mdxs-voice-environment::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
}
.mdxs-voice-environment::before {
  background-image:
    radial-gradient(circle at 28% 34%, rgba(155,137,255,.28) 0 1px, transparent 1.6px),
    radial-gradient(circle at 72% 62%, rgba(102,168,255,.24) 0 1px, transparent 1.6px),
    radial-gradient(circle at 62% 24%, rgba(255,255,255,.2) 0 .8px, transparent 1.4px);
  background-size: 143px 157px, 181px 173px, 211px 197px;
  opacity: .34;
  animation: mdxsVoiceDrift 18s linear infinite;
}
.mdxs-voice-environment::after {
  background: radial-gradient(ellipse at center, transparent 20%, rgba(0,0,0,.36) 72%, rgba(0,0,0,.7));
}

body.mdx main,
body.mdx .mdx-bar,
body.mdx .mdx-switch,
body.mdx .bottom-nav {
  transition: opacity .38s var(--mdxs-ease), filter .46s var(--mdxs-ease), transform .46s var(--mdxs-ease);
}
body.mdx.mdx-sphere-voice { overflow: hidden; background: #02040b; }
body.mdx.mdx-sphere-voice main,
body.mdx.mdx-sphere-voice .mdx-bar,
body.mdx.mdx-sphere-voice .mdx-switch,
body.mdx.mdx-sphere-voice .bottom-nav {
  opacity: 0;
  filter: blur(8px) saturate(.72);
  transform: scale(.985);
  pointer-events: none;
}

body.mdx.mdx-sphere-voice .mdxs-home {
  --mdxs-h: 100dvh;
  position: fixed !important;
  inset: 0 !important;
  z-index: 26020;
  width: 100vw !important;
  height: 100dvh !important;
  margin: 0 !important;
  display: block;
  isolation: isolate;
  pointer-events: none;
}
body.mdx.mdx-sphere-voice .mdxs-voice-environment { opacity: 1; }
body.mdx.mdx-sphere-voice .mdxs[data-size="voice"] {
  width: 100%;
  height: 100%;
  filter: saturate(1.2) drop-shadow(0 28px 74px rgba(68, 65, 218, .3));
}
body.mdx.mdx-sphere-voice .mdxs[data-size="voice"] .mdxs-caption,
body.mdx.mdx-sphere-voice .mdxs[data-size="voice"] .mdxs-hint,
body.mdx.mdx-sphere-voice .mdxs[data-size="voice"] .mdxs-think,
body.mdx.mdx-sphere-voice .mdxs[data-size="voice"] .mdxs-orbit,
body.mdx.mdx-sphere-voice .mdxs[data-size="voice"] .mdxs-nodes,
body.mdx.mdx-sphere-voice .mdxs[data-size="voice"] .mdxs-detail { display: none !important; }
body.mdx.mdx-sphere-voice .mdxs[data-size="voice"] .mdxs-core { cursor: default; pointer-events: none; }

body.mdx.mdx-sphere-voice .mdxs-voice-exit {
  position: fixed;
  top: calc(18px + env(safe-area-inset-top, 0px));
  right: calc(18px + env(safe-area-inset-right, 0px));
  z-index: 8;
  width: 34px;
  height: 34px;
  padding: 0;
  border: 1px solid rgba(220,229,255,.13);
  border-radius: 50%;
  background: rgba(214,224,255,.045);
  -webkit-backdrop-filter: blur(16px);
  backdrop-filter: blur(16px);
  opacity: .46;
  pointer-events: auto;
  transition: opacity .2s ease, background .2s ease, transform .2s ease;
}
.mdxs-voice-exit span::before,
.mdxs-voice-exit span::after {
  content: "";
  position: absolute;
  left: 10px;
  top: 16px;
  width: 13px;
  height: 1px;
  background: #e7ecff;
}
.mdxs-voice-exit span::before { transform: rotate(45deg); }
.mdxs-voice-exit span::after { transform: rotate(-45deg); }
.mdxs-voice-exit:hover, .mdxs-voice-exit:focus-visible { opacity: .9; background: rgba(220,228,255,.1); }
.mdxs-voice-exit:active { transform: scale(.9); }

body.mdx.mdx-sphere-voice[data-mdx-voice-state="activating"] .mdxs-stage::before,
body.mdx.mdx-sphere-voice[data-mdx-voice-state="connecting"] .mdxs-stage::before {
  content: "";
  position: absolute;
  inset: 8%;
  z-index: 0;
  border-radius: 50%;
  border: 1px solid rgba(142,121,255,.62);
  box-shadow: 0 0 24px rgba(100,89,255,.42), inset 0 0 20px rgba(70,139,255,.22);
  animation: mdxsVoiceActivate 1.35s cubic-bezier(.2,.75,.2,1) infinite;
  pointer-events: none;
}
@keyframes mdxsVoiceActivate {
  0% { transform: scale(.72); opacity: 0; }
  28% { opacity: .72; }
  100% { transform: scale(1.22); opacity: 0; }
}
@keyframes mdxsVoiceDrift { to { background-position: 143px -157px, -181px 173px, 211px 197px; } }

@media (max-width: 560px) {
  body.mdx.mdx-sphere-voice .mdxs-voice-exit { top: calc(13px + env(safe-area-inset-top, 0px)); right: 13px; width: 32px; height: 32px; }
  .mdxs-voice-exit span::before, .mdxs-voice-exit span::after { left: 9px; top: 15px; }
}

@media (prefers-reduced-motion: reduce) {
  .mdxs-voice-environment::before,
  body.mdx.mdx-sphere-voice[data-mdx-voice-state="activating"] .mdxs-stage::before,
  body.mdx.mdx-sphere-voice[data-mdx-voice-state="connecting"] .mdxs-stage::before { animation: none; }
  body.mdx main, body.mdx .mdx-bar, body.mdx .mdx-switch, body.mdx .bottom-nav { transition-duration: .001s; }
}

/* Light mode stays a white page. The dark renderer needs only a little local
   atmosphere behind the glass — never a dark hero section or a background
   object. This vignette lives on the Sphere's own coordinate system, fades to
   zero close to the rim and has no painted edge, border or ellipse box. */
body.mdx:not(.dark-mode).mdx-sphere-home .mdxs::before {
  display: none;
}

/* The orbit sits mostly beyond the vignette. Its words therefore belong to
   the light page, while the droplets/glyphs retain the dark Sphere palette. */
body.mdx:not(.dark-mode).mdx-sphere-home .mdxs[data-dark="1"] .mdxs-action-label {
  color: #53647c;
  text-shadow: 0 1px 12px rgba(255, 255, 255, 0.92);
}

/* Landscape phones have no vertical room to give: the sphere shrinks rather
   than pushing the question and the suggestions off the screen. */
@media (max-height: 620px) and (orientation: landscape) {
  body.mdx .mdxs-home { --mdxs-h: 208px; }
}

@media (min-width: 900px) {
  /* Desktop is not a stretched phone. See "The desktop composition" at the
     bottom of this file: the sphere takes the space it is owed, the
     suggestions move OUT of the column and sit either side of it, and the
     height they were using becomes glass. */
  body.mdx .mdxs-home {
    /* Two limits at once, and the second one is the important one. A pure vh
       clamp is right on a tall screen and wrong on a short one: at 768 px the
       block it belongs to is taller than the space between the header and the
       floating mode switch, and the Deck action lands underneath the switch.
       So the height is also capped by what is actually left after the header,
       the question, the Deck action and the composer have taken theirs. */
    --mdxs-h: clamp(280px, min(52vh, 100vh - 404px), 540px);
    width: clamp(340px, 42vw, 540px);
    align-self: center;
  }
}


/* ==========================================================================
   The status band
   ==========================================================================
   The same instance, reconfigured. Once there is a conversation to read, the
   hero would be in the way — but a sphere that disappears the moment MedDex
   starts thinking is a sphere that never shows thinking. So it steps aside
   into a band: small glass at the left, what it is doing beside it, and the
   subject's follow-ups on a rail underneath.
   ========================================================================== */

.mdxs[data-size="compact"] {
  --mdxs-h: 92px;
  transition: height 0.4s var(--mdxs-ease);
}
.mdxs[data-size="compact"].has-nodes { --mdxs-h: 138px; }

.mdxs[data-size="compact"] .mdxs-stage { left: 50px; top: 46px; }

.mdxs[data-size="compact"] .mdxs-caption {
  left: 100px;
  right: 10px;
  top: 46px;
  transform: translateY(-50%);
  text-align: left;
  font-size: 0.68rem;
}

.mdxs[data-size="compact"] .mdxs-nodes.is-rail { padding: 2px 12px 6px 12px; }
.mdxs[data-size="compact"] .mdxs-node { font-size: 0.75rem; padding: 6px 11px 6px 9px; }
.mdxs[data-size="compact"] .mdxs-detail { bottom: auto; top: 0; }

/* ==========================================================================
   The finding's own pixels
   ==========================================================================
   Selecting a finding shows where on the image it came from. The region is a
   rectangle over the source, not a mask: it is an honest pointer rather than
   a segmentation, and it is drawn to look like one.
   ========================================================================== */

.mdxs-detail-film {
  position: relative;
  margin: 0 0 12px;
  border-radius: var(--mdx-r-sm, 12px);
  overflow: hidden;
  background: #0d131b;
  line-height: 0;
}
.mdxs-detail-film img {
  display: block;
  width: 100%;
  max-height: 190px;
  object-fit: contain;
}
.mdxs-detail-roi {
  position: absolute;
  border: 1.5px solid var(--mdxs-blue);
  border-radius: 6px;
  box-shadow:
    0 0 0 1px rgba(255, 255, 255, 0.55),
    0 0 0 9999px color-mix(in srgb, var(--mdx-ink, #0e1726) 34%, transparent);
  pointer-events: none;
  animation: mdxsRoiIn 0.42s var(--mdxs-ease) both;
}
@keyframes mdxsRoiIn {
  from { opacity: 0; transform: scale(1.14); }
  to { opacity: 1; transform: scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .mdxs-detail-roi { animation: none; }
}

/* ==========================================================================
   Home composition
   ==========================================================================
   The sphere is the first thing on the home screen, and the type settles
   under it. Only applied when a sphere is actually mounted, so removing the
   script restores the previous home exactly.
   ========================================================================== */

body.mdx.mdx-sphere-home .mdx-empty {
  min-height: 0;
  align-items: center;
  text-align: center;
  /* Clears the bottom navigation, the MedDex Bar AND the floating
     Chat/Lens switch that sits above it — the switch is what the suggestion
     chips were disappearing behind. */
  padding-bottom: calc(var(--mdx-bottom-budget) + 58px);
  justify-content: flex-start;
}
body.mdx.mdx-sphere-home .mdx-empty-ask {
  max-width: 20ch;
  margin-top: 14px;
}

/* Short phones — an iPhone SE is 667 px tall and has to hold all seven tiers
   without scrolling. The Sphere is what gives up the height, because it is
   the one element that is still unmistakable at two thirds the size. */
@media (max-width: 899px) and (max-height: 700px) {
  /* There is enough unused air above the mode switch to keep a true orbit.
     At the old 25vh value the geometry collapsed the three actions into a
     horizontal rail, visually recreating the chip row the redesign removes. */
  body.mdx.mdx-sphere-home .mdxs-home { --mdxs-h: clamp(218px, 34vh, 244px); }
  /* With the smaller glass there is room to hang the two lower labels away
     from it instead of centring their words across the liquid surface. */
  .mdxs.is-orbit-always .mdxs-action { --mdxs-lean: var(--mdxs-side, 0); }
  body.mdx.mdx-sphere-home .mdx-empty-ask { font-size: clamp(1.3rem, 5.4vw, 1.6rem); margin-top: 2px; }
  body.mdx.mdx-sphere-home .mdx-empty { padding-bottom: calc(var(--mdx-bottom-budget) + 50px); }
}

/* ==========================================================================
   The THINKING label
   ==========================================================================
   A 30 px sphere alone in a conversation can be mistaken for an unfinished
   loading state. The word says what it is — and then gets out of the way the
   moment the answer starts, because by then the answer is the evidence.

   The dots are a `steps()` animation on generated content rather than three
   elements: no layout, no reflow, and it stops existing entirely when the
   label is not shown.
   ========================================================================== */

.mdxs-think {
  position: absolute;
  left: calc(var(--mdxs-cx, 50%) + var(--mdxs-r, 22px) + 14px);
  top: var(--mdxs-cy, 50%);
  margin: 0;
  transform: translateY(-50%);
  font-size: 0.74rem;
  font-weight: 640;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--mdxs-muted);
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  z-index: 3;
  transition: opacity 0.45s var(--mdxs-ease);
}

.mdxs[data-thinking="1"] .mdxs-think { opacity: 1; }

/* A role-to-role FLIP moves the glass through space. Its status text is tied
   to the destination layout, so letting it inherit that transform can carry
   the word across a transcript card on a slow first load. */
.mdxs-home.is-flipping .mdxs-think { opacity: 0 !important; }

.mdxs-think span::after {
  content: "";
  display: inline-block;
  width: 1.6em;
  text-align: left;
  animation: mdxsThinkDots 1.8s steps(1, end) infinite;
}
@keyframes mdxsThinkDots {
  0%   { content: ""; }
  25%  { content: "·"; }
  50%  { content: "··"; }
  75%  { content: "···"; }
  100% { content: ""; }
}

/* Beside the mark in a conversation; UNDER the sphere everywhere it is big
   enough to have an underneath. It is the same word about the same object —
   only the sphere's size decides where there is room for it. */
.mdxs[data-size="hero"] .mdxs-think,
.mdxs[data-size="stage"] .mdxs-think {
  left: var(--mdxs-cx, 50%);
  top: calc(var(--mdxs-cy, 50%) + var(--mdxs-r, 116px) + 30px);
  transform: translateX(-50%);
  font-size: 0.78rem;
  letter-spacing: 0.20em;
  color: var(--mdxs-muted);
}

/* The state caption and the word THINKING say the same thing, so only one of
   them is ever on the screen. */
.mdxs[data-thinking="1"] .mdxs-caption,
.mdxs[data-thinking="1"] .mdxs-hint { opacity: 0; }

/* The band is 92 px of strip with the caption already beside the glass. */
.mdxs[data-size="compact"] .mdxs-think { display: none; }

@media (prefers-reduced-motion: reduce) {
  .mdxs-think { transition: none; }
  /* No cycling dots — a steady word says the same thing. */
  .mdxs-think span::after { animation: none; content: "…"; }
}

/* ==========================================================================
   Narrow surfaces: one screen, no scroll to reach the composer
   ==========================================================================
   A phone has to hold the sphere, the question, the suggestions AND the
   floating Chat/Lens switch above the MedDex Bar. Something has to go, and the
   least useful thing on the screen is a name badge underneath an object that
   already is the name badge. It comes straight back on a wider surface, and
   everywhere the moment the sphere is not mounted.
   ========================================================================== */

@media (max-width: 899px) {
  body.mdx.mdx-sphere-home .mdx-empty-id,
  body.mdx.mdx-sphere-home .mdx-empty-sub { display: none; }
  body.mdx.mdx-sphere-home .mdx-empty-ask { margin-top: 4px; }
  body.mdx.mdx-sphere-home .mdx-empty-actions { margin-top: 16px; }
}

/* Short landscape phones have neither the height for a hero nor a use for it:
   the sphere becomes a small object beside the question rather than above it. */
@media (max-height: 620px) and (orientation: landscape) {
  body.mdx.mdx-sphere-home .mdx-empty {
    flex-direction: row;
    align-items: center;
    gap: 20px;
    text-align: left;
  }
  body.mdx.mdx-sphere-home .mdx-empty > .mdxs-home {
    flex: 0 0 auto;
    width: 220px;
    --mdxs-h: 200px;
  }
  body.mdx.mdx-sphere-home .mdx-empty-actions { justify-content: flex-start; }
}

/* ---- the drop target ----------------------------------------------------
   An image dragged anywhere over the home surface is heading for the sphere.
   The whole hero becomes the target, because a 300 px circle is a cruel thing
   to ask someone to hit with a file.

   The host has to establish a containing block, or the veil positions itself
   against the empty state and floats up the page as a line of stray text. */
body.mdx .mdxs-home { position: relative; }

body.mdx .mdxs-drop {
  position: absolute;
  inset: -10px;
  z-index: 7;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1.5px dashed color-mix(in srgb, var(--mdx-blue, #1769ff) 42%, transparent);
  border-radius: var(--mdx-r-lg, 24px);
  background: color-mix(in srgb, var(--mdx-blue, #1769ff) 6%, transparent);
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
  font-size: 0.84rem;
  font-weight: 640;
  color: var(--mdx-blue-ink, #0b46b5);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.2s var(--mdx-ease, cubic-bezier(0.22, 0.9, 0.24, 1)), visibility 0.2s;
}
body.mdx .mdxs-home.is-dropping .mdxs-drop { opacity: 1; visibility: visible; }

/* The inline role positions the host itself; it must not inherit the hero's
   containing-block rule as a static position. */
body.mdx.mdx-sphere-inline .mdxs-home { position: absolute; }

/* ==========================================================================
   The inline sphere
   ==========================================================================
   MedDex's own equivalent of a typing indicator: the same object, moved into
   the conversation. At 30–44 px the only things that survive are the glass
   edge, the blue core and the internal movement, so those are what the
   renderer spends its budget on there (see `uSmall`).
   ========================================================================== */

.mdxs[data-size="inline"] {
  --mdxs-h: var(--mdxs-inline, 44px);
  width: var(--mdxs-inline, 44px);
  min-width: var(--mdxs-inline, 44px);
  height: var(--mdxs-inline, 44px);
  transition: width 0.5s var(--mdxs-ease), height 0.5s var(--mdxs-ease);
}
.mdxs[data-size="inline"] .mdxs-caption,
.mdxs[data-size="inline"] .mdxs-hint { display: none; }
.mdxs[data-size="inline"] .mdxs-core { cursor: default; }

/* Nothing that needs room to be read belongs on a 44 px marker. */
.mdxs[data-size="inline"] .mdxs-nodes,
.mdxs[data-size="inline"] .mdxs-detail,
.mdxs[data-size="inline"] .mdxs-orbit { display: none !important; }

/* The host is placed against the conversation's own coordinates: last in the
   log while MedDex is thinking, level with the answer once it is writing. */
body.mdx.mdx-sphere-inline .mdxs-home {
  position: absolute;
  left: 0;
  top: var(--mdxs-anchor, 0px);
  width: var(--mdxs-inline, 44px);
  margin: 0;
  border: 0;
  z-index: 6;
  pointer-events: none;
  transition: top 0.42s var(--mdx-ease, cubic-bezier(0.22, 0.9, 0.24, 1));
}

body.mdx.mdx-sphere-inline #bfsLog {
  position: relative;
  /* Room for the sphere to sit below the last message without being clipped. */
  padding-bottom: 62px !important;
}

/* The sphere IS the typing indicator now; three bouncing dots beside it would
   be two answers to the same question. */
body.mdx.mdx-sphere-inline #bfsLog .bchat-typing { display: none !important; }

/* The gutter the answer opens so the sphere sits beside the sentence being
   written rather than under it. */
body.mdx.mdx-sphere-inline #bfsLog .bchat-msg.is-streaming {
  padding-left: 46px;
  transition: padding-left 0.42s var(--mdx-ease, cubic-bezier(0.22, 0.9, 0.24, 1));
}

@media (prefers-reduced-motion: reduce) {
  body.mdx.mdx-sphere-inline .mdxs-home,
  body.mdx.mdx-sphere-inline #bfsLog .bchat-msg.is-streaming,
  .mdxs[data-size="inline"] { transition: none; }
}

/* The state under the glass is a footnote to the sphere, not a label on it. */
body.mdx.mdx-sphere-home .mdxs-caption { opacity: 0.72; }

/* The hint was a white pill with its own shadow sitting directly beneath the
   one object that is meant to hold the eye — a second, smaller, brighter
   thing in the sphere's own space. It says the same thing as quiet type. */
body.mdx.mdx-sphere-home .mdxs-hint {
  padding: 4px 2px;
  border-color: transparent;
  background: none;
  box-shadow: none;
  color: var(--mdx-faint, #8b97a8);
  font-weight: 560;
  letter-spacing: 0.005em;
}

/* The switch and the composer are furniture on the empty home: two glass
   panels with lift shadows underneath a glass sphere is three glass objects
   arguing. They come back to full strength the moment there is a conversation
   on the screen, because then they are what the screen is for. */
body.mdx.mdx-sphere-home.mdx-chat-empty #mdxModeSwitch {
  box-shadow: 0 1px 2px rgba(14, 23, 38, 0.04), 0 6px 20px rgba(14, 23, 38, 0.05);
  border-color: color-mix(in srgb, var(--mdx-ink, #0e1726) 6%, transparent);
}
body.mdx.mdx-sphere-home.mdx-chat-empty #mdxModeSwitch .mdx-switch-thumb {
  box-shadow: 0 1px 2px rgba(14, 23, 38, 0.05), 0 2px 7px rgba(14, 23, 38, 0.07);
}
body.mdx.mdx-sphere-home.mdx-chat-empty #mdxBar {
  box-shadow: 0 1px 2px rgba(14, 23, 38, 0.04), 0 10px 30px rgba(14, 23, 38, 0.06);
  border-color: color-mix(in srgb, var(--mdx-ink, #0e1726) 6%, transparent);
}

/* ==========================================================================
   THE THINKING STAGE
   ==========================================================================
   Sending a message used to shrink the sphere to 44 px and file it into the
   conversation immediately. That is the right place for it once there is an
   answer to stand beside — and the wrong place while MedDex is still working,
   because the thing that is working IS the sphere, and it has just been given
   something to work on.

   So it stays large and centred while it thinks, the topic materialises
   inside it, and THINKING sits underneath. It lives exactly where the status
   band lives, so a second question grows the same object back up out of the
   band rather than producing a new one somewhere else.
   ========================================================================== */

.mdxs[data-size="stage"] {
  --mdxs-h: clamp(220px, 36vh, 340px);
  transition: height 0.52s var(--mdxs-ease);
}
@media (min-width: 900px) {
  .mdxs[data-size="stage"] { --mdxs-h: clamp(300px, 48vh, 460px); }
}

/* Nothing on a working sphere is a control. */
.mdxs[data-size="stage"] .mdxs-hint,
.mdxs[data-size="stage"] .mdxs-orbit { display: none; }
.mdxs[data-size="stage"] .mdxs-core { cursor: default; }

body.mdx.mdx-sphere-stage .mdxs-home {
  width: 100%;
  margin: 4px 0 2px;
  /* The conversation below it must not be pushed off the screen: on a phone
     the message that was just sent has to stay readable underneath. */
  flex: none;
}

/* The conversation keeps its place under the sphere and steps back a little
   while the sphere is the thing to look at. It is not disabled and it is not
   hidden — the question that was just asked is still there to be re-read. */
body.mdx.mdx-sphere-stage #bfsLog .bchat-typing { display: none !important; }

/* THE SPHERE IS THE THINKING STATE. There must not be two of them.
   While the sphere is on the stage — large, centred, holding the topic and
   carrying THINKING under it — the small status orb beside the word is a
   second, worse answer to the same question, drawn 400px below the first. */
body.mdx.mdx-sphere-stage #bfsLog { padding-top: 2px !important; }

@media (prefers-reduced-motion: reduce) {
  .mdxs[data-size="stage"] { transition: none; }
}

/* ==========================================================================
   THE ANSWER, MADE OUT OF THE SPHERE
   ==========================================================================
   The geometry of this is not here. It is a signed distance field on its own
   WebGL layer (`MedDexSphere.liquidBridge`) in which the sphere, the neck
   leaving it and the rectangle it becomes are ONE surface, smooth-unioned, so
   there is a real fillet where they join and a real pinch when they part.

   What is here is the two things the DOM has to do for that to land:

     * the container must not be on the screen until the liquid has made it,
       while still laying out so the bridge knows where it is going;
     * when it does arrive, it must arrive as the material it was made of, and
       settle out of it.

   Neither of them is a crossfade between the surface and the container. Both
   are drawn, in the same place, for the frame in which they swap.
   ========================================================================== */

/* Laid out, measurable, and not painted. `visibility` rather than `opacity`
   deliberately: there is no partly-there container at any point. */
body.mdx #bfsLog .bchat-msg.mdxs-forming { visibility: hidden; }

.mdxs-bridge {
  position: fixed;
  z-index: 2520;
  pointer-events: none;
  display: block;
}

/* The container arrives as glass and settles into a surface you can read.
   Optical depth, edge light and a faint internal drift, easing out over about
   a second — "living liquid intelligence becoming stable information", which
   is the whole reason the answer is worth making out of the sphere at all.

   It is an overlay rather than the bubble's own background because the shell
   sets that with `!important`, and an animation loses to `!important`. */
body.mdx #bfsLog .bchat-msg.mdxs-glassborn { position: relative; }

body.mdx #bfsLog .bchat-msg.mdxs-glassborn::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  /* The dye arrives with the material and settles out of it. Two hues either
     side of the MedDex blue — a cool teal and a soft violet — drifting across
     the surface while it forms, at an amplitude that never reads as a colour
     wash over the answer. */
  background:
    radial-gradient(120% 180% at 26% -30%, rgba(255, 255, 255, 0.95), rgba(255, 255, 255, 0.25) 42%, rgba(255, 255, 255, 0) 68%),
    radial-gradient(70% 150% at 18% 120%, color-mix(in srgb, #29b6cf 26%, transparent), transparent 62%),
    radial-gradient(80% 150% at 84% 130%, color-mix(in srgb, #6a5ad8 24%, transparent), transparent 64%),
    radial-gradient(90% 140% at 58% 120%, color-mix(in srgb, var(--mdx-blue, #1769ff) 20%, transparent), transparent 66%),
    linear-gradient(168deg, rgba(255, 255, 255, 0.50), color-mix(in srgb, var(--mdx-blue, #1769ff) 8%, rgba(240, 245, 253, 0.34)));
  background-size: 100% 100%, 160% 200%, 160% 200%, 140% 180%, 100% 100%;
  background-position: 0% 0%, 0% 100%, 100% 100%, 50% 100%, 0% 0%;
  box-shadow:
    inset 0 1px 1px rgba(255, 255, 255, 0.96),
    inset 0 0 0 1px color-mix(in srgb, var(--mdx-blue, #1769ff) 20%, rgba(255, 255, 255, 0.7)),
    inset 0 -10px 26px color-mix(in srgb, var(--mdx-blue, #1769ff) 12%, transparent),
    0 14px 34px rgba(14, 23, 38, 0.10);
  -webkit-backdrop-filter: blur(2px) saturate(1.18);
  backdrop-filter: blur(2px) saturate(1.18);
  animation:
    mdxsGlassSettle 1.05s var(--mdx-ease, cubic-bezier(0.22, 0.9, 0.24, 1)) both,
    mdxsDyeDrift 1.05s linear both;
}

@keyframes mdxsGlassSettle {
  /* Held for a beat at full strength, because the frame it hands over on is
     the frame it has to match the rendered surface. */
  0%, 12% { opacity: 1; transform: scale(1); }
  100% { opacity: 0; transform: scale(1); }
}

/* The colour is still moving while the surface settles — liquid, until it
   isn't. It goes out with the overlay, so the finished answer carries none of
   it and stays as readable as any other. */
@keyframes mdxsDyeDrift {
  from { background-position: 0% 0%, 6% 100%, 94% 100%, 50% 100%, 0% 0%; }
  to   { background-position: 0% 0%, 38% 62%, 66% 66%, 50% 74%, 0% 0%; }
}

/* The words are what the container was made for, so they arrive with it rather
   than before it — but a fraction later, once the surface has stopped moving. */
body.mdx #bfsLog .bchat-msg.mdxs-glassborn > * {
  animation: mdxsAnswerIn 0.42s var(--mdx-ease, cubic-bezier(0.22, 0.9, 0.24, 1)) 0.08s both;
}
@keyframes mdxsAnswerIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  body.mdx #bfsLog .bchat-msg.mdxs-glassborn::after,
  body.mdx #bfsLog .bchat-msg.mdxs-glassborn > * { animation: none !important; }
  body.mdx #bfsLog .bchat-msg.mdxs-glassborn::after { display: none; }
  .mdxs-bridge { display: none; }
}

/* Reading a set of findings is a different mode from asking a question: the
   labels need the width the suggestions are currently standing in, and each
   label is a sentence rather than an icon. So the glass takes the whole row and
   the two flanking chips stand down until the findings let go. Without this the
   sphere's own box is 470 px wide, the label columns do not fit, and the
   findings collapse into a rail underneath a spatial interface. */
@media (min-width: 1100px) {
  body.mdx.mdx-sphere-home.mdx-sphere-reading .mdxs-home {
    width: 100%;
  }
}

/* The one swap where the geometry is taken rather than eased: the sphere has
   just been contracted onto the answer's gutter by hand, so the inline role's
   own width/height/top transitions would spend half a second travelling to a
   place it is already standing in — and leave a gap where the sphere is
   nowhere at all. */
body.mdx.mdx-sphere-instant .mdxs,
body.mdx.mdx-sphere-instant .mdxs-home { transition: none !important; }

/* ==========================================================================
   ACTIONS IN ORBIT
   ==========================================================================
   The three quick actions used to be a row of chips under the question, which
   is the layout of every app home screen there has ever been — and it makes
   the sphere an illustration sitting above a toolbar.

   Held around the glass instead, they read as things the sphere is offering.
   So they stop being buttons: no fill, no border, no shadow, no disc. A small
   bead of the same material as the sphere, a quiet word beside it, and real
   space between them and the glass. The only object with weight on the screen
   is still the sphere.

   `is-orbit-always` is the permanent-orbit mode. The transitional orbit — the
   one that folds out of the glass on a press — keeps its original discs, and
   these rules are scoped so they cannot reach it.
   ========================================================================== */

.mdxs.is-orbit-always .mdxs-action {
  width: auto;
  height: auto;
  min-height: 44px;             /* a comfortable target under a small label */
  border-radius: 999px;
  padding: 0 6px;
  gap: 8px;
  justify-content: flex-start;
  transform:
    translate(calc(-50% + var(--mdxs-lean, 0) * 50%), -50%)
    translate(var(--mdxs-x, 0px), var(--mdxs-y, 0px));
  opacity: 1;
  transition:
    transform 0.5s var(--mdxs-ease),
    opacity 0.4s var(--mdxs-ease);
}

/* The bead. The same porcelain-and-blue the glass is made of, at 9 px — it
   reads as a droplet that left the sphere and stopped. */
.mdxs.is-orbit-always .mdxs-action-ring {
  position: relative;
  inset: auto;
  flex: none;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background:
    radial-gradient(circle at 34% 30%, rgba(255, 255, 255, 0.98), rgba(255, 255, 255, 0) 62%),
    linear-gradient(160deg, color-mix(in srgb, var(--mdxs-blue) 62%, #ffffff), var(--mdxs-blue));
  border: 0;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  box-shadow: 0 1px 3px color-mix(in srgb, var(--mdxs-blue) 26%, transparent);
  transition: transform 0.28s var(--mdxs-spring), box-shadow 0.28s var(--mdxs-ease);
}

/* Deck is the one paid thing on the screen. It keeps the gold it has always
   had — a different bead, not a louder one. */
.mdxs.is-orbit-always .mdxs-action[data-action="deck"] .mdxs-action-ring {
  background:
    radial-gradient(circle at 34% 30%, rgba(255, 255, 255, 0.95), rgba(255, 255, 255, 0) 62%),
    linear-gradient(150deg, #e2c06a, var(--mdxs-gold) 58%, #a5801e);
  box-shadow: 0 1px 3px color-mix(in srgb, var(--mdxs-gold) 34%, transparent);
}

.mdxs.is-orbit-always .mdxs-action-glyph { display: none; }

.mdxs.is-orbit-always .mdxs-action-label {
  position: static;
  transform: none;
  font-size: 0.795rem;
  font-weight: 500;
  letter-spacing: -0.006em;
  color: var(--mdxs-muted);
  transition: color 0.22s var(--mdxs-ease);
}

.mdxs.is-orbit-always .mdxs-action:hover .mdxs-action-label,
.mdxs.is-orbit-always .mdxs-action:focus-visible .mdxs-action-label { color: var(--mdxs-ink); }
.mdxs.is-orbit-always .mdxs-action:hover .mdxs-action-ring { transform: scale(1.28); }
.mdxs.is-orbit-always .mdxs-action:active { transform:
    translate(calc(-50% + var(--mdxs-lean, 0) * 50%), -50%)
    translate(var(--mdxs-x, 0px), var(--mdxs-y, 0px))
    scale(0.97); }

.mdxs.is-orbit-always .mdxs-action:focus-visible {
  outline: 2px solid var(--mdxs-blue);
  outline-offset: 3px;
  border-radius: 999px;
}

/* They arrive with the sphere rather than all at once, so the ring reads as
   settling into place. */
@media (prefers-reduced-motion: no-preference) {
  .mdxs.is-orbit-always .mdxs-orbit.is-open .mdxs-action {
    animation: mdxsOrbitIn 0.62s var(--mdxs-ease) both;
    animation-delay: calc(0.10s + var(--mdxs-i, 0) * 0.09s);
  }
  @keyframes mdxsOrbitIn {
    from { opacity: 0; transform:
      translate(calc(-50% + var(--mdxs-lean, 0) * 50%), -50%)
      translate(calc(var(--mdxs-x, 0px) * 0.55), calc(var(--mdxs-y, 0px) * 0.55)); }
    to { opacity: 1; }
  }
}

/* The home copy stepping back for an open orbit was right when the orbit was a
   menu that had just appeared. It is permanent now, so nothing steps back. */
body.mdx.mdx-sphere-home.mdx-sphere-open .mdx-empty-ask { opacity: 1; }

/* ==========================================================================
   THE ROW UNDER THE QUESTION IS GONE
   ==========================================================================
   Both of them: the shell's suggestion chips and its Deck block. The same
   three choices are in orbit around the glass, and offering them twice would
   undo the point of moving them. The shell is untouched — these are simply not
   shown while a sphere is mounted, and come straight back if it is removed.
   ========================================================================== */

body.mdx.mdx-sphere-home .mdx-empty-actions,
body.mdx.mdx-sphere-home .mdx-onboard { display: none; }

/* On a phone the labels are centred on their orbit point: leaning them outward
   needs room outside the ring, and there is none. Slightly smaller type keeps
   the ring clear of the glass without the sphere giving anything up. */
@media (max-width: 899px) {
  .mdxs.is-orbit-always .mdxs-action-label { font-size: 0.735rem; }
}

@media (min-width: 900px) {
  /* Room to lean. An action to the left of the glass hangs its label further
     left, so the words open away from the sphere instead of crowding it. */
  .mdxs.is-orbit-always .mdxs-action { --mdxs-lean: var(--mdxs-side, 0); }
}

/* ==========================================================================
   THE DESKTOP COMPOSITION, WITHOUT THE CHIPS
   ==========================================================================
   The three-column grid existed to seat two suggestion chips either side of
   the glass. They are in orbit now, so the grid has nothing to place and the
   composition goes back to what it should be: one centred object with its own
   actions around it, and the question beneath.

   The host gets noticeably wider than the glass — that width IS the orbit.
   The stage is sized by the shorter side, so it costs the sphere nothing.
   ========================================================================== */

@media (min-width: 900px) {
  body.mdx.mdx-sphere-home .mdx-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-start;
    row-gap: 0;
    padding-bottom: calc(var(--mdx-bottom-budget) + 88px);
  }

  /* The sphere already carries MedDex identity. Repeating the old name badge,
     tagline and tap hint underneath it turns one spatial interface back into
     a stack of introductions. */
  body.mdx.mdx-sphere-home .mdx-empty-id,
  body.mdx.mdx-sphere-home .mdx-empty-sub,
  body.mdx.mdx-sphere-home .mdxs-hint { display: none; }

  body.mdx .mdxs-home,
  body.mdx.mdx-sphere-home .mdxs-home {
    width: clamp(460px, 52vw, 660px);
    align-self: center;
  }

  body.mdx.mdx-sphere-home .mdx-empty-ask {
    margin: 6px 0 0;
    max-width: 20ch;
    font-size: clamp(1.9rem, 2.5vw, 2.5rem);
  }
}

/* Below 1100 px the old rules moved the chips back under the question. There
   are no chips. */
@media (min-width: 900px) and (max-width: 1099px) {
  body.mdx .mdxs-home { --mdxs-h: clamp(280px, min(50vh, 100vh - 392px), 540px); }
}

/* The phone hero gives the ring its width the same way: the host runs the full
   viewport so the two lower actions have somewhere to be, while the glass
   itself is still sized by the height. */
@media (max-width: 899px) {
  body.mdx.mdx-sphere-home .mdxs-home {
    width: 100vw;
    max-width: 100vw;
    margin-left: calc(50% - 50vw);
    margin-right: calc(50% - 50vw);
  }
}

/* Final mobile composition -------------------------------------------------
   The browser's visible height is measured by the shell (not guessed from
   layout-viewport vh). One reserved column ends exactly above the fixed
   Chat/Lens switch, composer and nav, so no tier can overlap another when
   Safari expands its address bar or an Android viewport is unusually short. */
@media (max-width: 899px) and (orientation: portrait) {
  /* Home is a self-contained column that already reserves the composer, the
     switch and the safe area inside itself. The shell's own bottom budget on
     top of that is 127px of scrollable nothing below a screen that is supposed
     to be exactly one screen — which is what let the whole composition drift
     upward under a thumb. Home does not scroll; only the transcript does. */
  body.mdx.mdx-sphere-home.mdx-chat-empty .app-shell { padding-bottom: 0; }

  body.mdx.mdx-sphere-home .mdx-home {
    /* What is left of the VISIBLE viewport below wherever Home begins. The
       offset is measured by the shell every time the chrome moves, so the
       column ends exactly at the bottom of the screen instead of hanging over
       it by the height of whatever sits above. */
    height: calc(var(--mdx-visual-vh, 100dvh) - var(--mdx-home-top, 0px));
    min-height: 0;
    overflow: hidden;
  }

  body.mdx.mdx-sphere-home .mdx-topline {
    min-height: 48px;
    padding-block: 8px 4px;
  }

  body.mdx.mdx-sphere-home .mdx-empty {
    flex: 1 1 auto;
    width: 100%;
    min-height: 0;
    box-sizing: border-box;
    /* CENTRED, not top-aligned. The bottom padding already reserves the switch,
       the composer and the safe area, so what is left is the free column — and
       a group pinned to the top of it leaves every spare pixel in one dead
       block above the composer. Centring inside an already bottom-weighted box
       also lands the sphere slightly above the true middle, which is where the
       eye expects the subject to be. */
    justify-content: center;
    overflow: hidden;
    padding: 0 0 calc(var(--mdx-bottom-budget) + var(--mdx-switch-h, 56px) + 10px);
  }

  body.mdx.mdx-sphere-home .mdxs-home {
    flex: 0 0 auto;
    /* The sphere takes the room the removed bottom navigation gave back. The
       reserved column is what is left after the fixed chrome; the sphere takes
       just under three quarters of it and the question takes the rest, which
       is what keeps a tall phone from showing a small ball in a large empty
       field. */
    --mdxs-h: clamp(
      208px,
      calc((var(--mdx-visual-vh, 100dvh) - var(--mdx-bottom-budget) - var(--mdx-switch-h, 56px) - 176px) * .72),
      372px
    );
  }

  body.mdx.mdx-sphere-home .mdx-empty-ask {
    flex: 0 0 auto;
    margin: clamp(4px, 1.1vh, 10px) auto 0;
    padding-inline: 18px;
    max-width: 19ch;
    font-size: clamp(1.42rem, 6vw, 2rem);
    line-height: 1.08;
  }
}

@media (max-width: 899px) and (orientation: portrait) and (max-height: 720px) {
  /* THE HOST IS THE ORBIT, NOT THE GLASS.
     A 44px label above a 57px-radius sphere needs 79px of vertical room to
     clear it, and the host only had 78. The renderer resolves that by pulling
     the GLASS in — correctly, it is the only lever it has — and on a 667px
     phone that drove it to its 0.52 floor: a hero sphere reduced to a marble
     so a caption could sit above it.

     The room is the fix. The stage inside is unchanged; the host is taller, so
     the ring has somewhere to be and the glass stays full size. */
  body.mdx.mdx-sphere-home .mdxs-home { --mdxs-h: clamp(214px, 34vh, 232px); }
  body.mdx.mdx-sphere-home .mdx-empty-ask {
    margin-top: 0;
    font-size: clamp(1.24rem, 5.2vw, 1.52rem);
  }
}

/* ==========================================================================
   Spatial Intelligence — the answer becomes a place you can watch
   ==========================================================================

   Two pieces of chrome and nothing else. A small control under a finished
   answer, on the light page where the answer lives; and the theatre, which is
   the SAME dark environment Live Voice already uses with a different set of
   things allowed on screen. The sphere, its materials, its lighting, its
   particles and the transition into the room are untouched — this file adds
   no rule that reaches inside .mdxs-stage.
   ========================================================================== */

.mdx-si-row {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin: 2px 0 14px;
  padding: 0;
  /* The answer's own gutter. The row belongs to the message above it, not to
     the log, so it lines up with the first character of the answer. */
  animation: mdxSiRowIn 0.42s cubic-bezier(0.22, 0.75, 0.2, 1) both;
}
@keyframes mdxSiRowIn { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }

.mdx-si-btn {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 32px;
  padding: 0 12px 0 9px;
  border: 1px solid rgba(23, 105, 255, 0.22);
  border-radius: 999px;
  background: rgba(23, 105, 255, 0.06);
  color: #1f4fbf;
  font: inherit;
  font-size: 0.78rem;
  font-weight: 620;
  letter-spacing: -0.008em;
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.18s ease, border-color 0.18s ease, transform 0.14s ease, opacity 0.2s ease;
  -webkit-tap-highlight-color: transparent;
}
.mdx-si-btn svg { width: 15px; height: 15px; flex: none; }
/* The glyph turns very slowly, once, on hover — the same idea as the sphere
   itself: never still, never animated at you. */
.mdx-si-btn svg .mdx-si-orbit { transform-origin: 12px 12px; transition: transform 0.9s cubic-bezier(0.3, 0.7, 0.2, 1); }
.mdx-si-btn:hover { background: rgba(23, 105, 255, 0.11); border-color: rgba(23, 105, 255, 0.34); }
.mdx-si-btn:hover svg .mdx-si-orbit { transform: rotate(38deg); }
.mdx-si-btn:active { transform: scale(0.965); }
.mdx-si-btn[disabled] { opacity: 0.5; cursor: default; }
.mdx-si-btn.is-busy { pointer-events: none; }
.mdx-si-btn.is-busy svg .mdx-si-orbit { animation: mdxSiSpin 1.4s linear infinite; transition: none; }
@keyframes mdxSiSpin { to { transform: rotate(360deg); } }

body.mdx.dark-mode .mdx-si-btn {
  border-color: rgba(150, 186, 255, 0.24);
  background: rgba(120, 160, 255, 0.10);
  color: #b8ccff;
}
body.mdx.dark-mode .mdx-si-btn:hover { background: rgba(120, 160, 255, 0.17); }

/* ---- the theatre --------------------------------------------------------
   Lives above the promoted sphere host (z-index 26020) and is transparent to
   the pointer everywhere except its own controls, so the glass underneath can
   still be dragged and turned while a story plays. */
.mdxs-theatre {
  position: fixed;
  inset: 0;
  z-index: 26030;
  display: none;
  pointer-events: none;
  color: #e9eeff;
  font: inherit;
  opacity: 0;
  transition: opacity 0.44s var(--mdxs-ease);
}
body.mdx.mdx-sphere-theatre .mdxs-theatre { display: block; opacity: 1; }

.mdxs-theatre-head {
  position: absolute;
  top: calc(20px + env(safe-area-inset-top, 0px));
  left: calc(22px + env(safe-area-inset-left, 0px));
  right: calc(74px + env(safe-area-inset-right, 0px));
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.mdxs-theatre-eyebrow {
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(178, 196, 255, 0.62);
}
.mdxs-theatre-title {
  font-size: 0.98rem;
  font-weight: 640;
  letter-spacing: -0.012em;
  color: rgba(238, 243, 255, 0.94);
  max-width: 30rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.mdxs-theatre-close {
  position: absolute;
  top: calc(18px + env(safe-area-inset-top, 0px));
  right: calc(18px + env(safe-area-inset-right, 0px));
  width: 34px;
  height: 34px;
  padding: 0;
  border: 1px solid rgba(220, 229, 255, 0.13);
  border-radius: 50%;
  background: rgba(214, 224, 255, 0.045);
  -webkit-backdrop-filter: blur(16px);
  backdrop-filter: blur(16px);
  opacity: 0.5;
  pointer-events: auto;
  cursor: pointer;
  transition: opacity 0.2s ease, background 0.2s ease, transform 0.2s ease;
}
.mdxs-theatre-close::before,
.mdxs-theatre-close::after {
  content: "";
  position: absolute;
  left: 10px;
  top: 16px;
  width: 13px;
  height: 1px;
  background: #e7ecff;
}
.mdxs-theatre-close::before { transform: rotate(45deg); }
.mdxs-theatre-close::after { transform: rotate(-45deg); }
.mdxs-theatre-close:hover, .mdxs-theatre-close:focus-visible { opacity: 0.92; background: rgba(220, 228, 255, 0.1); }
.mdxs-theatre-close:active { transform: scale(0.9); }

/* The narration. It sits low, under the glass, and it is the model's own
   sentence for this beat — never a phrase the engine composed. */
.mdxs-theatre-foot {
  position: absolute;
  left: 50%;
  bottom: calc(26px + env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%);
  width: min(38rem, calc(100vw - 44px));
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
}
.mdxs-theatre-caption {
  min-height: 2.6em;
  margin: 0;
  text-align: center;
  font-size: 0.94rem;
  font-weight: 500;
  line-height: 1.45;
  letter-spacing: -0.006em;
  color: rgba(232, 238, 255, 0.9);
  text-wrap: balance;
  overflow-wrap: anywhere;
  transition: opacity 0.3s var(--mdxs-ease);
}
.mdxs-theatre-caption.is-out { opacity: 0; }
.mdxs-theatre-caption em {
  display: block;
  margin-bottom: 5px;
  font-style: normal;
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(158, 178, 255, 0.62);
}

/* One dot per beat. A story you can see the length of is a story you can wait
   for; a story with no rail is an animation that might never stop. */
.mdxs-theatre-rail {
  display: flex;
  align-items: center;
  gap: 6px;
  pointer-events: auto;
}
.mdxs-theatre-dot {
  width: 22px;
  height: 4px;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: rgba(198, 213, 255, 0.2);
  cursor: pointer;
  transition: background 0.3s var(--mdxs-ease), width 0.3s var(--mdxs-ease);
}
.mdxs-theatre-dot.is-done { background: rgba(198, 213, 255, 0.4); }
.mdxs-theatre-dot.is-now { width: 34px; background: rgba(150, 186, 255, 0.92); }

.mdxs-theatre-transport {
  display: flex;
  align-items: center;
  gap: 10px;
  pointer-events: auto;
}
.mdxs-theatre-key {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  padding: 0;
  border: 1px solid rgba(220, 229, 255, 0.13);
  border-radius: 50%;
  background: rgba(214, 224, 255, 0.045);
  color: #dfe7ff;
  cursor: pointer;
  opacity: 0.72;
  transition: opacity 0.18s ease, background 0.18s ease, transform 0.14s ease;
}
.mdxs-story-scales, .mdxs-story-tools { display: flex; flex-wrap: wrap; gap: 8px; pointer-events: auto; margin-top: 12px; }
.mdxs-story-scales button, .mdxs-story-tools button { font: inherit; font-size: 12px; color: #c7d7f3; border: 1px solid #ffffff29; border-radius: 18px; background: #142238b8; padding: 8px 12px; cursor: pointer; }
.mdxs-story-scales button[aria-current="step"], .mdxs-story-tools button[aria-pressed="true"] { background: #31528b; color: white; border-color: #a9c7ff; }
.mdxs-story-scales button:focus-visible, .mdxs-story-tools button:focus-visible { outline: 2px solid #a9c7ff; outline-offset: 3px; }
.mdxs-theatre-key svg { width: 14px; height: 14px; }
.mdxs-theatre-key.is-play { width: 42px; height: 42px; background: rgba(120, 160, 255, 0.16); border-color: rgba(150, 186, 255, 0.3); opacity: 1; }
.mdxs-theatre-key.is-play svg { width: 16px; height: 16px; }
.mdxs-theatre-key:hover { opacity: 1; background: rgba(220, 228, 255, 0.11); }
.mdxs-theatre-key:active { transform: scale(0.92); }
.mdxs-theatre-key[disabled] { opacity: 0.28; pointer-events: none; }

.mdxs-theatre-note {
  font-size: 0.66rem;
  font-weight: 560;
  letter-spacing: 0.05em;
  color: rgba(168, 186, 236, 0.55);
  text-align: center;
}

.mdxs-scene-labels { position: absolute; inset: 0; z-index: 2; pointer-events: none; }
.mdxs-scene-label { position: absolute; transform: translate(-50%, -50%); max-width: 132px; padding: 5px 8px; border: 1px solid rgba(174, 205, 255, .24); border-radius: 999px; color: #e8f0ff; background: rgba(12, 20, 38, .68); box-shadow: 0 8px 22px rgba(0,0,0,.16); backdrop-filter: blur(12px); font: 650 .62rem/1.15 ui-sans-serif, system-ui, sans-serif; text-align: center; white-space: nowrap; }
.mdxs-scene-leader { position: absolute; left: 50%; top: 50%; height: 1px; transform-origin: left center; background: linear-gradient(90deg, rgba(155, 195, 255, .52), rgba(155, 195, 255, .08)); }
.mdxs-story-command { display: flex; align-items: center; width: min(320px, 100%); gap: 6px; pointer-events: auto; }
.mdxs-story-command input { min-width: 0; flex: 1; padding: 8px 11px; border: 1px solid rgba(220, 229, 255, .14); border-radius: 999px; outline: none; color: #eff4ff; background: rgba(214,224,255,.055); font: inherit; font-size: .7rem; }
.mdxs-story-command input::placeholder { color: rgba(196, 210, 241, .54); }
.mdxs-story-command input:focus { border-color: rgba(150,186,255,.55); box-shadow: 0 0 0 3px rgba(120,160,255,.1); }
.mdxs-story-command button { padding: 8px 11px; border: 1px solid rgba(150,186,255,.28); border-radius: 999px; color: #dce8ff; background: rgba(120,160,255,.13); cursor: pointer; font: 650 .68rem/1 inherit; }
.mdxs-story-command button:hover { background: rgba(120,160,255,.22); }

/* The theatre keeps the spatial labels the voice room hides: an `annotate`
   beat draws a leader line to the DOM chip, and a chip with display:none has
   no box for the line to reach. */
body.mdx.mdx-sphere-theatre .mdxs[data-size="voice"] .mdxs-nodes { display: block !important; }
body.mdx.mdx-sphere-theatre .mdxs[data-size="voice"] .mdxs-node {
  border-color: rgba(214, 224, 255, 0.16);
  background: rgba(18, 24, 46, 0.72);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  color: #e6ecff;
}
body.mdx.mdx-sphere-theatre .mdxs[data-size="voice"] .mdxs-node-meta { color: rgba(186, 200, 240, 0.66); }
/* The glass keeps its own pointer target so the subject can still be turned
   by hand while the story plays. */
body.mdx.mdx-sphere-theatre .mdxs[data-size="voice"] .mdxs-core { pointer-events: auto; cursor: grab; }

@media (max-width: 560px) {
  .mdxs-theatre-head { top: calc(14px + env(safe-area-inset-top, 0px)); left: 16px; right: 62px; }
  .mdxs-theatre-title { font-size: 0.9rem; }
  .mdxs-theatre-close { top: calc(13px + env(safe-area-inset-top, 0px)); right: 13px; width: 32px; height: 32px; }
  .mdxs-theatre-close::before, .mdxs-theatre-close::after { left: 9px; top: 15px; }
  .mdxs-theatre-foot { bottom: calc(18px + env(safe-area-inset-bottom, 0px)); gap: 11px; width: calc(100vw - 32px); }
  .mdxs-theatre-caption { font-size: 0.86rem; min-height: 3.2em; }
}

@media (prefers-reduced-motion: reduce) {
  .mdx-si-row { animation: none; }
  .mdx-si-btn svg .mdx-si-orbit { transition: none; }
  .mdx-si-btn.is-busy svg .mdx-si-orbit { animation-duration: 3s; }
  .mdxs-theatre { transition-duration: 0.001s; }
}

/* A closing theatre leaves WITH the room. Without this the chrome sits at full
   opacity over the shrinking sphere for the half second the exit takes. */
body.mdx.mdx-sphere-theatre .mdxs-theatre.is-leaving { opacity: 0; pointer-events: none; }

/* ==========================================================================
   AR — the same scene, standing in the room
   ==========================================================================
   The overlay is also the WebXR dom-overlay root, so these are the only
   controls that exist inside an immersive session. Everything is
   pointer-events: none except the controls themselves, because the whole
   surface has to stay available for placing, dragging and pinching the model.
   ========================================================================== */

body.mdx-ar-open { overflow: hidden; }

.mdxs-ar {
  position: fixed;
  inset: 0;
  z-index: 26040;
  color: #e9eeff;
  font: inherit;
  pointer-events: none;
  background: transparent;
}
.mdxs-ar-video,
.mdxs-ar-canvas {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  pointer-events: none;
}
.mdxs-ar-video { z-index: 0; background: #05070f; }
.mdxs-ar-canvas { z-index: 1; }

.mdxs-ar-head {
  position: absolute;
  top: calc(20px + env(safe-area-inset-top, 0px));
  left: calc(20px + env(safe-area-inset-left, 0px));
  right: calc(74px + env(safe-area-inset-right, 0px));
  z-index: 3;
  display: flex;
  flex-direction: column;
  gap: 3px;
  text-shadow: 0 1px 12px rgba(0, 0, 0, 0.6);
}
.mdxs-ar-eyebrow {
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(190, 206, 255, 0.78);
}
.mdxs-ar.is-model { background: radial-gradient(ellipse at 50% 42%, #182a40, #060b14 72%); }
.mdxs-ar .is-depth, .mdxs-theatre-head .mdxs-story-scales { flex-wrap: nowrap; max-width: 100%; overflow-x: auto; padding-bottom: 5px; }
.mdxs-ar .is-depth button, .mdxs-theatre-head .mdxs-story-scales button { flex-shrink: 0; }
.mdxs-ar-inspector { position: absolute; top: 132px; right: 20px; z-index: 5; width: min(280px, calc(100vw - 40px)); padding: 12px; border: 1px solid #ffffff26; border-radius: 14px; background: #0b1527eb; color: #dfebff; font: 12px/1.5 system-ui; pointer-events: auto; }
.mdxs-ar-inspector summary { cursor: pointer; font-weight: 650; }
.mdxs-ar .mdxs-ar-inspector label { display: grid; gap: 5px; margin-top: 12px; color: #d7e6ff; }
.mdxs-ar-inspector select, .mdxs-ar-inspector input { width: 100%; min-width: 0; accent-color: #91b9ff; }
.mdxs-ar .mdxs-ar-inspector select { background: #192b44; color: white; padding: 7px; border: 1px solid #496184; border-radius: 7px; }
.mdxs-ar-inspector[open] { max-height: calc(100dvh - 380px); overflow-y: auto; }
.mdxs-ar .mdxs-story-tools { justify-content: center; }
.mdxs-ar .mdxs-story-tools [hidden] { display: none; }
.mdxs-ar-rail, .mdxs-theatre-rail { max-width: 100%; overflow-x: auto; }
.mdxs-ar-dot, .mdxs-theatre-dot { flex-shrink: 0; }
@media (max-width: 600px) { .mdxs-ar-inspector { top: 130px; right: 18px; width: 210px; } .mdxs-ar-foot { gap: 7px; bottom: calc(12px + env(safe-area-inset-bottom, 0px)); } .mdxs-story-tools { gap: 5px; } }
.mdxs-ar-title {
  font-size: 0.95rem;
  font-weight: 640;
  letter-spacing: -0.012em;
  max-width: 26rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.mdxs-ar-close {
  position: absolute;
  top: calc(18px + env(safe-area-inset-top, 0px));
  right: calc(18px + env(safe-area-inset-right, 0px));
  z-index: 3;
  width: 38px;
  height: 38px;
  padding: 0;
  border: 1px solid rgba(220, 229, 255, 0.2);
  border-radius: 50%;
  background: rgba(12, 16, 30, 0.5);
  -webkit-backdrop-filter: blur(16px);
  backdrop-filter: blur(16px);
  pointer-events: auto;
  cursor: pointer;
}
.mdxs-ar-close::before,
.mdxs-ar-close::after {
  content: "";
  position: absolute;
  left: 12px;
  top: 18px;
  width: 13px;
  height: 1.4px;
  background: #e7ecff;
}
.mdxs-ar-close::before { transform: rotate(45deg); }
.mdxs-ar-close::after { transform: rotate(-45deg); }

/* The one instruction anyone needs, and only while they need it. */
.mdxs-ar-hint {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  z-index: 3;
  padding: 9px 16px;
  border-radius: 999px;
  background: rgba(10, 14, 28, 0.62);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  font-size: 0.78rem;
  font-weight: 560;
  letter-spacing: -0.006em;
  opacity: 0;
  transition: opacity 0.4s var(--mdxs-ease);
}
.mdxs-ar-hint.is-on { opacity: 1; }

.mdxs-ar-foot {
  position: absolute;
  left: 50%;
  bottom: calc(22px + env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%);
  z-index: 3;
  width: min(34rem, calc(100vw - 36px));
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
}
.mdxs-ar-caption {
  min-height: 2.4em;
  margin: 0;
  padding: 10px 16px;
  border-radius: 16px;
  background: rgba(9, 12, 24, 0.58);
  -webkit-backdrop-filter: blur(16px);
  backdrop-filter: blur(16px);
  text-align: center;
  font-size: 0.9rem;
  font-weight: 500;
  line-height: 1.42;
  color: rgba(234, 240, 255, 0.94);
  text-wrap: balance;
}
.mdxs-ar-caption:empty { display: none; }

.mdxs-ar-rail { display: flex; align-items: center; gap: 6px; pointer-events: auto; }
.mdxs-ar-dot {
  width: 20px; height: 4px; padding: 0; border: 0; border-radius: 999px;
  background: rgba(210, 222, 255, 0.28); cursor: pointer;
  transition: background 0.3s var(--mdxs-ease), width 0.3s var(--mdxs-ease);
}
.mdxs-ar-dot.is-done { background: rgba(210, 222, 255, 0.48); }
.mdxs-ar-dot.is-now { width: 32px; background: rgba(160, 194, 255, 0.95); }

.mdxs-ar-transport { display: flex; align-items: center; gap: 10px; pointer-events: auto; }
.mdxs-ar-key {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  padding: 0;
  border: 1px solid rgba(220, 229, 255, 0.2);
  border-radius: 50%;
  background: rgba(12, 16, 30, 0.5);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  color: #dfe7ff;
  cursor: pointer;
  transition: transform 0.14s ease, background 0.18s ease;
}
.mdxs-ar-key svg { width: 15px; height: 15px; }
.mdxs-ar-key.is-play { width: 48px; height: 48px; background: rgba(96, 138, 255, 0.34); border-color: rgba(160, 194, 255, 0.42); }
.mdxs-ar-key.is-play svg { width: 17px; height: 17px; }
.mdxs-ar-key:active { transform: scale(0.92); }

.mdxs-ar-note {
  font-size: 0.66rem;
  font-weight: 560;
  letter-spacing: 0.04em;
  color: rgba(196, 210, 250, 0.72);
  text-align: center;
  text-shadow: 0 1px 10px rgba(0, 0, 0, 0.6);
}

/* The AR control beside Spatial Intelligence in the answer's action row. */
.mdx-si-btn.is-ar { padding: 0 12px 0 10px; }
.mdx-si-btn.is-ar svg { width: 15px; height: 15px; }
.mdx-si-btn.is-ar[hidden] { display: none; }

/* ...and inside the theatre, where it means "this scene, in my room" rather
   than "start again from the answer". */
.mdxs-theatre-key.is-ar { width: 34px; height: 34px; }
.mdxs-theatre-key.is-ar[hidden] { display: none; }

@media (max-width: 560px) {
  .mdxs-ar-head { top: calc(14px + env(safe-area-inset-top, 0px)); left: 16px; right: 64px; }
  .mdxs-ar-foot { bottom: calc(16px + env(safe-area-inset-bottom, 0px)); gap: 10px; }
  .mdxs-ar-caption { font-size: 0.84rem; }
}

@media (prefers-reduced-motion: reduce) {
  .mdxs-ar-hint, .mdxs-ar-dot { transition-duration: 0.001s; }
}

/* ==========================================================================
   The Voice status line
   ==========================================================================
   One line under the Sphere, and it is TRUE. Every word in it comes from the
   live service's own events — connection, server VAD, response lifecycle,
   tool calls — so "Listening" means the microphone is open and the connection
   is up, and "Thinking" means a response is genuinely being generated. It is
   never driven by an animation or a timer, because a status that is sometimes
   theatre is a status nobody can rely on.
   ========================================================================== */
.mdxs-voice-status {
  position: absolute;
  left: 50%;
  bottom: 8%;
  transform: translateX(-50%);
  margin: 0;
  padding: 5px 13px;
  border-radius: 999px;
  background: rgba(10, 16, 28, 0.42);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 255, 255, 0.12);
  color: rgba(236, 244, 255, 0.9);
  font-size: 0.76rem;
  font-weight: 600;
  letter-spacing: 0.012em;
  white-space: nowrap;
  z-index: 8;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.24s var(--mdx-ease, ease);
}
/* Only ever visible inside the Voice environment: on Home it would be a
   second caption competing with the Sphere's own. */
body.mdx.mdx-sphere-voice .mdxs-voice-status { opacity: 1; }
.mdxs-voice-status[hidden] { display: none; }
@media (prefers-reduced-motion: reduce) { .mdxs-voice-status { transition: none; } }

/* The narration control: the same key as the rest of the transport, lit when
   it is on. It hides itself entirely on a device with no speech synthesis
   rather than offering a control that does nothing. */
.mdxs-theatre-key.is-audio.is-on {
  color: #fff;
  background: rgba(120, 165, 255, 0.26);
  border-color: rgba(150, 190, 255, 0.44);
}
.mdxs-theatre-key.is-audio[hidden] { display: none; }

/* Final mobile chrome pass: the composer is one calm, compact control surface
   with real hit areas and a keyboard-relative anchor. Safe-area math lives on
   the shell, not inside the field, so iOS Safari does not double-count it. */
@media (max-width: 620px) {
  body.mdx .mdx-bar {
    width: calc(100vw - 20px);
    bottom: calc(8px + var(--mdx-rail-h, 0px) + 8px + env(safe-area-inset-bottom, 0px));
    border-radius: 21px;
  }
  body.mdx .mdx-bar-row:has(> .mdx-composer) { padding: 4px; gap: 4px; }
  body.mdx .mdx-composer { gap: 5px; padding: 9px 10px 8px; border-radius: 18px; }
  body.mdx .mdx-composer-input { max-height: calc(1.45em * 5); }
  body.mdx .mdx-composer-btn,
  body.mdx .mdx-composer-send,
  body.mdx .mdx-composer-voice { width: 36px; height: 36px; }
  body.mdx .mdx-composer-tools { gap: 4px; }
  body.mdx .mdx-composer-note { font-size: .68rem; }
  body.mdx.mdx-keyboard .mdx-bar,
  body.mdx.mdx-composer-focus .mdx-bar { bottom: calc(var(--mdx-kb, 0px) + 8px); }
}

@media (max-width: 390px) {
  body.mdx .mdx-composer { padding-inline: 8px; }
  body.mdx .mdx-composer-btn,
  body.mdx .mdx-composer-send,
  body.mdx .mdx-composer-voice { width: 34px; height: 34px; }
}
