/* ============================================================================
   MAMBO — WATCH.  v3.2.0
   The Watch page shell, 1:1 to the Claude Design prototype. Scope: .mb-watch
   (the root <section>, which also keeps .eos-watch--cinema for the four kept
   watch scripts and the sheets that style their runtime-built UI).

   WHAT THIS SHEET OWNS: the root grid, the stage bar, the player wrap and its
   overlay states, the service hub, the side dock (rail + panel shells), the
   splitter, the replay rail, the mode/waiting states, and the LEGACY TOKEN
   BRIDGE that keeps chat-flagship/notes/bible/watch-controls resolving after
   watch-cinema.css and watch-redesign.css are dequeued.

   WHAT IT MUST NOT TOUCH: the .eos-cn-mtools / .eos-ytc-* / .eos-rxp / .eos-aqc-*
   surfaces watch-controls.js BUILDS at runtime — watch-controls.css owns those.
   Chat message ROWS belong to chat.css→chat-flagship.css. (#eos-cn-bar itself IS
   restyled here, in § 13: same engine, the prototype's face.)

   No IDs styled except the contract mounts, no !important, never a literal
   colour outside the token bridge.
   ============================================================================ */

/* ----------------------------------------------------------------------------
   § 0  TOKENS

   Watch-only page tokens (--screen, --onscreen, --panelW) plus the bridge: the
   kept legacy sheets resolve --cn-…, --eos-…, --gold, --glass and friends,
   which used to come from watch-redesign.css. Every bridge value routes through
   a mambo token, so dark mode needs NO second block — the upstream tokens
   re-tone.

   NB: never write a "star slash" pair inside these comments. An earlier
   revision listed the families as `--cn-*` + `/` + `--eos-*`, which closed this
   comment four lines early. Everything after it parsed as a selector, and the
   error recovery swallowed the entire .mb-watch token block below — so --gold
   fell through to the retired #F7B731 from a legacy sheet and --glass/--fg/--r
   resolved to nothing at all. That one typo is why gold kept coming back.
   -------------------------------------------------------------------------- */

.mb-watch {
  --panelW: 392px;

  /* legacy radii + blur the chat/notes/bible sheets read */
  --r:  16px;
  --r2: 13px;
  --r3: 10px;
  --blur: blur(16px) saturate(140%);

  /* redesign-era names -> mambo palette */
  --page:     var(--pg);
  --surf:     color-mix(in srgb, var(--ink) 4%, transparent);
  --surf2:    color-mix(in srgb, var(--ink) 7%, transparent);
  --glass:    color-mix(in srgb, var(--card) 78%, transparent);
  --glassBrd: var(--line);
  --hair:     var(--line2);
  --fg:       var(--ink);
  --fg2:      var(--muted);
  --fg3:      var(--faint);
  --inkFg:    var(--pg);
  --shadow:   var(--sh);
  --shadowSm: var(--sc);

  /* the gold accent era is over — clay everywhere */
  --gold:      var(--acc);
  --gold-ink:  var(--tint2ink);
  --on-gold:   var(--onacc);
  --gold-soft: var(--accsoft);

/* v3.36.1 (board catch, refuter R-CASCADE) — the bridge's DARK arm. brand.css
   :67-72 re-declares --gold-ink/--on-gold as the retired bright gold at
   [data-theme="dark"] .eos-watch--cinema — (0,2,0), which beat this block's
   (0,1,0) on specificity and painted retired-gold focus rings in dark under
   EVERY palette, clay included. (0,2,1) answers it; the media-dark twin in
   brand.css targets only .eos-app/.home and never reaches this page. */

  /* cinema-era names */
  --cn-radius:     var(--r);
  --cn-radius-sm:  var(--r2);
  --cn-amber:      var(--acc);
  --cn-amber-dark: var(--accHover);
  --cn-amber-soft: var(--accsoft);
  --cn-amber-glow: var(--accsoft);
  --cn-bg:         var(--glass);
  --cn-bg-soft:    var(--surf);
  --cn-bg-softer:  var(--surf);
  --cn-fg:         var(--ink);
  --cn-muted:      var(--muted);
  --cn-border:     var(--line2);
  --cn-shadow:     var(--sh);
  --cn-edge:       var(--line);

  --eos-ink:       var(--ink);
  --eos-ink-fg:    var(--pg);
  --eos-glass:     var(--glass);
  --eos-glass-brd: var(--line);
  --eos-blur:      var(--blur);

  background: var(--pg);
  color: var(--ink);
}
/* see the v3.36.1 note inside the block above */
html[data-theme="dark"] .mb-watch {
  --gold-ink: var(--tint2ink);
  --on-gold:  var(--onacc);
}

/* v3.36.1 (R-CASCADE) — FOCUS RINGS FOLLOW THE ACCENT. watch-controls.css
   :726-741 rings the player chrome in literal #E7B24B in BOTH arms (0,3,0)
   and overrides the dock rings' colour to the same literal in dark at
   (0,4,0) plain / (0,5,0) inside its prefers-dark media twin. All plain, so
   ordinary specificity answers all of them - no !important, tokens re-tone
   per palette and per arm. */
.eos-watch--cinema.mb-watch .eos-cn-cbtn:focus-visible,
.eos-watch--cinema.mb-watch .eos-cn-ibtn:focus-visible,
.eos-watch--cinema.mb-watch .eos-cn-livepill:focus-visible,
.eos-watch--cinema.mb-watch .eos-cn-menu__row:focus-visible,
.eos-watch--cinema.mb-watch .eos-cn-seg2 button:focus-visible { outline-color: var(--acc); }
.eos-watch--cinema.mb-watch .eos-cn-scrub:focus-visible .eos-cn-scrub__track { box-shadow: 0 0 0 2px var(--acc); }

/* the dock rings: light already rides var(--gold-ink) (now bridged in both
   arms above); these outrank the two hardcoded dark overrides so the token
   path decides everywhere. (0,5,1) beats (0,4,0) and the media twin's (0,5,0). */
html[data-theme="dark"] .mb-watch .eos-side-tabs .eos-side-tab:focus-visible,
html[data-theme="dark"] .mb-watch .mb-w-chatseg .eos-chat-mode-btn:focus-visible { outline-color: var(--gold-ink); } /* the seg wrapper is the real ancestor - the buttons sit ABOVE .mb-w-chat, not inside it */


/* ----------------------------------------------------------------------------
   § 1  ROOT GRID

   The root section IS the grid (the old sheets did the same, which is why
   studio.css/watch JS treat it as the one stateful element):

       "top    top    top"
       "stage  split  side"
       "rail   rail   rail"
   -------------------------------------------------------------------------- */

.mb-watch {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 5px var(--panelW);
  grid-template-areas:
    "top   top   top"
    "stage split side"
    "rail  rail  rail";
  align-items: start;
  gap: clamp(14px, 1.6vw, 20px);
  width: 100%;
  max-width: var(--shell-wide);
  margin-inline: auto;
  padding: 0 clamp(16px, 2.4vw, 28px) 96px;
  /* The dock animation: columns ease as the panel leaves in theater. */
  transition: grid-template-columns .42s var(--ease-header);
}

.eos-cn-top.mb-w-bar     { grid-area: top; }
.mb-watch .eos-watch-stage { grid-area: stage; }
.mb-w-split              { grid-area: split; }
.mb-watch .eos-side      { grid-area: side; }
.mb-watch .eos-watch-replays { grid-area: rail; }

.mb-watch .eos-watch-stage {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: clamp(14px, 1.6vw, 18px);
}

/* ----------------------------------------------------------------------------
   § 2  STAGE BAR
   -------------------------------------------------------------------------- */

.mb-w-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  /* the bottom clearance + the grid gap together give the prototype's
     clamp(22px,2.8vw,34px) between the bar and the player */
  padding: clamp(14px, 2vw, 20px) 0 clamp(8px, 1.2vw, 14px);
}

.mb-w-barsp { flex: 1; }

.mb-w-livepill {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 27px;
  padding: 0 11px;
  border-radius: 8px;
  background: var(--live);
  color: #fff;
  font-size: 10.5px;
  font-weight: 800;
  letter-spacing: .11em;
  text-transform: uppercase;
}

.mb-w-livepill > span {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #fff;
  animation: wPulse 2s ease-out infinite;
}

.mb-w-soonpill {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 27px;
  padding: 0 11px;
  border-radius: 8px;
  background: var(--stage);
  border: 1px solid var(--line2);
  color: var(--muted);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .11em;
  text-transform: uppercase;
}

/* Segmented view modes. Buttons carry [data-cn-mode] — watch-cinema.js owns
   the behaviour; mambo-watch.js only mirrors the root's is-cn-* class onto
   [aria-pressed] so the active paint below can be pure CSS. */
.mb-w-modes {
  display: inline-flex;
  gap: 2px;
  padding: 3px;
  border-radius: 11px;
  border: 1px solid var(--line);
  background: var(--stage);
}

.mb-w-mode {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 34px;
  padding: 0 13px;
  border: 0;
  border-radius: 9px;
  background: transparent;
  color: var(--muted);
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
  transition: background var(--dur) ease, color var(--dur) ease, transform .16s ease;
}

/* hover only applies to the segments that are NOT the current mode, per the
   design's own mouseenter guard */
.mb-w-mode:not([aria-checked="true"]):hover { background: var(--soft); color: var(--body); }
.mb-w-mode:active { transform: scale(.96); }

.mb-w-mode[aria-checked="true"] {
  background: var(--card);
  color: var(--ink);
  box-shadow: var(--sc);
}

/* 34px chips (ambient / share / the studio button studio.js appends). The
   legacy .eos-cn-ibtn class rides along for its JS consumers; the look is ours. */
.mb-w-baract { display: inline-flex; align-items: center; gap: 8px; }

.mb-watch .eos-cn-ibtn {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 34px;
  padding: 0 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--card);
  color: var(--body);
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
  transition: background var(--dur) ease, color var(--dur) ease, border-color var(--dur) ease, transform .16s ease;
}

.mb-watch .eos-cn-ibtn:hover { background: var(--soft); color: var(--ink); }
.mb-watch .eos-cn-ibtn:active { transform: scale(.96); }

.mb-watch .eos-cn-ibtn.is-on,
.mb-watch .eos-cn-ibtn[aria-pressed="true"] {
  background: var(--accsoft);
  border-color: var(--accLight);
  color: var(--acc);
}

/* The design shows no count in this bar — the prototype's stage bar is exactly
   modes → Ambient glow → Cast (hidden) → Studio → spacer → provider note
   (dc.html:125-142), and the watching figure lives in the hub pulse instead
   (dc.html:421, pulseWatchRef). This node survives only as a contract: three
   scripts read or write #eos-cn-viewers [data-cn-viewers] — watch-cinema.js:289,
   watch-hub.js:69 and our own initViewerMirror, which is what feeds the pulse.

   It must be display:none, not display:contents. `contents` removes only the
   wrapper's own box; the children keep painting, so the .eos-cn-vchev caret
   became a direct item of the bar's flex row and floated between the mode group
   and the action chips — visible on the live page at x=555.

   The caret cannot simply be dropped from the markup: watch-controls.js:426
   injects one whenever it is missing. It is printed there so that guard passes,
   then hidden here. display:none does not stop any of the three scripts, which
   only read and write textContent. It also keeps the node out of the tab order,
   which matters because watch-controls.js:438-440 stamps role="button" and
   tabindex="0" on it unconditionally. */
.mb-w-presence {
  display: none;
}

/* ---- LEGACY OVERRIDE: studio.js's own Studio button -----------------------
   studio.js:2259-2271 unconditionally builds
   <button id="eos-studio-toggle" class="eos-studio-toggle">Studio mode</button>
   and appends it to .eos-cn-top__act. The design has ONE studio control in the
   bar — the clay chip below (dc.html:134-136) — so on the live page the bar
   carried both: our chip and a grey "Studio mode" button beside it.

   It is hidden, not removed: studio.js holds a direct reference to the node it
   created and drives the whole workspace through it, so it must stay in the
   DOM. initStudio() in mambo-watch.js forwards our chip's click to it and
   mirrors its aria-pressed back. Scoped to the bar so studio.js's own
   workspace chrome is untouched. */
.mb-watch .eos-cn-top__act > .eos-studio-toggle:not([data-mb-studio]) {
  display: none;
}

/* Clay chip — the design's one accent control in the bar. */
.mb-watch .mb-w-chip--studio {
  border-color: var(--accLight);
  background: var(--tint2);
  color: var(--tint2ink);
  font-weight: 650;
}

.mb-watch .mb-w-chip--studio:hover { background: var(--accLight); color: var(--tint2ink); }

/* The "YouTube's own controls" provider note is not rendered. The prototype
   carries one (providerNoteRef) but keeps it display:none unless the embed
   offers no API control, and it is not wanted here — so the markup is gone
   from page-watch.php rather than hidden, and these rules with it. */

/* ----------------------------------------------------------------------------
   § 3  PLAYER WRAP + OVERLAY STATES

   The wrap (#eos-player) keeps its 16:9 box (ported from watch-hub.css — the
   guard skips cinema/PiP where the box is the viewport / a float). Overlay
   glass recipe: rgba(10,10,12,…) + blur + --onscreen text, exactly the
   prototype's on-photo chrome.
   -------------------------------------------------------------------------- */

.mb-watch .eos-player {
  position: relative;
  border-radius: 16px;
  overflow: hidden;
  background: var(--screen);
  box-shadow: var(--sh);
  transition: border-radius .3s ease;
}

.mb-watch.eos-watch--cinema:not(.is-cn-cinema):not(.is-cn-pip) .eos-player { aspect-ratio: 16 / 9; }

.mb-watch .eos-player-frame,
.mb-watch .eos-player-frame iframe,
.mb-watch .eos-player-frame video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

.mb-watch .eos-player-poster {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* The off-air / countdown stage. One overlay serves both (server prints the
   countdown inside it when a start time exists) — prototype soon/offair look. */
.mb-watch .eos-player-offair {
  position: absolute;
  inset: 0;
  z-index: 5;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: clamp(16px, 3vw, 36px);
  background: radial-gradient(130% 100% at 50% 45%, rgba(10, 9, 8, .74) 0%, rgba(10, 9, 8, .9) 100%);
  color: var(--onscreen);
  overflow: auto;
}

.mb-watch .eos-player-offair-content {
  position: relative;
  z-index: 2;
  max-width: 520px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
}

/* the four decorative orbs behind the off-air copy */
.mb-watch .eos-oa-orbs { position: absolute; inset: 0; z-index: 1; pointer-events: none; opacity: .5; }
.mb-watch .eos-oa-orbs span {
  position: absolute;
  width: 220px;
  height: 220px;
  border-radius: 50%;
  filter: blur(46px);
  background: radial-gradient(circle, color-mix(in srgb, var(--accBrand) 40%, transparent), transparent 70%); /* v3.36.0 - was the brand clay literal; follows the palette */
}
.mb-watch .eos-oa-orbs span:nth-child(2) { left: 70%; top: 8%;  background: radial-gradient(circle, rgba(8, 199, 210, .28), transparent 70%); }
.mb-watch .eos-oa-orbs span:nth-child(3) { left: 6%;  top: 62%; }
.mb-watch .eos-oa-orbs span:nth-child(4) { left: 76%; top: 66%; background: radial-gradient(circle, rgba(241, 209, 131, .3), transparent 70%); }

.mb-watch .eos-player-offair .eos-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 29px;
  padding: 0 13px;
  border-radius: 999px;
  background: rgba(10, 10, 12, .5);
  border: 1px solid rgba(244, 241, 236, .22);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  color: var(--onscreen);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .13em;
  text-transform: uppercase;
}

.mb-watch .eos-player-offair h2 {
  margin: 0;
  color: var(--onscreen);
  font-size: clamp(19px, 2.4vw, 24px);
  font-weight: 700;
  letter-spacing: -.026em;
  text-wrap: balance;
}

.mb-watch .eos-player-when { margin: 0; font-size: 13px; color: rgba(244, 241, 236, .66); }

/* countdown tiles — glass, warm seconds (last unit) */
.mb-watch .eos-countdown { display: flex; justify-content: center; gap: 8px; }

.mb-watch .eos-countdown-unit {
  min-width: 62px;
  padding: 11px 6px;
  border-radius: 12px;
  background: rgba(10, 10, 12, .44);
  border: 1px solid rgba(244, 241, 236, .16);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
}

.mb-watch .eos-countdown-unit .num {
  font-size: 22px;
  font-weight: 700;
  letter-spacing: -.04em;
  font-variant-numeric: tabular-nums;
  color: var(--onscreen);
}

.mb-watch .eos-countdown-unit .lbl {
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: rgba(244, 241, 236, .62);
}

.mb-watch .eos-countdown-unit:last-child {
  background: rgba(226, 139, 82, .2);
  border-color: rgba(226, 139, 82, .45);
}

.mb-watch .eos-countdown-unit:last-child .num { color: #F5B989; }

/* the restricted-upcoming banner = the prototype's soonGate chip */
.mb-watch .eos-watch-audience-banner {
  max-width: 400px;
  padding: 8px 13px;
  border-radius: 10px;
  background: rgba(226, 139, 82, .16);
  border: 1px solid rgba(226, 139, 82, .4);
  font-size: 12.5px;
  color: #F5B989;
}

/* off-air actions: one white primary, the rest glass outline.
   CHILD-scoped on purpose: the calendar and remind POPOVERS are descendants of
   .eos-oa-actions, and descendant selectors here out-ranked the popover-row
   rules — the "Google Calendar" row rendered as a 42px white CTA inside a
   light card. Every legitimate top-level action carries .eos-oa-btn. */
.mb-watch .eos-oa-actions { display: flex; flex-wrap: wrap; justify-content: center; gap: 9px; }

.mb-watch .eos-oa-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 42px;
  padding: 0 19px;
  border-radius: 11px;
  border: 1px solid rgba(244, 241, 236, .26);
  background: rgba(10, 10, 12, .34);
  color: var(--onscreen);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition: background var(--dur) ease, transform var(--dur) ease;
}

.mb-watch .eos-oa-btn--gold {
  background: var(--onscreen);
  border-color: transparent;
  color: #17150F;
  font-weight: 700;
}

.mb-watch .eos-oa-btn:hover { transform: translateY(-1px); }

/* the remind popover's own controls (ported from watch-hub.css onto tokens —
   that sheet is dequeued and nothing else styles these) */
.mb-watch .eos-oa-pop__h { font-size: 12px; font-weight: 700; color: var(--ink); margin-bottom: 8px; }

.mb-watch .eos-oa-pop__go {
  width: 100%;
  margin-top: 8px;
  padding: 9px;
  border: 0;
  border-radius: 9px;
  background: var(--acc);
  color: var(--onacc);
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
  transition: background var(--dur) ease;
}

.mb-watch .eos-oa-pop__go:hover { background: var(--accHover); }
.mb-watch .eos-oa-pop__go:disabled { opacity: .6; cursor: wait; }

.mb-watch .eos-oa-pop__cap { margin-top: 8px; font-size: 11px; color: var(--muted); }
.mb-watch .eos-oa-pop__err { margin-top: 8px; font-size: 11.5px; color: var(--live); }

/* remind-me popover (watch-hub.js) */
.mb-watch .eos-oa-pop {
  padding: 12px;
  border-radius: 13px;
  background: var(--card);
  border: 1px solid var(--line);
  box-shadow: var(--sh);
  color: var(--ink);
  animation: wPop .24s var(--spring);
}

.mb-watch .eos-oa-pop input[type="email"] {
  height: 38px;
  padding: 0 12px;
  border-radius: 9px;
  border: 1px solid var(--line);
  background: var(--stage);
  color: var(--ink);
  font: inherit;
  font-size: 13.5px;
}

/* "While you wait" strip */
.mb-watch .eos-oa-wait {
  max-width: 430px;
  width: 100%;
  padding-top: 20px;
  border-top: 1px solid rgba(244, 241, 236, .14);
  text-align: left;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* __h, matching the carried markup — the prototype-named ".eos-oa-wait-label"
   selector matched nothing. */
.mb-watch .eos-oa-wait__h {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .15em;
  text-transform: uppercase;
  color: rgba(244, 241, 236, .5);
}

.mb-watch .eos-oa-wait__row { display: flex; flex-direction: column; gap: 10px; }

.mb-watch .eos-oa-replay {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 10px;
  border-radius: 12px;
  border: 1px solid rgba(244, 241, 236, .14);
  background: rgba(10, 10, 12, .4);
  color: var(--onscreen);
  transition: background var(--dur) ease;
}

.mb-watch .eos-oa-replay:hover { background: rgba(10, 10, 12, .56); }

/* interiors, ported from the dequeued watch-hub.css onto tokens — without them
   the thumbnail <img> renders at natural size and blows the row apart. .dur is
   anchored by .th's position:relative. */
.mb-watch .eos-oa-replay .th {
  position: relative;
  flex: 0 0 62px;
  width: 62px;
  height: 44px;
  border-radius: 8px;
  overflow: hidden;
  background: rgba(10, 10, 12, .6);
  display: flex;
  align-items: center;
  justify-content: center;
}

.mb-watch .eos-oa-replay .th img { width: 100%; height: 100%; object-fit: cover; display: block; }

.mb-watch .eos-oa-replay .dur {
  position: absolute;
  bottom: 4px;
  right: 5px;
  padding: 1px 5px;
  border-radius: 5px;
  background: rgba(0, 0, 0, .7);
  color: var(--onscreen);
  font-size: 9.5px;
}

.mb-watch .eos-oa-replay .tx { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.mb-watch .eos-oa-replay .k { font-size: 10px; letter-spacing: .1em; text-transform: uppercase; color: var(--accLight); }
.mb-watch .eos-oa-replay .t { font-size: 13px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mb-watch .eos-oa-replay .m { font-size: 11px; color: rgba(244, 241, 236, .6); }

.mb-watch .eos-oa-quick { display: flex; gap: 8px; }

.mb-watch .eos-oa-quick > * {
  flex: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  height: 38px;
  border-radius: 10px;
  border: 1px solid rgba(244, 241, 236, .2);
  background: transparent;
  color: rgba(244, 241, 236, .82);
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
  transition: background var(--dur) ease;
}

.mb-watch .eos-oa-quick > *:hover { background: rgba(244, 241, 236, .1); }

/* ----------------------------------------------------------------------------
   § 4  SERVICE HUB (below the player) — prototype arrangement on the carried
        .eos-hub markup. watch-hub.js renders the flow items (.eos-hub-fs).
   -------------------------------------------------------------------------- */

.mb-watch .eos-hub,
.mb-watch .eos-watch-meta {
  display: flex;
  flex-direction: column;
  gap: 16px;
  min-width: 0;
}

.mb-watch .eos-watch-status {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--live);
}

.mb-watch.is-offair .eos-watch-status { color: var(--muted); }

.mb-watch .eos-live-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--live);
  animation: wPulse 2s ease-out infinite;
}

.mb-watch .eos-watch-title {
  margin: 0;
  font-size: clamp(21px, 2.5vw, 29px);
  font-weight: 700;
  letter-spacing: -.03em;
  line-height: 1.14;
  color: var(--ink);
  text-wrap: balance;
}

/* the composite title row: status+h1+pills · flow rail · actions (§7.1).
   align-items flex-start per the prototype; the meta-main rule is scoped under
   the toprow so it cannot leak onto the legacy fallback strip's meta-main,
   whose parent stays a column. */
.mb-watch .eos-hub-toprow {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 16px 20px;
}

.mb-watch .eos-hub-toprow .eos-watch-meta-main {
  flex: 1 1 340px;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* meta pills row */
.mb-watch .eos-hub-metarow { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

.mb-watch .eos-hub-speaker {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 32px;
  padding: 0 12px 0 4px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--card);
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
}

.mb-watch .eos-hub-avatar {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--tint);
  color: var(--tintink);
  font-size: 10px;
  font-weight: 700;
}

.mb-watch .eos-hub-pill {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 32px;
  padding: 0 12px;
  border-radius: 999px;
  border: 1px solid transparent;
  font-size: 12.5px;
  font-weight: 600;
}

.mb-watch .eos-hub-pill--series { background: var(--tint); color: var(--tintink); }

.mb-watch .eos-hub-pill--scripture {
  border-color: var(--accLight);
  background: var(--tint2);
  color: var(--tint2ink);
  cursor: pointer;
  transition: background var(--dur) ease, transform var(--dur) ease;
}

.mb-watch .eos-hub-pill--scripture:hover { background: var(--accLight); transform: translateY(-1px); }
.mb-watch .eos-hub-pill--scripture .dim { opacity: .66; font-weight: 500; }

/* Order-of-service rail (#eos-hub-flow; watch-hub.js emits .eos-hub-fs chips,
   each carrying a bare <span class="dot">).

   THREE states, and the build had two of them backwards: a COMPLETED stage is
   the one that reads solid (stage wash, muted ink, filled dot), and a stage
   still to come is the faint one. The 18px gap is a lane for the connector
   rules drawn as ::before on every chip after the first — accent up to and
   including the live stage, hairline after it, which is what makes the rail
   read as a progress track rather than a row of pills. */
.mb-watch .eos-hub-flow {
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 11px 13px;
  border: 1px solid var(--line2);
  border-radius: 13px;
  background: var(--stage);
  overflow-x: auto;
  scrollbar-width: thin;
}

.mb-watch .eos-hub-fs {
  position: relative;
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 28px;
  padding: 0 11px 0 8px;
  border: 1px solid var(--line2);
  border-radius: 999px;
  background: transparent;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--faint);
  white-space: nowrap;
}

.mb-watch .eos-hub-fs .dot {
  flex: 0 0 14px;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--line);
}

.mb-watch .eos-hub-fs.is-done {
  background: var(--stage);
  color: var(--muted);
}

.mb-watch .eos-hub-fs.is-done .dot { background: var(--muted); }

.mb-watch .eos-hub-fs.is-now {
  background: var(--accsoft);
  border-color: var(--accLight);
  color: var(--acc);
  font-weight: 650;
}

.mb-watch .eos-hub-fs.is-now .dot {
  background: var(--acc);
  animation: wPulse 2s ease-out infinite;
}

/* the connector living in the 18px lane */
.mb-watch .eos-hub-fs + .eos-hub-fs::before {
  content: "";
  position: absolute;
  left: -18px;
  top: 50%;
  width: 18px;
  height: 2px;
  margin-top: -1px;
  border-radius: 2px;
  background: var(--line2);
}

/* [53] --acc, not --accLight. The prototype paints the run that has already happened
   in the full accent and the run still to come in --line2 (dc.html:2602); --accLight is
   a pale peach that reads as an unfinished stage on a step the service has passed. The
   predicate already matches the prototype's: it colours the connector when `i <= now`,
   and a chip is .is-done for i<now or .is-now for i===now — the same set. */
.mb-watch .eos-hub-fs.is-done::before,
.mb-watch .eos-hub-fs.is-now::before { background: var(--acc); }

/* action buttons + popovers */
/* [20] `position: relative` restores half of an anchor the purge dropped. watch-hub.css
   put it on this row (:85) and `top: 46px; left: 0` on the pop (:102-103); dequeuing
   eos-watch-hub (inc/mambo-enqueue.php:602-604) removed both, so the pops had no
   positioned ancestor and fell back to their static position — on top of the buttons.
   The per-control wrappers in § 21 are the real fix; this is the belt for any pop that
   ends up outside one. */
.mb-watch .eos-hub-actions { position: relative; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

.mb-watch .eos-hub-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 40px;
  padding: 0 16px;
  border-radius: 11px;
  border: 1px solid var(--line);
  background: var(--card);
  color: var(--ink);
  font-size: 13.5px;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--dur) ease, transform var(--dur) ease;
}

/* Every one of these six buttons ships a 24-viewBox glyph with no width or
   height attribute, and platform.css declares `svg { height: auto }`. With no
   intrinsic size and no flex basis the icons collapsed to 0x0 — measured on
   the live page: all six, invisible. The label then had the whole button to
   itself and "Add to calendar" wrapped to two lines, which is what pushed the
   action row to 50px. Sizing the glyph fixes both. */
.mb-watch .eos-hub-btn > svg { flex: 0 0 auto; width: 16px; height: 16px; }

.mb-watch .eos-hub-btn:hover { background: var(--soft); transform: translateY(-1px); }

.mb-watch .eos-hub-btn--gold {
  background: var(--acc);
  border-color: transparent;
  color: var(--onacc);
  font-weight: 700;
}

.mb-watch .eos-hub-btn--gold:hover { background: var(--accHover); }

.mb-watch .eos-hub-pop {
  position: absolute;
  /* [20] the other half of the dropped anchor. With `top` auto the pop sat at its static
     position, inside the action row. `left: 0` is only the floor: watch-hub.js:144 writes
     an inline `left` from `btn.offsetLeft`, and once the per-control wrapper in § 21 is in
     place that inline value IS 0px, because the button is then at its wrapper's left edge.
     The CSS and the script agree instead of resolving against different boxes, so no JS
     change is needed. Prototype: dc.html:370/384. */
  left: 0;
  top: calc(100% + 8px);
  z-index: 20;
  min-width: 232px;
  padding: 7px;
  border-radius: 13px;
  background: var(--card);
  border: 1px solid var(--line);
  box-shadow: var(--sh);
  animation: wPop .24s var(--spring);
}

.mb-watch .eos-hub-pop a,
.mb-watch .eos-hub-pop button {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 10px 11px;
  border: 0;
  border-radius: 9px;
  background: transparent;
  color: var(--ink);
  font-size: 13.5px;
  font-weight: 600;
  cursor: pointer;
  transition: background var(--dur) ease;
}

.mb-watch .eos-hub-pop a:hover,
.mb-watch .eos-hub-pop button:hover { background: var(--soft); }

/* about disclosure */
.mb-watch .eos-hub-about {
  border: 1px solid var(--line2);
  border-radius: 13px;
  background: var(--stage);
  overflow: hidden;
}

.mb-watch .eos-hub-about > button {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 14px 16px;
  border: 0;
  background: transparent;
  color: var(--ink);
  font-size: 14px;
  font-weight: 650;
  cursor: pointer;
}

/* Targets the bare <svg> the markup actually prints — `.eos-hub-chev` is a
   prototype class name that appears nowhere in this build, so the chevron was
   unsized, ink-coloured and never rotated (watch-hub.css, which used to style
   it, is dequeued on this page). */
.mb-watch .eos-hub-about > button > svg {
  flex: 0 0 auto;
  margin-left: auto;
  width: 17px;
  height: 17px;
  color: var(--muted);
  transition: transform .32s var(--ease-header);
}

.mb-watch .eos-hub-about.is-open > button > svg { transform: rotate(180deg); }

.mb-watch .eos-hub-about .body {
  display: none;
  padding: 0 16px 16px 43px;
  font-size: 14.5px;
  line-height: 1.65;
  color: var(--body);
}

.mb-watch .eos-hub-about.is-open .body { display: block; animation: wIn .3s var(--ease); }

/* up next */
.mb-watch .eos-hub-strip {
  border: 1px solid var(--line2);
  border-radius: 13px;
  background: var(--card);
  padding: 15px 16px;
  display: flex;
  flex-direction: column;
  gap: 9px;
}

/* __head/__h/__link match the carried markup; "eos-hub-next-label" existed only
   in the prototype's vocabulary. */
.mb-watch .eos-hub-strip__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}

.mb-watch .eos-hub-strip__h {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--muted);
}

.mb-watch .eos-hub-strip__link { font-size: 12.5px; font-weight: 600; color: var(--acc); text-decoration: none; }
.mb-watch .eos-hub-strip__link:hover { text-decoration: underline; }

.mb-watch .eos-hub-nx {
  display: flex;
  align-items: baseline;
  gap: 12px;
  flex-wrap: wrap;
}

.mb-watch .eos-hub-nx .when { font-size: 13px; font-weight: 650; color: var(--ink); white-space: nowrap; }
.mb-watch .eos-hub-nx .what { flex: 1; font-size: 13.5px; color: var(--body); }
.mb-watch .eos-hub-nx .rel  { font-size: 12.5px; color: var(--muted); white-space: nowrap; }

/* pulse chips */
.mb-watch .eos-hub-pulse { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

.mb-watch .eos-hub-pulse > span {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 34px;
  padding: 0 13px;
  border-radius: 999px;
  background: var(--stage);
  border: 1px solid var(--line2);
  font-size: 12.5px;
  color: var(--body);
}

.mb-watch .eos-hub-pulse b,
.mb-watch .eos-hub-pulse strong { font-weight: 700; color: var(--ink); font-variant-numeric: tabular-nums; }

/* on-screen verse card — the sand moment */
.mb-watch .eos-hub-verse {
  display: flex;
  gap: 14px;
  border: 1px solid var(--accLight);
  background: var(--sand);
  border-radius: 14px;
  padding: 18px 20px;
}

/* The carried markup's anatomy is > svg (with a hardcoded gold stroke attr) +
   .lbl + .txt — NOT the prototype's tile/eyebrow/blockquote. The CSS stroke
   property outranks the svg's presentation attribute, which is how the gold
   glyph turns clay-on-sand without touching the contract markup. */
.mb-watch .eos-hub-verse > svg {
  flex: 0 0 34px;
  width: 34px;
  height: 34px;
  padding: 8px;
  box-sizing: border-box;
  border-radius: 9px;
  background: rgba(52, 34, 0, .08);
  stroke: var(--sandink);
}

.mb-watch .eos-hub-verse .lbl {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--sandink);
  opacity: .66;
}

.mb-watch .eos-hub-verse .txt {
  margin: 4px 0 10px;
  font-family: var(--font-serif);
  font-size: clamp(16px, 1.8vw, 19px);
  line-height: 1.45;
  color: var(--sandink);
}

.mb-watch .eos-hub-verse .ref,
.mb-watch .eos-hub-verse button {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 30px;
  padding: 0 12px;
  border-radius: 8px;
  border: 1px solid rgba(52, 34, 0, .16);
  background: transparent;
  color: var(--sandink);
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
  transition: background var(--dur) ease;
}

.mb-watch .eos-hub-verse .ref:hover,
.mb-watch .eos-hub-verse button:hover { background: rgba(52, 34, 0, .07); }

/* hub recent-services strip */
.mb-watch .eos-hub-replays { display: flex; gap: 10px; overflow-x: auto; padding-bottom: 4px; scrollbar-width: thin; }

.mb-watch .eos-hub-rp {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px 8px 8px;
  border-radius: 12px;
  border: 1px solid var(--line2);
  background: var(--card);
  color: var(--ink);
  transition: transform .22s var(--spring), box-shadow .22s ease;
}

.mb-watch .eos-hub-rp:hover { transform: translateY(-2px); box-shadow: var(--sc); }

/* interiors — the .play overlay MUST be absolute + opacity:0, or the fallback
   icon and the overlay icon render side by side (the markup emits both). */
.mb-watch .eos-hub-rp .thumb {
  position: relative;
  flex: 0 0 62px;
  width: 62px;
  height: 44px;
  border-radius: 8px;
  overflow: hidden;
  background: var(--stage);
  display: flex;
  align-items: center;
  justify-content: center;
}

.mb-watch .eos-hub-rp .thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }

.mb-watch .eos-hub-rp .thumb .play {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, .25);
  opacity: 0;
  transition: opacity .15s ease;
}

.mb-watch .eos-hub-rp:hover .thumb .play { opacity: 1; }

.mb-watch .eos-hub-rp .dur {
  position: absolute;
  bottom: 4px;
  right: 5px;
  padding: 1px 5px;
  border-radius: 5px;
  background: rgba(0, 0, 0, .7);
  color: #fff;
  font-size: 10px;
}

.mb-watch .eos-hub-rp .t { font-size: 12.5px; font-weight: 600; color: var(--ink); line-height: 1.35; }
.mb-watch .eos-hub-rp .m { font-size: 11px; color: var(--muted); }

/* legacy no-hub strip */
.mb-watch .eos-watch-credits    { margin: 0; font-size: 13.5px; color: var(--body); }
.mb-watch .eos-watch-scripture  { margin: 0; font-size: 13px; color: var(--muted); }
.mb-watch .eos-watch-description { font-size: 14.5px; line-height: 1.65; color: var(--body); max-width: 70ch; }
.mb-watch .eos-watch-actions { display: flex; gap: 8px; flex-wrap: wrap; }

.mb-watch .eos-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 40px;
  padding: 0 16px;
  border-radius: 11px;
  border: 1px solid var(--line);
  background: var(--card);
  color: var(--ink);
  font-size: 13.5px;
  font-weight: 600;
  cursor: pointer;
  transition: background var(--dur) ease, transform var(--dur) ease;
}

.mb-watch .eos-chip:hover { background: var(--soft); transform: translateY(-1px); }

/* ----------------------------------------------------------------------------
   § 5  SPLITTER
   -------------------------------------------------------------------------- */

.mb-w-split {
  position: relative;
  align-self: stretch;
  width: 5px;
  border-radius: 999px;
  background: transparent;
  cursor: col-resize;
  touch-action: none;
  /* the wash eases in; without this the 5px track snaps */
  transition: background .16s ease;
  /* the grip reads currentColor, and .mb-watch sets colour to --ink — so the
     grip needs its own inherited tone, not the page's text colour */
  color: var(--muted);
}

.mb-w-split:hover { background: var(--accLight); }
.mb-w-split:focus-visible { background: var(--acc); outline: none; }

.mb-w-split-hit { position: absolute; inset: 0 -6px; }

.mb-w-split-grip {
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 5px;
  height: 34px;
  border-radius: 999px;
  background: var(--line);
  transition: height var(--dur) ease, background var(--dur) ease;
}

.mb-w-split:hover .mb-w-split-grip,
.mb-w-split:focus-visible .mb-w-split-grip { height: 56px; background: currentColor; }

/* ----------------------------------------------------------------------------
   § 6  SIDE DOCK

   The sticky card. The min-height:0 CHAIN below is load-bearing (ported from
   watch-hub.css v2.10.x): without every link the chat column grows unbounded
   instead of scrolling.
   -------------------------------------------------------------------------- */

.mb-watch .eos-side {
  position: sticky;
  top: 78px;
  /* v3.34.0 — the member's dock height. --panelH is written by
     mambo-watch.js initDockHeight() and is DELIBERATELY left undeclared: the
     var() fallback IS the default, which is what makes "reset" a
     removeProperty() and what lets every mode block further down this sheet
     that re-states a literal height keep winning on ordinary source order.

     THESE TWO LINES MUST STAY HERE, inside § 6. Appended at the end of the
     sheet they would come after theater (:1653), the stacked block (:1824)
     and the 620 block (:1836) and invert all three — the dock would obey
     --panelH in modes where it must not. */
  height: var(--panelH, calc(100vh - 100px));
  max-height: var(--panelH, calc(100vh - 100px));
  /* Required, and not decoration. No sheet declared min-height on
     `.mb-watch .eos-side`, so the winning floor was chat-studio.css:32's
     `.eos-side { min-height: 600px }` — a member asking for 500px would have
     got 600 and the control would read as broken. (0,2,0) beats its (0,1,0),
     so this needs no !important. It also removes a pre-existing overhang:
     below a 700px viewport the shipped dock already exceeded its own
     calc(100vh - 100px) sticky window. */
  min-height: 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  border: 1px solid var(--line);
  background: var(--card);
  border-radius: 16px;
  box-shadow: var(--sc);
  overflow: hidden;
  will-change: transform;
}

.mb-watch .eos-side-tabs {
  flex: 0 0 auto;
  display: flex;
  gap: 2px;
  padding: 7px;
  border-bottom: 1px solid var(--line2);
  background: var(--stage);
  overflow-x: auto;
  scrollbar-width: none;
}

/* Geometry is the prototype's, value for value (dc.html:465-484): gap 6, height
   36, padding 0 12, radius 9, 13px, and a .2s transition — not the layer's
   default .18s. */
.mb-watch .eos-side-tab {
  flex: 1 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  height: 36px;
  padding: 0 12px;
  border: 0;
  border-radius: 9px;
  background: transparent;
  color: var(--muted);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: background .2s ease, color .2s ease;
}

.mb-watch .eos-side-tab:hover { color: var(--ink); }

.mb-watch .eos-side-tab.is-active,
.mb-watch .eos-side-tab[aria-selected="true"] {
  background: var(--card);
  color: var(--ink);
  font-weight: 650;
  box-shadow: var(--sc);
}

.mb-watch .eos-side-tab__badge {
  min-width: 17px;
  height: 17px;
  padding: 0 5px;
  border-radius: 999px;
  background: var(--live);
  color: #fff;
  font-size: 10px;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* The rail SCROLLS — that is the design, not a defect. Measured on the running
   prototype at the default 392px panel: rail clientWidth 391, scrollWidth 557,
   overflow-x auto, all seven tabs fully labelled at 36px tall. Our tab widths
   match it exactly (Chat 74, Notes 81, Bible 74, Prayer 83, Flow 73, Give 72),
   so the horizontal overflow is faithful. An earlier revision collapsed the
   labels on unselected tabs below a 520px rail to make them all fit; that was
   a deviation and has been removed. */

.mb-watch .eos-side-panel {
  display: none;
  flex: 1;
  min-height: 0;
  flex-direction: column;
}

.mb-watch .eos-side-panel.is-active { display: flex; }

/* the scroll-bound chain (do not break a single link) */
.mb-watch #eos-chat { display: flex; flex-direction: column; flex: 1; min-height: 0; }
.mb-watch #eos-chat-stream { flex: 1 1 auto; min-height: 212px; overflow-y: auto; }
.mb-watch .eos-chat-pane { display: none; flex: 1; min-height: 0; }
.mb-watch .eos-chat-pane.is-active { display: flex; flex-direction: column; }
.mb-watch .eos-chat-embed { flex: 1; width: 100%; border: 0; min-height: 0; }

/* expand toolbar (notes/bible) */
.mb-watch .eos-side-expand {
  display: flex;
  gap: 4px;
  padding: 6px 8px;
  border-bottom: 1px solid var(--line2);
  background: var(--stage);
}

.mb-watch .eos-side-expand-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 26px;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: var(--card);
  color: var(--muted);
  cursor: pointer;
  transition: background var(--dur) ease, color var(--dur) ease;
}

.mb-watch .eos-side-expand-btn:hover { background: var(--soft); color: var(--ink); }

/* new-panel shells (prayer / flow / give) */
.mb-w-panelbody { flex: 1; min-height: 0; overflow-y: auto; padding: 14px; display: flex; flex-direction: column; gap: 10px; }
.mb-w-paneltitle { margin: 0; font-size: 15px; font-weight: 700; letter-spacing: -.015em; color: var(--ink); }
.mb-w-panelsub { margin: 0 0 4px; font-size: 12.5px; color: var(--muted); }

.mb-w-fieldlabel {
  margin: 12px 0 0;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--muted);
}

.mb-w-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 40px;
  padding: 0 16px;
  border: 1px solid var(--line);
  border-radius: 11px;
  background: var(--card);
  color: var(--ink);
  font-size: 13.5px;
  font-weight: 650;
  cursor: pointer;
  transition: background var(--dur) ease, transform var(--dur) ease, box-shadow var(--dur) ease;
}

.mb-w-btn--acc { background: var(--acc); border-color: transparent; color: var(--onacc); font-weight: 700; box-shadow: var(--sc); }
.mb-w-btn--acc:hover { background: var(--accHover); transform: translateY(-1px); box-shadow: var(--sh); }

.mb-w-formnote { margin: 0; font-size: 11.5px; color: var(--muted); }
.mb-w-center { text-align: center; }

.mb-w-prayform { display: flex; flex-direction: column; gap: 9px; }

.mb-w-prayform textarea {
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 11px;
  background: var(--stage);
  color: var(--ink);
  font: inherit;
  font-size: 13.5px;
  resize: vertical;
  min-height: 74px;
}

.mb-w-prayform textarea:focus { outline: none; border-color: var(--acc); box-shadow: 0 0 0 3px var(--accsoft); }

.mb-w-linkcard {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 2px 10px;
  align-items: center;
  padding: 13px 14px;
  border: 1px solid var(--line2);
  border-radius: 12px;
  background: var(--stage);
  color: var(--ink);
  transition: background var(--dur) ease;
}

.mb-w-linkcard:hover { background: var(--soft); }
.mb-w-linkcard svg { grid-row: span 2; color: var(--faint); }
.mb-w-linkcard-t { font-size: 13.5px; font-weight: 650; }
.mb-w-linkcard-s { font-size: 12px; color: var(--muted); }

/* flow panel list */
.mb-w-flowlist { display: flex; flex-direction: column; }

.mb-w-flowitem {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 9px 6px;
  font-size: 13.5px;
  color: var(--body);
}

.mb-w-flowitem .dot {
  flex: 0 0 9px;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  border: 2px solid var(--line);
  background: transparent;
}

.mb-w-flowitem.is-done { color: var(--faint); text-decoration: line-through; }
.mb-w-flowitem.is-done .dot { border: 0; background: var(--faint); }

.mb-w-flowitem.is-now { color: var(--ink); font-weight: 650; }

.mb-w-flowitem.is-now .dot {
  flex-basis: 13px;
  width: 13px;
  height: 13px;
  border: 0;
  background: var(--acc);
  box-shadow: 0 0 0 3px var(--accsoft);
  animation: wPulse 2s ease-out infinite;
}

.mb-w-flowitem .when { margin-left: auto; font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }

.mb-w-flownow {
  display: inline-flex;
  align-items: center;
  height: 20px;
  padding: 0 8px;
  border-radius: 999px;
  background: var(--accsoft);
  color: var(--acc);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
}

.mb-w-flowempty { padding: 12px 6px; font-size: 13px; color: var(--muted); }

/* give panel */
.mb-w-fundrow { display: flex; flex-wrap: wrap; gap: 6px; }

.mb-w-fund {
  height: 32px;
  padding: 0 13px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--card);
  color: var(--body);
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
  transition: background var(--dur) ease, border-color var(--dur) ease, color var(--dur) ease;
}

.mb-w-fund.is-on { border-color: var(--acc); background: var(--accsoft); color: var(--acc); }

.mb-w-amtgrid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }

.mb-w-amt {
  height: 44px;
  border-radius: 11px;
  border: 1px solid var(--line);
  background: var(--card);
  color: var(--ink);
  font-size: 15px;
  font-weight: 700;
  cursor: pointer;
  transition: background var(--dur) ease, border-color var(--dur) ease;
}

.mb-w-amt.is-on { border-color: var(--acc); background: var(--accsoft); color: var(--tint2ink); }
.mb-w-amt--other { border-style: dashed; color: var(--muted); font-size: 13px; font-weight: 600; }

.mb-w-givego { margin-top: 6px; }

/* ----------------------------------------------------------------------------
   § 6.8  DOCK HEIGHT HANDLE  (v3.34.0)

   (Numbered 6.8 beside § 6.7 HOST PANEL: '6b' is already spoken for by the
   GIVE PANEL block appended further down this sheet.)

   The horizontal twin of § 5's splitter, and deliberately NOT an overlay.

   The v3.33 design put it at `position: absolute; bottom: 0; z-index: 4` inside
   the aside, and review killed it for two reasons that are really one reason:

     1. it lost the stacking contest to `.eos-bible-layout-sheet` (z-index 8,
        which bible-flagship.css:250-257 forces permanently visible in cinema),
        so in the Bible panel `elementFromPoint` returned the layout buttons
        across the whole band, at every height tested;
     2. at some heights it covered real controls instead — the Give panel's
        primary CTA, the Host panel's input. The MEMBER chooses the height, so
        "clear at the heights we tested" is not a property an overlay can hold.

   The width splitter has neither problem because it lives in its own 5px grid
   column. So this is a TRACK, not an overlay: the last flex item of the dock's
   own column, in flow, 14px, with the panels laid out above it. An in-flow
   track cannot be painted over and cannot be painted over anything, at any
   height, for any panel — which answers both failures by construction rather
   than by testing heights one at a time.

   SPECIFICITY MIRRORS § 5 DELIBERATELY. The base rule below is a BARE
   `.mb-w-vsplit` (0,1,0), exactly like `.mb-w-split` at :1193 — NOT
   `.mb-watch .mb-w-vsplit`. The stacked block in § 11 turns the control off
   with a bare `.mb-w-vsplit` too, and a (0,2,0) base outranks it: measured at
   900px wide the handle stayed `display: block` in the stacked layout, where
   --panelH is inert and the control is dead. Do not add a `.mb-watch ` prefix
   to the base rule.

   No !important, no ID selectors, no new breakpoint. Every "off" rule below
   outranks the base on ordinary specificity or on source order, and every mode
   that re-states a literal height disables the control by itself.
   -------------------------------------------------------------------------- */

.mb-w-vsplit {
  position: relative;
  flex: 0 0 14px;
  align-self: stretch;
  display: block;
  padding: 0;
  border: 0;
  border-top: 1px solid var(--line2);
  background: var(--stage);
  cursor: row-resize;
  touch-action: none;
  /* same reason as § 5: .mb-watch sets colour to --ink and the grip reads
     currentColor, so the handle needs its own tone */
  color: var(--muted);
  transition: background .16s ease;
}

.mb-w-vsplit:hover         { background: var(--accLight); }
.mb-w-vsplit:focus-visible { background: var(--acc); outline: none; }

/* The whole track is the grab area. It does not need to reach outside itself —
   that is the entire point of having a track. */
.mb-w-vsplit-hit { position: absolute; inset: 0; }

.mb-w-vsplit-grip {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 34px;
  height: 4px;
  border-radius: 999px;
  background: var(--line);
  transition: width var(--dur) ease, background var(--dur) ease;
}

.mb-w-vsplit:hover .mb-w-vsplit-grip,
.mb-w-vsplit:focus-visible .mb-w-vsplit-grip { width: 56px; background: currentColor; }

/* The readout. Decorative (aria-hidden) — the same figure goes onto the
   handle's aria-valuetext, which is what a screen reader announces. */
.mb-w-vsplit-pct {
  position: absolute;
  right: 8px;
  bottom: 20px;
  height: 20px;
  line-height: 20px;
  padding: 0 7px;
  border-radius: 999px;
  background: var(--ink);
  color: var(--pg);
  font-size: 11px;
  font-weight: 650;
  opacity: 0;
  transform: translateY(3px);
  transition: opacity .16s ease, transform .16s ease;
  pointer-events: none;
}

.mb-w-vsplit.is-resizing .mb-w-vsplit-pct { opacity: 1; transform: none; }

/* Nowhere to travel: initDockHeight() sets .is-locked (and aria-disabled) when
   the active panel's measured floor meets the dock's natural height, which the
   Bible panel does — its own sheets floor it above what the sticky window can
   give. The track stays (removing it would jog the dock 14px on every tab
   switch) but stops offering a grab it cannot honour. Listed after the base and
   the :hover rules so it wins on source order at equal specificity. */
.mb-w-vsplit.is-locked,
.mb-w-vsplit.is-locked:hover { cursor: default; background: var(--stage); }
.mb-w-vsplit.is-locked .mb-w-vsplit-grip { opacity: .35; width: 34px; }

/* --- where the control must not exist (all plain declarations) ------------- */

/* Theater re-states height as min(62vh, 520px) at § 7 and wins on (0,3,0); a
   handle that cannot move anything must not be shown. */
.mb-watch.is-cn-theater .mb-w-vsplit { display: none; }

/* studio.css:404 dissolves .eos-side with `display: contents !important`, so a
   height on it is meaningless AND every surviving child of the aside becomes an
   auto-placed grid item — which is the v2.26.1 "the studio space is a mess"
   bug. is-studio sits on the same root as .mb-watch, so (0,3,0) answers
   studio.css's own !important on plain specificity, no !important needed here.
   Note this is now load-bearing in a way it was not for the overlay: an in-flow
   track is a real child and WOULD be promoted. */
.mb-watch.is-studio .mb-w-vsplit { display: none; }

/* platform.css:2598-2603 / :2615-2620 pin BOTH min-height and max-height to
   calc(100vh - 80px) with an author !important, so --panelH cannot move the box
   at all: used = max(min-height, min(max-height, height)). Rather than ship a
   control that silently does nothing, hide it. (Both states are currently
   unreachable — initSideExpand() early-returns because the .eos-side-expand
   toolbar no longer prints anywhere — so this is insurance.) */
body.eos-side-expand-v .mb-w-vsplit,
body.eos-side-expand-full .mb-w-vsplit { display: none; }

/* ----------------------------------------------------------------------------
   § 7  DOCK TAB (panel restore, theater/fullscreen)
   -------------------------------------------------------------------------- */

.mb-w-docktab {
  position: fixed;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  z-index: 60;
  width: 22px;
  height: 76px;
  border: 1px solid var(--line);
  border-right: 0;
  border-radius: 10px 0 0 10px;
  background: var(--card);
  color: var(--muted);
  box-shadow: -6px 0 18px -12px rgba(0, 0, 0, .4);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: right .42s var(--ease-header), color var(--dur) ease;
}

.mb-w-docktab:hover { background: var(--soft); color: var(--ink); }
.mb-w-docktab-ic { transition: transform .3s var(--spring); }
.mb-w-docktab[aria-expanded="true"] .mb-w-docktab-ic { transform: rotate(180deg); }

/* [hidden] GUARDS. Four rules in this sheet (and chat.css's badge rule) set an
   author display on elements the templates print with the hidden attribute —
   author display beats the UA's [hidden]{display:none}, so without these the
   dock tab floated permanently, the empty unread badge showed as a red pill,
   the flow rail rendered as an empty strip and the geo pill read "Gathering
   in —". Same pattern mambo-chrome.css already carries. */
/* v3.26.0 - and now the Cast chip, which is the fifth. Caught by measuring, not by
   reading: `initCast()` sets `chip.hidden = true` at build and only clears it when a
   real device is reported available, but the chip carries `.eos-cn-ibtn`, whose
   `display: inline-flex` above beats the UA rule. Measured 108x34 and fully tabbable
   while still carrying the hidden attribute - i.e. a "Cast to TV" button offering to
   cast to nothing, which is the one outcome this feature was specified never to
   produce. The popover is guarded for the same reason. */
.mb-w-docktab[hidden],
.mb-watch .eos-side-tab__badge[hidden],
.mb-watch .eos-hub-flow[hidden],
.mb-watch .mb-w-cast[hidden],
.mb-watch .mb-w-castpop[hidden],
.mb-watch .mb-w-castqr[hidden],
.mb-watch .eos-hub-pulse > span[hidden] { display: none; }

/* docked-away state: mambo-watch.js swaps the grid columns; the aside slides */
.mb-watch.mb-w-dockhidden { grid-template-columns: minmax(0, 1fr) 0px 0px; }

.mb-watch.mb-w-dockhidden .eos-side {
  transform: translateX(calc(100% + 24px));
  opacity: 0;
  pointer-events: none;
}

.mb-watch .eos-side { transition: transform .42s var(--ease-header), opacity .3s ease; }
.mb-watch.mb-w-dockhidden .mb-w-split { visibility: hidden; }

/* v3.34.0 — and the height handle with it. `visibility: hidden`, not
   `display: none`: the dock is TRANSLATED off-screen rather than removed, so a
   focusable child stays in the tab order and Tab lands on a control nobody can
   see. Driven: without this the handle takes focus while off-screen; with it,
   it leaves the tab order alongside the dock. `display:none` would work for
   focus too but would collapse the track and make the slide-out jump. */
.mb-watch.mb-w-dockhidden .mb-w-vsplit { visibility: hidden; }

/* ----------------------------------------------------------------------------
   § 8  REPLAY RAIL
   -------------------------------------------------------------------------- */

/* The design leaves 96px between the stage/side row and the rail. The grid gap
   already supplies part of it, and the kept watch-redesign.css adds a 6px
   margin to this element, so both come off the top padding. */
.mb-watch .eos-watch-replays { min-width: 0; padding-top: calc(96px - clamp(14px, 1.6vw, 20px) - 6px); }

.mb-watch .eos-watch-replays .eos-section-head {
  display: flex;
  align-items: baseline;
  gap: 12px;
  margin-bottom: 12px;
}

.mb-watch .eos-watch-replays h2 { margin: 0; font-size: 15px; font-weight: 700; letter-spacing: -.015em; color: var(--ink); flex: 1; }

.mb-watch .eos-watch-replays .eos-section-link { font-size: 13px; font-weight: 600; color: var(--acc); white-space: nowrap; }

.mb-watch .eos-rail { display: flex; gap: 12px; overflow-x: auto; padding-bottom: 4px; scrollbar-width: thin; }

.mb-watch .eos-rail-card {
  flex: 0 0 236px;
  border: 1px solid var(--line);
  border-radius: var(--r-panel);
  background: var(--card);
  overflow: hidden;
  color: var(--ink);
  transition: transform .22s var(--spring), box-shadow .22s ease;
}

.mb-watch .eos-rail-card:hover { transform: translateY(-3px); box-shadow: var(--sc); }

.mb-watch .eos-rail-thumb { position: relative; aspect-ratio: 16 / 9; background: var(--stage); }
.mb-watch .eos-rail-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }

.mb-watch .eos-rail-info { padding: 10px 12px 12px; }
.mb-watch .eos-rail-info h3 { margin: 0; font-size: 13.5px; font-weight: 650; line-height: 1.3; letter-spacing: -.01em; }
.mb-watch .eos-rail-info p { margin: 3px 0 0; font-size: 12px; color: var(--muted); }

/* ----------------------------------------------------------------------------
   § 9  MODE + WAITING STATES
   -------------------------------------------------------------------------- */

/* Theater: stacked single column (the dock tab appears via JS). */
/* No max-width override: theater keeps the 1680px shell (the prototype only
   goes full-width in TV mode, which has its own rule below). Same wrapper
   dissolve as the stacked breakpoint, for the same reason — the panel sits
   under the picture, not under the hub. */
.mb-watch.is-cn-theater {
  grid-template-columns: minmax(0, 1fr);
  grid-template-areas: none;
}

.mb-watch.is-cn-theater .eos-watch-stage { display: contents; }

.mb-watch.is-cn-theater .eos-cn-top.mb-w-bar,
.mb-watch.is-cn-theater .eos-watch-stage > *,
.mb-watch.is-cn-theater .eos-side,
.mb-watch.is-cn-theater .eos-watch-replays { grid-area: auto; }

.mb-watch.is-cn-theater .eos-cn-top.mb-w-bar   { order: 1; }
.mb-watch.is-cn-theater .eos-watch-stage > *   { order: 2; }
.mb-watch.is-cn-theater .eos-side              { order: 3; }
.mb-watch.is-cn-theater .eos-hub,
.mb-watch.is-cn-theater .eos-watch-meta        { order: 4; }
.mb-watch.is-cn-theater .eos-watch-replays     { order: 5; }

.mb-watch.is-cn-theater .mb-w-split { display: none; }
.mb-watch.is-cn-theater .eos-player { border-radius: 0; }

.mb-watch.is-cn-theater .eos-side {
  position: static;
  height: min(62vh, 520px);
  max-height: min(62vh, 520px);
}

/* Docked-away IN theater: the theater template above out-orders the generic
   dockhidden column collapse and keeps a "side" row, so the slid-out aside
   still reserved up to 520px of blank space between stage and rail. */
.mb-watch.is-cn-theater.mb-w-dockhidden { grid-template-areas: "top" "stage" "rail"; }
.mb-watch.is-cn-theater.mb-w-dockhidden .eos-side { display: none; }

/* Cinema: the player becomes the viewport (watch-cinema.js locks scroll). */
.mb-watch.is-cn-cinema .eos-player {
  position: fixed;
  inset: 0;
  z-index: 120;
  border-radius: 0;
  aspect-ratio: auto;
}

/* PiP — ported verbatim in intent from watch-hub.css v2.16.2: a placeholder
   keeps the grid row open while the player floats, and the float anchors to
   the viewport because NO ancestor may carry transform/filter (the mambo
   watch shell deliberately never transforms an ancestor of #eos-player). */
.mb-watch.is-cn-pip .eos-watch-stage::before {
  content: "Playing in a floating window";
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 16 / 9;
  border-radius: 16px;
  border: 1px dashed var(--line);
  background: var(--stage);
  color: var(--muted);
  font-size: 13.5px;
  font-weight: 600;
}

.mb-watch.is-cn-pip .eos-player {
  position: fixed;
  right: 18px;
  bottom: 78px;
  width: min(360px, 42vw);
  z-index: 80;
  aspect-ratio: 16 / 9;
  border-radius: 14px;
  box-shadow: var(--sh);
}

/* Fullscreen hand-back: the stage box returns to normal flow inside the
   fullscreened element. Two ungrouped rules — a browser that cannot parse one
   prefix must not drop the other. */
.mb-watch .eos-player:fullscreen { aspect-ratio: auto; border-radius: 0; }
.mb-watch .eos-player:-webkit-full-screen { aspect-ratio: auto; border-radius: 0; }

/* Waiting layout (off-air server state): single centred 1040px column, side
   dock and splitter gone — the prototype's "waiting" arrangement. */
.mb-watch.is-offair {
  grid-template-columns: minmax(0, 1fr);
  grid-template-areas: "top" "stage" "rail";
  max-width: 1040px;
}

/* [37] v3.20.0 — `.mb-w-modes` NO LONGER HIDES OFF AIR.
   Hiding the splitter and the side dock before a service is correct; the
   prototype does the same in its waiting branch (dc.html:5505-5526). Hiding the
   VIEW-MODE group is not: buildViewModes (dc.html:2463-2493) always renders all
   four segments and paintViewModes (:2504-2521) repaints them in every service
   state, and only `denied` suppresses the bar (dc.html:5622).

   page-watch.php:92 puts `is-offair` on every non-live render — the page's most
   common state — so this one selector removed Normal / Theater / Smart TV /
   Picture in picture from the switcher almost all the time, leaving only the two
   controls that sit outside the group. That is what Dennis saw. */
.mb-watch.is-offair .mb-w-split,
.mb-watch.is-offair .eos-side { display: none; }

/* Panel expand modes (platform.js, sessionStorage 'eos-side-expand'): the kept
   platform.css rules assume the OLD 2-column grid and put the 420-720px track
   on this grid's 5px splitter column. watch-cinema.css used to hide the expand
   toolbar on watch; that sheet is purged, so the buttons are reachable again.
   !important here matches platform.css's own — equal specificity, later sheet
   wins. The two justified exceptions to this file's no-!important rule. */
body.eos-side-expand-h .mb-watch { grid-template-columns: minmax(0, 1fr) 5px minmax(420px, 720px) !important; }

body.eos-side-expand-full .mb-watch {
  grid-template-columns: 1fr !important;
  grid-template-areas: "top" "side" "rail" !important;
}

body.eos-side-expand-full .mb-watch .eos-watch-stage { display: none; }
body.eos-side-expand-full .mb-w-split { display: none; }

/* Smart-TV mode (body class, server ?tv= or the TV button): smart-tv.css
   (kept) hides nav/side/meta/replays and full-viewports the player; this
   only stops the grid fighting it. */
body.eos-tv-mode .mb-watch {
  display: block;
  max-width: 100%;
  padding: 0;
}

body.eos-tv-mode .mb-w-bar { display: none; }

/* ----------------------------------------------------------------------------
   § 10  RESTRICTED GATE (server-rendered .eos-eac card, function-owned markup)
   -------------------------------------------------------------------------- */

.mb-w-denied-wrap { max-width: 720px; margin-inline: auto; padding: clamp(40px, 8vw, 96px) 20px; }

.mb-watch .eos-eac {
  border: 1px solid var(--line);
  border-radius: 20px;
  background: var(--card);
  box-shadow: var(--sh);
  padding: clamp(24px, 4vw, 44px);
  text-align: center;
}

.mb-watch .eos-eac-pill {
  display: inline-flex;
  align-items: center;
  height: 26px;
  padding: 0 12px;
  border-radius: 999px;
  background: var(--tint2);
  border: 1px solid var(--accLight);
  color: var(--tint2ink);
  font-size: 12px;
  font-weight: 650;
}

/* ----------------------------------------------------------------------------
   § 11  RESPONSIVE (the prototype is JS-responsive; the WP build uses media
         queries so layout survives with JS off)
   -------------------------------------------------------------------------- */

/* Stacked. The panel belongs directly UNDER THE PLAYER, not under the whole
   stage column — otherwise a phone viewer scrolls past the entire hub (title,
   flow rail, actions, about, up-next, pulse, verse) before reaching chat.
   .eos-watch-stage dissolves with display:contents so the player and the hub
   become grid items in their own right and the panel can sit between them; the
   DOM is untouched, because that nesting is a contract for studio.css and the
   expand-full rules. Named areas go with it — placement is by order here. */
/* [44] v3.25.0 — this opened at 1100px and the prototype stacks at 1060.
   dc.html:5498-5499 is literal: `const narrow = this.state.mobile || w < 1060;`, and
   every stacking behaviour hangs off `narrow`. So every viewport from 1061 to 1100
   stacked here while the prototype still drew two columns with a sticky dock. */
@media (max-width: 1059.98px) {
  .mb-watch {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: none;
  }

  .mb-watch .eos-watch-stage { display: contents; }

  .eos-cn-top.mb-w-bar,
  .mb-watch .eos-watch-stage > *,
  .mb-watch .eos-side,
  .mb-watch .eos-watch-replays { grid-area: auto; }

  .eos-cn-top.mb-w-bar          { order: 1; }
  .mb-watch .eos-watch-stage > * { order: 2; }   /* the player and its siblings */
  .mb-watch .eos-side            { order: 3; }
  .mb-watch .eos-hub,
  .mb-watch .eos-watch-meta      { order: 4; }   /* hub (or the legacy strip) */
  .mb-watch .eos-watch-replays   { order: 5; }

  .mb-w-split { display: none; }
  /* v3.34.0 — the block below re-states a literal height and wins on source
     order, so --panelH is inert here and the handle would be a dead control. */
  .mb-w-vsplit { display: none; }

  .mb-watch .eos-side {
    position: static;
    height: max(566px, min(80vh, 660px));
    max-height: max(566px, min(80vh, 660px));
  }
}

@media (max-width: 620px) {
  /* Labels collapse only on the INACTIVE segments — the current view mode must
     stay named, or the control becomes three unlabelled glyphs. */
  .mb-w-mode[aria-checked="false"] span { display: none; }
  .mb-watch .eos-cn-ibtn span { display: none; }
  .mb-watch .eos-side { height: max(480px, 70vh); max-height: max(480px, 70vh); }
  .mb-watch { padding-inline: 12px; }
}

/* ----------------------------------------------------------------------------
   § 12  SCROLLBARS + KEYFRAMES + REDUCED MOTION
   -------------------------------------------------------------------------- */

.mb-watch [data-scroll] { scrollbar-width: thin; scrollbar-color: var(--line) transparent; }
.mb-watch [data-scroll]::-webkit-scrollbar { width: 7px; height: 7px; }
.mb-watch [data-scroll]::-webkit-scrollbar-thumb { background: var(--line); border-radius: 999px; }

/* The 70% stop is what makes a live dot PULSE: the ring completes and fades by
   1.4s, then rests. Without it the ring crawls across the whole 2s and reads as
   a slow breath. */
@keyframes wPulse {
  0%   { box-shadow: 0 0 0 0 rgba(241, 65, 42, .5); }
  70%  { box-shadow: 0 0 0 9px rgba(241, 65, 42, 0); }
  100% { box-shadow: 0 0 0 0 rgba(241, 65, 42, 0); }
}

@keyframes wIn {
  from { opacity: 0; transform: translateY(8px) scale(.99); }
  to   { opacity: 1; transform: none; }
}

@keyframes wPop {
  from { opacity: 0; transform: translateY(6px) scale(.97); }
  to   { opacity: 1; transform: none; }
}

@keyframes wSlide {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}

/* The kept engines write INLINE animation/transition styles; only !important
   outranks an inline declaration, so the clamp carries it — the third and
   final justified exception to this sheet's no-!important rule (MOTION-SPEC's
   reduced-motion contract depends on it). */
@media (prefers-reduced-motion: reduce) {
  .mb-watch *,
  .mb-watch *::before,
  .mb-watch *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

/* ============================================================================
   § 13  THE STAGE — player chrome, overlays, the control bar
   ============================================================================ */

/* ----------------------------------------------------------------------------
   § 13  PLAYER STAGE — the prototype's on-picture chrome and control bar

   Appended to mambo-watch.css. Scope: .mb-watch. Rebuilds prototype lines
   155-335 on the SHIPPED engine:

     • watch-controls.js keeps EOS_PLAYER, the YouTube/Vimeo APIs, seek,
       volume, speed, quality, captions and the keyboard layer. Nothing here
       adds behaviour — every rule below only re-dresses nodes that script
       already owns, or paints nodes service-modes.js / moment.js append.
     • watch-controls.css still ships (it skins the runtime chat toolbar,
       .eos-cn-mtools, .eos-ytc-*, .eos-aqc-*). Its bar rules are keyed
       `.eos-watch--cinema .eos-cn-*` — the same 2-class weight as ours — and
       mb-watch is enqueued with eos-watch-controls as a dependency, so every
       override here wins on source order alone. No !important, no ID hooks.

   COLOUR NOTE: this whole section is on-picture chrome floating over video, so
   it uses the prototype's literal rgba()/#fff glass values (the sheet's stated
   exception, already used by §3's off-air overlay). Everything that can be a
   token — --live, --onscreen, --acc, --spring, --dur — is one.
   -------------------------------------------------------------------------- */

/* --- 13.1  Ambient glow -----------------------------------------------------
   watch-controls.css paints .eos-player::before as the halo the Ambient
   toggles switch (root class .is-cn-ambient, localStorage['eosAmbient']).
   Geometry and the opacity switch stay theirs; only the paint becomes the
   prototype's clay + teal pair (line 156). */

.mb-watch .eos-player::before {
  background:
    radial-gradient(50% 60% at 30% 40%, color-mix(in srgb, var(--accBrand) 50%, transparent), transparent 70%), /* v3.36.0 - palette-aware */
    radial-gradient(45% 55% at 72% 62%, rgba(8, 199, 210, .34), transparent 70%);
  filter: blur(56px) saturate(160%);
}

/* --- 13.2  Poster veil (prototype 161) --------------------------------------
   The scrim that makes on-picture chrome readable: dark at the very top behind
   the pills, near-clear through the middle, dark at the foot behind the bar.
   It is why §13.4 drops the control bar's own gradient — one scrim, not two. */

.mb-watch .mb-w-veil {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background: linear-gradient(180deg,
    rgba(6, 6, 7, .5) 0%,
    rgba(6, 6, 7, .06) 34%,
    rgba(6, 6, 7, .14) 62%,
    rgba(6, 6, 7, .86) 100%);
}

/* --- 13.3  Top overlay pills (prototype 260-272) --------------------------- */

.mb-watch .mb-w-toprow {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 5;
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 13px 14px;
  pointer-events: none;
}

.mb-watch .mb-w-toppill {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 27px;
  padding: 0 11px;
  border-radius: 8px;
  font-size: 10.5px;
  font-weight: 800;
  letter-spacing: .11em;
  text-transform: uppercase;
}

.mb-watch .mb-w-toppill--live {
  background: var(--live);
  color: #fff;
}

.mb-watch .mb-w-toplivedot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #fff;
  animation: wPulse 2s ease-out infinite;
}

.mb-watch .mb-w-toppill--viewers {
  background: rgba(10, 10, 12, .5);
  border: 1px solid rgba(244, 241, 236, .16);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  color: var(--onscreen);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
}

.mb-watch .mb-w-toppill--viewers b {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* --- 13.4  The control bar (prototype 274-333) ------------------------------
   The bar spans the whole picture and is transparent + pointer-events:none, so
   the 74px big-play circle can live inside it and still be a real
   [data-bar="play"] for watch-controls.js's click delegate (which is bound to
   #eos-cn-bar). Children opt back into pointer events. The reveal rules stay
   watch-controls.css's: hover / focus-within / .is-cn-ctlshow / .is-pinned. */

.mb-watch .eos-cn-bar {
  position: absolute;
  inset: 0;
  z-index: 8;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 8px;
  padding: 0 12px 11px;
  background: none;
  color: var(--onscreen);
  transform: none;
  transition: opacity .3s ease;
  pointer-events: none;
}

.mb-watch .eos-cn-bar > * { pointer-events: auto; }

/* the reveal states must not re-apply the legacy translate */
.mb-watch .eos-player:hover .eos-cn-bar,
.mb-watch .eos-player:focus-within .eos-cn-bar,
.mb-watch.is-cn-ctlshow .eos-cn-bar,
.mb-watch .eos-cn-bar.is-pinned { transform: none; }

/* 13.4a  Big play */

.mb-watch .mb-w-bigplay {
  position: absolute;
  left: 50%;
  top: 50%;
  z-index: 4;
  display: none;
  align-items: center;
  justify-content: center;
  width: 74px;
  height: 74px;
  padding: 0;
  border: 1px solid rgba(244, 241, 236, .3);
  border-radius: 50%;
  background: rgba(12, 11, 10, .42);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  color: var(--onscreen);
  cursor: pointer;
  transform: translate(-50%, -50%);
  transition: transform .3s var(--spring), background .25s ease;
}

.mb-watch .mb-w-bigplay svg { margin-left: 3px; }

.mb-watch .mb-w-bigplay:hover {
  transform: translate(-50%, -50%) scale(1.08);
  background: rgba(12, 11, 10, .66);
}

/* .is-pinned is watch-controls.js:192 writing `!M.isPlaying` — the prototype's
   "hidden while playing" rule, for free. */
.mb-watch .eos-cn-bar.is-pinned .mb-w-bigplay { display: inline-flex; }

/* .no-api (raw iframe / bunny / embed) never learns the play state, so the
   circle would sit over a playing picture forever. Hide it there. */
.mb-watch .eos-cn-bar.no-api .mb-w-bigplay { display: none; }

/* 13.4b  Seek — 16px hit area, 4px rails, spring knob */

.mb-watch .eos-cn-scrub {
  position: relative;
  height: 16px;
  display: flex;
  align-items: center;
  margin: 0;
  cursor: pointer;
  touch-action: none;
}

.mb-watch .eos-cn-scrub__track {
  position: absolute;
  left: 0;
  right: 0;
  height: 4px;
  border-radius: 4px;
  background: rgba(244, 241, 236, .24);
  overflow: hidden;
  transition: none;
}

/* the prototype's rail does not thicken on hover — only the knob springs in */
.mb-watch .eos-cn-scrub:hover .eos-cn-scrub__track { height: 4px; }

.mb-watch .eos-cn-scrub__buf { background: rgba(244, 241, 236, .34); }
.mb-watch .eos-cn-scrub__played { background: var(--live); }

.mb-watch .eos-cn-scrub__thumb {
  top: 50%;
  width: 12px;
  height: 12px;
  margin-left: -6px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 4px rgba(0, 0, 0, .5);
  transform: translateY(-50%) scale(0);
  transition: transform .18s var(--spring);
}

.mb-watch .eos-cn-scrub:hover .eos-cn-scrub__thumb,
.mb-watch .eos-cn-scrub:focus-visible .eos-cn-scrub__thumb { transform: translateY(-50%) scale(1); }

/* live edge: watch-controls.css pins played to 100% with !important (its one
   unavoidable declaration) — we only retone it and the edge dot. */
.mb-watch .eos-cn-bar.is-bar-live .eos-cn-scrub__played { background: var(--live); }

.mb-watch .eos-cn-bar.is-bar-live .eos-cn-scrub__live {
  right: -1px;
  width: 11px;
  height: 11px;
  background: var(--live);
  border: 2px solid #fff;
}

/* hover time bubble = the prototype's scrubTip */
.mb-watch .eos-cn-scrub__prev {
  bottom: calc(100% + 6px);
  padding: 3px 8px;
  border: 0;
  border-radius: 7px;
  background: rgba(10, 9, 8, .92);
  color: var(--onscreen);
  font-size: 11.5px;
  font-weight: 650;
  font-variant-numeric: tabular-nums;
}

/* 13.4c  Control row */

.mb-watch .eos-cn-bar__row {
  display: flex;
  align-items: center;
  gap: 4px;
  flex-wrap: wrap;
}

.mb-watch .eos-cn-bar__sp { flex: 1; }

/* Contract class with no prototype counterpart — the row groups with a flex
   spacer instead. Kept in the markup, collapsed here. */
.mb-watch .eos-cn-bar__sep { display: none; }

.mb-watch .eos-cn-cbtn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  width: 36px;
  min-width: 36px;
  height: 36px;
  padding: 0;
  border: 0;
  border-radius: 9px;
  background: transparent;
  color: inherit;
  font: inherit;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: .05em;
  opacity: 1;
  cursor: pointer;
  transition: background var(--dur) ease, color var(--dur) ease, transform .3s var(--spring);
}

.mb-watch .eos-cn-cbtn:hover,
.mb-watch .eos-cn-cbtn--amber:hover { background: rgba(244, 241, 236, .14); }

.mb-watch .eos-cn-cbtn:active { transform: scale(.94); }

/* the prototype's "on" paint (captions engaged): inverted chip */
.mb-watch .eos-cn-cbtn.is-on {
  background: rgba(244, 241, 236, .94);
  color: #17150F;
}

/* the two tabler glyphs watch-controls.js re-classNames (play / volume) */
.mb-watch .eos-cn-cbtn i { font-size: 19px; }

/* CC is a text button, not a 36px square */
.mb-watch .mb-w-ccc {
  width: auto;
  min-width: 0;
  height: 30px;
  padding: 0 9px;
  border-radius: 8px;
}

/* Studio carries a label */
.mb-watch .mb-w-cstudio {
  width: auto;
  min-width: 0;
  padding: 0 12px;
  font-size: 12.5px;
  font-weight: 650;
  letter-spacing: 0;
  white-space: nowrap;
}

/* the gear turns while its menu is open (watch-controls.js writes aria-expanded) */
.mb-watch .mb-w-cgear[aria-expanded="true"] { transform: rotate(45deg); }

/* 13.4d  Volume — the track expands out of the mute button */

.mb-watch .eos-cn-vol {
  display: flex;
  align-items: center;
  gap: 2px;
}

.mb-watch .eos-cn-vol__slider {
  display: flex;
  align-items: center;
  width: 0;
  overflow: hidden;
  transition: width .28s var(--ease-header);
}

.mb-watch .eos-cn-vol:hover .eos-cn-vol__slider,
.mb-watch .eos-cn-vol:focus-within .eos-cn-vol__slider,
.mb-watch .eos-cn-vol.is-open .eos-cn-vol__slider { width: 74px; }

.mb-watch .eos-cn-vol__slider input[type="range"] {
  width: 66px;
  height: 4px;
  margin: 0 4px;
  accent-color: var(--onscreen);
  cursor: pointer;
}

/* 13.4e  Live chip + elapsed time */

.mb-watch .eos-cn-livepill {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 26px;
  margin-left: 6px;
  padding: 0 11px;
  border: 0;
  border-radius: 8px;
  background: var(--live);
  color: #fff;
  font: inherit;
  font-size: 10.5px;
  font-weight: 800;
  letter-spacing: .11em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background var(--dur) ease;
}

.mb-watch .eos-cn-livepill span {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #fff;
  animation: wPulse 2s ease-out infinite;
}

/* behind-live: watch-controls.js:253 replaces the dot with a tabler glyph and
   the label with "Go live" */
.mb-watch .eos-cn-livepill.is-behind {
  background: rgba(244, 241, 236, .12);
  color: var(--onscreen);
}

.mb-watch .eos-cn-livepill.is-behind:hover { background: rgba(244, 241, 236, .2); }
.mb-watch .eos-cn-livepill i { font-size: 13px; }

.mb-watch .eos-cn-time {
  margin-left: 6px;
  padding: 0;
  color: rgba(244, 241, 236, .86);
  font-size: 12px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  opacity: 1;
}

/* 13.4f  Settings menu */

.mb-watch .eos-cn-menuwrap { position: relative; display: inline-flex; }

.mb-watch .eos-cn-menu {
  right: 0;
  bottom: calc(100% + 10px);
  width: auto;
  min-width: 214px;
  padding: 8px;
  border: 1px solid rgba(244, 241, 236, .14);
  border-radius: 13px;
  background: rgba(18, 16, 14, .97);
  -webkit-backdrop-filter: blur(16px);
  backdrop-filter: blur(16px);
  box-shadow: 0 20px 44px -18px rgba(0, 0, 0, .8);
  animation: wPop .24s var(--spring);
}

.mb-watch .eos-cn-menu__h {
  padding: 8px 10px 5px;
  color: rgba(244, 241, 236, .5);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  opacity: 1;
}

.mb-watch .eos-cn-menu__div {
  height: 1px;
  margin: 5px 6px;
  background: rgba(244, 241, 236, .12);
}

.mb-watch .eos-cn-seg2 {
  gap: 3px;
  margin: 2px 6px 5px;
  padding: 3px;
  border-radius: 9px;
  background: rgba(244, 241, 236, .08);
}

.mb-watch .eos-cn-seg2 button {
  padding: 6px 4px;
  border-radius: 7px;
  color: var(--onscreen);
  font-size: 11.5px;
  font-weight: 600;
  opacity: .72;
  transition: background var(--dur) ease, opacity var(--dur) ease;
}

.mb-watch .eos-cn-seg2 button:hover { background: rgba(244, 241, 236, .1); opacity: 1; }

.mb-watch .eos-cn-seg2 button.is-on {
  background: var(--onscreen);
  color: #17150F;
  opacity: 1;
}

.mb-watch .eos-cn-menu__row {
  padding: 9px 11px;
  border-radius: 9px;
  color: var(--onscreen);
  font-size: 12.5px;
}

.mb-watch .eos-cn-menu__row:hover { background: rgba(244, 241, 236, .1); }

.mb-watch .eos-cn-menu__val {
  color: rgba(244, 241, 236, .62);
  font-size: 11.5px;
  opacity: 1;
}

/* --- 13.5  Overlays the live-ops scripts mount into #eos-player -------------
   Not printed by stage.php — service-modes.js creates .eos-svm-badge and
   moment.js creates .eos-mc-btn, both appended to #eos-player at boot. These
   rules give the runtime nodes the prototype's clothes.

   The mode badge sits at the RIGHT of the same 13/14px top band as the pills:
   the badge is a direct child of #eos-player, not of .mb-w-toprow, so it
   cannot flow after the viewers pill the way prototype line 271 does. Same
   band, same anatomy, opposite end. */

.mb-watch .eos-svm-badge {
  top: 13px;
  right: 14px;
  left: auto;
  z-index: 6;
  height: 27px;
  padding: 0 11px;
  border: 1px solid rgba(226, 139, 82, .5);
  border-radius: 8px;
  background: rgba(226, 139, 82, .24);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  color: #F5C9A6;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  white-space: nowrap;
  animation: none;
}

.mb-watch .eos-svm-badge__ico { font-size: 12px; }

/* Capture this moment — POST eos/v1/moment-share. moment.js sets the glyph
   (an emoji) via textContent, so only the circle is ours. */
.mb-watch .eos-mc-btn {
  top: 50%;
  right: 14px;
  z-index: 6;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border: 1px solid rgba(244, 241, 236, .26);
  border-radius: 50%;
  background: rgba(10, 9, 8, .6);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  color: var(--onscreen);
  font-size: 18px;
  line-height: 1;
  opacity: 1;
  transform: translateY(-50%);
  transition: transform .2s var(--spring), background var(--dur) ease;
}

.mb-watch .eos-mc-btn:hover {
  background: rgba(10, 9, 8, .78);
  opacity: 1;
  transform: translateY(-50%) scale(1.08);
}

.mb-watch .eos-mc-btn.is-pressed { transform: translateY(-50%) scale(.92); }

/* --- 13.6  Narrow -----------------------------------------------------------
   The prototype has no media queries (its JS re-lays out), but a 36px control
   is below the touch minimum and the row would crowd on a phone. Only sizes
   change; nothing is removed that a member can reach nowhere else — Studio,
   Ambient, Smart TV and Share all also live in the stage bar. */

@media (max-width: 720px) {
  .mb-watch .eos-cn-bar { padding: 0 8px 8px; }
  .mb-watch .eos-cn-cbtn { width: 40px; min-width: 40px; height: 40px; }
  .mb-watch .mb-w-ccc { width: auto; min-width: 0; height: 34px; }
  .mb-watch .mb-w-bigplay { width: 64px; height: 64px; }
}

@media (max-width: 620px) {
  .mb-watch .mb-w-cstudio span { display: none; }
  .mb-watch .mb-w-cstudio { width: 40px; min-width: 40px; padding: 0; }
  .mb-watch .mb-w-toprow { padding: 10px 11px; gap: 7px; }
}

/* ============================================================================
   § 14  THE CHAT PANEL
   ============================================================================ */

/* ============================================================================
   MAMBO — WATCH · CHAT PANEL.  v3.3.0
   Appended to mambo-watch.css. Scope: .mb-watch (never wider).

   1:1 to the Claude Design prototype §8.2 (markup lines 489-625) plus the Q&A
   mode (prototype JS 4850-4900). Every measurement below is the prototype's.

   WHAT THIS SHEET DRESSES: the server-printed chrome (toolbar, panes, pin,
   presence mount, stream, typing, composer, sign-in, Q&A pane) AND the nodes
   the already-shipped JS builds inside it at runtime — message rows
   (.eos-chat-msg*, chat.js), reaction pills, the announcement card
   (.eos-ann-bar), the give row (.eos-tg-give-btn), the quick replies
   (.eos-qr-row/.eos-qr-chip), the photo/GIF buttons (.au-attach-btn/.au-gif-btn,
   chat-upgrade.js), presence (.eos-chat-pr__*), search, bookmarks and the Q&A
   queue (.eos-chat-qa__*). Those are runtime CHILDREN of this surface, so they
   are this surface's paint.

   WHAT IT MUST NOT TOUCH: .eos-aqc-* (the admin gear watch-controls.js parks in
   the utility lane — watch-controls.css owns it), .eos-cn-* and every other
   surface outside the chat panel.

   The composer is FLAT on purpose: chat-upgrade.js inserts the photo and GIF
   buttons as DIRECT CHILDREN of #eos-chat-form, so the prototype's field shell
   is painted by .mb-w-composer::before and the icon order is `order`.
   ============================================================================ */

/* ----------------------------------------------------------------------------
   § C1  PANEL + PANES
   -------------------------------------------------------------------------- */

.mb-watch .mb-w-chatpanel { overflow: hidden; }

.mb-watch .mb-w-chatpane { min-width: 0; }

.mb-watch .mb-w-chat {
  position: relative;
  background: var(--card);
}

/* The lane controls chat.js actually binds; watch-controls.js forwards the
   visible toolbar buttons to them. Present, never visible. */
.mb-watch .mb-w-chatproxy { display: none; }

/* ----------------------------------------------------------------------------
   § C2  TOOLBAR (source switch · language pill · search · bookmarks · shield)
   -------------------------------------------------------------------------- */

/* One row, never two. The prototype's lane is flex/nowrap (measured: 391px
   content in a 391px lane, scrollWidth == clientWidth), and a legacy sheet
   turns wrapping on — which is what let the pill and the icons drop out of
   line with the segmented control. */
.mb-watch .mb-w-chatbar {
  flex: 0 0 auto;
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: 6px;
  padding: 9px 10px;
  border-bottom: 1px solid var(--line2);
  background: var(--card);
}

.mb-watch .mb-w-chatbar-sp { flex: 1 1 auto; }

.mb-watch .mb-w-chatseg {
  display: flex;
  gap: 2px;
  padding: 3px;
  border: 1px solid var(--line2);
  border-radius: 9px;
  background: var(--stage);
}

.mb-watch .mb-w-chatsegbtn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  height: 28px;
  padding: 0 11px;
  border: 0;
  border-radius: 7px;
  background: transparent;
  color: var(--muted);
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--dur) ease, color var(--dur) ease;
}

.mb-watch .mb-w-chatsegbtn:hover { color: var(--ink); }

.mb-watch .mb-w-chatsegbtn.is-on {
  background: var(--card);
  color: var(--ink);
  font-weight: 650;
  box-shadow: var(--sc);
}

.mb-watch .mb-w-langpill:not([hidden]) {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 32px;
  padding: 0 11px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--stage);
  color: var(--body);
  font: inherit;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .09em;
  text-transform: uppercase;
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--dur) ease, color var(--dur) ease;
}

.mb-watch .mb-w-langpill:hover { background: var(--soft); color: var(--ink); }

.mb-watch .mb-w-chatico {
  flex: 0 0 auto;
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  transition: background var(--dur) ease, color var(--dur) ease;
}

.mb-watch .mb-w-chatico:hover { background: var(--soft); color: var(--ink); }

/* ---- LEGACY OVERRIDE: chat-studio.css pins the lane controls --------------
   Verified on the live page, not inferred. In the legacy design these three
   controls float on top of the stream as absolutely-positioned dots, and
   chat-studio.css nails that down:

     .eos-chat-search-toggle, .eos-chat-bm-toggle, .eos-chat-langpill {
       top: 52px !important; width: 26px !important; height: 26px !important;
       background: rgba(0,0,0,.05) !important; border: 0 !important; ... }

   In this design they are ordinary flex children of the utility lane. The
   26px cage is what crushed the language pill to a single letter — its
   label span still measured its full 54px and simply spilled out of the
   button, which is what read as a stray "E" beside the segmented control.

   !important is the only thing that outranks !important, so it is used
   here deliberately and only for the declarations chat-studio.css forces.
   Scoped to the lane so the legacy floating placement survives anywhere
   this layer is not active. */
.mb-watch .eos-chat-utility-lane .eos-chat-langpill,
.mb-watch .eos-chat-utility-lane .eos-chat-search-toggle,
.mb-watch .eos-chat-utility-lane .eos-chat-bm-toggle,
.mb-watch .eos-chat-utility-lane .eos-chat-mod-toggle {
  position: static !important;
  top: auto !important;
  right: auto !important;
  height: 32px !important;
  border: 1px solid var(--line) !important;
  box-shadow: none !important;
}

/* Only the language pill carries the --stage ground. The icon buttons are
   TRANSPARENT on a --line hairline at radius 8 — measured on the prototype,
   where all three icons read as outlines, not filled wells. An earlier
   revision washed all four in --stage together. */
.mb-watch .eos-chat-utility-lane .eos-chat-langpill { background: var(--stage) !important; }

.mb-watch .eos-chat-utility-lane .eos-chat-search-toggle,
.mb-watch .eos-chat-utility-lane .eos-chat-bm-toggle,
.mb-watch .eos-chat-utility-lane .eos-chat-mod-toggle {
  width: 32px !important;
  background: transparent !important;
  border-radius: 8px !important;
}

/* The pill is sized by its word. Nothing in this lane shrinks: squeezing the
   segmented control clips "YouTube", and a truncated mode label is worse
   than a pill that shows only its globe. */
.mb-watch .eos-chat-utility-lane .eos-chat-langpill { width: auto !important; }
.mb-watch .mb-w-langpill { flex: 0 0 auto; }
.mb-watch .mb-w-chatseg { flex: 0 0 auto; }
.mb-watch .mb-w-chatbar-sp { min-width: 0; }

/* The pill keeps its word. Measured on the running prototype, the lane is
   flex/nowrap and everything fits the 391px panel at natural size: segmented
   141 + spacer + pill 98 + three 32px icons + 6px gaps = 385 of 391. The pill
   is 98x32, uppercase, 11px/700, letter-spacing .99px, --stage on a --line
   hairline at radius 999. An earlier revision collapsed the pill to its globe
   below a 430px lane; the crush it was compensating for was chat-studio.css's
   26px cage, which the override above now lifts, so the collapse is gone. */

/* ----------------------------------------------------------------------------
   § C3  SEARCH ROW + BOOKMARKS PANEL  (chat.js fills both)
   -------------------------------------------------------------------------- */

.mb-watch .mb-w-chatsearch:not([hidden]) {
  flex: 0 0 auto;
  padding: 9px 10px;
  border-bottom: 1px solid var(--line2);
  background: var(--stage);
  animation: wSlide var(--dur) ease both;
}

.mb-watch .mb-w-chatsearch .eos-chat-search__head {
  display: flex;
  align-items: center;
  gap: 8px;
  height: 36px;
  padding: 0 12px;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: var(--card);
  color: var(--muted);
  transition: border-color var(--dur) ease, box-shadow var(--dur) ease;
}

.mb-watch .mb-w-chatsearch .eos-chat-search__head:focus-within {
  border-color: var(--acc);
  box-shadow: 0 0 0 3px var(--accsoft);
}

.mb-watch .mb-w-chatsearch input {
  flex: 1;
  min-width: 0;
  border: 0;
  outline: none;
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-size: 13.5px;
}

.mb-watch .mb-w-chatsearch .eos-chat-search__count { font-size: 11.5px; color: var(--faint); }

.mb-watch .mb-w-chatsearch .eos-chat-search__x {
  width: 22px;
  height: 22px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--muted);
  font: inherit;
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
}

.mb-watch .mb-w-chatsearch .eos-chat-search__x:hover { background: var(--soft); color: var(--ink); }

.mb-watch .mb-w-chatsearch .eos-chat-search__results {
  max-height: 198px;
  overflow-y: auto;
  margin-top: 7px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.mb-watch .mb-w-chatbm:not([hidden]) {
  position: absolute;
  left: 10px;
  right: 10px;
  top: 8px;
  z-index: 16;
  max-height: 264px;
  overflow-y: auto;
  padding: 5px;
  border: 1px solid var(--line);
  border-radius: 13px;
  background: var(--card);
  box-shadow: var(--pop);
  animation: wPop var(--dur-pop) var(--ease) both;
}

.mb-watch .mb-w-chatbm .eos-chat-bm-panel__head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 8px 8px;
  font-size: 12.5px;
  font-weight: 700;
  color: var(--ink);
}

.mb-watch .mb-w-chatbm .eos-chat-bm-panel__count { margin-left: auto; font-size: 11.5px; font-weight: 600; color: var(--muted); }

.mb-watch .mb-w-chatbm .eos-chat-bm-panel__x {
  width: 22px;
  height: 22px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--muted);
  font: inherit;
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
}

.mb-watch .mb-w-chatbm .eos-chat-bm-panel__list { display: flex; flex-direction: column; gap: 4px; }

/* ----------------------------------------------------------------------------
   § C4  SLOW-MODE BAR
   -------------------------------------------------------------------------- */

.mb-watch .mb-w-chatslow:not([hidden]) {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 9px;
  margin: 9px 10px 0;
  padding: 8px 11px;
  border: 1px solid color-mix(in srgb, var(--sandink) 16%, transparent);
  border-radius: 11px;
  background: var(--sand);
  color: var(--sandink);
  font-size: 12px;
  font-weight: 600;
}

.mb-watch .mb-w-chatslow .eos-chat-slowbar__lbl { display: inline-flex; align-items: center; gap: 7px; min-width: 0; }
.mb-watch .mb-w-chatslow .eos-chat-slowbar__ctrl { margin-left: auto; }

/* ----------------------------------------------------------------------------
   § C5  PINNED-BY-HOST BANNER
   -------------------------------------------------------------------------- */

.mb-watch .mb-w-chatpin:not([hidden]) {
  flex: 0 0 auto;
  display: flex;
  align-items: flex-start;
  gap: 9px;
  margin: 9px 10px 0;
  padding: 11px 12px;
  border: 1px solid color-mix(in srgb, var(--tintink) 14%, transparent);
  border-radius: 11px;
  background: var(--tint);
  cursor: pointer;
  animation: wSlide var(--dur-enter) ease both;
}

.mb-watch .mb-w-chatpin .eos-chat-pin__ico { flex: 0 0 auto; margin-top: 2px; color: var(--tintink); display: inline-flex; }
.mb-watch .mb-w-chatpin .eos-chat-pin__col { min-width: 0; flex: 1; }

/* The prototype's label is FULL --tintink at 10px/700/1.2px tracking — no
   opacity. The .72 an earlier revision carried made it read washed-out. */
.mb-watch .mb-w-chatpin .eos-chat-pin__lbl {
  display: block;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--tintink);
}

.mb-watch .mb-w-chatpin .eos-chat-pin__txt {
  display: block;
  margin-top: 4px;
  font-size: 13px;
  line-height: 1.45;
  color: var(--tintink);
  word-break: break-word;
}

.mb-watch .mb-w-chatpin .eos-chat-pin__x {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--tintink);
  opacity: .6;
  cursor: pointer;
  transition: opacity var(--dur) ease;
}

.mb-watch .mb-w-chatpin .eos-chat-pin__x:hover { opacity: 1; }

/* ----------------------------------------------------------------------------
   § C6  PRESENCE STRIP  (chat.js fills it; watch-controls.js may relocate it
   into the stage-bar watching pill, where watch-controls.css takes over)
   -------------------------------------------------------------------------- */

.mb-watch .mb-w-chat > .mb-w-chatpr:not([hidden]) {
  flex: 0 0 auto;
  margin: 9px 10px 0;
  padding: 8px 11px;
  border: 1px solid var(--line2);
  border-radius: 11px;
  background: var(--stage);
}

.mb-watch .mb-w-chat > .mb-w-chatpr .eos-chat-pr__bar {
  display: flex;
  align-items: center;
  gap: 9px;
  cursor: pointer;
}

.mb-watch .mb-w-chat > .mb-w-chatpr .eos-chat-pr__dot {
  flex: 0 0 7px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--live);
}

.mb-watch .mb-w-chat > .mb-w-chatpr .eos-chat-pr__lbl {
  flex: 0 0 auto;
  font-size: 12px;
  font-weight: 700;
  color: var(--ink);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.mb-watch .mb-w-chat > .mb-w-chatpr .eos-chat-pr__strip {
  flex: 1 1 auto;
  display: flex;
  gap: 5px;
  min-width: 0;
  overflow: hidden;
}

.mb-watch .mb-w-chat > .mb-w-chatpr .eos-chat-pr__avatar {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border: 1px solid var(--line2);
  border-radius: 999px;
  background: var(--card);
  color: var(--body);
  font-size: 10px;
  font-weight: 650;
}

.mb-watch .mb-w-chat > .mb-w-chatpr .eos-chat-pr__chev {
  flex: 0 0 auto;
  color: var(--muted);
  transition: transform var(--dur) ease;
}

.mb-watch .mb-w-chat > .mb-w-chatpr .eos-chat-pr__list {
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid var(--line2);
  display: flex;
  flex-direction: column;
  gap: 8px;
  animation: wSlide var(--dur) ease both;
}

.mb-watch .mb-w-chat > .mb-w-chatpr .eos-chat-pr__list-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 9px;
  font-size: 11.5px;
  color: var(--muted);
}

.mb-watch .mb-w-chat > .mb-w-chatpr .eos-chat-pr__total-big { font-size: 12.5px; font-weight: 700; color: var(--ink); }

.mb-watch .mb-w-chat > .mb-w-chatpr .eos-chat-pr__optout {
  height: 24px;
  padding: 0 9px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--card);
  color: var(--body);
  font: inherit;
  font-size: 11px;
  font-weight: 650;
  cursor: pointer;
}

.mb-watch .mb-w-chat > .mb-w-chatpr .eos-chat-pr__group-head {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  font-weight: 650;
  color: var(--body);
  font-variant-numeric: tabular-nums;
}

.mb-watch .mb-w-chat > .mb-w-chatpr .eos-chat-pr__total { color: var(--muted); font-weight: 600; }

.mb-watch .mb-w-chat > .mb-w-chatpr .eos-chat-pr__names {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  margin-top: 5px;
}

.mb-watch .mb-w-chat > .mb-w-chatpr .eos-chat-pr__name {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  height: 22px;
  padding: 0 7px;
  border: 1px solid var(--line2);
  border-radius: 999px;
  background: var(--card);
  color: var(--body);
  font-size: 11px;
  font-weight: 650;
}

.mb-watch .mb-w-chat > .mb-w-chatpr .eos-chat-pr__name-avatar {
  width: 15px;
  height: 15px;
  border-radius: 999px;
  background: var(--tint);
  color: var(--tintink);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 8px;
  font-weight: 700;
}

/* ----------------------------------------------------------------------------
   § C7  ANNOUNCEMENT CARD  (chat.js, from EOS_CONFIG.chatAnnouncement)
   -------------------------------------------------------------------------- */

.mb-watch .mb-w-chat > .eos-ann-bar {
  flex: 0 0 auto;
  display: flex;
  gap: 9px;
  margin: 9px 10px 0;
  padding: 10px 11px;
  border: 1px solid color-mix(in srgb, var(--sandink) 16%, transparent);
  border-radius: 11px;
  background: var(--sand);
  color: var(--sandink);
  cursor: pointer;
  animation: wSlide var(--dur-enter) ease both;
}

.mb-watch .mb-w-chat > .eos-ann-bar .eos-ann-bar__ico { flex: 0 0 auto; margin-top: 1px; display: inline-flex; }
.mb-watch .mb-w-chat > .eos-ann-bar .eos-ann-bar__col { min-width: 0; flex: 1; display: flex; flex-direction: column; }

.mb-watch .mb-w-chat > .eos-ann-bar .eos-ann-bar__lbl {
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  opacity: .72;
}

.mb-watch .mb-w-chat > .eos-ann-bar .eos-ann-bar__msg { margin-top: 3px; font-size: 13px; line-height: 1.45; }

.mb-watch .mb-w-chat > .eos-ann-bar .eos-ann-bar__cta {
  margin-top: 6px;
  font-size: 12px;
  font-weight: 650;
  text-decoration: underline;
}

.mb-watch .mb-w-chat > .eos-ann-bar .eos-ann-bar__x {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: inherit;
  opacity: .6;
  font: inherit;
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
  transition: opacity var(--dur) ease;
}

.mb-watch .mb-w-chat > .eos-ann-bar .eos-ann-bar__x:hover { opacity: 1; }

/* ----------------------------------------------------------------------------
   § C8  MESSAGE STREAM + ROW ANATOMY  (rows are chat.js-built)
   -------------------------------------------------------------------------- */

/* ---- LEGACY OVERRIDE: stream inset + the "continuation" mode -------------
   Measured on the running prototype: the stream is padding 10px 10px 4px with
   gap 2px, and EVERY row is a full row — avatar, name, place, time — including
   consecutive messages from the same speaker. There is no grouped/continuation
   collapse in this design at all.

   Two kept sheets disagree, both with !important:
     chat-flagship.css:174  #eos-chat-stream { padding-top: 22px !important }
     chat-flagship.css:187  .is-continuation { padding-left: 54px !important }
     chat-flagship.css:188  .is-continuation .__avatar { display: none }
     chat-aurora.css:141-143 .is-continuation { margin-top:-3px; padding-top:2px
                             !important } + avatar visibility:hidden;height:0
                             + .who { display:none }

   Together those produced the crowded top gap and the run of avatar-less
   messages shoved 54px to the right. chat.js still stamps .is-continuation —
   the class is left alone, it simply carries no visual weight here. */
.mb-watch .mb-w-chatstream {
  padding: 10px 10px 4px !important;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

/* Honest empty state — hidden the moment the first real row lands. */
.mb-watch .mb-w-chatempty {
  flex: 0 0 auto;
  margin: 0;
  padding: 4px 18px 12px;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--muted);
}

.mb-watch .mb-w-chatstream:not(:empty) + .mb-w-chatempty { display: none; }

.mb-watch .mb-w-chatstream .eos-chat-msg {
  display: flex;
  gap: 9px;
  padding: 7px 8px;
  border-radius: 10px;
  transition: background var(--dur-micro) ease;
  animation: wMsg .34s var(--ease) both;
}

/* v3.31.0 — the row no longer takes the hover; the BUBBLE does. Dennis: "each hover
   on user's text should be distinct on the user's side and not be a highlight across
   the chat width." Superseded by § 25.2, which paints .eos-chat-msg__text instead.
   Left as a no-op rather than deleted so the transition above still has something to
   animate and the selector stays greppable. */
.mb-watch .mb-w-chatstream .eos-chat-msg:hover { background: transparent; }

.mb-watch .mb-w-chatstream .eos-chat-msg__avatar {
  flex: 0 0 auto;
  width: 29px;
  height: 29px;
  border-radius: 50%;
  object-fit: cover;
  background: var(--tint);
  color: var(--tintink);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  font-weight: 700;
}

/* ORDER IS LOAD-BEARING. chat.js emits who → badge → .body → .time → .pills,
   so with plain wrapping the timestamp landed BELOW the message instead of
   beside the name, and the row read as three ragged lines. Leaving the header
   parts at the default order 0 and pushing .body/.pills after them rebuilds
   the design's shape without chat.js changing a thing:

     line 1   name · badges · time
     line 2   the message
     line 3   reaction pills                                                */
.mb-watch .mb-w-chatstream .eos-chat-msg__body {
  min-width: 0;
  flex: 1;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 7px;
}

.mb-watch .mb-w-chatstream .eos-chat-msg__body > .who {
  order: 0;
  font-size: 12.5px;
  font-weight: 700;
  color: var(--ink);
  cursor: pointer;
}

.mb-watch .mb-w-chatstream .eos-chat-msg__body > .time {
  order: 0;
  font-size: 10.5px;
  font-weight: 400;
  color: var(--faint);
  font-variant-numeric: tabular-nums;
}

/* The message text. chat-aurora.css sets .eos-chat-msg__text to 14.5px on
   --au-ink and nothing here answered it, so every message ran a point large in
   the wrong ink. The prototype's message body is 13.5px/1.5 on --body. */
.mb-watch .mb-w-chatstream .eos-chat-msg__text {
  font-size: 13.5px;
  line-height: 1.45;
  color: var(--body);
  word-break: break-word;
}

@media (max-width: 640px) {
  .mb-watch .mb-w-chatstream .eos-chat-msg__text { font-size: 13.5px; }
}

/* The design tints each speaker's name so a busy room stays readable at a
   glance. mambo-watch.js hashes the name to one of six and stamps the class;
   the palette re-tones per theme like everything else. */
.mb-watch .mb-w-chatstream .eos-chat-msg__body > .who.mb-w-n0 { color: var(--chatname-0); }
.mb-watch .mb-w-chatstream .eos-chat-msg__body > .who.mb-w-n1 { color: var(--chatname-1); }
.mb-watch .mb-w-chatstream .eos-chat-msg__body > .who.mb-w-n2 { color: var(--chatname-2); }
.mb-watch .mb-w-chatstream .eos-chat-msg__body > .who.mb-w-n3 { color: var(--chatname-3); }
.mb-watch .mb-w-chatstream .eos-chat-msg__body > .who.mb-w-n4 { color: var(--chatname-4); }
.mb-watch .mb-w-chatstream .eos-chat-msg__body > .who.mb-w-n5 { color: var(--chatname-5); }

/* role badges — clay for host, teal for mod/leader, tinted for NEW */
.mb-watch .mb-w-chatstream .eos-chat-rb {
  order: 0;
  display: inline-flex;
  align-items: center;
  height: 16px;
  padding: 0 6px;
  border-radius: 5px;
  font-size: 9.5px;
  font-weight: 800;
  letter-spacing: .09em;
  text-transform: uppercase;
}

/* Measured on the running prototype: HOST is a SOFT clay chip — --tint2 fill
   with --acc text — not a solid clay one. LEADER and NEW are both the teal
   pair. All three are 9.5px/800 at .855px tracking on a 5px radius. */
.mb-watch .mb-w-chatstream .eos-chat-rb--host { background: var(--tint2) !important; color: var(--acc) !important; }
.mb-watch .mb-w-chatstream .eos-chat-rb--mod  { background: var(--tint) !important; color: var(--tintink) !important; }
.mb-watch .mb-w-chatstream .eos-chat-rb--new  { background: var(--tint) !important; color: var(--tintink) !important; }

.mb-watch .mb-w-chatstream .eos-chat-msg__body > .body {
  order: 1;
  flex: 1 0 100%;
  min-width: 0;
  margin-top: 3px;
  font-size: 13.5px;
  line-height: 1.45;
  color: var(--body);
  word-break: break-word;
}

.mb-watch .mb-w-chatstream .eos-chat-msg__link { color: var(--link); text-decoration: underline; }

/* role badges — HOST / MOD / NEW */
.mb-watch .mb-w-chatstream .eos-chat-rb {
  display: inline-flex;
  align-items: center;
  height: 16px;
  padding: 0 6px;
  border-radius: 5px;
  font-size: 9.5px;
  font-weight: 800;
  letter-spacing: .09em;
  text-transform: uppercase;
}

/* HOST is a soft clay chip; LEADER and NEW are the teal pair. Values read off
   the running prototype, not inferred. !important is required because
   chat-flagship.css sets .eos-chat-rb--host with !important of its own. */
.mb-watch .mb-w-chatstream .eos-chat-rb--host { background: var(--tint2) !important; color: var(--acc) !important; }
.mb-watch .mb-w-chatstream .eos-chat-rb--mod  { background: var(--tint) !important; color: var(--tintink) !important; }
.mb-watch .mb-w-chatstream .eos-chat-rb--new  { background: var(--tint) !important; color: var(--tintink) !important; }

/* chat-flagship.css:174 writes that 22px through `#eos-chat-stream`, an ID, so
   a two-class selector loses to it even when both carry !important. This is one
   of the contract mounts the header allows styling by id for exactly this
   reason — (1,1,0) against its (1,0,0). */
.mb-watch #eos-chat-stream { padding: 10px 10px 4px !important; }

/* Every row is a FULL row. The design has no grouped/continuation state, so a
   repeat message from the same speaker keeps its avatar, its name and its
   normal inset — see the override note on .mb-w-chatstream above for the five
   legacy declarations this answers. */
.mb-watch .mb-w-chatstream .eos-chat-msg.is-continuation {
  margin-top: 0 !important;
  padding: 7px 8px !important;
}

.mb-watch .mb-w-chatstream .eos-chat-msg.is-continuation .eos-chat-msg__avatar {
  display: inline-flex !important;
  visibility: visible !important;
  width: 29px !important;
  height: 29px !important;
}

.mb-watch .mb-w-chatstream .eos-chat-msg.is-continuation .who { display: block !important; }

/* rows are spaced by the stream's 2px gap alone */
.mb-watch .mb-w-chatstream .eos-chat-msg { margin: 0 !important; }

/* ---- A ROW NEVER RUNS EDGE TO EDGE ---------------------------------------
   The message body is capped at half the row. Measured on the live page, an
   uncapped line at a 1130px panel ran 1053px — about 160 characters, against
   a comfortable reading measure of 45-75 — so the eye lost the start of each
   line. The panel is resizable to 70% of the shell, so this is not a rare
   case; it is what a widened panel always did.

   A PERCENTAGE, not a ch measure: it is always relative to the row, so it can
   never overflow its container the way a fixed measure can at narrow widths.
   flex: 0 1 auto lets the body shrink below the cap for a short message, so a
   two-word line stays a two-word line instead of being padded out to half the
   row. */
.mb-watch .mb-w-chatstream .eos-chat-msg__body {
  flex: 0 1 auto;
  max-width: 50%;
}

/* Others grow from the left, yours from the right — the cap only ever shortens
   the line, it never moves the row. */
.mb-watch .mb-w-chatstream .eos-chat-msg:not(.is-mine) { justify-content: flex-start; }

/* ---- YOUR OWN MESSAGE ----------------------------------------------------
   Measured by posting one in the running prototype: the row stays transparent
   with NO border and the same 7px 8px / radius 10 as any other, but the
   content right-aligns and the avatar moves to the right-hand end, where it
   is the only clay avatar in the stream (--acc on --onacc).

   The legacy sheets instead paint the whole own-message run in dark tokens —
   which is why the reaction pill under your own message came out near-black
   on a light page — so the pill is restated here for every row. */
.mb-watch .mb-w-chatstream .eos-chat-msg.is-mine { justify-content: flex-end; }

.mb-watch .mb-w-chatstream .eos-chat-msg.is-mine .eos-chat-msg__body { order: 1; flex: 0 1 auto; }

.mb-watch .mb-w-chatstream .eos-chat-msg.is-mine .eos-chat-msg__avatar {
  order: 2;
  background: var(--acc) !important;
  color: var(--onacc) !important;
}

.mb-watch .mb-w-chatstream .eos-chat-pill {
  background: var(--card) !important;
  color: var(--body) !important;
  border-color: var(--line2) !important;
}

/* The avatar is 29px — chat-aurora.css:.eos-chat-msg__avatar ships 36px (32px
   under 640px) and watch-cinema re-sizes it again, so the measurement is
   restated here rather than left to specificity alone. object-fit keeps a
   real photo circular instead of letterboxed. */
.mb-watch .mb-w-chatstream .eos-chat-msg__avatar {
  width: 29px !important;
  height: 29px !important;
  min-width: 29px !important;
  flex: 0 0 29px !important;
  object-fit: cover;
}

/* The host's message is OUTLINED — a full hairline box, nothing more.
   Measured on the running prototype: background transparent, a 1px
   var(--accLight) border on ALL FOUR sides, radius 10px, padding 7px 8px.
   A member row is identical but with border-width 0, so the box is the only
   thing that marks the host out besides the badge.

   Two earlier revisions got this wrong: the first washed the row in
   `linear-gradient(90deg, var(--tint2), transparent 70%)` with a 2px --acc
   rule (which is what made host messages read as peach blocks), and the
   second read only the computed border-LEFT off the prototype and concluded
   it was a left rule alone.

   Keyed off [data-role="host"] — the attribute chat.js always writes — as well
   as the badge, which only exists when leadership has role badges switched on. */
.mb-watch .mb-w-chatstream .eos-chat-msg[data-role="host"],
.mb-watch .mb-w-chatstream .eos-chat-msg:has(.eos-chat-rb--host) {
  background: none;
  border: 1px solid var(--accLight);
  border-radius: 10px;
}

/* The host avatar is the SAME as everyone else's — --tint on --tintink, 29px,
   no ring. Verified on the prototype (the "EG" host avatar is byte-identical
   in style to the "AB" member avatar). chat-flagship.css dresses it in
   #F5A312 with a gold halo, so that is undone here rather than re-tinted. */
.mb-watch .mb-w-chatstream .eos-chat-msg[data-role="host"] .eos-chat-msg__avatar,
.mb-watch .mb-w-chatstream .eos-chat-msg:has(.eos-chat-rb--host) .eos-chat-msg__avatar {
  background: var(--tint);
  color: var(--tintink);
  box-shadow: none;
}

/* ---- LEGACY OVERRIDE: the last gold bubble --------------------------------
   Verified on the live page, not inferred. chat-flagship.css dresses a host
   message as a gold bubble with TWO !important rules — a #F5A312 3px left
   border, an --au-coral-soft wash and the 5px/14px asymmetric radius:

     .eos-chat-msg[data-role="host"]:not(.is-mine) .eos-chat-msg__body
     .eos-watch--cinema .eos-chat-msg[data-role="host"]:not(.is-mine) .eos-chat-msg__body

   That sheet is kept (it skins the chat surfaces chat.js builds at runtime), so
   the bubble has to be undone here. Both classes below sit on the same root
   element, which puts this at (0,6,0) — above their (0,5,0) — and mambo-watch
   is the last sheet on the page. The accent now lives on the ROW, as designed. */
.eos-watch--cinema.mb-watch .mb-w-chatstream .eos-chat-msg[data-role="host"] .eos-chat-msg__body {
  background: transparent !important;
  border-left: 0 !important;
  border-radius: 0 !important;
  padding: 0 !important;
  box-shadow: none !important;
}

.mb-watch .mb-w-chatstream .eos-chat-msg--pinned { border: 1px solid var(--accLight); }

.mb-watch .mb-w-chatstream .eos-chat-msg--mentioned-me {
  background: var(--accsoft);
  border-left: 2px solid var(--acc);
  padding-left: 6px;
}

.mb-watch .mb-w-chatstream .eos-chat-msg--tomb .eos-chat-msg__body--tomb,
.mb-watch .mb-w-chatstream .eos-chat-msg--muted { color: var(--faint); font-style: italic; }

/* reaction chips — order 2 keeps them under the message, not beside the name */
.mb-watch .mb-w-chatstream .eos-chat-msg__pills {
  order: 2;
  flex: 1 0 100%;
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  margin-top: 6px;
}

.mb-watch .mb-w-chatstream .eos-chat-msg__pills:empty { display: none; margin: 0; }

.mb-watch .mb-w-chatstream .eos-chat-pill {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  height: 23px;
  padding: 0 8px;
  border: 1px solid var(--line2);
  border-radius: 999px;
  background: var(--card);
  color: var(--body);
  font: inherit;
  font-size: 11.5px;
  font-weight: 650;
  cursor: pointer;
  transition: background var(--dur) ease, border-color var(--dur) ease, color var(--dur) ease;
}

.mb-watch .mb-w-chatstream .eos-chat-pill:hover { background: var(--soft); }

.mb-watch .mb-w-chatstream .eos-chat-pill.is-mine {
  background: var(--accsoft);
  border-color: var(--accLight);
  color: var(--tint2ink);
}

.mb-watch .mb-w-chatstream .eos-chat-pill__c { font-variant-numeric: tabular-nums; }

/* ---- the in-chat verse card ------------------------------------------------
   chat.js hydrates .eos-chat-vc when a message names a passage. Teal ground,
   the reference set as a small uppercase label, the verse itself in the serif
   the rest of the site reserves for scripture, and two quiet actions. Nothing
   here styled it before, so the card arrived unskinned. */

.mb-watch .mb-w-chatstream .eos-chat-vc { display: block; margin-top: 8px; }
.mb-watch .mb-w-chatstream .eos-chat-vc[hidden] { display: none; }

.mb-watch .mb-w-chatstream .eos-chat-vc__card {
  padding: 12px 13px;
  border-radius: 12px;
  background: var(--tint);
  border: 1px solid var(--line2);
}

.mb-watch .mb-w-chatstream .eos-chat-vc__head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 7px;
}

.mb-watch .mb-w-chatstream .eos-chat-vc__ref {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--tintink);
}

.mb-watch .mb-w-chatstream .eos-chat-vc__trans {
  height: 20px;
  padding: 0 7px;
  border: 0;
  border-radius: 5px;
  background: transparent;
  color: var(--tintink);
  font: inherit;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  opacity: .72;
  cursor: pointer;
}

.mb-watch .mb-w-chatstream .eos-chat-vc__trans:hover { opacity: 1; }

.mb-watch .mb-w-chatstream .eos-chat-vc__text {
  font-family: var(--font-serif);
  font-size: 15px;
  line-height: 1.5;
  color: var(--ink);
}

.mb-watch .mb-w-chatstream .eos-chat-vc__more { font-size: 11.5px; color: var(--muted); }

.mb-watch .mb-w-chatstream .eos-chat-vc__foot { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 10px; }

.mb-watch .mb-w-chatstream .eos-chat-vc__cta,
.mb-watch .mb-w-chatstream .eos-chat-vc__foot button {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 30px;
  padding: 0 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--card);
  color: var(--ink);
  font: inherit;
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
  transition: background var(--dur) ease;
}

.mb-watch .mb-w-chatstream .eos-chat-vc__cta:hover,
.mb-watch .mb-w-chatstream .eos-chat-vc__foot button:hover { background: var(--soft); }

/* ----------------------------------------------------------------------------
   § C9  TYPING INDICATOR
   -------------------------------------------------------------------------- */

.mb-watch .mb-w-chattyping:not([hidden]) {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 0 18px 6px;
  font-size: 11.5px;
  color: var(--muted);
}

.mb-watch .mb-w-chattyping .eos-chat-typing__dots { display: inline-flex; gap: 3px; }

.mb-watch .mb-w-chattyping .eos-chat-typing__dots span {
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--faint);
  animation: wDot 1.2s ease-in-out infinite;
}

.mb-watch .mb-w-chattyping .eos-chat-typing__dots span:nth-child(2) { animation-delay: .15s; }
.mb-watch .mb-w-chattyping .eos-chat-typing__dots span:nth-child(3) { animation-delay: .3s; }

/* ----------------------------------------------------------------------------
   § C10  THE COMPOSER WELL
   The prototype's composer block is one stage-tinted well holding the give row,
   the composer and the quick replies. Those three cannot share a wrapper —
   chat.js does chatEl.insertBefore(x, formEl), so the form must stay a direct
   child of #eos-chat — so the well is painted per element and the quick-reply
   row is ordered last, where the design puts it.
   -------------------------------------------------------------------------- */

.mb-watch .mb-w-chat > .eos-tg-give-btn,
.mb-watch .mb-w-chat > .eos-qr-row,
.mb-watch .mb-w-chat > .mb-w-composer,
.mb-watch .mb-w-chat > .mb-w-chatsignin {
  flex: 0 0 auto;
  background: var(--stage);
  border-top: 1px solid var(--line2);
}

.mb-watch .mb-w-chat > .eos-tg-give-btn ~ .eos-qr-row,
.mb-watch .mb-w-chat > .eos-tg-give-btn ~ .mb-w-composer,
.mb-watch .mb-w-chat > .eos-tg-give-btn ~ .mb-w-chatsignin,
.mb-watch .mb-w-chat > .eos-qr-row ~ .mb-w-composer,
.mb-watch .mb-w-chat > .eos-qr-row ~ .mb-w-chatsignin,
.mb-watch .mb-w-chat > .mb-w-composer ~ .mb-w-chatsignin { border-top: 0; }

/* the quick replies belong under the composer, whatever order chat.js inserts in */
.mb-watch .mb-w-chat > .eos-qr-row { order: 1; }

/* give row — clay tint, full width, 38px (dc.html:585)

   ---- LEGACY OVERRIDE ----
   chat-aurora.css:419-424 dresses this anchor as a gold 99px bar with white
   text — `background:var(--au-coral)!important; color:#fff!important;
   border-radius:99px!important` — and (0,1,0) with !important beats this
   layer's (0,3,0) without it. Because ::before paints ON TOP of the element's
   own background, the clay pill sat over the gold bar while the white label
   stayed white on cream. chat-studio.css:1155 also pushed `margin:0 14px 6px`,
   which this layer never contested, so the row was not full-bleed either.

   The pill itself is still drawn by ::before below; these !importants only
   strip aurora's fill, radius, ink, glow and studio's margin off the anchor. */
.mb-watch .mb-w-chat > .eos-tg-give-btn {
  position: relative;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 55px;
  margin: 0 !important;
  padding: 9px 10px 8px;
  background: var(--stage) !important;
  border-radius: 0 !important;
  box-shadow: none !important;
  color: var(--tint2ink) !important;
  font-size: 13px;
  font-weight: 650;
  text-decoration: none;
}

/* the label chat.js prints inherits the anchor's ink, so aurora's #fff cannot
   survive on either span */
.mb-watch .mb-w-chat > .eos-tg-give-btn .eos-tg-give-btn__lbl,
.mb-watch .mb-w-chat > .eos-tg-give-btn .eos-tg-give-btn__chev {
  color: var(--tint2ink) !important;
}

.mb-watch .mb-w-chat > .eos-tg-give-btn::before {
  content: "";
  position: absolute;
  inset: 9px 10px 8px;
  border: 1px solid var(--accLight);
  border-radius: 11px;
  background: var(--tint2);
  transition: background var(--dur) ease;
}

.mb-watch .mb-w-chat > .eos-tg-give-btn:hover::before { background: var(--accsoft); }
.mb-watch .mb-w-chat > .eos-tg-give-btn > * { position: relative; }

/* quick replies */
.mb-watch .mb-w-chat > .eos-qr-row {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  padding: 0 10px 11px;
}

.mb-watch .mb-w-chat > .eos-qr-row .eos-qr-chip {
  height: 27px;
  padding: 0 11px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--card);
  color: var(--body);
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  transition: background var(--dur) ease, transform var(--dur) ease;
}

.mb-watch .mb-w-chat > .eos-qr-row .eos-qr-chip:hover { background: var(--soft); transform: translateY(-1px); }

/* the composer keeps 7px of air above the quick replies, as the design does */
.mb-watch .mb-w-chat:has(> .eos-qr-row) > .mb-w-composer { padding-bottom: 7px; }

/* ----------------------------------------------------------------------------
   § C11  COMPOSER — flat row, shell painted behind it
   Visual order: text · photo · @ · GIF · newline · emoji · send.
   -------------------------------------------------------------------------- */

.mb-watch .mb-w-composer {
  position: relative;
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 9px 10px;
}

/* the field shell: everything except the 42px send button */
/* The WELL. It has to be a pseudo-element rather than a real wrapper, because
   chat-upgrade.js inserts the photo and GIF buttons as DIRECT CHILDREN of
   #eos-chat-form — a wrapper <div> would leave them outside the field.

   The right inset clears the send button exactly: 10px form padding + 42px
   send + 7px gap = 59px. Top matches the form's 9px, bottom its 11px — the
   form's REAL padding is § 24.4's prototype-exact 9px 10px 11px (which
   answers chat-studio.css:327-333), so the well must register against that,
   not against the plain declaration above that chat-studio was beating.
   v3.35.0: bottom 9 → 11 with the [05] fix; measured registered in the
   chatpar demo. The pointer:coarse variant below stays 61 = 10 + 44 + 7. */
.mb-watch .mb-w-composer::before {
  content: "";
  position: absolute;
  inset: 9px 59px 11px 10px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--card);
  transition: border-color var(--dur) ease, box-shadow var(--dur) ease;
}

.mb-watch .mb-w-composer:focus-within::before {
  border-color: var(--acc);
  box-shadow: 0 0 0 3px var(--accsoft);
}

.mb-watch .mb-w-composer > * { position: relative; }

/* ---- LEGACY OVERRIDE: the composer field ---------------------------------
   The prototype's composer is ONE box (dc.html:594) with the textarea naked
   inside it (dc.html:595). This layer paints that box as .mb-w-composer::before
   and keeps the input transparent. Two kept sheets dress the input as a field
   of its own, both with !important, so the page showed a bordered pill nested
   inside our shell — two fields, one inside the other:

     chat-flagship.css:127-132  .eos-chat .eos-chat-input[contenteditable]
        background/border/border-radius:20px/color   (0,3,0) !important
     watch-cinema.css:438-451   .eos-watch--cinema .eos-chat-input
        border-radius:999px / padding:8px 16px / background   (0,2,0) !important

   .eos-watch--cinema is on the page root, so both apply. Only !important can
   answer !important, so it is used here for exactly the contested properties. */
/* SPECIFICITY, not just importance. chat-flagship.css:127 is
   `.eos-chat .eos-chat-input[contenteditable="true"]` — (0,3,0) WITH
   !important. The old selector here was (0,2,0) with !important: equal
   importance, so specificity decided and flagship won every contested
   property. Measured on the live page, the field still computed
   border-radius:20px with its own border while our ::before well computed
   inset:0 and transparent — i.e. the well was never drawn and the icons
   looked stranded beside a pill.

   `.mb-watch .mb-w-composer > .mb-w-composer-in[contenteditable]` reaches
   (0,4,0) and takes it back. */
.mb-watch .mb-w-composer > .mb-w-composer-in[contenteditable],
.mb-watch .mb-w-composer-in {
  order: 0;
  flex: 1;
  min-width: 0;
  max-height: 96px;
  overflow-y: auto;
  /* 7px vertical is the prototype's textarea; the 12px left is the WELL's own
     left padding, which the field has to carry because the well is a
     pseudo-element and cannot pad its siblings. */
  padding: 7px 0 7px 12px !important;
  border: 0 !important;
  border-radius: 0 !important;
  outline: none;
  background: transparent !important;
  box-shadow: none !important;
  color: var(--ink) !important;
  font: inherit;
  font-size: 13.5px;
  line-height: 1.45;
  word-break: break-word;
}

/* watch-cinema.css:444-447 raises the field to 16px on coarse pointers to stop
   iOS zooming the page on focus. That is a platform requirement, not a style
   choice, so it is kept rather than overridden. */
@media (pointer: coarse) {
  .mb-watch .mb-w-composer-in { font-size: 16px; }
}

.mb-watch .mb-w-composer-in:empty::before {
  content: attr(data-placeholder);
  color: var(--faint);
  pointer-events: none;
}

/* ---- THE WELL HOLDS TWO CONTROLS ------------------------------------------
   Emoji and "+", nothing else. Measured on the panel this ships at: five icons
   in the well left the field 121px of a 392px panel (31%); two leave it 235px
   (60%). The other four are reached through the drawer.

   They are HIDDEN, never removed — chat-upgrade.js builds .au-attach-btn and
   .au-gif-btn itself, chat.js binds #eos-chat-nl, and the drawer forwards a
   click to each real control. display:none does not stop .click().

   The rule needs !important because chat-flagship.css and watch-cinema.css
   both size these buttons with !important of their own. */
.mb-watch .mb-w-composer > .au-attach-btn,
.mb-watch .mb-w-composer > .au-gif-btn,
.mb-watch .mb-w-composer > .mb-w-composer-at,
.mb-watch .mb-w-composer > .eos-chat-nl,
.mb-watch .mb-w-composer > .eos-chat-poll-btn {
  display: none !important;
}

.mb-watch .mb-w-composer > .mb-w-composer-plus {
  order: 5;
  /* the + turns into an x while its drawer is open */
  transition: background var(--dur-micro) ease, color var(--dur-micro) ease,
              transform var(--dur) var(--ease-out, ease);
}

.mb-watch .mb-w-composer > .mb-w-composer-plus[aria-expanded="true"] {
  transform: rotate(45deg);
  background: var(--accsoft);
  color: var(--acc);
}

/* ---- the drawer ---------------------------------------------------------- */

/* The drawer opens UPWARD — it is printed before the <form> and carries the
   composer's own order, so DOM order puts it between the stream and the text
   row. Opening downward pushed the field away from the thumb and shoved the
   quick replies off the bottom. */
.mb-watch .mb-w-chat > .mb-w-composer-drawer {
  flex: 0 0 auto;
  order: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  padding: 0 10px 10px;
  background: var(--stage);
  animation: wSlide var(--dur-enter) ease both;
}

.mb-watch .mb-w-chat > .mb-w-composer-drawer[hidden] { display: none; }

.mb-watch .mb-w-chat > .mb-w-composer-drawer button {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 32px;
  padding: 0 12px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--card);
  color: var(--body);
  font: inherit;
  font-size: 12px;
  font-weight: 650;
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--dur) ease, border-color var(--dur) ease, color var(--dur) ease;
}

.mb-watch .mb-w-chat > .mb-w-composer-drawer button:hover {
  background: var(--soft);
  border-color: var(--accLight);
  color: var(--ink);
}

.mb-watch .mb-w-chat > .mb-w-composer-drawer button:focus-visible {
  outline: 2px solid var(--acc);
  outline-offset: 1px;
}

.mb-watch .mb-w-more-gif { font-size: 11px; font-weight: 800; }
.mb-watch .mb-w-more-at  { font-size: 15px; font-weight: 700; line-height: 1; }

@media (prefers-reduced-motion: reduce) {
  .mb-watch .mb-w-chat > .mb-w-composer-drawer { animation: none; }
  .mb-watch .mb-w-composer > .mb-w-composer-plus { transition: none; }
}

/* GIF is the one lettered control: 35x30 at 11px/800 (prototype). */
.mb-watch .mb-w-composer > .au-gif-btn {
  width: 35px !important;
  padding: 0 8px !important;
  font-size: 11px !important;
  font-weight: 800 !important;
  letter-spacing: 0;
}

.mb-watch .mb-w-composer > .au-attach-btn { order: 1; }
.mb-watch .mb-w-composer > .mb-w-composer-at { order: 2; }
.mb-watch .mb-w-composer > .au-gif-btn { order: 3; }
.mb-watch .mb-w-composer > .eos-chat-nl { order: 4; }
.mb-watch .mb-w-composer > .eos-chat-emoji-btn { order: 5; }
.mb-watch .mb-w-composer > .eos-chat-send { order: 6; }

/* Every control in the well is the same 30px ghost square on --muted
   (prototype: 30x30, radius 8, transparent, --muted; GIF is 35x30 at 11px/800).
   The emoji and newline buttons were missing from this list, so chat.js's own
   sheets kept dressing emoji as a 36px filled circle sitting among the ghosts.
   Those two are contested with !important because chat-flagship.css and
   watch-cinema.css both size .eos-chat-emoji-btn that way. */
.mb-watch .mb-w-composer > .mb-w-composer-ic,
.mb-watch .mb-w-composer > .au-attach-btn,
.mb-watch .mb-w-composer > .au-gif-btn,
.mb-watch .mb-w-composer > .eos-chat-emoji-btn,
.mb-watch .mb-w-composer > .eos-chat-nl {
  flex: 0 0 auto;
  width: 30px !important;
  height: 30px !important;
  margin-bottom: 5px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0 !important;
  border-radius: 8px !important;
  background: transparent !important;
  color: var(--muted) !important;
  box-shadow: none !important;
  font: inherit;
  cursor: pointer;
  transition: background var(--dur-micro) ease, color var(--dur-micro) ease;
}

.mb-watch .mb-w-composer > .au-gif-btn {
  width: auto;
  padding: 0 8px;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: .04em;
}

.mb-watch .mb-w-composer > .mb-w-composer-at { font-size: 16px; font-weight: 700; line-height: 1; }

.mb-watch .mb-w-composer > .mb-w-composer-ic:hover,
.mb-watch .mb-w-composer > .au-attach-btn:hover,
.mb-watch .mb-w-composer > .au-gif-btn:hover { background: var(--soft); color: var(--ink); }

/* ---- LEGACY OVERRIDE: the send button ------------------------------------
   The prototype's send is a 42px clay SQUIRCLE at radius 12 with no shadow
   (dc.html:608). Two kept sheets make it a 40px gold circle with a gold glow,
   both with !important, and functions.php's dependency chain prints flagship
   after cinema so they split the spoils:

     watch-cinema.css:461-470   40px / 40px / border-radius:50% / --cn-amber
     chat-flagship.css:116-125  #F5A312 fill, #2a1e04 ink, 0 2px 10px gold glow

   Nothing here contested them and this layer never declared a box-shadow, so
   the glow was uncontested. The class stays — chat.js binds submit through it. */
.mb-watch .mb-w-composer > .mb-w-composer-send {
  order: 6;
  flex: 0 0 auto;
  width: 42px !important;
  height: 42px !important;
  margin-left: 8px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0 !important;
  border-radius: 12px !important;
  background: var(--acc) !important;
  color: var(--onacc) !important;
  box-shadow: none !important;
  cursor: pointer;
  transition: background var(--dur) ease, transform var(--dur) ease, opacity var(--dur) ease;
}

.mb-watch .mb-w-composer > .mb-w-composer-send:hover { background: var(--accHover) !important; transform: translateY(-1px); }

/* The glyph must be white ON the clay, not the near-black chat-flagship.css:118
   paints with `color: #2a1e04 !important`. Setting the button's own colour is
   not enough: the icon only follows it if it draws with currentColor, and this
   one carries its own fill.

   Each declaration is guarded on the attribute actually being present and not
   "none", so a stroked icon stays stroked and a filled icon stays filled —
   neither is converted into the other, whichever glyph chat.js renders. */
.mb-watch .mb-w-composer > .mb-w-composer-send,
.mb-watch .mb-w-composer > .mb-w-composer-send svg { color: var(--onacc) !important; }

.mb-watch .mb-w-composer > .mb-w-composer-send svg[fill]:not([fill="none"]),
.mb-watch .mb-w-composer > .mb-w-composer-send svg [fill]:not([fill="none"]) {
  fill: var(--onacc) !important;
}

.mb-watch .mb-w-composer > .mb-w-composer-send svg[stroke]:not([stroke="none"]),
.mb-watch .mb-w-composer > .mb-w-composer-send svg [stroke]:not([stroke="none"]) {
  stroke: var(--onacc) !important;
}

/* the file input chat-upgrade.js appends to the form must never take a slot */
.mb-watch .mb-w-composer > input[type="file"] { position: absolute; width: 1px; height: 1px; opacity: 0; }

/* attachment preview strip (chat-upgrade.js, inserted before the form) */
.mb-watch .mb-w-chat > .au-attach-preview {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 9px;
  margin: 0 10px 8px;
  padding: 7px 9px;
  border: 1px solid var(--line2);
  border-radius: 11px;
  background: var(--card);
  font-size: 12.5px;
  color: var(--body);
}

.mb-watch .mb-w-chat > .au-attach-preview .au-attach-preview__thumb {
  flex: 0 0 auto;
  width: 38px;
  height: 38px;
  border-radius: 8px;
  background-color: var(--soft);
  background-size: cover;
  background-position: center;
}

/* ----------------------------------------------------------------------------
   § C12  SIGNED-OUT SWAP
   -------------------------------------------------------------------------- */

.mb-watch .mb-w-chat.is-signedout > .mb-w-composer { display: none; }

.mb-watch .mb-w-chat > .mb-w-chatsignin { margin: 0; padding: 9px 10px 11px; }

.mb-watch .mb-w-chat > .mb-w-chatsignin a {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 40px;
  padding: 9px 14px;
  border: 1px dashed var(--line);
  border-radius: 11px;
  background: var(--card);
  color: var(--body);
  font-size: 13px;
  font-weight: 600;
  text-align: center;
  text-decoration: none;
  transition: background var(--dur) ease, border-color var(--dur) ease;
}

.mb-watch .mb-w-chat > .mb-w-chatsignin a:hover { background: var(--soft); border-color: var(--acc); }
.mb-watch .mb-w-chat > .mb-w-chatsignin svg { flex: 0 0 auto; color: var(--acc); }

/* ----------------------------------------------------------------------------
   § C13  Q&A MODE
   The pane is switched by platform.js (data-chat-mode="qa" ↔ data-pane="qa");
   everything inside the rail is chat.js on the real /chat/qa/* routes.
   -------------------------------------------------------------------------- */

.mb-watch .mb-w-qapane { overflow-y: auto; }

.mb-watch .mb-w-chatqa:not([hidden]) {
  display: flex;
  flex-direction: column;
  gap: 9px;
  padding: 10px;
}

.mb-watch .mb-w-qaempty {
  margin: 0;
  padding: 14px 12px;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--muted);
}

.mb-watch .mb-w-chatqa:not([hidden]) + .mb-w-qaempty { display: none; }

.mb-watch .mb-w-chatqa .eos-chat-qa__bar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 11px;
  border: 1px solid var(--line2);
  border-radius: 11px;
  background: var(--stage);
  font-size: 12px;
  font-weight: 650;
  color: var(--ink);
}

.mb-watch .mb-w-chatqa .eos-chat-qa__ico { flex: 0 0 auto; color: var(--muted); }
.mb-watch .mb-w-chatqa .eos-chat-qa__count { margin-left: auto; font-size: 11px; font-weight: 600; color: var(--muted); font-variant-numeric: tabular-nums; }

.mb-watch .mb-w-chatqa .eos-chat-qa__live {
  display: inline-flex;
  align-items: center;
  height: 17px;
  padding: 0 6px;
  border-radius: 5px;
  background: var(--accsoft);
  color: var(--acc);
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
}

.mb-watch .mb-w-chatqa .eos-chat-qa__toggle {
  height: 26px;
  padding: 0 10px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--btn2);
  color: var(--body);
  font: inherit;
  font-size: 11.5px;
  font-weight: 650;
  cursor: pointer;
  transition: background var(--dur) ease;
}

.mb-watch .mb-w-chatqa .eos-chat-qa__toggle:hover { background: var(--btn2Hover); }

/* ask box */
.mb-watch .mb-w-chatqa .eos-chat-qa__submit {
  display: flex;
  flex-direction: column;
  gap: 7px;
}

.mb-watch .mb-w-chatqa .eos-chat-qa__submit-head {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--muted);
}

.mb-watch .mb-w-chatqa .eos-chat-qa__submit-input {
  min-height: 36px;
  padding: 9px 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--card);
  color: var(--ink);
  font: inherit;
  font-size: 13px;
  line-height: 1.45;
  resize: vertical;
  outline: none;
  transition: border-color var(--dur) ease, box-shadow var(--dur) ease;
}

.mb-watch .mb-w-chatqa .eos-chat-qa__submit-input:focus {
  border-color: var(--acc);
  box-shadow: 0 0 0 3px var(--accsoft);
}

.mb-watch .mb-w-chatqa .eos-chat-qa__submit-row { display: flex; align-items: center; gap: 9px; }
.mb-watch .mb-w-chatqa .eos-chat-qa__submit-count { font-size: 11px; color: var(--faint); font-variant-numeric: tabular-nums; }

.mb-watch .mb-w-chatqa .eos-chat-qa__submit-send {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 36px;
  padding: 0 14px;
  border: 0;
  border-radius: 10px;
  background: var(--acc);
  color: var(--onacc);
  font: inherit;
  font-size: 12.5px;
  font-weight: 650;
  cursor: pointer;
  transition: background var(--dur) ease, transform var(--dur) ease;
}

.mb-watch .mb-w-chatqa .eos-chat-qa__submit-send:hover { background: var(--accHover); transform: translateY(-1px); }

/* question cards — upvote-sorted, answered ones dimmed */
.mb-watch .mb-w-chatqa .eos-chat-qa__list { display: flex; flex-direction: column; gap: 8px; }

.mb-watch .mb-w-chatqa .eos-chat-qa__item {
  display: flex;
  gap: 10px;
  padding: 11px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--card);
  animation: wSlide var(--dur-enter) ease both;
}

.mb-watch .mb-w-chatqa .eos-chat-qa__item.answered { border-color: var(--line2); opacity: .72; }
.mb-watch .mb-w-chatqa .eos-chat-qa__item.top-voted { border-color: var(--accLight); }

.mb-watch .mb-w-chatqa .eos-chat-qa__vote {
  flex: 0 0 40px;
  width: 40px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1px;
  padding: 5px 0;
  border: 1px solid var(--line2);
  border-radius: 9px;
  background: var(--stage);
  color: var(--body);
}

.mb-watch .mb-w-chatqa .eos-chat-qa__vote-btn {
  border: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  cursor: pointer;
  display: inline-flex;
}

.mb-watch .mb-w-chatqa .eos-chat-qa__vote-num { font-size: 12px; font-weight: 700; font-variant-numeric: tabular-nums; }

.mb-watch .mb-w-chatqa .eos-chat-qa__item .eos-chat-qa__vote:has(.voted) {
  border-color: var(--acc);
  background: var(--accsoft);
  color: var(--acc);
}

.mb-watch .mb-w-chatqa .eos-chat-qa__content { min-width: 0; flex: 1; }

.mb-watch .mb-w-chatqa .eos-chat-qa__content-head {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 11px;
  color: var(--muted);
}

.mb-watch .mb-w-chatqa .eos-chat-qa__who { font-weight: 650; color: var(--body); }
.mb-watch .mb-w-chatqa .eos-chat-qa__time { display: inline-flex; align-items: center; gap: 7px; }

.mb-watch .mb-w-chatqa .eos-chat-qa__answered-tick {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  height: 17px;
  padding: 0 6px;
  border-radius: 5px;
  background: var(--tint);
  color: var(--tintink);
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
}

.mb-watch .mb-w-chatqa .eos-chat-qa__q {
  margin-top: 5px;
  font-size: 13px;
  line-height: 1.45;
  color: var(--ink);
  word-break: break-word;
}

.mb-watch .mb-w-chatqa .eos-chat-qa__answer {
  margin-top: 7px;
  padding: 8px 10px;
  border-left: 2px solid var(--acc);
  border-radius: 0 9px 9px 0;
  background: var(--tint2);
  color: var(--tint2ink);
  font-size: 12.5px;
  line-height: 1.5;
}

.mb-watch .mb-w-chatqa .eos-chat-qa__answer-by { display: block; margin-top: 4px; font-size: 11px; opacity: .8; }

/* operator-only row — chat.js prints it for leadership, the panel is marked
   [data-ops] server-side by eos_live_ops_can('service_setup') */
.mb-watch .mb-w-chatqa .eos-chat-qa__admin { flex: 0 0 auto; display: flex; align-self: flex-start; gap: 5px; }

.mb-watch .mb-w-chatqa .eos-chat-qa__admin-answer,
.mb-watch .mb-w-chatqa .eos-chat-qa__admin-dismiss {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  height: 26px;
  padding: 0 10px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--btn2);
  color: var(--body);
  font: inherit;
  font-size: 11.5px;
  font-weight: 650;
  cursor: pointer;
  transition: background var(--dur) ease, color var(--dur) ease, border-color var(--dur) ease;
}

.mb-watch .mb-w-chatqa .eos-chat-qa__admin-answer:hover {
  background: var(--accsoft);
  border-color: var(--accLight);
  color: var(--tint2ink);
}

.mb-watch .mb-w-chatqa .eos-chat-qa__admin-dismiss { width: 26px; padding: 0; justify-content: center; }
.mb-watch .mb-w-chatqa .eos-chat-qa__admin-dismiss:hover { background: var(--soft); color: var(--ink); }

.mb-watch .mb-w-chatqa .eos-chat-qa__empty { margin: 0; padding: 10px 2px; font-size: 12.5px; color: var(--muted); }

/* ----------------------------------------------------------------------------
   § C14  EXTERNAL PANE FALLBACK
   -------------------------------------------------------------------------- */

.mb-watch .mb-w-chatfallback:not([hidden]) {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding: 18px 16px;
  text-align: center;
}

.mb-watch .mb-w-chatfallback p { margin: 0; font-size: 13px; line-height: 1.5; color: var(--muted); }

/* ----------------------------------------------------------------------------
   § C15  RESPONSIVE — RESPONSIVE-SPEC: below 620px the toolbar wraps, the quick
   replies scroll on one line, and every hit target clears 44px on touch.
   -------------------------------------------------------------------------- */

@media (max-width: 620px) {
  .mb-watch .mb-w-chatbar { flex-wrap: wrap; row-gap: 7px; }
  .mb-watch .mb-w-chatseg { order: 0; flex: 1 1 100%; }
  .mb-watch .mb-w-chatsegbtn { flex: 1 1 0; }
  .mb-watch .mb-w-chatbar-sp { display: none; }

  .mb-watch .mb-w-chat > .eos-qr-row {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
  }

  .mb-watch .mb-w-chat > .eos-qr-row .eos-qr-chip { flex: 0 0 auto; }
}

@media (pointer: coarse) {
  .mb-watch .mb-w-chatico,
  .mb-watch .mb-w-langpill:not([hidden]) { min-height: 44px; }
  .mb-watch .mb-w-chatsegbtn { min-height: 44px; }

  .mb-watch .mb-w-composer > .mb-w-composer-ic,
  .mb-watch .mb-w-composer > .au-attach-btn,
  .mb-watch .mb-w-composer > .au-gif-btn { width: 44px; height: 44px; margin-bottom: 0; }

  .mb-watch .mb-w-composer::before { inset: 9px 61px 11px 10px; }
  .mb-watch .mb-w-chat > .eos-qr-row .eos-qr-chip { height: 36px; }
}

/* ----------------------------------------------------------------------------
   § C16  KEYFRAMES this surface adds (wPulse / wIn / wPop / wSlide already live
   in mambo-watch.css § 12)
   -------------------------------------------------------------------------- */

@keyframes wDot {
  0%, 60%, 100% { transform: translateY(0);    opacity: .4; }
  30%           { transform: translateY(-3px); opacity: 1;  }
}

@keyframes wMsg {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}

/* ============================================================================
   § 15  THE NOTES PANEL
   ============================================================================ */

/* ----------------------------------------------------------------------------
   § 7.2  NOTES PANEL

   1:1 to the prototype's §8.4 (lines 662–809): head row with the Type|Write
   segmented switch, the scrolling format rail with its clay timestamp chip, the
   contenteditable writing stage with its ink dock, and the status bar that ends
   in the clay "Writing help" chip.

   Every selector is scoped under .mb-watch, and the mb-w-nt-* classes are
   chained through .eos-ntp so this layer out-specifies the legacy notes-*.css
   rules wherever those sheets are still enqueued — no !important anywhere.
   The contract ids (#eos-nt-editor, #eos-ntp-*) are JS hooks, not style hooks:
   the two exceptions below (#eos-ntp-inktb / #eos-ntp-inksub) are unavoidable,
   because notes-ink.js builds their children at runtime and there is no class
   on those runtime nodes to hang the shell on.
   -------------------------------------------------------------------------- */

/* Token bridge — the same move as the --bp-* bridge for the Bible panel.
   notes-pro.css declares a private GOLD palette on `.eos-watch--cinema
   .eos-notes.eos-ntp` (0,3,0), re-declares it under [data-theme="dark"]
   (0,4,0), and again inside a prefers-dark media query (0,5,0). Without a
   bridge the member's own typed headings came out bronze in light and the
   retired gold in dark. `html:root ...` reaches (0,5,1), which clears all
   three arms in either theme with no dark duplicate — the mambo tokens it
   points at already re-tone.

   --ntp-green is deliberately NOT bridged: notes-pro pairs it with a
   hard-coded teal wash on the save chip, so remapping it to --success would
   put an olive glyph on a teal ground — a new mismatch, not a fix. */
html:root .eos-watch--cinema.mb-watch .eos-notes.eos-ntp {
  --ntp-amber:      var(--acc);
  --ntp-amber-dark: var(--accHover);
  --ntp-amber-txt:  var(--tint2ink);
  --ntp-amber-glow: var(--accsoft);
  --ntp-on-amber:   var(--onacc);
  --ntp-blue:       var(--info);
  --ntp-red:        var(--live);
  --ntp-bg:         var(--card);
  --ntp-soft:       var(--soft);
  --ntp-softer:     var(--stage);
  --ntp-fg:         var(--ink);
  --ntp-fg2:        var(--body);
  --ntp-muted:      var(--muted);
  --ntp-border:     var(--line);
  --ntp-shadow:     var(--sh);
}

.mb-watch .mb-w-nt {
  display: flex;
  flex: 1;
  min-height: 0;
  flex-direction: column;
  background: var(--card);
}

/* ---- head row (prototype 663–680) ---------------------------------------- */

.mb-watch .eos-ntp .mb-w-nt-head {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 9px 10px;
  border-bottom: 1px solid var(--line2);
}

.mb-watch .eos-ntp .mb-w-nt-grow { flex: 1; }

.mb-watch .eos-ntp .mb-w-nt-seg {
  display: flex;
  gap: 2px;
  padding: 3px;
  border: 1px solid var(--line2);
  border-radius: 9px;
  background: var(--stage);
}

.mb-watch .eos-ntp .mb-w-nt-segbtn {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  height: 28px;
  padding: 0 10px;
  border: 0;
  border-radius: 7px;
  background: transparent;
  color: var(--muted);
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  transition: color var(--dur) ease, background var(--dur) ease;
}

.mb-watch .eos-ntp .mb-w-nt-segbtn:hover { color: var(--ink); }

.mb-watch .eos-ntp .mb-w-nt-segbtn.on,
.mb-watch .eos-ntp .mb-w-nt-segbtn[aria-selected="true"] {
  background: var(--card);
  color: var(--ink);
  font-weight: 650;
  box-shadow: var(--sc);
}

/* ---- ghost icon buttons (head row + format rail) -------------------------- */

.mb-watch .eos-ntp .mb-w-nt-ghost,
.mb-watch .eos-ntp .mb-w-nt-tbtn {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  padding: 0;
  border: 0;
  border-radius: 8px;
  background: transparent;
  cursor: pointer;
  transition: background var(--dur-micro) ease, color var(--dur-micro) ease, opacity var(--dur-micro) ease;
}

.mb-watch .eos-ntp .mb-w-nt-ghost { color: var(--muted); }
.mb-watch .eos-ntp .mb-w-nt-tbtn  { color: var(--body); }

.mb-watch .eos-ntp .mb-w-nt-ghost:hover,
.mb-watch .eos-ntp .mb-w-nt-tbtn:hover {
  background: var(--soft);
  color: var(--ink);
}

.mb-watch .eos-ntp .mb-w-nt-tbtn[aria-pressed="true"],
.mb-watch .eos-ntp .mb-w-nt-tbtn.on {
  background: var(--accsoft);
  color: var(--acc);
}

.mb-watch .eos-ntp .mb-w-nt-tbtn[disabled] { opacity: .38; cursor: default; }
.mb-watch .eos-ntp .mb-w-nt-tbtn[disabled]:hover { background: transparent; color: var(--body); }

/* ---- format rail (prototype 682–741) ------------------------------------- */

.mb-watch .eos-ntp .mb-w-nt-tb {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 3px;
  padding: 7px 10px;
  border-bottom: 1px solid var(--line2);
  background: var(--stage);
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;
}

/* notes-type.css:60 injects `.eos-ntp-tb::before { content:""; flex:1 1 auto }`
   as the rail's FIRST item. In the legacy markup that spacer was mirrored by a
   trailing `.grow`; this rail has none, so whenever the toolbar is not
   overflowing the whole thing was shoved to the right edge instead of starting
   against the 10px left padding as the prototype does (dc.html:675). */
.mb-watch .eos-ntp .mb-w-nt-tb::before { content: none; }

/* ---- splitter percentage readout -----------------------------------------
   Two pills either side of the grip, showing the split while you drag. Built
   by initSplitter() in mambo-watch.js; .is-resizing is on for the length of a
   drag and flashes for ~1.1s after a keyboard or double-click resize.

   .mb-w-split is position:relative, so these anchor to the grip and sit
   outside it on both sides. pointer-events:none so they never swallow the
   drag they are reporting on. */
.mb-watch .mb-w-split-pct {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 6;
  height: 20px;
  padding: 0 7px;
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--card);
  color: var(--body);
  font-size: 10.5px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  box-shadow: var(--sc);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur) ease;
}

.mb-watch .mb-w-split-pct--l { right: calc(100% + 8px); }
.mb-watch .mb-w-split-pct--r { left:  calc(100% + 8px); }

.mb-watch .mb-w-split.is-resizing .mb-w-split-pct { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .mb-watch .mb-w-split-pct { transition: none; }
}

/* ---- The rail WRAPS rather than scrolls ----------------------------------
   A DELIBERATE DEVIATION, made at the operator's request. The prototype keeps
   one non-wrapping overflow-x:auto row (dc.html:675), which is fine at its own
   proportions but not here: this toolbar carries ~790px of controls in a 392px
   panel, so more than half of them — lists, indent, timestamp, card, link,
   More and Insert scripture — sat off-screen behind a scroll almost nobody
   discovers.

   Wrapping keeps every control reachable without a scroll gesture. The five
   .mb-w-nt-div separators already group the rail (undo+style · B/I/U/S+colour ·
   lists+indent · timestamp/card/link · more+scripture), and because a wrap
   breaks at flex-item boundaries those groups stay intact as they reflow.
   row-gap gives the rows air; align-items keeps each row's controls centred. */
.mb-watch .eos-ntp .mb-w-nt-tb {
  flex-wrap: wrap;
  overflow-x: visible;
  row-gap: 4px;
}

/* A separator should never be left stranded at the end of a wrapped row. */
.mb-watch .eos-ntp .mb-w-nt-tb .mb-w-nt-div { align-self: stretch; }

.mb-watch .eos-ntp .mb-w-nt-tb::-webkit-scrollbar { height: 0; }

.mb-watch .eos-ntp .mb-w-nt-div {
  flex: 0 0 auto;
  width: 1px;
  height: 20px;
  margin: 0 4px;
  background: var(--line);
}

/* the four letterform buttons carry their meaning in the glyph itself */
.mb-watch .eos-ntp .mb-w-nt-tbtn--b { font-size: 14px; font-weight: 800; }
.mb-watch .eos-ntp .mb-w-nt-tbtn--i { font-size: 14px; font-weight: 600; font-style: italic; font-family: var(--font-serif); }
.mb-watch .eos-ntp .mb-w-nt-tbtn--u { font-size: 14px; font-weight: 600; text-decoration: underline; }
.mb-watch .eos-ntp .mb-w-nt-tbtn--s { font-size: 14px; font-weight: 600; text-decoration: line-through; }

.mb-watch .eos-ntp .mb-w-nt-select {
  flex: 0 0 auto;
  height: 30px;
  padding: 0 8px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--card);
  color: var(--ink);
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
  outline: none;
}

/* text colour: the "A" sitting on its live colour bar */
.mb-watch .eos-ntp .mb-w-nt-fg {
  flex-direction: column;
  gap: 1px;
  font-size: 13px;
  font-weight: 800;
}

.mb-watch .eos-ntp .mb-w-nt-fgA { line-height: 1; }

.mb-watch .eos-ntp .mb-w-nt-fgbar {
  width: 15px;
  height: 3px;
  border-radius: 2px;
  background: var(--ink);
}

/* the clay timestamp chip — the one accented control in the rail */
.mb-watch .eos-ntp .mb-w-nt-stamp {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  height: 30px;
  padding: 0 10px;
  border: 1px solid var(--accLight);
  border-radius: 8px;
  background: var(--tint2);
  color: var(--tint2ink);
  font-size: 12px;
  font-weight: 650;
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--dur-micro) ease;
}

.mb-watch .eos-ntp .mb-w-nt-stamp:hover { background: var(--accLight); }
.mb-watch .eos-ntp .mb-w-nt-stamp span { font-variant-numeric: tabular-nums; }

/* ---- LEGACY OVERRIDE: "More" must scroll with the rail -------------------
   notes-type.css:64-68 pins it — `.eos-ntp-tb .more { position: sticky;
   right: 0; z-index: 2; background: var(--ntp-softer);
   box-shadow: -8px 0 8px -6px var(--ntp-softer) }` — and this block declared
   no `position` at all, so sticky won by default. Its `background:
   transparent` did beat the legacy scrim, which made it worse: the rail
   scrolled visibly THROUGH the frozen label, and "Insert scripture"
   (#eos-ntp-bible-btn), the last control in the rail, came to rest underneath
   it and could not be clicked.

   In the prototype (dc.html:675) the rail is one plain overflow-x:auto row
   where every child is flex:0 0 auto and nothing is sticky. */
.mb-watch .eos-ntp .mb-w-nt-more {
  position: static;
  box-shadow: none;
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 30px;
  padding: 0 11px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--body);
  font-size: 12.5px;
  font-weight: 650;
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--dur-micro) ease, color var(--dur-micro) ease;
}

.mb-watch .eos-ntp .mb-w-nt-more:hover { background: var(--soft); color: var(--ink); }

/* the context sub-row: empty until find/replace or a breadcrumb fills it */
.mb-watch .eos-ntp .mb-w-nt-subrow {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 7px 10px;
  border-bottom: 1px solid var(--line2);
  background: var(--stage);
  font-size: 12px;
  color: var(--body);
}

.mb-watch .eos-ntp .mb-w-nt-subrow:empty { display: none; }

/* ---- the writing stage (prototype 743–779) ------------------------------- */

.mb-watch .eos-ntp .mb-w-nt-stage {
  position: relative;
  flex: 1;
  min-height: 0;
  display: flex;
}

.mb-watch .eos-ntp .mb-w-nt-edwrap {
  position: relative;
  flex: 1;
  min-width: 0;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  padding: 14px 16px;
}

.mb-watch .eos-ntp .mb-w-nt-editor {
  position: relative;
  z-index: 1;
  min-height: 100%;
  outline: none;
  font-size: 14.5px;
  line-height: 1.65;
  color: var(--ink);
  word-break: break-word;
}

/* paper ruling sits under the text, ink layers over it; notes-ink.js flips
   pointer-events on #eos-ntp-ink when Write mode is on */
.mb-watch .eos-ntp .mb-w-nt-paper,
.mb-watch .eos-ntp .mb-w-nt-ink {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  touch-action: none;
}

.mb-watch .eos-ntp .mb-w-nt-paper { z-index: 0; }
.mb-watch .eos-ntp .mb-w-nt-ink   { z-index: 2; }

.mb-watch .eos-ntp .mb-w-nt-inkring {
  position: absolute;
  z-index: 3;
  display: none;
  border: 1px solid var(--line);
  border-radius: 50%;
  pointer-events: none;
}

/* Write mode: the stage takes the inset tone and the pen cursor.

   The draw flag is a CLASS on #eos-nt-root — notes-rich.js:572 does
   `root.classList.toggle('is-draw', draw)`. The data-mode attribute it reads at
   :569 lives on the Type/Write BUTTONS, never on the root, so the
   [data-mode="draw"] halves of these selectors never matched and are gone. */
.mb-watch .eos-ntp.is-draw .mb-w-nt-edwrap { background: var(--stage); }

/* ---- ruled paper: the text sits centred in its band ----------------------
   notes-pro.css:141 rules the lined paper with a 32px band and a rule at
   31–32px, but anchors the grid with `background-position: 0 12px` while the
   editor's own text starts at its 18px padding-top. The 6px difference is
   constant, so every typed line sat low in its band and the rule cut close
   under it instead of sitting at the foot of the line box.

   Rather than hard-code a matching offset — which would break again the moment
   the padding changes, and it does change in focus mode (22px) and under 640px
   (12px) — the ruling is anchored to the CONTENT box. The grid then starts
   exactly where the first line box starts, at any padding, so each line is
   centred in its band and the rule lands under it. Same treatment for the
   dotted paper, which carries the same 16px offset. */
.mb-watch .eos-ntp .eos-ntp-editor.tpl-lined,
.mb-watch .eos-ntp .eos-ntp-editor.tpl-dotted {
  background-origin: content-box;
  background-position: 0 0;
}

.mb-watch .eos-ntp.is-draw .mb-w-nt-ink { pointer-events: auto; cursor: crosshair; }

/* ---- the floating ink dock (prototype 749–778) ---------------------------

   In the prototype the pen tools live INSIDE the canvas wrapper, which
   setNoteMode() hides outright in Type mode (dc.html:740/742, 4908) — so they
   are not on screen at all unless you are drawing. Here the dock is a sibling
   of the editor, so the mode gate has to be in CSS.

   It matters because notes-ink.js fills both rows at boot (start() → setTool),
   not on first draw, so the `:empty` guard below stops matching immediately and
   the dock floated over the note the whole time you were typing. */
.mb-watch .eos-ntp:not(.is-draw) .mb-w-nt-inkdock { display: none; }

.mb-watch .eos-ntp .mb-w-nt-inkdock {
  position: absolute;
  left: 50%;
  bottom: 14px;
  z-index: 4;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  max-width: calc(100% - 20px);
  pointer-events: none;
}

/* both rows are runtime-built by notes-ink.js, so the shell has to hang off the
   contract ids — there is no class on the nodes it injects. Gated on .is-draw:
   an ID selector outranks notes-ink.css:62's `.eos-ntp-inktb{display:none}`, so
   an ungated `display:flex` here forced the pen rows open in Type mode too. */
.mb-watch .eos-ntp.is-draw #eos-ntp-inktb,
.mb-watch .eos-ntp.is-draw #eos-ntp-inksub {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 5px;
  max-width: 100%;
  padding: 5px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--card);
  box-shadow: var(--sh);
  pointer-events: auto;
  overflow: visible;
}

/* nothing floats over the note until the pen tools actually exist */
.mb-watch .eos-ntp #eos-ntp-inktb:empty,
.mb-watch .eos-ntp #eos-ntp-inksub:empty { display: none; }

.mb-watch .eos-ntp #eos-ntp-inktb button,
.mb-watch .eos-ntp #eos-ntp-inksub button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-width: 30px;
  height: 26px;
  padding: 0 6px;
  border: 0;
  border-radius: 7px;
  background: transparent;
  color: var(--body);
  font-size: 11.5px;
  font-weight: 650;
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--dur-micro) ease, color var(--dur-micro) ease;
}

.mb-watch .eos-ntp #eos-ntp-inktb button:hover,
.mb-watch .eos-ntp #eos-ntp-inksub button:hover { background: var(--soft); }

.mb-watch .eos-ntp #eos-ntp-inktb button[aria-pressed="true"],
.mb-watch .eos-ntp #eos-ntp-inktb button.on {
  background: var(--accsoft);
  color: var(--acc);
}

/* the two chip-shaped controls (pen name, ink colour) read as wells */
.mb-watch .eos-ntp #eos-ntp-inktb select,
.mb-watch .eos-ntp #eos-ntp-inksub select {
  height: 26px;
  padding: 0 8px;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: var(--stage);
  color: var(--ink);
  font-size: 11.5px;
  font-weight: 650;
  cursor: pointer;
}

.mb-watch .eos-ntp #eos-ntp-inktb .danger:hover,
.mb-watch .eos-ntp #eos-ntp-inktb button[data-ink-clear]:hover { color: var(--live); }

/* ---- status bar (prototype 781–808) -------------------------------------- */

.mb-watch .eos-ntp .mb-w-nt-status {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 8px 10px;
  border-top: 1px solid var(--line2);
  background: var(--stage);
  font-size: 11.5px;
  color: var(--muted);
  overflow-x: auto;
}

.mb-watch .eos-ntp .mb-w-nt-fbtn {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  height: 30px;
  min-width: 30px;
  padding: 0 11px;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: var(--card);
  color: var(--body);
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--dur-micro) ease, color var(--dur-micro) ease;
}

/* the icon-only chips are square */
.mb-watch .eos-ntp .mb-w-nt-fbtn--icon { width: 30px; padding: 0; }

.mb-watch .eos-ntp .mb-w-nt-fbtn:hover { background: var(--soft); }
.mb-watch .eos-ntp .mb-w-nt-fbtn:not(.mb-w-nt-fbtn--danger):hover { color: var(--ink); }
.mb-watch .eos-ntp .mb-w-nt-fbtn--danger { color: var(--muted); }
.mb-watch .eos-ntp .mb-w-nt-fbtn--danger:hover { color: var(--live); }

.mb-watch .eos-ntp .mb-w-nt-fbtn[aria-pressed="true"] {
  background: var(--accsoft);
  border-color: var(--accLight);
  color: var(--acc);
}

/* A pressed 30px icon button was indistinguishable from an idle one: the
   token bridge above maps --ntp-amber-glow to --accsoft, and #FAEDE3 on a
   --card white chip is a ~5% tint - invisible at this size. Focus and
   privacy are MODES; a mode you cannot see you are in is how the focus-mode
   trap happened (OUTSTANDING.md § 36). Solid accent, onacc glyph. (0,5,0)
   beats the (0,4,0) base pressed rule and the (0,4,0) hover above it by
   specificity, so this block is position-independent. No !important. */
.mb-watch .eos-ntp .mb-w-nt-fbtn.mb-w-nt-fbtn--icon[aria-pressed="true"] {
  background: var(--acc);
  border-color: var(--acc);
  color: var(--onacc);
}
.mb-watch .eos-ntp .mb-w-nt-fbtn.mb-w-nt-fbtn--icon[aria-pressed="true"]:hover {
  background: var(--accHover);
  border-color: var(--accHover);
  color: var(--onacc);
}

/* word count: a ghost chip, not a bordered one */
.mb-watch .eos-ntp .mb-w-nt-words {
  flex: 0 0 auto;
  height: 28px;
  padding: 0 10px;
  border: 0;
  border-radius: 9px;
  background: transparent;
  color: var(--muted);
  font-size: 11.5px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--dur-micro) ease;
}

.mb-watch .eos-ntp .mb-w-nt-words:hover { background: var(--soft); }

/* the save chip: teal by default, clay while a write is in flight */
.mb-watch .eos-ntp .mb-w-nt-save {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 28px;
  padding: 0 11px;
  border: 1px solid transparent;
  border-radius: 999px;
  background: var(--tint);
  color: var(--tintink);
  font-size: 12px;
  font-weight: 650;
  white-space: nowrap;
}

.mb-watch .eos-ntp .mb-w-nt-savedot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--success);
}

.mb-watch .eos-ntp .mb-w-nt-save.is-saving { background: var(--tint2); color: var(--tint2ink); }
.mb-watch .eos-ntp .mb-w-nt-save.is-saving .mb-w-nt-savedot { background: var(--acc); }
.mb-watch .eos-ntp .mb-w-nt-save.is-error { background: var(--tint2); color: var(--live); }
.mb-watch .eos-ntp .mb-w-nt-save.is-error .mb-w-nt-savedot { background: var(--live); }

/* "Writing help": the clay chip that closes the bar */
.mb-watch .eos-ntp .mb-w-nt-help {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 30px;
  border: 1px solid var(--accLight);
  border-radius: 9px;
  background: var(--tint2);
  color: var(--tint2ink);
  font-size: 12.5px;
  font-weight: 650;
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--dur-micro) ease;
}

.mb-watch .eos-ntp .mb-w-nt-help:hover { background: var(--accLight); }

/* ---- popovers and menus -------------------------------------------------- */

.mb-watch .eos-ntp .mb-w-nt-pop,
.mb-watch .eos-ntp .mb-w-nt-menu {
  position: absolute;
  z-index: 40;
  display: none;
  min-width: 208px;
  max-width: calc(100% - 20px);
  padding: 10px;
  border: 1px solid var(--line);
  border-radius: 13px;
  background: var(--card);
  box-shadow: var(--sh);
  animation: mbNtPop var(--dur-pop) var(--ease);
}

.mb-watch .eos-ntp .mb-w-nt-menu { padding: 6px; }

/* `.open` IS THE CLASS THE SHIPPED SCRIPTS ACTUALLY WRITE, AND IT WAS MISSING.
   notes-rich.js:378 place() does `el.classList.add('open')`, and notes-type.js:286
   and :1027 do the same for the More menu. This sheet answered only `.is-open` and
   `.on`, so five member-facing controls — Add a link, Highlight, Insert image,
   Insert scripture and the whole More menu — were opened by the script and then
   hidden again by the rule above.

   notes-pro.css:72 `.eos-ntp-pop.open { display: block }` was supposed to catch it,
   but it is (0,2,0) against this block's (0,3,0) and loses; the nodes carry both
   class families (panel-notes.php:291/301/342/352) so both selectors match the same
   element. Adding the class the code uses costs one line and needs no !important. */
.mb-watch .eos-ntp .mb-w-nt-pop.is-open,
.mb-watch .eos-ntp .mb-w-nt-menu.is-open,
.mb-watch .eos-ntp .mb-w-nt-pop.on,
.mb-watch .eos-ntp .mb-w-nt-menu.on,
.mb-watch .eos-ntp .mb-w-nt-pop.open,
.mb-watch .eos-ntp .mb-w-nt-menu.open { display: block; }

@keyframes mbNtPop {
  from { opacity: 0; transform: translateY(6px) scale(.97); }
  to   { opacity: 1; transform: none; }
}

.mb-watch .eos-ntp .mb-w-nt-pop h4 {
  margin: 0 0 8px;
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: -.01em;
  color: var(--ink);
}

.mb-watch .eos-ntp .mb-w-nt-field {
  display: flex;
  align-items: center;
  gap: 6px;
}

.mb-watch .eos-ntp .mb-w-nt-field input,
.mb-watch .eos-ntp .mb-w-nt-field select {
  min-width: 0;
  height: 32px;
  padding: 0 10px;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: var(--stage);
  color: var(--ink);
  font-size: 12.5px;
}

.mb-watch .eos-ntp .mb-w-nt-field input { flex: 1; }
.mb-watch .eos-ntp .mb-w-nt-field select { flex: 0 0 auto; font-weight: 650; cursor: pointer; }

.mb-watch .eos-ntp .mb-w-nt-field input:focus,
.mb-watch .eos-ntp .mb-w-nt-field select:focus {
  outline: none;
  border-color: var(--acc);
  box-shadow: 0 0 0 3px var(--accsoft);
}

.mb-watch .eos-ntp .mb-w-nt-go {
  flex: 0 0 auto;
  height: 32px;
  padding: 0 12px;
  border: 0;
  border-radius: 9px;
  background: var(--acc);
  color: var(--onacc);
  font-size: 12.5px;
  font-weight: 700;
  cursor: pointer;
  transition: background var(--dur-micro) ease;
}

.mb-watch .eos-ntp .mb-w-nt-go:hover { background: var(--accHover); }

.mb-watch .eos-ntp .mb-w-nt-err {
  display: none;
  margin-top: 7px;
  font-size: 11.5px;
  font-weight: 600;
  color: var(--live);
}

/* `.show` for the same reason as `.open` above: notes-rich.js writes `.show` on the
   validation messages (:392 bad link URL, :489 bad image URL, :558 scripture not
   found) and never `.is-on`. Without this, a visitor who typed a malformed URL got
   no message at all — the control simply did nothing. */
.mb-watch .eos-ntp .mb-w-nt-err.is-on,
.mb-watch .eos-ntp .mb-w-nt-err.show { display: block; }

.mb-watch .eos-ntp .mb-w-nt-hint {
  margin-top: 7px;
  font-size: 11.5px;
  line-height: 1.45;
  color: var(--muted);
}

.mb-watch .eos-ntp .mb-w-nt-bload {
  display: none;
  margin-top: 7px;
  font-size: 11.5px;
  color: var(--muted);
}

/* And the scripture loader: notes-rich.js:543 adds `.show` before the lookup and
   :555 removes it after, so "Looking up scripture…" never once appeared. */
.mb-watch .eos-ntp .mb-w-nt-bload.is-on,
.mb-watch .eos-ntp .mb-w-nt-bload.show { display: block; }

.mb-watch .eos-ntp .mb-w-nt-bchips {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  margin-top: 8px;
}

.mb-watch .eos-ntp .mb-w-nt-bchips:empty { display: none; }

.mb-watch .eos-ntp .mb-w-nt-bchips button {
  height: 26px;
  padding: 0 9px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--stage);
  color: var(--body);
  font-size: 11.5px;
  font-weight: 600;
  cursor: pointer;
  transition: background var(--dur-micro) ease;
}

.mb-watch .eos-ntp .mb-w-nt-bchips button:hover { background: var(--soft); color: var(--ink); }

/* menu rows */
.mb-watch .eos-ntp .mb-w-nt-menu button {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  height: 34px;
  padding: 0 9px;
  border: 0;
  border-radius: 9px;
  background: transparent;
  color: var(--ink);
  font-size: 13px;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
  transition: background var(--dur-micro) ease;
}

.mb-watch .eos-ntp .mb-w-nt-menu button:hover { background: var(--soft); }
.mb-watch .eos-ntp .mb-w-nt-menu button svg { color: var(--muted); flex: 0 0 auto; }

.mb-watch .eos-ntp .mb-w-nt-lab {
  padding: 8px 9px 4px;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--muted);
}

.mb-watch .eos-ntp .mb-w-nt-md {
  height: 1px;
  margin: 5px 0;
  background: var(--line2);
}

/* swatch rows (notes-colour.js injects the buttons) */
.mb-watch .eos-ntp .mb-w-nt-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 2px 9px 8px;
}

.mb-watch .eos-ntp .mb-w-nt-row button {
  width: 22px;
  height: 22px;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 7px;
  cursor: pointer;
  transition: transform var(--dur-micro) ease, box-shadow var(--dur-micro) ease;
}

.mb-watch .eos-ntp .mb-w-nt-row button:hover { transform: translateY(-1px); box-shadow: var(--sc); }

/* ----------------------------------------------------------------------------
   PROSE — the prototype's helmet block (lines 44–52), which the brief requires
   verbatim. Without it the editor renders headings, quotes and highlights as
   plain paragraphs. The link rule is the deliberate opt-out from the page-wide
   `a { color: inherit; text-decoration: none }` reset: text a member typed has
   to look like a link.
   -------------------------------------------------------------------------- */

.mb-watch .eos-ntp [contenteditable]:empty:before {
  content: attr(data-ph);
  color: var(--faint);
  pointer-events: none;
}

.mb-watch .eos-ntp [contenteditable] h1 { font-size: 22px; font-weight: 700; letter-spacing: -.02em; margin: 18px 0 8px; }
/* colour is load-bearing: notes-pro.css paints editor headings --ntp-amber-txt,
   and the design's headings are plain ink. */
.mb-watch .eos-ntp [contenteditable] h2 { font-size: 18px; font-weight: 700; letter-spacing: -.018em; margin: 16px 0 7px; color: var(--ink); }
.mb-watch .eos-ntp [contenteditable] h3 { font-size: 15.5px; font-weight: 700; margin: 14px 0 6px; }

.mb-watch .eos-ntp [contenteditable] blockquote {
  margin: 12px 0;
  padding: 2px 0 2px 14px;
  border-left: 3px solid var(--accLight);
  color: var(--body);
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 16.5px;
}

.mb-watch .eos-ntp [contenteditable] ul,
.mb-watch .eos-ntp [contenteditable] ol { margin: 10px 0; padding-left: 22px; }
.mb-watch .eos-ntp [contenteditable] li { margin: 4px 0; }
.mb-watch .eos-ntp [contenteditable] p  { margin: 9px 0; }

.mb-watch .eos-ntp [contenteditable] mark {
  padding: 1px 3px;
  border-radius: 4px;
  background: var(--sand);
  color: var(--ink);
}

.mb-watch .eos-ntp .mb-w-nt-editor a {
  color: var(--acc);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.mb-watch .eos-ntp .mb-w-nt-editor a:hover { color: var(--acc); text-decoration-thickness: 2px; }

.mb-watch .eos-ntp [contenteditable] img {
  max-width: 100%;
  height: auto;
  border-radius: 10px;
}

/* checklist rows the notes engine writes */
.mb-watch .eos-ntp [contenteditable] ul[data-check] { list-style: none; padding-left: 4px; }
.mb-watch .eos-ntp [contenteditable] input[type="checkbox"] { accent-color: var(--acc); margin-right: 8px; }

/* v3.35.0 — focus mode no longer touches the chrome. Three rules stood here
   hiding the format rail AND the head cluster (Type/Write, Search, Outline)
   under .is-focus, citing a "behaviour report §9.2" that exists nowhere in
   the project. The feature inventory — the authority for rule 6 — specifies
   focus mode three times (:1204, :1335, :1780) as "dims everything except
   the line you are on … remembered across sessions", which is what
   notes-type.js markCaretBlock() + notes-type.css:160-161 already do with no
   help from this sheet. Because the preference persists in
   localStorage['eos-type-prefs'], the deleted rules re-trapped the member on
   every visit, with the only exit an unlabelled icon (OUTSTANDING.md § 36).
   Do not reintroduce them. */

/* privacy screen: the note blurs until it is dismissed */
.mb-watch .eos-ntp.is-private .mb-w-nt-editor { filter: blur(7px); }

/* the legacy compat trio and the kept-but-hidden info bubble take no space */
.mb-watch .eos-ntp [hidden] { display: none; }

/* ---- narrow docks and touch ---------------------------------------------- */

@media (max-width: 640px) {
  .mb-watch .eos-ntp .mb-w-nt-edwrap { padding: 12px 13px; }
  .mb-watch .eos-ntp .mb-w-nt-inkdock { bottom: 10px; max-width: calc(100% - 12px); }
}

@media (prefers-reduced-motion: reduce) {
  .mb-watch .eos-ntp .mb-w-nt-pop,
  .mb-watch .eos-ntp .mb-w-nt-menu { animation: none; }
}

/* ============================================================================
   § 16  THE BIBLE PANEL
   ============================================================================ */

/* ============================================================================
   MAMBO — WATCH · § B  BIBLE PANEL.  v3.3.0
   Appended to mambo-watch.css. Scope: .mb-watch. Prototype §8.5 (811–867).

   WHAT THIS OWNS: the Bible header, the one-row nav bar, the reading pane and
   its verse typography, the empty/recents state, the passage / translation /
   text-size popovers, the layout sheet, the hand-off card and footer — plus
   the RE-TONING of the three bands that bible-pro.js / bible-follow.js build
   at runtime (the follow banner, the selection action bar, the broadcast
   console), which the prototype draws but no template can print.

   THE TOKEN BRIDGE (§B1) IS THE LOAD-BEARING PIECE. bible-pro.css declares a
   whole private palette (--bp-*) on `.eos-watch--cinema .eos-bible`, anchored
   to the pre-mambo gold (#7E560F) and to --color-* names mambo no longer
   defines. Re-pointing those eleven customs at mambo tokens re-tones ~400
   lines of kept CSS — the follow bar, the console, the sheets, the recap — in
   one block, in both themes, without touching a single one of their rules.
   Same technique, same reasoning as mambo-watch.css § 0.

   TWO VALUES THIS SHEET CANNOT REACH, both `!important` in bible-flagship.css
   and both deliberate there, so they are documented rather than fought:
     · `.eos-bible-verse { line-height: 1.75 }` (:121) — prototype asks 1.62.
     · `.eos-bible-card-head { display:none }` (:24) — and the prototype agrees:
       the reference lives in the nav-bar chip, not above the text.
   The rebuild instead drops the legacy CLASS names flagship keys its chrome
   reclaim off (.eos-bible-brand, .eos-bible-toolbar, .eos-bible-chip,
   .eos-bible-nav, .eos-bible-result, .eos-bible-flag-btn); see panel-bible.php.

   No literal colours. No !important. No IDs as style hooks except the contract
   mounts platform.js already styles by id.
   ============================================================================ */


/* ----------------------------------------------------------------------------
   § B1  SHELL + LEGACY PALETTE BRIDGE
   -------------------------------------------------------------------------- */

.mb-watch #eos-bible {
  position: relative;              /* popovers, the layout sheet, .eos-bp-sheet */
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  font-family: var(--font);
  color: var(--ink);

  /* the reading scale the AA popover writes through data-bible-fontsize */
  --mb-w-bfs: 16.5px;
}

.mb-watch #eos-bible[data-bible-fontsize="s"]  { --mb-w-bfs: 15px; }
.mb-watch #eos-bible[data-bible-fontsize="m"]  { --mb-w-bfs: 16.5px; }
.mb-watch #eos-bible[data-bible-fontsize="l"]  { --mb-w-bfs: 18.5px; }
.mb-watch #eos-bible[data-bible-fontsize="xl"] { --mb-w-bfs: 21px; }

/* The bridge. Ties bible-pro.css's private palette to mambo's, so its own
   rules (and bible-follow.js's console, which reads the same customs) come out
   clay-and-parchment in light mode and re-tone by themselves in dark. */
/* Both arms carry .eos-watch--cinema so the compound reaches (0,4,1). At the
   plain `.mb-watch .eos-bible` weight this bridge LOST in dark mode: bible-pro
   re-declares the same customs at `[data-theme="dark"] .eos-watch--cinema
   .eos-bible` (0,4,0) and again inside a prefers-dark media query, so the whole
   panel reverted to the retired gold the moment the theme flipped. Both classes
   sit on the same root element, so the compound is safe. */
html[data-theme] .eos-watch--cinema.mb-watch .eos-bible,
html:not([data-theme]) .eos-watch--cinema.mb-watch .eos-bible {
  --bp-amber:      var(--acc);
  --bp-amber-dark: var(--accHover);
  --bp-amber-txt:  var(--tint2ink);
  --bp-amber-glow: var(--accsoft);
  --bp-on-amber:   var(--onacc);
  --bp-green:      var(--success);
  --bp-blue:       var(--info);
  --bp-red:        var(--live);
  --bp-card:       var(--card);
  --bp-soft:       var(--soft);
  --bp-softer:     var(--stage);
  --bp-fg:         var(--ink);
  --bp-fg2:        var(--body);
  --bp-muted:      var(--muted);
  --bp-border:     var(--line);
  --bp-shadow:     var(--sh);
  font-family: var(--font);
}

/* Shared bits of prototype furniture. */
.mb-watch #eos-bible .mb-w-biblesp { flex: 1; }


/* ----------------------------------------------------------------------------
   § B2  HEADER (812–820) + NAV BAR (821–848)

   Two 1px-ruled bands. The nav bar is one non-wrapping row; its children carry
   an explicit `order` because bible-follow.js inserts the operator's broadcast
   console before #eos-bible-aa, and the prototype puts it after "Read on".
   -------------------------------------------------------------------------- */

.mb-watch .mb-w-biblehead {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 9px 10px;
  border-bottom: 1px solid var(--line2);
}

.mb-watch .mb-w-biblehead__t {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  margin: 0;
  font-size: 13.5px;
  font-weight: 700;
  letter-spacing: -.01em;
  color: var(--ink);
}

.mb-watch .mb-w-biblehead__t svg { flex: none; color: var(--acc); }

.mb-watch .mb-w-bibleheadacts { display: inline-flex; align-items: center; gap: 2px; }

.mb-watch .mb-w-bibleic {
  width: 30px;
  height: 30px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  transition: background var(--dur-micro) ease, color var(--dur-micro) ease;
}

.mb-watch .mb-w-bibleic:hover { background: var(--soft); color: var(--ink); }
.mb-watch .mb-w-bibleic:focus-visible { outline: 2px solid var(--acc); outline-offset: 2px; }

/* ---- the nav row --------------------------------------------------------- */

.mb-watch #eos-bible-toolbar {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 9px 10px;
  border-bottom: 1px solid var(--line2);
  overflow-x: auto;
  scrollbar-width: none;
}

.mb-watch #eos-bible-toolbar::-webkit-scrollbar { display: none; }

.mb-watch #eos-bible-chip-ref     { order: 1; }
.mb-watch #eos-bible-chip-trans   { order: 2; }
.mb-watch #eos-bible-aa           { order: 3; }
.mb-watch #eos-bible-layout-btn   { order: 4; }
.mb-watch #eos-bible-open-site    { order: 5; }
.mb-watch #eos-bible-toolbar .eos-bf-contgl { order: 6; }
.mb-watch #eos-bible-toolbar .mb-w-biblesp  { order: 7; }
.mb-watch #eos-bible-nav          { order: 8; }

.mb-watch .mb-w-biblechip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  flex: 0 1 auto;
  min-width: 0;
  height: 32px;
  padding: 0 12px;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: var(--card);
  color: var(--ink);
  font-family: inherit;
  font-size: 13px;
  font-weight: 650;
  cursor: pointer;
  transition: background var(--dur) ease, border-color var(--dur) ease;
}

.mb-watch .mb-w-biblechip:hover { background: var(--soft); }
.mb-watch .mb-w-biblechip:focus-visible { outline: 2px solid var(--acc); outline-offset: 2px; }
.mb-watch .mb-w-biblechip svg { flex: none; color: var(--muted); }

.mb-watch .mb-w-biblechip__t {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.mb-watch .mb-w-biblechip--t {
  flex: none;
  gap: 6px;
  padding: 0 10px;
  font-size: 12.5px;
  white-space: nowrap;
}

/* 30px square icon buttons — AA, layout, prev/next, and the injected
   broadcast-console toggle, which arrives as .eos-bible-tb-btn. */
.mb-watch .eos-bible-tb-btn {
  flex: none;
  width: 30px;
  height: 30px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: transparent;
  color: var(--muted);
  font-family: inherit;
  cursor: pointer;
  transition: background var(--dur) ease, color var(--dur) ease, border-color var(--dur) ease;
}

.mb-watch .eos-bible-tb-btn:hover { background: var(--soft); color: var(--ink); }
.mb-watch .eos-bible-tb-btn:focus-visible { outline: 2px solid var(--acc); outline-offset: 2px; }
.mb-watch .eos-bible-tb-btn[aria-expanded="true"] { background: var(--soft); color: var(--ink); }

.mb-watch .mb-w-bibleaa {
  color: var(--body);
  font-size: 12px;
  font-weight: 800;
  letter-spacing: -.03em;
}

/* Operator only. bible-follow.js sets aria-pressed=true while the console is
   open and hangs a live pip off .eos-bf-contgl__pip. */
.mb-watch .eos-bf-contgl { position: relative; }
.mb-watch .eos-bf-contgl[aria-pressed="true"] {
  background: var(--accsoft);
  border-color: var(--accLight);
  color: var(--acc);
}

.mb-watch .eos-bf-contgl__pip {
  position: absolute;
  top: 3px;
  right: 3px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--live);
  opacity: 0;
  transition: opacity var(--dur) ease;
}

.mb-watch .eos-bf-contgl.live .eos-bf-contgl__pip { opacity: 1; animation: wPulse 2s ease-out infinite; }

.mb-watch .mb-w-biblereadon {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex: none;
  height: 30px;
  padding: 0 10px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: transparent;
  color: var(--body);
  font-family: inherit;
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--dur) ease, color var(--dur) ease;
}

.mb-watch .mb-w-biblereadon:hover { background: var(--soft); color: var(--ink); }
.mb-watch .mb-w-biblereadon:focus-visible { outline: 2px solid var(--acc); outline-offset: 2px; }
.mb-watch .mb-w-biblereadon svg { flex: none; }
.mb-watch .mb-w-biblereadon[hidden] { display: none; }

/* Chapter pager. platform.js:966 flips [hidden] the moment a chapter card exists. */
.mb-watch .mb-w-biblepager { display: flex; align-items: center; gap: 6px; flex: none; }
.mb-watch .mb-w-biblepager[hidden] { display: none; }


/* ----------------------------------------------------------------------------
   § B3  FOLLOW BANNER  (850–855)

   Built by bible-follow.js from GET/POST eos/v1/bible-follow, inserted directly
   under the nav bar (above the collapsed .eos-bp-tools row). `.synced` is the
   prototype's clay band; `.drift` is the paused state the prototype does not
   draw, toned down so "paused" reads as paused.
   -------------------------------------------------------------------------- */

.mb-watch .eos-bf-bar {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 9px 12px;
  border-bottom: 1px solid var(--line2);
  font-family: var(--font);
  font-size: 12px;
  font-weight: 600;
}

.mb-watch .eos-bf-bar[hidden] { display: none; }
.mb-watch .eos-bf-bar.synced { background: var(--tint2); color: var(--tint2ink); }
.mb-watch .eos-bf-bar.drift  { background: var(--stage); color: var(--muted); }

.mb-watch .eos-bf-bar .i {
  width: 12px;
  height: 12px;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.mb-watch .eos-bf-dot {
  width: 6px;
  height: 6px;
  flex: 0 0 auto;
  border-radius: 50%;
}

.mb-watch .eos-bf-dot.live { background: var(--acc); box-shadow: none; animation: wPulse 2s ease-out infinite; }
.mb-watch .eos-bf-dot.grey { background: var(--faint); animation: none; }

.mb-watch .eos-bf-txt   { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mb-watch .eos-bf-txt b { font-weight: 750; }
.mb-watch .eos-bf-sp    { flex: 1; }

.mb-watch .eos-bf-cnt {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  flex: none;
  font-size: 11.5px;
  font-weight: 600;
  color: currentColor;
  opacity: .74;
  white-space: nowrap;
}

/* One chip shape for Turn-off / Focus / Amen / Resume — the prototype's 24px
   accLight-bordered pill. */
.mb-watch .eos-bf-bar .eos-bf-icn,
.mb-watch .eos-bf-bar .eos-bf-amen,
.mb-watch .eos-bf-bar .eos-bf-resume {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  flex: none;
  height: 24px;
  padding: 0 9px;
  border: 1px solid var(--accLight);
  border-radius: 6px;
  background: transparent;
  color: currentColor;
  font-family: inherit;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0;
  cursor: pointer;
  transition: background var(--dur) ease;
}

.mb-watch .eos-bf-bar .eos-bf-icn { width: 24px; padding: 0; justify-content: center; }

.mb-watch .eos-bf-bar .eos-bf-icn:hover,
.mb-watch .eos-bf-bar .eos-bf-icn.on,
.mb-watch .eos-bf-bar .eos-bf-amen:hover,
.mb-watch .eos-bf-bar .eos-bf-resume:hover { background: var(--accLight); }

.mb-watch .eos-bf-bar .eos-bf-amen.sent { background: var(--accLight); opacity: .72; }
.mb-watch .eos-bf-bar.drift .eos-bf-resume { border-color: var(--line); }

.mb-watch .eos-bf-bar :focus-visible { outline: 2px solid var(--acc); outline-offset: 2px; }

/* Screen-reader announcer — never occupies space. */
.mb-watch .eos-bf-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Broadcast console (operator only) — kept out of the reading rhythm: a quiet
   inset card, not a second banner. Its internals are bible-follow.js's and stay
   on the bridged --bp-* palette above. */
.mb-watch .eos-bf-host {
  flex: 0 0 auto;
  margin: 10px 10px 0;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--stage);
  overflow: hidden;
}

.mb-watch .eos-bf-host[hidden] { display: none; }
.mb-watch .eos-bf-host.is-conhidden .eos-bf-condrawer { display: none; }
.mb-watch .eos-bf-host .i { fill: none; stroke: currentColor; }


/* ----------------------------------------------------------------------------
   § B4  READING PANE  (857)

   Newsreader, 16.5px, superscript verse numbers, the broadcast range washed in
   --sand. The scroll shape (wrap scrolls · result natural height · card fills
   then grows) is bible-flagship.css v2.16.9's and is NOT re-declared here.
   -------------------------------------------------------------------------- */

.mb-watch .mb-w-biblepane { position: relative; }

.mb-watch #eos-bible-result {
  padding: 14px 16px 20px;
  font-family: var(--font-serif);
  font-size: var(--mb-w-bfs);
  line-height: 1.62;
  color: var(--ink);
}

/* bible-follow.js's reading-comfort steps ride on the same scale. */
.mb-watch #eos-bible-result.eos-bf-size-1 .eos-bible-verse { font-size: calc(var(--mb-w-bfs) - 1.5px); }
.mb-watch #eos-bible-result.eos-bf-size-3 .eos-bible-verse { font-size: calc(var(--mb-w-bfs) + 2px); }
.mb-watch #eos-bible-result.eos-bf-hc .eos-bible-verse { color: var(--ink); font-weight: 500; }

.mb-watch .eos-bible-card { color: inherit; }

/* .eos-bible-card-head is display:none by flagship's reclaim, which is what the
   prototype wants: the reference lives in the nav-bar chip. These rules keep it
   presentable for any surface that does show it. */
.mb-watch .eos-bible-card-head h4 {
  margin: 0;
  font-family: var(--font);
  font-size: 14px;
  font-weight: 700;
  letter-spacing: -.015em;
  color: var(--ink);
}

.mb-watch .eos-bible-trans {
  font-family: var(--font);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .11em;
  text-transform: uppercase;
  color: var(--muted);
}

.mb-watch .eos-bible-card-tools { display: flex; align-items: center; gap: 2px; margin-left: auto; }

.mb-watch .eos-bible-card-tools button,
.mb-watch .eos-bible-card-tools a {
  width: 26px;
  height: 26px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 7px;
  background: transparent;
  color: var(--faint);
  cursor: pointer;
  transition: background var(--dur) ease, color var(--dur) ease;
}

.mb-watch .eos-bible-card-tools button:hover,
.mb-watch .eos-bible-card-tools a:hover { background: var(--soft); color: var(--ink); }

.mb-watch .eos-bible-card-body { padding: 0; color: inherit; }

.mb-watch .eos-bible-verse { color: var(--ink); }

.mb-watch .eos-bible-verse sup {
  font-family: var(--font);
  font-size: .58em;
  font-weight: 700;
  line-height: 0;
  vertical-align: super;
  margin-right: .3em;
  color: var(--acc);
  font-variant-numeric: tabular-nums;
}

/* Reading layouts — bible-flagship.js writes data-bible-layout on #eos-bible. */
.mb-watch #eos-bible[data-bible-layout="verse"] .eos-bible-verse {
  display: block;
  margin: 0 0 .35em;
  padding: 2px 4px 2px 2.2em;
  text-indent: -2.2em;
  border-radius: 6px;
}

.mb-watch #eos-bible[data-bible-layout="verse"] .eos-bible-verse:hover { background: var(--stage); }
.mb-watch #eos-bible[data-bible-layout="cont"] .eos-bible-verse { display: inline; }
.mb-watch #eos-bible[data-bible-layout="para"] .eos-bible-verse { display: inline; }

.mb-watch #eos-bible[data-bible-layout="para"] .eos-bible-verse[data-pstart="1"] {
  display: block;
  margin-top: .7em;
}

/* THE PINNED VERSE. In the prototype this is a hard-coded highlight on Hebrews
   6:19; here it is whatever range the preacher is actually broadcasting —
   bible-follow.js marks the range .eos-bf-band and its head .eos-bf-cur. */
.mb-watch .eos-bible-verse.eos-bf-band {
  background: var(--sand);
  color: var(--sandink);
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
  padding: .08em .22em;
  border-radius: 4px;
  transition: background var(--dur-crossfade) ease;
}

.mb-watch .eos-bible-verse.eos-bf-first { box-shadow: inset 2px 0 0 var(--acc); }
.mb-watch #eos-bible-result.eos-bf-focus .eos-bible-verse:not(.eos-bf-band) { opacity: .34; }

/* bible-pro.js selection + its four highlight pens (its swatches carry inline
   colours; these are the applied washes, all token-derived). */
.mb-watch .eos-bible-verse.eos-bp-sel { background: var(--accsoft); border-radius: 4px; }
.mb-watch .eos-bible-verse.eos-bp-hl-y { background: var(--sand); }
.mb-watch .eos-bible-verse.eos-bp-hl-g { background: color-mix(in srgb, var(--success) 20%, transparent); }
.mb-watch .eos-bible-verse.eos-bp-hl-b { background: color-mix(in srgb, var(--info) 20%, transparent); }
.mb-watch .eos-bible-verse.eos-bp-hl-p { background: color-mix(in srgb, var(--teal) 22%, transparent); }

.mb-watch .eos-bible-loading,
.mb-watch .eos-bible-error {
  margin: 0;
  padding: 14px 2px;
  font-family: var(--font);
  font-size: 13px;
  line-height: 1.55;
  color: var(--muted);
}

.mb-watch .eos-bible-error em { font-style: normal; font-weight: 650; color: var(--body); }

/* bible-flagship.js's chapter-progress ring. */
.mb-watch .eos-bible-ring { color: var(--acc); }
.mb-watch .eos-bible-ring .rbg { stroke: var(--line2); }
.mb-watch .eos-bible-ring .rfg { stroke: var(--acc); }


/* ----------------------------------------------------------------------------
   § B5  EMPTY / FIRST-RUN STATE

   The prototype opens on a seeded chapter. A real member opens on nothing, so
   this band carries their own recent references (platform.js, localStorage) and
   one honest sentence — and collapses entirely the moment a passage lands.
   -------------------------------------------------------------------------- */

.mb-watch .mb-w-biblerecents {
  flex: 0 0 auto;
  padding: 12px 14px;
  border-bottom: 1px solid var(--line2);
}

.mb-watch #eos-bible[data-has-passage="1"] .mb-w-biblerecents { display: none; }

.mb-watch .mb-w-biblerecents__h { display: flex; align-items: center; gap: 8px; }
.mb-watch .mb-w-biblerecents .mb-w-fieldlabel { margin: 0; }

.mb-watch .mb-w-biblerecents__x {
  margin-left: auto;
  height: 22px;
  padding: 0 8px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: transparent;
  color: var(--muted);
  font-family: inherit;
  font-size: 11px;
  font-weight: 600;
  cursor: pointer;
  transition: background var(--dur) ease, color var(--dur) ease;
}

.mb-watch .mb-w-biblerecents__x:hover { background: var(--soft); color: var(--ink); }
.mb-watch .mb-w-biblerecents__x[hidden] { display: none; }

.mb-watch .mb-w-biblequick {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 9px 0 0;
  padding: 0;
  list-style: none;
}

.mb-watch .mb-w-biblequick:empty { margin: 0; }
.mb-watch .mb-w-biblequick li { display: inline-flex; align-items: center; gap: 2px; }

.mb-watch .mb-w-biblequick .eos-bible-recent {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  height: 28px;
  padding: 0 11px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--card);
  color: var(--body);
  font-family: inherit;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  transition: background var(--dur) ease, border-color var(--dur) ease, color var(--dur) ease;
}

.mb-watch .mb-w-biblequick .eos-bible-recent:hover { background: var(--accsoft); border-color: var(--accLight); color: var(--tint2ink); }
.mb-watch .mb-w-biblequick .eos-bible-recent em { font-style: normal; font-size: 10.5px; font-weight: 700; color: var(--faint); }
.mb-watch .mb-w-biblequick .eos-bible-recent:hover em { color: var(--tint2ink); }

.mb-watch .mb-w-biblequick .eos-bible-recent-x {
  width: 22px;
  height: 22px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--faint);
  cursor: pointer;
  transition: background var(--dur) ease, color var(--dur) ease;
}

.mb-watch .mb-w-biblequick .eos-bible-recent-x:hover { background: var(--soft); color: var(--ink); }

.mb-watch .mb-w-bibleempty {
  margin: 9px 0 0;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--muted);
}


/* ----------------------------------------------------------------------------
   § B6  POPOVERS + LAYOUT SHEET

   Passage, translation and text-size all hang off the nav row. They are
   absolutely positioned so opening one never reflows the reading pane.
   -------------------------------------------------------------------------- */

.mb-watch .mb-w-biblepop {
  position: absolute;
  z-index: 8;
  top: 82px;
  left: 10px;
  right: 10px;
  max-height: calc(100% - 100px);
  display: flex;
  flex-direction: column;
  border: 1px solid var(--line);
  border-radius: 13px;
  background: var(--card);
  box-shadow: var(--sh);
  overflow: hidden;
}

.mb-watch .mb-w-biblepop[hidden] { display: none; }

.mb-watch .mb-w-biblepop__h {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 11px 12px;
  border-bottom: 1px solid var(--line2);
  background: var(--stage);
}

.mb-watch .mb-w-biblepop__h strong { font-size: 13px; font-weight: 700; color: var(--ink); }

.mb-watch .mb-w-biblepop__x {
  margin-left: auto;
  width: 26px;
  height: 26px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 7px;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  transition: background var(--dur) ease, color var(--dur) ease;
}

.mb-watch .mb-w-biblepop__x:hover { background: var(--soft); color: var(--ink); }

.mb-watch .mb-w-biblepop__b {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.mb-watch .mb-w-biblesel {
  display: grid;
  grid-template-columns: 1fr .72fr .72fr auto;
  gap: 7px;
  align-items: end;
}

.mb-watch .mb-w-biblesel label { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.mb-watch .mb-w-biblesel .mb-w-fieldlabel { margin: 0; }

.mb-watch .mb-w-biblesel select,
.mb-watch .mb-w-bibleform input {
  width: 100%;
  min-width: 0;
  height: 36px;
  padding: 0 10px;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: var(--stage);
  color: var(--ink);
  font-family: inherit;
  font-size: 13px;
}

.mb-watch .mb-w-biblesel select:focus,
.mb-watch .mb-w-bibleform input:focus {
  outline: none;
  border-color: var(--acc);
  box-shadow: 0 0 0 3px var(--accsoft);
}

.mb-watch .mb-w-biblego { height: 36px; padding: 0 14px; border-radius: 9px; font-size: 13px; }

.mb-watch .mb-w-biblerule { height: 1px; background: var(--line2); margin: 2px 0; }

.mb-watch .mb-w-bibleform { display: flex; gap: 7px; align-items: center; }

.mb-watch .mb-w-biblepicks { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px; }

.mb-watch .mb-w-biblepick {
  height: 32px;
  padding: 0 10px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--card);
  color: var(--body);
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  transition: background var(--dur) ease, border-color var(--dur) ease, color var(--dur) ease;
}

.mb-watch .mb-w-biblepick:hover { background: var(--accsoft); border-color: var(--accLight); color: var(--tint2ink); }

.mb-watch .mb-w-bibletsel {
  width: 100%;
  padding: 6px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--stage);
  color: var(--ink);
  font-family: inherit;
  font-size: 13px;
}

.mb-watch .mb-w-bibletsel:focus { outline: none; border-color: var(--acc); box-shadow: 0 0 0 3px var(--accsoft); }
.mb-watch .mb-w-bibletsel option { padding: 6px 8px; color: var(--ink); }

/* ---- text-size mini-popover, anchored under the AA button ----------------- */

.mb-watch .mb-w-biblefspop {
  position: absolute;
  z-index: 8;
  top: 82px;
  right: 10px;
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 6px;
  border: 1px solid var(--line);
  border-radius: 11px;
  background: var(--card);
  box-shadow: var(--sh);
}

.mb-watch .mb-w-biblefspop[hidden] { display: none; }

.mb-watch .mb-w-biblefs {
  width: 34px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: transparent;
  color: var(--body);
  font-family: inherit;
  font-weight: 700;
  cursor: pointer;
  transition: background var(--dur) ease, border-color var(--dur) ease, color var(--dur) ease;
}

.mb-watch .mb-w-biblefs:nth-child(1) { font-size: 11px; }
.mb-watch .mb-w-biblefs:nth-child(2) { font-size: 13px; }
.mb-watch .mb-w-biblefs:nth-child(3) { font-size: 15px; }
.mb-watch .mb-w-biblefs:nth-child(4) { font-size: 17px; }
.mb-watch .mb-w-biblefs:hover { background: var(--soft); }
.mb-watch .mb-w-biblefs.is-on { border-color: var(--acc); background: var(--accsoft); color: var(--tint2ink); }

/* ---- reading-layout sheet (bible-flagship.js toggles .is-on) -------------- */

.mb-watch .eos-bible-layout-sheet {
  position: absolute;
  z-index: 8;
  top: 82px;
  left: 10px;
  right: 10px;
  margin: 0;
  padding: 7px;
  border: 1px solid var(--line);
  border-radius: 13px;
  background: var(--card);
  box-shadow: var(--sh);
}

.mb-watch .eos-bible-layout-sheet #eos-bible-layout-opts { display: flex; flex-direction: column; gap: 4px; }

.mb-watch .mb-w-bibleopt {
  display: block;
  width: 100%;
  padding: 9px 11px;
  border: 1px solid transparent;
  border-radius: 10px;
  background: transparent;
  color: var(--body);
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  transition: background var(--dur) ease, border-color var(--dur) ease;
}

.mb-watch .mb-w-bibleopt b { display: block; margin-bottom: 2px; font-size: 12.5px; font-weight: 650; color: var(--ink); }
.mb-watch .mb-w-bibleopt span { display: block; font-size: 11.5px; line-height: 1.5; color: var(--muted); }
.mb-watch .mb-w-bibleopt:hover { background: var(--soft); }
.mb-watch .mb-w-bibleopt.is-on { border-color: var(--accLight); background: var(--accsoft); }
.mb-watch .mb-w-bibleopt.is-on b { color: var(--tint2ink); }


/* ----------------------------------------------------------------------------
   § B7  SELECTION ACTION BAR  (859–866)  +  bible-pro's other injected surfaces

   The prototype's bottom band: "N verses" · Highlight · solid-clay Send to
   notes. bible-pro.js appends it as the last child of #eos-bible, so docking it
   (rather than floating it 12px off the panel, as bible-pro.css does) puts it
   exactly where the prototype draws it.
   -------------------------------------------------------------------------- */

.mb-watch .eos-bp-bar {
  position: static;
  flex: 0 0 auto;
  align-items: center;
  gap: 6px;
  padding: 9px 10px;
  border: 0;
  border-top: 1px solid var(--line2);
  border-radius: 0;
  background: var(--stage);
  box-shadow: none;
}

.mb-watch .eos-bp-bar .cnt {
  padding-left: 4px;
  font-family: var(--font);
  font-size: 12px;
  font-weight: 600;
  color: var(--muted);
}

.mb-watch .eos-bp-bar .grp { flex: 1; display: flex; align-items: center; justify-content: flex-end; gap: 6px; }

.mb-watch .eos-bp-bar button {
  height: 32px;
  min-width: 32px;
  padding: 0 9px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--card);
  color: var(--body);
  font-family: var(--font);
  font-size: 12.5px;
  font-weight: 600;
  transition: background var(--dur) ease, border-color var(--dur) ease, color var(--dur) ease;
}

.mb-watch .eos-bp-bar button:hover { background: var(--soft); color: var(--ink); }
.mb-watch .eos-bp-bar button:active { transform: none; }

.mb-watch .eos-bp-bar button.prim {
  padding: 0 12px;
  border-color: transparent;
  background: var(--acc);
  color: var(--onacc);
  font-weight: 650;
  box-shadow: var(--sc);
}

.mb-watch .eos-bp-bar button.prim:hover { background: var(--accHover); color: var(--onacc); }
.mb-watch .eos-bp-bar .eos-bp-mi { width: 13px; height: 13px; stroke-width: 1.8; }

.mb-watch .eos-bp-hlsw {
  width: 16px;
  height: 16px;
  border: 1px solid var(--line);
  border-radius: 50%;
  outline: 0;
}

.mb-watch .eos-bp-hlsw.off { background: var(--card); border-style: dashed; border-color: var(--faint); }

/* The Search / Plans / Highlights sheet bible-pro.js reuses. */
.mb-watch .eos-bp-sheet {
  z-index: 12;
  border-radius: 0;
  background: var(--card);
}

.mb-watch .eos-bp-sheet__head { padding: 12px 14px; border-bottom: 1px solid var(--line2); background: var(--stage); }
.mb-watch .eos-bp-sheet__head h4 { font-family: var(--font); font-size: 13.5px; font-weight: 700; color: var(--ink); }

.mb-watch .eos-bp-sheet__x {
  width: 28px;
  height: 28px;
  border-radius: 8px;
  background: transparent;
  color: var(--muted);
  transition: background var(--dur) ease, color var(--dur) ease;
}

.mb-watch .eos-bp-sheet__x:hover { background: var(--soft); color: var(--ink); }
.mb-watch .eos-bp-sheet__body { padding: 12px 14px; }

/* Verse of the day — an empty-state card, collapsed by flagship's reclaim the
   moment a passage lands. */
.mb-watch .eos-bp-votd {
  margin: 10px 12px 0;
  border: 1px solid var(--line2);
  border-left: 3px solid var(--acc);
  border-radius: 12px;
  background: var(--stage);
}

.mb-watch .eos-bp-votd .l { color: var(--acc); }
.mb-watch .eos-bp-votd .r { font-family: var(--font-serif); color: var(--ink); }

/* Reading-comfort cluster bible-follow.js drops into the collapsed tools row. */
.mb-watch .eos-bf-cf { border-color: var(--line); background: var(--stage); }
.mb-watch .eos-bf-cf-btn { color: var(--muted); }
.mb-watch .eos-bf-cf-btn.on,
.mb-watch .eos-bf-cf-btn:hover { background: var(--card); color: var(--acc); }


/* ----------------------------------------------------------------------------
   § B8  HAND-OFF CARD + EXTERNAL READERS

   Neither is in the prototype's five bands — its single hand-off is the
   "Read on ↗" chip. Both stay because their ids are contracts, and both are
   kept out of the way: the card only appears once there is a passage to hand
   off, and the footer is display:none'd by bible-flagship.css's reclaim.
   -------------------------------------------------------------------------- */

.mb-watch .mb-w-bibleroute {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0;
  padding: 10px 12px;
  border: 0;
  border-top: 1px solid var(--line2);
  border-radius: 0;
  background: var(--stage);
  color: var(--ink);
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  transition: background var(--dur) ease;
}

.mb-watch .mb-w-bibleroute:hover { background: var(--soft); }
.mb-watch .mb-w-bibleroute:focus-visible { outline: 2px solid var(--acc); outline-offset: -2px; }
.mb-watch .mb-w-bibleroute[hidden] { display: none; }
.mb-watch #eos-bible:not([data-has-passage="1"]) .mb-w-bibleroute { display: none; }

.mb-watch .mb-w-bibleroute .eos-bible-route__ico { flex: none; display: inline-flex; color: var(--acc); }
.mb-watch .mb-w-bibleroute .eos-bible-route__t { flex: 1; min-width: 0; }
.mb-watch .mb-w-bibleroute .eos-bible-route__t b { display: block; font-size: 12.5px; font-weight: 650; color: var(--ink); }
.mb-watch .mb-w-bibleroute .eos-bible-route__t span { display: block; font-size: 11.5px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mb-watch .mb-w-bibleroute__go { flex: none; display: inline-flex; color: var(--faint); }

.mb-watch .mb-w-biblefoot {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  padding: 9px 12px;
  border-top: 1px solid var(--line2);
  background: var(--card);
}

.mb-watch .mb-w-biblefoot[hidden] { display: none; }
.mb-watch .mb-w-biblefoot__l { font-size: 11px; font-weight: 700; letter-spacing: .11em; text-transform: uppercase; color: var(--muted); }
.mb-watch .mb-w-biblefoot__r { display: flex; align-items: center; gap: 5px; flex-wrap: wrap; }

.mb-watch .mb-w-bibleext {
  display: inline-flex;
  align-items: center;
  height: 26px;
  padding: 0 10px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--card);
  color: var(--body);
  font-size: 11.5px;
  font-weight: 600;
  text-decoration: none;
  transition: background var(--dur) ease, border-color var(--dur) ease, color var(--dur) ease;
}

.mb-watch .mb-w-bibleext:hover { background: var(--accsoft); border-color: var(--accLight); color: var(--tint2ink); }
.mb-watch .mb-w-bibleext[hidden] { display: none; }

/* bible-flagship.js's toast, which reports a missing/disabled hand-off. */
.mb-watch .eos-bible-toast {
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--card);
  color: var(--ink);
  box-shadow: var(--sh);
  font-family: var(--font);
  font-size: 12.5px;
}


/* ----------------------------------------------------------------------------
   § B9  NARROW DOCK

   Under ~360px of panel the nav row is the first thing to hurt. The chips keep
   their height (touch), the pager stays pinned right, and the popovers go
   full-bleed rather than inheriting a 10px inset they cannot afford.
   -------------------------------------------------------------------------- */

@media (max-width: 420px) {
  .mb-watch .mb-w-biblehead,
  .mb-watch #eos-bible-toolbar { padding-left: 8px; padding-right: 8px; }
  .mb-watch .mb-w-biblechip { max-width: 42vw; }
  .mb-watch #eos-bible-result { padding: 12px 13px 18px; }
  .mb-watch .mb-w-biblepop,
  .mb-watch .eos-bible-layout-sheet { left: 6px; right: 6px; }
  .mb-watch .mb-w-biblefspop { right: 6px; }
  .mb-watch .mb-w-biblepicks { grid-template-columns: minmax(0, 1fr); }
  .mb-watch .mb-w-biblesel { grid-template-columns: 1fr 1fr; }
  .mb-watch .mb-w-biblesel .mb-w-biblego { grid-column: 1 / -1; }
}

@media (prefers-reduced-motion: reduce) {
  .mb-watch .eos-bf-dot.live,
  .mb-watch .eos-bf-contgl.live .eos-bf-contgl__pip { animation: none; }
  .mb-watch .eos-bible-verse.eos-bf-band { transition: none; }
}

/* ============================================================================
   § 17  THE PRAYER + FLOW PANELS
   ============================================================================ */

/* ============================================================================
   MAMBO watch — § 13  PRAYER PANEL + FLOW PANEL
   Fragment appended to assets/css/mambo-watch.css.

   Source of truth: "EGW Watch - Redesign.dc.html" — prayer markup 627–660
   (§8.3), flow markup 869–875 with the row builder at JS 1696–1736 (§9.4).
   Every value below is that file's, resolved through the LIGHT/DARK palettes
   (JS 1075–1104) into the mambo token set. The prototype's inline
   style-hover="…" pairs are the real :hover rules here.

   Conventions: every selector scoped under .mb-watch; tokens only; no
   !important; no id hooks; new classes carry the mb-w- prefix.

   TWO DELIBERATE DIVERGENCES, both called out again at their rules:
     1. § 13.2 supersedes the § 6 .mb-w-flowitem block — those rules draw a
        single-line row, the prototype draws a vertical timeline.
     2. The prototype's now-dot reuses @keyframes wPulse, which is the LIVE-red
        halo the live pill uses; on a clay dot ringed in --accsoft that reads as
        a copy-paste artefact, so the ring pulses in accent here instead.
   ========================================================================== */

/* ----------------------------------------------------------------------------
   § 13.0  PANEL BODY RHYTHM

   .mb-w-panelbody is a flex column with gap:10px, which would add to every
   margin the prototype specifies. These two panels lay their own vertical
   rhythm out in exact margins (h2 → 6px → sub → 12px → form → 16px → wall;
   h2 → 6px → sub → 14px → timeline), so the gap is zeroed for them only. The
   shared component itself is untouched everywhere else.
   -------------------------------------------------------------------------- */

.mb-watch [data-eos-panel="prayer"] .mb-w-panelbody,
.mb-watch [data-eos-panel="flow"] .mb-w-panelbody { gap: 0; }

.mb-watch [data-eos-panel="prayer"] .mb-w-panelsub,
.mb-watch [data-eos-panel="flow"] .mb-w-panelsub { margin: 6px 0 0; }

/* ----------------------------------------------------------------------------
   § 13.1  PRAYER PANEL (prototype 627–660)
   -------------------------------------------------------------------------- */

/* --- composer ------------------------------------------------------------- */

.mb-watch .mb-w-prayform {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 12px;
}

.mb-watch .mb-w-prayform textarea {
  width: 100%;
  padding: 11px 12px;
  border: 1px solid var(--line);
  border-radius: 11px;
  background: var(--card);
  color: var(--ink);
  font-family: inherit;
  font-size: 13.5px;
  line-height: 1.5;
  resize: vertical;
  outline: none;
  transition: border-color var(--dur) ease, box-shadow var(--dur) ease;
}

.mb-watch .mb-w-prayform textarea::placeholder { color: var(--faint); }

/* prototype style-focus="border-color:var(--acc);box-shadow:0 0 0 3px var(--accsoft)" */
.mb-watch .mb-w-prayform textarea:focus {
  border-color: var(--acc);
  box-shadow: 0 0 0 3px var(--accsoft);
}

.mb-watch .mb-w-prayrow {
  display: flex;
  align-items: center;
  gap: 8px;
}

.mb-watch .mb-w-praycheck {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 12.5px;
  color: var(--body);
  cursor: pointer;
}

/* Native control, tinted — the prototype's accent-color:var(--acc). Keeping it
   native keeps the keyboard and assistive behaviour the browser already gives. */
.mb-watch .mb-w-praycheck input {
  width: 15px;
  height: 15px;
  margin: 0;
  accent-color: var(--acc);
  cursor: pointer;
}

.mb-watch .mb-w-praycheck input:focus-visible {
  outline: 2px solid var(--acc);
  outline-offset: 2px;
}

/* .mb-w-btn is 40px / radius 11 / 13.5px; the prototype's send button is a
   shorter 36px / radius 10 / 13px. Modifier, not a redefinition. */
.mb-watch .mb-w-praysend {
  margin-left: auto;
  height: 36px;
  padding: 0 16px;
  border-radius: 10px;
  font-size: 13px;
  font-weight: 650;
}

/* --- the wall ------------------------------------------------------------- */

.mb-watch .mb-w-praylist {
  margin-top: 16px;
  display: flex;
  flex-direction: column;
  gap: 9px;
}

/* Honest empty state: this build has no prayer feed, so the wall says so
   rather than showing invented requests. */
.mb-watch .mb-w-prayempty {
  margin: 0;
  padding: 14px;
  border: 1px dashed var(--line);
  border-radius: 12px;
  background: var(--stage);
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--muted);
}

.mb-watch .mb-w-praycard {
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--card);
  padding: 13px 14px;
}

.mb-watch .mb-w-prayhead {
  display: flex;
  align-items: center;
  gap: 8px;
}

.mb-watch .mb-w-prayav {
  flex: 0 0 auto;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--tint);
  color: var(--tintink);
  font-size: 10px;
  font-weight: 700;
  line-height: 1;
}

.mb-watch .mb-w-prayav--anon {
  background: var(--soft);
  color: var(--muted);
}

.mb-watch .mb-w-prayname {
  font-size: 12.5px;
  font-weight: 700;
  color: var(--ink);
}

.mb-watch .mb-w-prayage {
  font-size: 11.5px;
  color: var(--faint);
}

.mb-watch .mb-w-praybody {
  margin: 8px 0 0;
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--body);
  overflow-wrap: anywhere;
}

/* --- "I prayed" ----------------------------------------------------------- */

.mb-watch .mb-w-praybtn {
  margin-top: 10px;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 30px;
  padding: 0 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: transparent;
  color: var(--body);
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
  transition: background var(--dur) ease, color var(--dur) ease, border-color var(--dur) ease;
}

.mb-watch .mb-w-praybtn svg { flex: 0 0 auto; }

/* prototype style-hover="background:var(--accsoft);color:var(--tint2ink);border-color:var(--accLight)" */
.mb-watch .mb-w-praybtn:hover {
  background: var(--accsoft);
  color: var(--tint2ink);
  border-color: var(--accLight);
}

.mb-watch .mb-w-praybtn:focus-visible {
  outline: 2px solid var(--acc);
  outline-offset: 2px;
}

/* Active = you already prayed (prototype §9.1 bindPray): the chip fills clay
   and the heart fills with it. */
.mb-watch .mb-w-praybtn[aria-pressed="true"] {
  background: var(--accsoft);
  border-color: var(--accLight);
  color: var(--tint2ink);
}

.mb-watch .mb-w-praybtn[aria-pressed="true"] svg path { fill: currentColor; }

.mb-watch .mb-w-praycount {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* ----------------------------------------------------------------------------
   § 13.2  FLOW PANEL — the vertical timeline (prototype JS 1696–1736)

   SUPERSEDES the .mb-w-flowitem block in § 6. Those rules render a single
   horizontal line per stage (dot · label · right-aligned time). The prototype
   is a timeline: a rail of dots joined by a 2px line, with the label and the
   time stacked in a body column beside it. Same markup contract — the class
   and child names mambo-watch.js writes are untouched — different geometry.

   One correction to the prototype's own layout: there, the rail column is a
   flex column whose width equals its dot, so the 13px "now" dot pushes that
   row's rail 2px right of every other row's and the connecting line visibly
   jogs. The rail here is a constant 13px track with the dots centred in it, so
   the line runs straight. Every other value — dot sizes, colours, gaps, type —
   is the prototype's.
   -------------------------------------------------------------------------- */

.mb-watch .mb-w-flowlist {
  margin: 14px 0 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
}

/* Grid: [13px rail] [label] [chip]  ×  [row 1 label] [row 2 time].
   Row padding 6px/16px == the prototype's body padding. */
.mb-watch .mb-w-flowitem {
  position: relative;
  display: grid;
  grid-template-columns: 13px minmax(0, auto) minmax(0, 1fr);
  grid-template-rows: auto auto;
  align-items: center;
  padding: 6px 0 16px;
  color: var(--body);
  /* neutralise the § 6 row-level line-through; it belongs on the label */
  text-decoration: none;
  font-weight: 400;
}

/* The rail. Starts below the dot (dot bottom + the prototype's 5px) and runs
   to the foot of the row; the last stage has no line under it. */
.mb-watch .mb-w-flowitem::before {
  content: "";
  position: absolute;
  left: 5.5px;
  top: 26px;
  bottom: 0;
  width: 2px;
  background: var(--line2);
}

.mb-watch .mb-w-flowitem.is-now::before { top: 28px; }

.mb-watch .mb-w-flowitem:last-child::before { content: none; }

/* --- dots ----------------------------------------------------------------- */

/* upcoming: 9px hollow outline */
.mb-watch .mb-w-flowitem .dot {
  grid-column: 1;
  grid-row: 1 / span 2;
  justify-self: center;
  align-self: start;
  width: 9px;
  height: 9px;
  margin-top: 6px;
  border: 2px solid var(--line);
  border-radius: 50%;
  background: transparent;
  box-shadow: none;
  animation: none;
}

/* done: filled faint, no ring */
.mb-watch .mb-w-flowitem.is-done .dot {
  border: 0;
  background: var(--faint);
}

/* now: 13px clay, ringed in --accsoft, pulsing */
.mb-watch .mb-w-flowitem.is-now .dot {
  width: 13px;
  height: 13px;
  margin-top: 4px;
  border: 0;
  background: var(--acc);
  box-shadow: 0 0 0 3px var(--accsoft);
  animation: mbwFlowPulse 2s ease-out infinite;
}

/* --- body ----------------------------------------------------------------- */

.mb-watch .mb-w-flowitem .lbl {
  grid-column: 2;
  grid-row: 1;
  min-width: 0;
  margin-left: 12px;
  font-size: 13.5px;
  font-weight: 600;
  line-height: 1.35;
  color: var(--ink);
  overflow-wrap: anywhere;
}

.mb-watch .mb-w-flowitem.is-now .lbl { font-weight: 700; }

.mb-watch .mb-w-flowitem.is-done .lbl {
  color: var(--muted);
  text-decoration: line-through;
  text-decoration-color: var(--faint);
}

.mb-watch .mb-w-flowitem .when {
  grid-column: 2 / -1;
  grid-row: 2;
  margin: 3px 0 0 12px;
  font-size: 11.5px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

/* ON NOW chip — text comes through as "On now", uppercased here. */
.mb-watch .mb-w-flownow {
  grid-column: 3;
  grid-row: 1;
  justify-self: start;
  align-self: center;
  margin-left: 8px;
  display: inline-flex;
  align-items: center;
  height: 19px;
  padding: 0 7px;
  border-radius: 5px;
  background: var(--acc);
  color: var(--onacc);
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: .07em;
  text-transform: uppercase;
  white-space: nowrap;
}

/* Empty state — the panel with no flow configured for the service. */
.mb-watch .mb-w-flowempty {
  padding: 14px;
  border: 1px dashed var(--line);
  border-radius: 12px;
  background: var(--stage);
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--muted);
}

/* ----------------------------------------------------------------------------
   § 13.3  MOTION

   The prototype hangs @keyframes wPulse on the now-dot, but wPulse is the
   LIVE-red halo the live pill uses — on a clay dot ringed in --accsoft that is
   a copy-paste artefact, not an intent. This keyframe holds the 3px --accsoft
   ring steady and breathes an --accLight halo out past it.
   -------------------------------------------------------------------------- */

@keyframes mbwFlowPulse {
  0%   { box-shadow: 0 0 0 3px var(--accsoft), 0 0 0 3px var(--accLight); }
  70%  { box-shadow: 0 0 0 3px var(--accsoft), 0 0 0 11px transparent; }
  100% { box-shadow: 0 0 0 3px var(--accsoft), 0 0 0 3px transparent; }
}

@media (prefers-reduced-motion: reduce) {

  .mb-watch .mb-w-flowitem.is-now .dot {
    animation: none;
    box-shadow: 0 0 0 3px var(--accsoft);
  }

  .mb-watch .mb-w-prayform textarea,
  .mb-watch .mb-w-praybtn { transition: none; }
}

/* ===  end § 13  =========================================================== */

/* ============================================================================
   § 18  THE GIVE PANEL + in-chat pinned / announcement cards
   ============================================================================ */

/* ============================================================================
   MAMBO — WATCH § 6b.  GIVE PANEL + CHAT PINNED / ANNOUNCEMENT CARDS.  v3.2.1
   Appended to mambo-watch.css. Scope: .mb-watch. Tokens only, no !important.

   Sources of truth:
     Give panel ......... prototype 877–912 (§8.7) + runtime paintGive() 5834–5851
     Pinned banner ...... prototype 515–524 (chatPinRef)
     Announcement card .. prototype JS 4953 (the sand in-list card)

   Note on the fund pill: the STATIC markup snapshot paints the selected pill
   accsoft/acc, but paintGive() runs on init and repaints it solid —
   background var(--acc), colour var(--onacc), border var(--acc). The runtime
   state is what a member sees, so that is what is reproduced here.
   ============================================================================ */

/* ----------------------------------------------------------------------------
   § 6b.1  GIVE PANEL

   The shared .mb-w-panelbody stacks with gap:10px; the prototype's Give body
   spaces itself with per-child margins instead. .mb-w-givebody switches the gap
   off for THIS body only (the shared class is untouched) so the 16/7/14/12/10
   rhythm lands exactly.
   -------------------------------------------------------------------------- */

.mb-watch .mb-w-givebody { gap: 0; }

.mb-watch .mb-w-givebody .mb-w-panelsub  { margin: 6px 0 0; line-height: 1.5; }
.mb-watch .mb-w-givebody .mb-w-fieldlabel { margin: 16px 0 7px; }
.mb-watch .mb-w-givebody .mb-w-formnote   { margin: 10px 0 0; line-height: 1.5; }

/* Fund pills --------------------------------------------------------------- */

.mb-watch .mb-w-fundrow {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.mb-watch .mb-w-fund {
  height: 32px;
  padding: 0 13px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--card);
  color: var(--body);
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
  transition: background var(--dur) ease, border-color var(--dur) ease, color var(--dur) ease;
}

.mb-watch .mb-w-fund.is-on {
  border-color: var(--acc);
  background: var(--acc);
  color: var(--onacc);
}

/* Amount grid -------------------------------------------------------------- */

.mb-watch .mb-w-amtgrid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 6px;
}

.mb-watch .mb-w-amt {
  height: 44px;
  border: 1px solid var(--line);
  border-radius: 11px;
  background: var(--card);
  color: var(--ink);
  font-size: 15px;
  font-weight: 700;
  cursor: pointer;
  transition: background var(--dur) ease, border-color var(--dur) ease,
              color var(--dur) ease, transform var(--dur) ease;
}

.mb-watch .mb-w-amt:hover { transform: translateY(-2px); }

.mb-watch .mb-w-amt.is-on {
  border-color: var(--acc);
  background: var(--accsoft);
  color: var(--tint2ink);
}

.mb-watch .mb-w-amt--other {
  border-style: dashed;
  background: transparent;
  color: var(--muted);
  font-size: 13px;
  font-weight: 600;
}

/* "Other" clears the amount rather than latching one, so it never wears the
   selected skin even though the shared JS marks it .is-on. */
.mb-watch .mb-w-amt--other.is-on {
  border-color: var(--line);
  background: transparent;
  color: var(--muted);
}

.mb-watch .mb-w-amt--other:hover {
  transform: none;
  background: var(--soft);
  color: var(--ink);
}

/* Gift Aid ----------------------------------------------------------------- */

.mb-watch .mb-w-giftaid {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  margin-top: 14px;
  padding: 11px 12px;
  border: 1px solid var(--line2);
  border-radius: 11px;
  background: var(--stage);
  cursor: pointer;
}

.mb-watch .mb-w-giftaid input {
  flex: 0 0 auto;
  width: 15px;
  height: 15px;
  margin: 1px 0 0;
  accent-color: var(--acc);
  cursor: pointer;
}

.mb-watch .mb-w-giftaid span {
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--body);
}

/* Submit + footnote --------------------------------------------------------- */

.mb-watch .mb-w-givego {
  width: 100%;
  height: 46px;
  margin-top: 12px;
  border-radius: 12px;
  font-size: 14.5px;
  font-weight: 700;
  text-decoration: none;
}

.mb-watch .mb-w-givego:hover { transform: translateY(-2px); }

/* ----------------------------------------------------------------------------
   § 6b.2  CHAT — "PINNED BY HOST" BANNER

   Mount: #eos-chat-pin (chat.js renderPinStrip() writes .eos-chat-pin__lbl /
   .eos-chat-pin__txt, toggles .eos-chat-pin--tomb and the [hidden] attribute;
   the X is #eos-chat-pin-x.eos-chat-pin__x). The id is used as the hook because
   chat.css/chat-studio.css/chat-aurora.css stay enqueued and carry
   [data-theme="dark"]-prefixed rules for this element — a class-only selector
   would tie with them on specificity and win or lose by print order.
   chat.css's `.eos-chat-pin[hidden]{display:none!important}` still governs
   visibility, so no display rule here can leak the strip when it is empty.
   -------------------------------------------------------------------------- */

.mb-watch #eos-chat-pin {
  flex: 0 0 auto;
  display: flex;
  align-items: flex-start;
  gap: 9px;
  margin: 9px 10px 0;
  padding: 11px 12px;
  border: 1px solid var(--line2);
  border: 1px solid color-mix(in srgb, var(--tintink) 14%, transparent);
  border-radius: 11px;
  background: var(--tint);
  cursor: pointer;
  transition: background var(--dur) ease;
}

.mb-watch #eos-chat-pin .eos-chat-pin__ico {
  flex: 0 0 auto;
  display: inline-flex;
  margin-top: 2px;
  color: var(--tintink);
}

.mb-watch #eos-chat-pin .eos-chat-pin__col {
  min-width: 0;
  flex: 1;
  display: flex;
  flex-direction: column;
}

.mb-watch #eos-chat-pin .eos-chat-pin__lbl {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--tintink);
  opacity: .72;
}

.mb-watch #eos-chat-pin .eos-chat-pin__txt {
  margin-top: 4px;
  font-size: 13px;
  line-height: 1.45;
  color: var(--tintink);
}

.mb-watch #eos-chat-pin .eos-chat-pin__x {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--tintink);
  opacity: .6;
  cursor: pointer;
  transition: opacity var(--dur) ease;
}

.mb-watch #eos-chat-pin .eos-chat-pin__x:hover { opacity: 1; background: transparent; }

/* Tombstone: chat.js flips this on when the pinned message is deleted and the
   strip is about to auto-clear. It must stop reading as a live host notice. */
.mb-watch #eos-chat-pin.eos-chat-pin--tomb {
  border-color: var(--line2);
  background: var(--stage);
}

.mb-watch #eos-chat-pin.eos-chat-pin--tomb .eos-chat-pin__ico,
.mb-watch #eos-chat-pin.eos-chat-pin--tomb .eos-chat-pin__lbl,
.mb-watch #eos-chat-pin.eos-chat-pin--tomb .eos-chat-pin__txt,
.mb-watch #eos-chat-pin.eos-chat-pin--tomb .eos-chat-pin__x {
  color: var(--muted);
}

/* ----------------------------------------------------------------------------
   § 6b.3  CHAT — ANNOUNCEMENT CARD

   Mount: .eos-ann-bar, injected by chat.js announcementBar() into #eos-chat
   immediately before #eos-chat-stream, from EOS_CONFIG.chatAnnouncement
   {label,message,url,v}. Children: __ico (speaker glyph), __col > __lbl + __msg,
   __cta ("Tap to read →"), __x (dismiss, stores the version in localStorage).

   The prototype's card lives inside the message list with `margin:4px 0`; the
   real one is a banner above the list, so it takes the pinned banner's
   `9px 10px 0` inset instead of running edge to edge. Everything else — sand
   fill, 16% sandink hairline, uppercase label, 13px/1.45 message, underlined
   action link, wSlide entrance — is the prototype's.
   -------------------------------------------------------------------------- */

.mb-watch #eos-chat .eos-ann-bar {
  flex: 0 0 auto;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 9px;
  margin: 9px 10px 0;
  padding: 10px 11px;
  border: 1px solid var(--line2);
  border: 1px solid color-mix(in srgb, var(--sandink) 16%, transparent);
  border-radius: 11px;
  background: var(--sand);
  cursor: pointer;
  animation: wSlide .22s ease both;
}

.mb-watch #eos-chat .eos-ann-bar:hover { background: var(--sand); }

.mb-watch #eos-chat .eos-ann-bar__ico {
  flex: 0 0 auto;
  display: inline-flex;
  margin-top: 1px;
  color: var(--sandink);
}

.mb-watch #eos-chat .eos-ann-bar__col {
  min-width: 0;
  flex: 1;
  display: flex;
  flex-direction: column;
}

.mb-watch #eos-chat .eos-ann-bar__lbl {
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--sandink);
  opacity: .72;
}

.mb-watch #eos-chat .eos-ann-bar__msg {
  margin-top: 3px;
  font-size: 13px;
  line-height: 1.45;
  color: var(--sandink);
}

/* The CTA is a sibling of __col in the real markup; the wrap + 23px indent
   (14px glyph + 9px gap) puts it under the message exactly as the prototype
   places its action link.

   Order matters here. chat.js emits ico → col → cta → x, so a full-width CTA
   in source order pushes the dismiss button onto a third line and the card
   grows to 125px with a stray × floating under the link. Ordering the CTA
   last keeps row one as ico | message | ×, with the link beneath — the
   prototype's two-row card, 94px. */
.mb-watch #eos-chat .eos-ann-bar__cta {
  order: 1;
  flex: 1 0 100%;
  margin: 6px 0 0 23px;
  font-size: 12px;
  font-weight: 650;
  color: var(--sandink);
  text-decoration: underline;
}

.mb-watch #eos-chat .eos-ann-bar__x {
  order: 0;
  margin-left: auto;
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--sandink);
  opacity: .6;
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  transition: opacity var(--dur) ease;
}

.mb-watch #eos-chat .eos-ann-bar__x:hover { opacity: 1; background: transparent; }

/* ============================================================================
   § 19  THE HOST CONSOLE
   ============================================================================ */

/* ----------------------------------------------------------------------------
   § 6.7  HOST PANEL (operator console)  — appended to mambo-watch.css

   The prototype's §8.8 column: a scrolling stack of stage-tinted cards, each
   opened by an uppercase label strip. Rendered only for leadership (the partial
   returns before printing when eos_live_ops_can('service_setup') is false), so
   nothing here ever reaches a member's stylesheet-resolved DOM.

   Every value is the prototype's, resolved through the mambo palette. Two
   deliberate substitutions, both because a hard #fff would invert wrongly in
   dark: the live button's label and the switch knob use --onscreen, the token
   that is #F4F1EC in BOTH themes precisely because it sits on a dark ground.

   Reuses without redefining: .mb-w-panelbody, .mb-w-paneltitle, .mb-w-panelsub.
   -------------------------------------------------------------------------- */

.mb-watch .mb-w-hostbody { gap: 14px; }

/* ---- header ---- */

.mb-watch .mb-w-hosthead {
  display: flex;
  align-items: center;
  gap: 9px;
}

.mb-watch .mb-w-hostic {
  flex: 0 0 auto;
  width: 30px;
  height: 30px;
  border-radius: 9px;
  background: var(--tint2);
  color: var(--tint2ink);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.mb-watch .mb-w-hosthead-t { min-width: 0; flex: 1; }
.mb-watch .mb-w-hosthead .mb-w-panelsub { margin: 2px 0 0; font-size: 12px; }

/* ---- the card ---- */

.mb-watch .mb-w-hostcard {
  flex: 0 0 auto;
  border: 1px solid var(--line2);
  border-radius: 13px;
  background: var(--stage);
  overflow: hidden;
}

.mb-watch .mb-w-hostcard-head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 11px 13px;
  border-bottom: 1px solid var(--line2);
}

.mb-watch .mb-w-hostlabel {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--muted);
}

.mb-watch .mb-w-hostcard-body {
  padding: 12px 13px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.mb-watch .mb-w-hostcard-body--tight { gap: 9px; }

.mb-watch .mb-w-hostnote {
  margin: 0;
  font-size: 12px;
  line-height: 1.5;
  color: var(--muted);
}

.mb-watch .mb-w-hostempty {
  margin: 0;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--muted);
}

.mb-watch .mb-w-hostrow {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.mb-watch .mb-w-hostrow--split { flex-wrap: nowrap; }

/* ---- 1 · broadcast ---- */

.mb-watch .mb-w-hostchip {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 22px;
  padding: 0 9px;
  border: 1px solid var(--line2);
  border-radius: 999px;
  background: var(--card);
  font-size: 11px;
  font-weight: 650;
  color: var(--body);
}

.mb-watch .mb-w-hostchip.is-live { color: var(--live); }

.mb-watch .mb-w-hostgo {
  flex: 1 1 auto;
  min-width: 130px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 40px;
  padding: 0 15px;
  border: 0;
  border-radius: 11px;
  background: var(--live);
  color: var(--onscreen);
  font-size: 13.5px;
  font-weight: 650;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: filter var(--dur) ease, background var(--dur) ease;
}

.mb-watch .mb-w-hostgo:hover { filter: brightness(1.06); }

.mb-watch .mb-w-hostgo.is-live {
  background: var(--ink);
  color: var(--card);
}

.mb-watch .mb-w-hostrec {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 40px;
  padding: 0 14px;
  border: 1px solid var(--line);
  border-radius: 11px;
  background: var(--card);
  color: var(--ink);
  font-size: 13px;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--dur) ease;
}

.mb-watch .mb-w-hostrec:hover { background: var(--soft); }

.mb-watch .mb-w-hostdot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--faint);
  transition: background var(--dur) ease;
}

.mb-watch .mb-w-hostrec.is-recording .mb-w-hostdot { background: var(--live); }

/* ---- 2 · on screen ---- */

.mb-watch .mb-w-hostfield {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.mb-watch .mb-w-hostfield-t {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--body);
}

.mb-watch .mb-w-hostfield-t--block {
  display: block;
  margin-bottom: 7px;
}

.mb-watch .mb-w-hostinputrow {
  display: flex;
  gap: 7px;
}

.mb-watch .mb-w-hostinput {
  flex: 1;
  min-width: 0;
  height: 38px;
  padding: 0 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--card);
  color: var(--ink);
  font: inherit;
  font-size: 13.5px;
  outline: none;
  transition: border-color var(--dur) ease, box-shadow var(--dur) ease;
}

.mb-watch .mb-w-hostinput:focus {
  border-color: var(--acc);
  box-shadow: 0 0 0 3px var(--accsoft);
}

.mb-watch .mb-w-hostset,
.mb-watch .mb-w-hostpost {
  flex: 0 0 auto;
  height: 38px;
  padding: 0 15px;
  border-radius: 10px;
  font-size: 13px;
  font-weight: 650;
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--dur) ease;
}

.mb-watch .mb-w-hostset {
  border: 0;
  background: var(--acc);
  color: var(--onacc);
}

.mb-watch .mb-w-hostset:hover { background: var(--accHover); }

.mb-watch .mb-w-hostpost {
  border: 1px solid var(--line);
  background: var(--card);
  color: var(--ink);
}

.mb-watch .mb-w-hostpost:hover { background: var(--soft); }

/* ---- 3 · on the picture ---- */

.mb-watch .mb-w-hostmoderow {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.mb-watch .mb-w-hostmode {
  height: 32px;
  padding: 0 12px;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: var(--card);
  color: var(--body);
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
  transition: background var(--dur-micro) ease, border-color var(--dur-micro) ease, color var(--dur-micro) ease;
}

.mb-watch .mb-w-hostmode:hover { background: var(--soft); }

.mb-watch .mb-w-hostmode.is-on,
.mb-watch .mb-w-hostmode[aria-pressed="true"] {
  border-color: var(--acc);
  background: var(--acc);
  color: var(--onacc);
}

.mb-watch .mb-w-hostspot,
.mb-watch .mb-w-hostshower {
  flex: 1 1 auto;
  min-width: 132px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 38px;
  padding: 0 13px;
  border-radius: 10px;
  font-size: 13px;
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--dur) ease, border-color var(--dur) ease;
}

.mb-watch .mb-w-hostspot {
  border: 1px solid var(--line);
  background: var(--card);
  color: var(--ink);
  font-weight: 600;
}

.mb-watch .mb-w-hostspot:hover { background: var(--soft); }

.mb-watch .mb-w-hostshower {
  border: 1px solid var(--accLight);
  background: var(--tint2);
  color: var(--tint2ink);
  font-weight: 650;
}

.mb-watch .mb-w-hostshower:hover { border-color: var(--acc); background: var(--accsoft); }

/* ---- 4 + 5 · switch lists ---- */

.mb-watch .mb-w-hostlist { padding: 4px 13px 12px; }

.mb-watch .mb-w-hostitem {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 10px 0;
  border-bottom: 1px solid var(--line2);
}

.mb-watch .mb-w-hostitem:last-child { border-bottom: 0; }

.mb-watch .mb-w-hostitem-t { min-width: 0; flex: 1; }

.mb-watch .mb-w-hostitem-n {
  display: block;
  font-size: 13px;
  font-weight: 650;
  color: var(--ink);
}

.mb-watch .mb-w-hostitem-d {
  display: block;
  margin-top: 2px;
  font-size: 12px;
  color: var(--muted);
}

/* a row whose backend switch does not exist yet: visibly unavailable, never
   pretending to save (see the catalogue note in panel-host.php) */
.mb-watch .mb-w-hostitem.is-await .mb-w-hostitem-n { color: var(--body); }
.mb-watch .mb-w-hostitem.is-await .mb-w-switch { opacity: .5; cursor: not-allowed; }

/* the spring switch — 44×26 track, 20px knob travelling 3px → 21px */
.mb-watch .mb-w-switch {
  flex: 0 0 auto;
  position: relative;
  width: 44px;
  height: 26px;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: var(--line);
  cursor: pointer;
  transition: background var(--dur-enter) var(--spring);
}

.mb-watch .mb-w-switch-knob {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--onscreen);
  box-shadow: var(--sc);
  transition: left var(--dur-enter) var(--spring);
}

.mb-watch .mb-w-switch[aria-checked="true"] { background: var(--acc); }
.mb-watch .mb-w-switch[aria-checked="true"] .mb-w-switch-knob { left: 21px; }

.mb-watch .mb-w-switch:focus-visible {
  outline: 2px solid var(--acc);
  outline-offset: 2px;
}

/* ---- 6 · order of service ---- */

.mb-watch .mb-w-hostpos {
  margin-left: auto;
  font-size: 11.5px;
  font-weight: 650;
  color: var(--body);
}

.mb-watch .mb-w-hostflownow {
  margin: 0;
  font-size: 13.5px;
  font-weight: 650;
  color: var(--ink);
}

.mb-watch .mb-w-hostprev,
.mb-watch .mb-w-hostnext {
  flex: 1;
  height: 38px;
  border-radius: 10px;
  font-size: 13px;
  cursor: pointer;
  transition: background var(--dur) ease, filter var(--dur) ease, opacity var(--dur) ease;
}

.mb-watch .mb-w-hostprev {
  border: 1px solid var(--line);
  background: var(--card);
  color: var(--ink);
  font-weight: 600;
}

.mb-watch .mb-w-hostprev:hover:not(:disabled) { background: var(--soft); }

.mb-watch .mb-w-hostnext {
  border: 0;
  background: var(--ink);
  color: var(--card);
  font-weight: 650;
}

.mb-watch .mb-w-hostnext:hover:not(:disabled) { filter: brightness(1.12); }

.mb-watch .mb-w-hostprev:disabled,
.mb-watch .mb-w-hostnext:disabled {
  opacity: .45;
  cursor: default;
}

/* ---- 7 · attendance ---- */

.mb-watch .mb-w-hoststats {
  display: flex;
  gap: 9px;
  flex-wrap: wrap;
}

.mb-watch .mb-w-hoststat {
  flex: 1 1 auto;
  min-width: 96px;
  padding: 10px 12px;
  border: 1px solid var(--line2);
  border-radius: 10px;
  background: var(--card);
}

.mb-watch .mb-w-hoststat b {
  display: block;
  font-size: 19px;
  font-weight: 700;
  letter-spacing: -.03em;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.mb-watch .mb-w-hoststat span {
  font-size: 11.5px;
  color: var(--muted);
}

.mb-watch .mb-w-hostexport {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 38px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--card);
  color: var(--ink);
  font-size: 13px;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--dur) ease;
}

.mb-watch .mb-w-hostexport:hover { background: var(--soft); }

/* ---- motion opt-out ---- */

@media (prefers-reduced-motion: reduce) {
  .mb-watch .mb-w-switch,
  .mb-watch .mb-w-switch-knob { transition: none; }
}


/* =============================================================================
   SPOTLIGHT PICK MODE                                              v3.19.0

   [16] — the host button now RAISES a spotlight instead of only clearing one.
   Nothing in the theme could put a message on the picture before this: both
   POSTs in assets/js (mambo-watch-host.js and spotlight.js) sent { clear: true }
   and nothing ever sent a message, while the route had accepted msgId/name/text
   all along.

   The operator presses "Spotlight a message", the stream becomes a field of
   targets, and one click puts that message on the picture. The affordance has to
   read instantly on a live service, so it is a border and a lift rather than a
   colour wash alone — an operator glancing at a second monitor must see that the
   stream is in a different mode.
   ========================================================================== */

.mb-watch .mb-w-hostspot.is-picking {
  border-color: var(--acc);
  background: var(--accsoft);
  color: var(--acc);
}

/* The clear action, kept as its own control. Quieter than the raise, because
   raising is the thing an operator reaches for during a service. */
.mb-watch .mb-w-hostspotx {
  height: 34px;
  padding: 0 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: transparent;
  color: var(--muted);
  font: inherit;
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
  transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease),
              background var(--dur) var(--ease);
}

.mb-watch .mb-w-hostspotx:hover {
  border-color: var(--line2);
  background: var(--soft);
  color: var(--ink);
}

.mb-watch .mb-w-hostspotx:focus-visible {
  outline: 2px solid var(--acc);
  outline-offset: 2px;
}

/* ---- the stream, while a message is being chosen ---- */

.mb-watch .eos-chat-stream.is-mb-spotpick {
  cursor: crosshair;
}

/* Every message becomes a target. The rule is scoped to the pick class, so the
   stream is untouched at every other moment. */
.mb-watch .eos-chat-stream.is-mb-spotpick .eos-chat-msg {
  border-radius: 10px;
  outline: 1px solid transparent;
  outline-offset: 2px;
  transition: outline-color var(--dur) var(--ease), background var(--dur) var(--ease),
              transform var(--dur-pop) var(--spring);
}

.mb-watch .eos-chat-stream.is-mb-spotpick .eos-chat-msg:hover,
.mb-watch .eos-chat-stream.is-mb-spotpick .eos-chat-msg:focus-within {
  outline-color: var(--acc);
  background: var(--accsoft);
  transform: translateY(-1px);
}

/* The tools a message normally reveals on hover would compete with the target
   affordance and could be clicked by mistake while picking. */
.mb-watch .eos-chat-stream.is-mb-spotpick .eos-chat-actions,
.mb-watch .eos-chat-stream.is-mb-spotpick .eos-chat-react-bar,
.mb-watch .eos-chat-stream.is-mb-spotpick .eos-cn-mtools {
  pointer-events: none;
  opacity: .35;
}

@media (prefers-reduced-motion: reduce) {
  .mb-watch .eos-chat-stream.is-mb-spotpick .eos-chat-msg {
    transition: outline-color var(--dur-instant) linear, background var(--dur-instant) linear;
  }
  .mb-watch .eos-chat-stream.is-mb-spotpick .eos-chat-msg:hover,
  .mb-watch .eos-chat-stream.is-mb-spotpick .eos-chat-msg:focus-within {
    transform: none;
  }
}

/* =============================================================================
   PRAYER — THE JUST-SENT CARD                                      v3.19.0

   [35]. The prototype (dc.html:4881-4892) prepends a confirmation card the moment
   a request is sent: accsoft ground, accLight border, a tick line reading "Sent to
   the intercession team", and the viewer never leaves the broadcast. The build had
   no such state — `.mb-w-praycard` (5954) was the only card rule in the sheet.

   The card carries role="status", so a screen-reader user is told the request went
   without having to go looking for it.
   ========================================================================== */

.mb-watch .mb-w-praycard--sent {
  border-color: var(--accLight);
  background: var(--accsoft);
  animation: mbPraySent .38s cubic-bezier(.16, .84, .44, 1) both;
}

.mb-watch .mb-w-praycard--sent .mb-w-prayav {
  background: var(--acc);
  color: var(--onacc);
}

.mb-watch .mb-w-praysentnote {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 7px;
  font-size: 12px;
  font-weight: 600;
  /* --body, not --muted: this is the confirmation that someone's request was
     received, which is not fine print. */
  color: var(--body);
}

@keyframes mbPraySent {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .mb-watch .mb-w-praycard--sent { animation: none; }
}

/* =============================================================================
   OFF-AIR STAGE — ARRANGEMENT                                     v3.20.0

   Dennis: "the features in this area are poorly arranged and positioned and
   sized. fix them."

   MEASURED, NOT GUESSED. In a harness carrying this sheet and the real off-air
   markup, all three action labels reported TWO client rects each — every button
   was breaking its own label mid-word ("REMIND / ME", "ADD TO / CALENDAR"),
   because `.eos-oa-btn` inherited `white-space: normal`. Tall ragged buttons then
   pushed the row to wrap, which is why one button sat orphaned on a second line.

   The row is not made narrower by wrapping the words — it is made uglier. With
   the labels held on one line the three buttons measure ~498px including gaps,
   which fits the content column, so the row resolves itself.
   ========================================================================== */

/* THE ROOT CAUSE. A button label is a label, not a paragraph. */
.mb-watch .eos-oa-btn {
  white-space: nowrap;
}

/* A little more room than 520px so the three buttons sit on one line at the
   width the player actually gets, without the column becoming a wide band of
   text over the poster. */
.mb-watch .eos-player-offair-content {
  max-width: 620px;
}

/* Consistent sizing: the buttons were free-height and grew when their labels
   wrapped. Height is now fixed and the icon is not allowed to shrink. */
.mb-watch .eos-oa-actions {
  align-items: center;
  row-gap: 10px;
}

.mb-watch .eos-oa-btn > svg {
  flex: 0 0 auto;
  width: 16px;
  height: 16px;
}

/* The quick links inside "While you wait" are the same control at a smaller
   scale; they were inheriting the same wrap. */
.mb-watch .eos-oa-quick .eos-oa-btn {
  justify-content: flex-start;
  white-space: nowrap;
}

/* Narrow players cannot fit three buttons on a line at any font size. Let them
   stack cleanly and fill the column rather than wrap into a ragged 2 + 1. */
@media (max-width: 620px) {
  .mb-watch .eos-oa-actions {
    flex-direction: column;
    align-items: stretch;
  }
  .mb-watch .eos-oa-actions .eos-oa-btn {
    justify-content: center;
    width: 100%;
  }
}

/* =============================================================================
   [17] ONE REPLAY RAIL, NOT TWO

   Dennis: "remove the area in red bound from the page. its conflicting with the
   one below it."

   The hub prints a "Recent services" strip AND template-parts/watch/replay-rail.php
   prints "Recent replays" below the fold — the same content twice, one above the
   other. The prototype has exactly ONE replay list (dc.html:1032-1037,
   replayRailRef); hubRef closes at dc.html:447 with no replay markup in it at all.

   The markup is left alone and the strip is hidden here rather than deleted,
   because EOS_Hub_Settings still owns the `replays` toggle and its admin screen,
   and the legacy theme still renders it. This is the mambo layer stating that
   this design has one rail — the bottom one, which is the prototype's.
   ========================================================================== */

.mb-watch .eos-hub-strip:has(.eos-hub-replays) { display: none; }

/* :has() is unsupported in a few older engines, so the same suppression is
   stated a second way. .eos-hub-replays is only ever inside that strip. */
.mb-watch .eos-hub-replays { display: none; }

/* =============================================================================
   OFF-AIR STAGE — WHAT THE watch-hub PURGE LEFT BEHIND        v3.22.0

   Dennis, twice: the off-air area is "poorly arranged and positioned and sized",
   and after v3.20.0 "the problem was still not fixed".

   HE WAS RIGHT, AND MY v3.20.0 FIX WAS MEASURED AGAINST THE WRONG THING. I sized
   the action row in a harness that loaded only the mambo sheets, so it fell back
   to system-ui and reported the three buttons at 482px. The live page loads
   Figtree, where the same three measure ~630px — past the 620px column I had
   just set, so they still wrapped 2 + 1. Fitting a row by guessing a pixel width
   is the mistake; the row now gets room instead of a number.

   THE FLOATING THUMBNAIL WAS MY OWN PURGE. watch-hub.css hid the "While you
   wait" block in two places — line 297 and, with !important, line 540:

       .eos-player-offair .eos-oa-wait { display: none !important; }

   Purging eos-watch-hub removed that decision and the block appeared for the
   first time, which is the stray poster sitting over the countdown. The
   prototype's off-air stage is the pill, the title, the countdown, the date and
   the actions — nothing else — so the decision is restated here rather than the
   block being restyled into a design that never had it.
   ========================================================================== */

/* ---- the row gets room, not a guessed width ---------------------------- */

/* The prose stays at a readable measure; the ACTIONS may use the stage. This is
   font-independent, so a different face or a longer translation cannot push a
   button onto a second row again. */
.mb-watch .eos-player-offair-content {
  max-width: min(940px, 100%);
}

.mb-watch .eos-oa-title,
.mb-watch .eos-oa-when,
.mb-watch .eos-player-offair-content > p {
  max-width: 620px;
}

.mb-watch .eos-oa-actions {
  width: 100%;
  flex-wrap: wrap;
}

/* ---- restore the decision the purge removed ---------------------------- */
.mb-watch .eos-player-offair .eos-oa-wait { display: none; }

/* ---- and the [hidden] guards it also removed ---------------------------
   watch-hub.css owned `[hidden]` rules for these, and purging it left them
   governed only by the UA sheet — which any author `display` rule outranks.
   Restated so a hidden popover or a cleared error cannot paint permanently.
   Same trap as .eos-chat-pin[hidden], which the cascade analysis flagged. */
.mb-watch .eos-hub-pop[hidden],
.mb-watch .eos-oa-pop__err[hidden] { display: none; }

@media (max-width: 620px) {
  .mb-watch .eos-oa-actions { flex-direction: column; align-items: stretch; }
  .mb-watch .eos-oa-actions .eos-oa-btn { justify-content: center; width: 100%; }
}

/* =============================================================================
   REPLAY RAIL — THE GAP ABOVE IT                                  v3.23.0

   Dennis: "the space as seen in the red mark is too much. reduce it a bit.
   ensure proper spacing."

   TWO REASONS IT GREW.

   1. The original rule reads
        padding-top: calc(96px - clamp(14px, 1.6vw, 20px) - 6px)
      and its comment explains the 6px as "the kept watch-redesign.css adds a 6px
      margin to this element". That sheet is no longer kept — mambo_purge_watch()
      dequeues eos-watch-redesign — so the subtraction now removes 6px that
      nothing contributes. Small, but the arithmetic is describing a page that no
      longer exists, and a stale calc is how a gap drifts.

   2. The 96px was chosen against a LIVE stage, where the side dock is a tall
      column beside the player and the rail needs air to separate two dense
      blocks. OFF AIR the dock is hidden (.mb-watch.is-offair .eos-side), so the
      same 96px sits under a short meta block with nothing beside it and reads as
      a void — which is the state Dennis screenshotted.

   The target drops to 64px, and to 36px off air where there is no dock to
   balance. The grid gap is still subtracted because it genuinely contributes;
   the phantom 6px is not.
   ========================================================================== */

.mb-watch .eos-watch-replays {
  padding-top: calc(64px - clamp(14px, 1.6vw, 20px));
}

.mb-watch.is-offair .eos-watch-replays {
  padding-top: calc(36px - clamp(14px, 1.6vw, 20px));
}

/* The heading sits closer to its own cards than to whatever precedes it, so the
   group reads as one block rather than a floating title. */
.mb-watch .eos-watch-replays .eos-section-head {
  margin-bottom: 10px;
}

/* =============================================================================
   21. THE HUB REGION — findings [18] [20] [21] [22] [52] [53]     v3.25.0

   Five of these six are the same root cause: `watch-hub.css` is dequeued
   (inc/mambo-enqueue.php:602-604) and rules it owned were never ported. That is
   the port-before-purge rule, caught after the fact. Every size below is the
   prototype's, read out of `EGW Watch - Redesign.dc.html`, not invented.
   ========================================================================== */

/* ---- 21.1 [20] THE PER-CONTROL POPOVER ANCHOR ---------------------------
   The prototype anchors each menu to its OWN control, not to the row
   (dc.html:366/370 for calendar, 380/384 for QR): a `position: relative;
   display: inline-flex` wrapper per control, with the pop at
   `left: 0; top: calc(100% + 8px)`. The calendar already ships its wrapper
   (hub.php:78, `<span data-hub-cal …>`); the QR pair are bare siblings, so the
   template gains a matching `data-hub-qrwrap` in this same pass.

   This is also what makes watch-hub.js:144's inline `left` correct rather than
   merely overridden — see the note on `.eos-hub-pop` above. */
.mb-watch .eos-hub-actions [data-hub-cal],
.mb-watch .eos-hub-actions [data-hub-qrwrap] {
  position: relative;
  display: inline-flex;
}

/* ---- 21.2 [22] THE GLYPHS THAT HAVE NO SIZE AT ALL ----------------------
   Not flex-shrink, and not a wrong width — these SVGs have NO size in either
   layer. hub.php prints `<svg viewBox="0 0 24 24">` with no width/height at
   :150 and :154 (pulse chips), :51 (scripture pill) and :81-82 (calendar menu
   rows), and the global reset removes the replaced-element fallback that would
   otherwise give them a box: platform.css:2114 `svg { height: auto }` and
   parent/global.css:34. So they compute to 0 wide.

   This is the identical pattern the comment above `.eos-hub-btn > svg` records
   as measured-invisible on the live page for the six action buttons; these are
   the three families that were missed. watch-hub.css:65 and :118 used to size
   the pulse and pop glyphs and went with the purge. The scripture pill was
   never sized in EITHER layer — a genuine gap, not a purge loss.

   Prototype sizes, per family: 14px pulse (dc.html:420/424/428), 13px pill
   (dc.html:346), 17px menu row (dc.html:372/375). `flex: 0 0 auto` is the
   second guard, because all three containers are flex and a correctly sized
   glyph can still be squeezed below its width inside a tight chip. */
.mb-watch .eos-hub-pulse > span > svg {
  flex: 0 0 auto;
  width: 14px;
  height: 14px;
  color: var(--muted);
}

.mb-watch .eos-hub-pill > svg {
  flex: 0 0 auto;
  width: 13px;
  height: 13px;
}

.mb-watch .eos-hub-pop a > svg,
.mb-watch .eos-hub-pop button > svg {
  flex: 0 0 auto;
  width: 17px;
  height: 17px;
  color: var(--muted);
}

/* ---- 21.3 [21] THE QR POPOVER INTERIOR ---------------------------------
   watch-hub.css:119-122 owned all four of these selectors, so after the purge
   the QR pop inherited the 232px menu geometry meant for the calendar list and
   printed its caption at inherited body size. The prototype (dc.html:384-386)
   is a pop that HUGS its code: 14px padding, 15px radius, no min-width, a
   150x150 white plate at 9px radius, and an 11.5px muted caption capped at
   172px.

   DELIBERATELY NOT PORTED — watch-hub.css:120's `padding: 10px` on the plate.
   The generated image already carries its own 8px quiet zone: watch-hub.js:213
   calls `createImgTag(4, 8)` and vendor-qrcode.js computes
   `size = moduleCount * cellSize + margin * 2`. A second ring would push the
   plate to 170px and double-quiet the code. That ring existed only because the
   legacy pop sat on a dark ground; this one sits on var(--card). */
.mb-watch .eos-hub-pop--qr {
  /* 150px plate + 2x14px padding. NOT `min-width: 0`, which is what I first wrote and
     what measuring caught: the pop is absolutely positioned, so it shrink-wraps to
     fit-content, and platform.css:2114's unscoped `img { max-width: 100% }` then resolves
     the plate against a width that does not exist yet. The percentage fell back to the
     caption's 172px cap and the plate rendered 106x150 instead of 150x150 — a QR code
     squashed out of square is a QR code a phone cannot read. A definite width breaks the
     cycle. */
  min-width: 178px;
  padding: 14px;
  border-radius: 15px;
  text-align: center;
}

/* The plate keeps a literal dark ink on a literal white ground, because
   watch-hub.js:208/:216 falls back to `box.textContent = location.host` when the
   QR vendor is missing, and that text has to stay readable in either theme. */
.mb-watch .eos-hub-pop--qr .qrbox {
  display: inline-block;
  overflow: hidden;
  border-radius: 9px;
  background: #fff;
  color: #17150F;
  font-size: 12.5px;
  line-height: 1.4;
}

/* watch-hub.js:215 strips the generated img's width/height attributes, so the
   box can only come from here. `pixelated` because the natural size is
   moduleCount*4 + 16 — 132-164px depending on the URL — and smooth-scaling that
   up to 150 softens the module edges a scanner has to read. */
.mb-watch .eos-hub-pop--qr .qrbox img,
.mb-watch .eos-hub-pop--qr .qrbox canvas {
  display: block;
  width: 150px;
  height: 150px;
  /* Belt for the same trap the min-width above fixes: platform.css:2114 sets
     `max-width: 100%` on every img in the document, and a QR code must stay square
     whatever box it lands in. */
  max-width: none;
  image-rendering: pixelated;
}

.mb-watch .eos-hub-pop--qr .cap {
  margin: 10px auto 0;
  max-width: 172px;
  font-size: 11.5px;
  line-height: 1.45;
  color: var(--muted);
}

/* ---- 21.4 [52] UP-NEXT ROWS HAVE NO GAP --------------------------------
   `.eos-hub-strip`'s own gap separates its heading from this wrapper, one level
   up — it never reaches the rows inside it, so with the shipped upnext_count of
   2 the two rows stacked flush against each other. The prototype puts them in a
   flex column at 9px, 11px below the label (dc.html:404). `.eos-hub-next` is a
   live token this sheet never mentioned: only watch-hub.css styled it, and that
   sheet is dequeued. */
.mb-watch .eos-hub-next {
  display: flex;
  flex-direction: column;
  gap: 9px;
}

/* ---- 21.5 [18] THE ACTION ROW IS NEUTRAL -------------------------------
   The prototype's row is five neutral outline controls — Prayer, Testimony,
   Share, Add to calendar, Invite via QR (dc.html:356/359/362/367/381), every one
   on var(--card). It has no filled accent slab, and no Give: Give lives in the
   top nav (dc.html:72) and as a side-panel tab (dc.html:475).

   The build's row ships a sixth button, Give, and it is the row's only filled
   accent slab (hub.php:71) — so it reads as the primary action of the hub.

   WHAT THIS DOES AND DOES NOT DO. It neutralises the FILL, so the row matches
   the prototype's visual language. It does NOT hide the button, because that
   would remove a working entry point, and whether Give keeps a place in the hub
   is Dennis's call, not a re-skin decision. The `btn_give` toggle in
   EOS_Hub_Settings already exists if he wants it gone. */
.mb-watch .eos-hub-actions .eos-hub-btn--gold {
  background: var(--card);
  border-color: var(--line);
  color: var(--ink);
  font-weight: 600;
}
.mb-watch .eos-hub-actions .eos-hub-btn--gold:hover { background: var(--soft); }

/* ---- 21.6 [44] RECLAIM THE 1060-1100 BAND ------------------------------
   Moving mambo's own stacked query down to 1059.98 is only half the fix, because
   a SECOND sheet collapses this layout independently: responsive.css:25 opens at
   `max-width: 1100px` and sets `.eos-watch { grid-template-columns: 1fr }` plus
   `.eos-side { position: static !important; margin-top: 24px }` at :30-38. That
   sheet is still enqueued on every page (functions.php:214) and is not a
   candidate for purging — it carries the site's nav collapse.

   So the desktop shell has to be restated across the recovered band. The
   `!important` on position is not decoration and not a shortcut: it is the only
   way to answer an author `!important` in a sheet that has to stay. Everything
   else here wins on ordinary specificity and is written without it.

   1060 is the Watch-only breakpoint the responsive spec already reserves; the
   .98 is how "below 1060" is expressed against a `min-width: 1060px` partner so
   the two cannot both match at a fractional zoom width. */
@media (min-width: 1060px) and (max-width: 1100px) {
  .mb-watch {
    grid-template-columns: minmax(0, 1fr) 5px var(--panelW);
  }

  /* v3.32.0 — `:not(.mb-w-nostick)` added, NOT a new !important. § 26 turns stickiness
     off on the few shells where the stage row has no slack to reserve for the replay
     rail, and it does that by putting `mb-w-nostick` on the root. Without narrowing
     this selector the `!important` here would keep the dock sticky in that band and the
     overlap would come back at exactly the widths § 26 exists to protect. Measured:
     `position` stayed "sticky" at 1080px wide even with the class present, until this
     selector was retargeted. */
  .mb-watch:not(.mb-w-nostick) .eos-side {
    position: sticky !important;
    top: 78px;
    /* v3.34.0 — the same substitution as § 6. This band is LATER in the sheet
       than § 6, so without it --panelH dies silently across a 40px-wide range
       of widths and the handle stops working there and nowhere else. */
    height: var(--panelH, calc(100vh - 100px));
    max-height: var(--panelH, calc(100vh - 100px));
    min-height: 0;
    margin-top: 0;
  }

  .mb-watch .mb-w-split { display: block; }
}

/* ============================================================================
   § 20  CAST TO TV
   ============================================================================

   The stage bar's third chip, between Ambient glow and Studio — the prototype's
   own slot (dc.html:130) and the one § 2's comment at :257-259 already names.

   The chip does not exist in the markup: mambo-watch.js initCast() creates it,
   and only when the stage is a real <video> that exposes a device picker. On
   the shipped default provider (YouTube, an <iframe>) nothing here matches
   anything, which is the intended outcome — the control degrades to ABSENT,
   never to a dead button.

   THE ON-STATE COSTS NOTHING HERE. The chip carries .eos-cn-ibtn, so the
   accsoft / accLight / acc triple at :252-257 already paints .is-on — the same
   three values the prototype writes inline at dc.html:2403-2405. Only the
   wrapper, the popover, the connecting state and the QR box are new.

   The wrapper is the § 21 "per-control wrapper" the note at :853/:897 asks for:
   .eos-hub-pop is position:absolute with left:0 / top:calc(100% + 8px)
   (:893-908), so it needs a positioned parent of its own or it resolves against
   the wrong box. Ours is that parent, so no inline left is ever written.
   -------------------------------------------------------------------------- */

.mb-w-castwrap {
  position: relative;
  display: inline-flex;
  align-items: center;
}

/* Connecting: dimmed, not hidden, and never clickable twice. The chip keeps its
   width so the toolbar does not jump between "Cast to TV" and "Connecting…". */
.mb-watch .mb-w-cast.is-connecting {
  opacity: .62;
  cursor: progress;
}

.mb-watch .mb-w-cast.is-connecting > svg {
  animation: mbwCastSpin 1.1s linear infinite;
  transform-origin: 50% 50%;
}

.mb-watch .mb-w-cast[disabled] { pointer-events: none; }

/* The popover inherits .eos-hub-pop's card, radius, shadow and row styling
   (:893-931); only the width and the two text elements are ours. */
.mb-watch .mb-w-castpop {
  min-width: 268px;
  max-width: min(320px, calc(100vw - 32px));
}

.mb-watch .mb-w-casth {
  padding: 6px 11px 7px;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--muted);
}

.mb-watch .mb-w-castnote {
  margin: 0;
  padding: 0 11px 8px 42px;
  font-size: 11.5px;
  line-height: 1.5;
  color: var(--muted);
}

.mb-watch .mb-w-castrule {
  height: 1px;
  margin: 5px 7px;
  background: var(--line2);
}

.mb-watch .mb-w-castqr {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 7px;
  margin: 2px 7px 4px;
  padding: 11px;
  border-radius: 11px;
  border: 1px solid var(--line2);
  background: var(--stage);
}

.mb-watch .mb-w-castqr img,
.mb-watch .mb-w-castqr canvas {
  width: 132px;
  height: 132px;
  image-rendering: pixelated;
  border-radius: 6px;
  background: #fff;
}

.mb-watch .mb-w-casturl {
  font-size: 11px;
  font-weight: 600;
  color: var(--body);
  word-break: break-all;
  text-align: center;
}

/* The live region: announced, never seen, never focusable. */
.mb-w-castsr {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

@keyframes mbwCastSpin {
  to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
  .mb-watch .mb-w-cast.is-connecting > svg { animation: none; }
  .mb-watch .mb-w-castpop { animation: none; }
}

@media (max-width: 620px) {
  /* :1825 already collapses .eos-cn-ibtn labels here, so the chip is a glyph and
     its name comes from the aria-label initCast() keeps in step with the state.
     The popover is anchored to a chip that is now ~40px wide, so let it grow
     leftwards instead of pushing the page sideways. */
  .mb-watch .mb-w-castpop {
    left: auto;
    right: 0;
    min-width: 232px;
  }
}

/* =============================================================================
   § 22  THE CHAT CASCADE PORT — what chat-aurora.css and chat-flagship.css
         were the LAST owners of                                    (Step 1)

   Both sheets are dequeued in mambo_purge_watch(). Between them they carried
   151 !important lines and 17 findings — but they were also the only skin in
   the theme for eleven components that chat-upgrade.js and chat.js build on
   every watch page. Purging without this block does not re-skin those
   components, it un-skins them, and in two cases un-HIDES them:

     chat-aurora.css:527   .au-gif-pop { display: none }      <- body-mounted,
     chat-aurora.css:615   .au-lightbox { display: none }     <- never removed

   That is the .eos-oa-wait trap again (v3.22.0): a purge must carry the
   FUNCTIONAL rules across, not only the colours. Each block below states which
   line it replaces and, where the property is load-bearing, why.

   The prototype has no GIF picker markup, no thread drawer and no lightbox, so
   those three are drawn in the prototype's own popover language — chatPop()
   at dc.html:3506 is `border-radius:15px; background:var(--card);
   border:1px solid var(--line2)` over `box-shadow:0 2px 6px rgba(0,0,0,.05),
   0 26px 60px -26px rgba(0,0,0,.42)`, animating with wPop — rather than
   invented from nothing or carried over in aurora's coral.
   ========================================================================== */

/* ---- 22.1  ATTACHMENT PREVIEW — the five children mambo never covered ------
   mambo-watch.css:3897/3911 already own .au-attach-preview and its __thumb.
   These five are chat-upgrade.js:164-171 and had no rule outside aurora.
   __meta's `min-width:0` and __name's ellipsis clamp are what stop a long
   filename from pushing the remove button off the strip. ---------------------*/

.mb-watch .mb-w-chat > .au-attach-preview .au-attach-preview__meta {
  min-width: 0;
  flex: 1;
}

.mb-watch .mb-w-chat > .au-attach-preview .au-attach-preview__name {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.mb-watch .mb-w-chat > .au-attach-preview .au-attach-preview__sub {
  font-size: 11px;
  color: var(--muted);
}

/* The upload progress bar. Without a height and a fill it is invisible, and
   the only feedback that an image is still uploading goes with it. */
.mb-watch .mb-w-chat > .au-attach-preview .au-attach-preview__bar {
  height: 3px;
  margin-top: 4px;
  border-radius: 99px;
  background: var(--line);
  overflow: hidden;
}

.mb-watch .mb-w-chat > .au-attach-preview .au-attach-preview__bar i {
  display: block;
  height: 100%;
  width: 0;
  background: var(--acc);
  transition: width .2s var(--ease);
}

.mb-watch .mb-w-chat > .au-attach-preview .au-attach-preview__x {
  margin-left: auto;
  flex: 0 0 auto;
  width: 28px;
  height: 28px;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--muted);
  font-size: 17px;
  line-height: 1;
  cursor: pointer;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}

.mb-watch .mb-w-chat > .au-attach-preview .au-attach-preview__x:hover {
  background: var(--soft);
  color: var(--acc);
}

.mb-watch .mb-w-chat > .au-attach-preview .au-attach-preview__x:focus-visible {
  outline: 2px solid var(--acc);
  outline-offset: 2px;
}

/* ---- 22.2  IMAGE / GIF MESSAGE BADGE --------------------------------------
   watch-controls.css:239 survives and keeps .au-msg-media's frame, so only the
   badge needs an owner. position:absolute is load-bearing — without it the
   "GIF" chip renders AFTER the image instead of on it. -----------------------*/

.mb-watch .mb-w-chatstream .au-msg-media__badge {
  position: absolute;
  left: 7px;
  bottom: 7px;
  padding: 2px 7px;
  border-radius: 99px;
  background: rgba(0, 0, 0, .68);
  color: #fff;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .5px;
}

/* ---- 22.3  THE GIF PICKER  (chat-upgrade.js:230-300) ----------------------
   TRAP. chat-aurora.css:527 was the ONLY display:none for this node, and
   chat-upgrade.js:237 appends it to <body> and never removes it — the outside-
   click handler at :258 only strips .is-open. Drop this rule and a 320px
   picker paints permanently over the page. Restated first, on purpose.

   position:ABSOLUTE, not fixed: chat-upgrade.js:265-266 positions it with
   `window.scrollX + rect.left` / `window.scrollY + rect.top`, i.e. DOCUMENT
   coordinates. Switching to fixed would put it in the wrong place the moment
   the page is scrolled. ------------------------------------------------------*/

.mb-watch ~ .au-gif-pop,
body.mb .au-gif-pop {
  display: none;
}

body.mb .au-gif-pop {
  position: absolute;
  z-index: 200;
  width: 320px;
  max-width: 92vw;
  padding: 6px;
  border-radius: 15px;
  background: var(--card);
  border: 1px solid var(--line2);
  box-shadow: 0 2px 6px rgba(0, 0, 0, .05), 0 26px 60px -26px rgba(0, 0, 0, .42);
  transform-origin: top left;
}

body.mb .au-gif-pop.is-open {
  display: block;
  animation: wPop .2s var(--ease) both;
}

body.mb .au-gif-pop .au-gif-pop__search {
  width: calc(100% - 12px);
  height: 34px;
  margin: 0 6px 7px;
  padding: 0 11px;
  box-sizing: border-box;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: var(--stage);
  color: var(--ink);
  font-family: inherit;
  font-size: 13px;
  outline: none;
}

body.mb .au-gif-pop .au-gif-pop__search:focus-visible {
  border-color: var(--acc);
  box-shadow: 0 0 0 3px var(--accsoft);
}

/* display:grid + the bounded overflow are load-bearing: the grid returns up to
   30 cells and without them they stack in one unscrollable column. The
   prototype's own picker (dc.html:4309) is 2 columns at max-height 230. */
body.mb .au-gif-pop .au-gif-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 6px;
  padding: 0 6px 6px;
  max-height: 230px;
  overflow-y: auto;
  overscroll-behavior: contain;
}

body.mb .au-gif-pop .au-gif-cell {
  aspect-ratio: 4 / 3;
  border: 1px solid var(--line2);
  border-radius: 9px;
  background: var(--stage);
  overflow: hidden;
  cursor: pointer;
  transition: border-color var(--dur) var(--ease), transform var(--dur) var(--ease);
}

body.mb .au-gif-pop .au-gif-cell:hover {
  border-color: var(--acc);
  transform: scale(1.03);
}

body.mb .au-gif-pop .au-gif-cell img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

body.mb .au-gif-pop .au-gif-pop__note {
  grid-column: 1 / -1;
  padding: 12px 4px;
  text-align: center;
  font-size: 12.5px;
  color: var(--muted);
}

body.mb .au-gif-pop .au-gif-pop__powered {
  padding: 0 10px 8px;
  font-size: 11px;
  color: var(--muted);
  text-align: right;
  letter-spacing: .3px;
}

/* ---- 22.4  THE MEDIA LIGHTBOX  (chat-upgrade.js:479-487) ------------------
   Second trap. Created lazily on the first image click, appended to <body>,
   closed with classList.remove('is-open') — never removed. chat-aurora.css:615
   was the only display:none. --------------------------------------------------*/

body.mb .au-lightbox {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 99999;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: rgba(20, 16, 12, .86);
  cursor: zoom-out;
}

body.mb .au-lightbox.is-open {
  display: flex;
  animation: mbChatFade .18s var(--ease) both;
}

body.mb .au-lightbox img {
  max-width: 100%;
  max-height: 100%;
  border-radius: 12px;
  box-shadow: var(--sh);
}

@keyframes mbChatFade { from { opacity: 0; } to { opacity: 1; } }

/* ---- 22.5  THE REACTION FLY-UP  (chat-upgrade.js:338) ---------------------
   pointer-events:none is the load-bearing half: the glyph is inserted over the
   stream on every reaction, and without it — and without the animation whose
   `forwards` parks it off-screen — it becomes a click-blocking overlay. -------*/

body.mb .au-react-fly {
  position: fixed;
  z-index: 9999;
  pointer-events: none;
  font-size: 22px;
  animation: mbChatFly .7s ease-out forwards;
}

@keyframes mbChatFly {
  0%   { opacity: 1; transform: translateY(0) scale(.6); }
  60%  { opacity: 1; }
  100% { opacity: 0; transform: translateY(-46px) scale(1.5); }
}

/* ---- 22.6  THE THREAD DRAWER  (chat-upgrade.js:430-460) -------------------
   Mounted on #eos-chat, which mambo-watch.css:2456 already gives
   `position: relative`, so inset:0 resolves against the chat column. Without
   the absolute positioning the drawer appends BELOW the composer as a
   transparent block and the chat behind it stays interactive. ----------------*/

.mb-watch .mb-w-chat > .au-thread-drawer {
  position: absolute;
  inset: 0;
  z-index: 40;
  display: flex;
  flex-direction: column;
  background: var(--card);
  animation: mbChatDrawerIn .22s var(--ease) both;
}

@keyframes mbChatDrawerIn {
  from { transform: translateX(14px); opacity: 0; }
  to   { transform: none; opacity: 1; }
}

.mb-watch .mb-w-chat > .au-thread-drawer .au-thread-drawer__head {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 12px 14px;
  border-bottom: 1px solid var(--line2);
  background: var(--stage);
}

.mb-watch .mb-w-chat > .au-thread-drawer .au-thread-drawer__back {
  flex: 0 0 auto;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: var(--card);
  color: var(--body);
  cursor: pointer;
  transition: border-color var(--dur) var(--ease), color var(--dur) var(--ease);
}

.mb-watch .mb-w-chat > .au-thread-drawer .au-thread-drawer__back:hover {
  border-color: var(--acc);
  color: var(--acc);
}

.mb-watch .mb-w-chat > .au-thread-drawer .au-thread-drawer__back:focus-visible {
  outline: 2px solid var(--acc);
  outline-offset: 2px;
}

.mb-watch .mb-w-chat > .au-thread-drawer .au-thread-drawer__title {
  font-weight: 700;
  font-size: 15px;
  color: var(--ink);
}

.mb-watch .mb-w-chat > .au-thread-drawer .au-thread-drawer__title small {
  display: block;
  font-weight: 400;
  font-size: 11.5px;
  color: var(--muted);
}

/* flex:1 + overflow-y are what make the drawer scroll instead of overflowing
   the panel — the same defect class as the § 19.1/19.2 editor scrollers. */
.mb-watch .mb-w-chat > .au-thread-drawer .au-thread-drawer__body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 8px;
}

.mb-watch .mb-w-chat > .au-thread-drawer .au-thread-parent {
  margin: 4px 4px 10px;
  padding: 10px 12px;
  border-radius: 12px;
  border: 1px solid var(--line2);
  background: var(--accsoft);
}

.mb-watch .mb-w-chat > .au-thread-drawer .au-tp-who {
  font-weight: 700;
  font-size: 13px;
  color: var(--acc);
}

.mb-watch .mb-w-chat > .au-thread-drawer .au-tp-text {
  margin-top: 2px;
  font-size: 14px;
  color: var(--ink);
}

.mb-watch .mb-w-chat > .au-thread-drawer .au-thread-reply {
  display: flex;
  gap: 9px;
  padding: 7px 6px;
}

.mb-watch .mb-w-chat > .au-thread-drawer .au-thread-reply__av {
  flex: 0 0 auto;
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  font-size: 11px;
  font-weight: 700;
  color: #fff;
}

.mb-watch .mb-w-chat > .au-thread-drawer .au-thread-reply__who {
  font-weight: 700;
  font-size: 12.5px;
  color: var(--ink);
}

.mb-watch .mb-w-chat > .au-thread-drawer .au-thread-reply__time {
  margin-left: 5px;
  font-size: 10px;
  color: var(--faint);
}

.mb-watch .mb-w-chat > .au-thread-drawer .au-thread-reply__text {
  font-size: 13.5px;
  line-height: 1.45;
  color: var(--body);
}

.mb-watch .mb-w-chat > .au-thread-drawer .au-thread-drawer__foot {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  border-top: 1px solid var(--line2);
  background: var(--stage);
}

.mb-watch .mb-w-chat > .au-thread-drawer .au-thread-drawer__foot button {
  flex: 1;
  padding: 9px;
  border: 0;
  border-radius: 12px;
  background: var(--acc);
  color: var(--onacc);
  font-family: inherit;
  font-size: 13.5px;
  font-weight: 700;
  cursor: pointer;
  transition: background var(--dur) var(--ease), transform var(--dur) var(--ease);
}

.mb-watch .mb-w-chat > .au-thread-drawer .au-thread-drawer__foot button:hover {
  background: var(--accHover);
  transform: translateY(-1px);
}

/* ---- 22.7  THE THREAD PILL on a message row ------------------------------ */

.mb-watch .mb-w-chatstream .au-thread-pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  margin-top: 6px;
  padding: 2px 0;
  border: 0;
  background: none;
  font-family: inherit;
  font-size: 12px;
  font-weight: 700;
  color: var(--acc);
  cursor: pointer;
}

.mb-watch .mb-w-chatstream .au-thread-pill:hover { text-decoration: underline; }

.mb-watch .mb-w-chatstream .au-thread-pill:focus-visible {
  outline: 2px solid var(--acc);
  outline-offset: 2px;
}

.mb-watch .mb-w-chatstream .au-thread-pill__av { display: inline-flex; }

.mb-watch .mb-w-chatstream .au-thread-pill__av span {
  width: 17px;
  height: 17px;
  margin-left: -5px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  box-shadow: 0 0 0 1.5px var(--card);
  font-size: 8px;
  font-weight: 700;
  color: #fff;
}

/* ---- 22.8  REACTION-COUNT BUMP  (.au-bump, chat-upgrade.js) -------------- */

.mb-watch .mb-w-chatstream .eos-chat-pill.au-bump {
  animation: mbChatBump .32s cubic-bezier(.3, 1.4, .5, 1);
}

@keyframes mbChatBump {
  0%   { transform: scale(1); }
  40%  { transform: scale(1.28); }
  100% { transform: scale(1); }
}

/* ---- 22.9  THE JUMP-TO-LATEST PILL  (chat.js:1470-1505) ------------------
   chat.js:1474 forces the wrapper to position:relative for this rule's sake,
   and drives visibility with an INLINE display (:1480 none / :1504 inline-flex)
   — so the purge does not un-hide it, it just drops it into the flow. The
   absolute placement is the whole affordance. --------------------------------*/

.mb-watch .mb-w-chat .eos-chat-jump {
  position: absolute;
  left: 50%;
  bottom: 12px;
  transform: translateX(-50%);
  z-index: 30;
  align-items: center;
  gap: 6px;
  padding: 8px 15px;
  border: 0;
  border-radius: 999px;
  background: var(--ink);
  color: var(--card);
  font-family: inherit;
  font-size: 11.5px;
  font-weight: 700;
  line-height: 1;
  box-shadow: var(--sh);
  cursor: pointer;
}

.mb-watch .mb-w-chat .eos-chat-jump:focus-visible {
  outline: 2px solid var(--acc);
  outline-offset: 2px;
}

/* ---- 22.10  THE "NEW MESSAGES" DIVIDER  (chat.js:1494-1498) -------------- */

.mb-watch .mb-w-chatstream .eos-chat-newdvd {
  display: flex;
  align-items: center;
  gap: 9px;
  margin: 4px 6px;
}

.mb-watch .mb-w-chatstream .eos-chat-newdvd::before,
.mb-watch .mb-w-chatstream .eos-chat-newdvd::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--line);
}

.mb-watch .mb-w-chatstream .eos-chat-newdvd span {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--acc);
}

/* ---- 22.11  THE :shortcode: EMOJI MENU  (chat.js:1200-1222) --------------
   position:fixed is not decoration. chat.js:1218-1220 sets .style.left and
   .style.bottom from getBoundingClientRect(), i.e. VIEWPORT coordinates, which
   only resolve against a fixed box. Body-mounted, so it is scoped on body.mb
   rather than .mb-watch. scClose() removes the node, so no hide rule is
   needed — display:flex at rest is correct. ---------------------------------*/

body.mb .eos-chat-scmenu {
  position: fixed;
  z-index: 2147482000;
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 230px;
  max-width: 320px;
  padding: 5px;
  border: 1px solid var(--line2);
  border-radius: 12px;
  background: var(--card);
  box-shadow: 0 2px 6px rgba(0, 0, 0, .05), 0 26px 60px -26px rgba(0, 0, 0, .42);
  animation: wPop .16s var(--ease) both;
}

body.mb .eos-chat-scmenu button {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 7px 10px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--ink);
  font-family: inherit;
  font-size: 12.5px;
  text-align: left;
  cursor: pointer;
  transition: background var(--dur) var(--ease);
}

body.mb .eos-chat-scmenu button .e {
  flex: none;
  font-size: 18px;
  line-height: 1;
}

body.mb .eos-chat-scmenu button .n {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--muted);
}

body.mb .eos-chat-scmenu button:hover,
body.mb .eos-chat-scmenu button.is-on {
  background: var(--accsoft);
}

/* ---- 22.12  REDUCED MOTION ----------------------------------------------
   chat-aurora.css:636 and chat-flagship.css:332-344 both honoured the setting.
   Restated for the animations § 20 introduces, so the port does not quietly
   drop an accessibility decision the purged sheets were making. -------------*/

@media (prefers-reduced-motion: reduce) {
  body.mb .au-gif-pop.is-open,
  body.mb .au-lightbox.is-open,
  body.mb .au-react-fly,
  body.mb .eos-chat-scmenu,
  .mb-watch .mb-w-chat > .au-thread-drawer,
  .mb-watch .mb-w-chatstream .eos-chat-pill.au-bump {
    animation: none;
  }

  .mb-watch .mb-w-chat > .au-thread-drawer .au-thread-drawer__foot button:hover {
    transform: none;
  }
}

/* ---- 22.13  NARROW PANEL -------------------------------------------------
   chat-aurora.css:631 used `@media (max-width: 640px)`. 640 is NOT an authored
   breakpoint — the set is {1120,1020,940,900,860,782,760,680,620,520,430},
   plus 1060 for Watch only. Re-targeted to 620, the nearest authored value
   below, rather than carrying an invented one across. -----------------------*/

@media (max-width: 620px) {
  body.mb .au-gif-pop { width: 280px; }
}

/* ===  end § 20  ============================================================ */

/* =============================================================================
   23. NO DOCK, NO COLUMN                                            v3.29.0

   Prayer, Flow and Give became per-event switchable alongside Chat, Notes and
   Bible, which means an operator can now switch off all six. page-watch.php
   then prints no <aside> at all — the Setup copy promises a switched-off feature
   is "completely hidden from members: no tab, nothing in the page", so it is
   absent from view-source rather than hidden with CSS.

   That leaves the shell's third grid track holding nothing. The track is a fixed
   var(--panelW) — 392px — so without this the stage would sit beside 392px of
   empty page. `:has()` lets the shell answer the question it is actually asking:
   is there a dock to make room for?

   `:has()` is unsupported in a few older engines. The degradation is graceful
   rather than broken — the column stays empty, exactly as it would have without
   this rule — so no second formulation is needed, unlike the [17] replay-strip
   suppression where a miss would have shown a duplicate component.
   ========================================================================== */
.mb-watch:not(:has(.eos-side)) {
  grid-template-columns: minmax(0, 1fr);
  grid-template-areas: "top" "stage" "rail";
}

.mb-watch:not(:has(.eos-side)) .mb-w-split { display: none; }

/* =============================================================================
   24. CHAT PANEL PARITY                                             v3.30.0

   Two findings, both re-verified against the prototype and against a harness
   loading EXACTLY the production sheet set. That last part matters: an earlier
   pass of mine loaded watch-cinema.css, which mambo_purge_watch() dequeues, and
   every reading taken through it was an artefact — see the note in
   scratchpad/mkchat.py.
   ========================================================================== */

/* ---- 24.1 [06] YOUR OWN MESSAGE: the bubble belongs to the TEXT ----------
   The prototype does NOT fill the row. It fills the message text and nothing
   else (dc.html:4735):

       padding: 7px 11px; border-radius: 12px 12px 4px 12px;
       background: var(--acc); color: var(--onacc); text-align: left

   with the content column at `max-width: 84%` and, crucially,
   `display:flex; flex-direction:column; align-items:flex-end` (dc.html:4665).

   THAT COLUMN IS THE WHOLE TRICK, and getting it wrong is easy. The obvious
   shortcut — `text-align: right` on the body — was drafted and rejected: the
   body also carries the quoted reply-preview, the verse card, the link preview,
   the translation block and the care button (chat.js:1858-1867), and none of
   them declares a text-align of its own. Every own message that is a REPLY —
   the commonest kind there is — would have had its quoted preview flung right.
   A flex column with `align-items: flex-end` right-aligns the BOXES and leaves
   the text inside each one alone, which is what the prototype actually does.

   The avatar and the name need nothing: both already resolve to the prototype's
   values (--acc on --onacc, and --ink for your own name). */
.mb-watch .mb-w-chatstream .eos-chat-msg.is-mine .eos-chat-msg__body {
  max-width: 84%;
  justify-content: flex-end;
}

.mb-watch .mb-w-chatstream .eos-chat-msg.is-mine .eos-chat-msg__body > .body {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
}

/* inline-block, because chat.css leaves this span inline and an inline box
   cannot take the vertical padding or the corner radius the bubble needs. */
.mb-watch .mb-w-chatstream .eos-chat-msg.is-mine .eos-chat-msg__text {
  display: inline-block;
  padding: 7px 11px;
  border-radius: 12px 12px 4px 12px;
  background: var(--acc);
  color: var(--onacc);
  text-align: left;
}

/* ---- 24.2 [03] THE GIVE ROW'S ARROW ------------------------------------
   The pill itself is already right: mambo draws a 55px carrier whose ::before
   is inset 9px/10px/8px, giving the prototype's 38px pill on --tint2 with an
   --accLight border. The one thing left is the chevron.

   chat-studio.css:1185-1190 declares `.eos-tg-give-btn__chev { margin-left:
   auto; opacity: .65; font-weight: 700; font-size: 14px }`, and mambo's own
   rule on that span sets `color` alone — so `margin-left: auto` is
   uncontested and flings the arrow to the far edge of a row the prototype
   centres as one group (dc.html:585, `justify-content: center; gap: 8px`).

   No !important needed: this is (0,4,0) against chat-studio's (0,1,0), and
   that sheet does not mark these declarations important. */
.mb-watch .mb-w-chat > .eos-tg-give-btn .eos-tg-give-btn__chev {
  margin-left: 0;
  opacity: 1;
  font-size: 13px;
  font-weight: 650;
}


/* ---- 24.3  [12] THE REPLY-PREVIEW STRIP ----------------------------------
   chat.js:2048-2058 builds .eos-chat-reply-preview > (__col > __w + __t) + __x
   and chat.js:2066-2067 inserts it as a DIRECT CHILD of #eos-chat, immediately
   before the form - i.e. inside the composer well. This layer never covered it,
   so chat.css:415-500 dressed it alone: a gold label, a square-topped card and
   a bare x.

   dc.html:567 - the strip is a --card pill with an 11px radius, a 1px --line2
   hairline and a 3px --acc rail, sitting ON the --stage well.

   .mb-w-chat is --card and the well is painted per element in § C10, so the
   strip must carry the well ground itself or it punches a white band through
   the middle of it. Same answer § C10 already uses for the give row: stage on
   the element, the pill on ::before at the same 9/10/8 inset, children lifted
   to position: relative.

   (0,3,0) / (0,4,0) / (0,5,0) against chat.css (0,1,0)-(0,3,0). The only
   !important in that chat.css block is :432 [hidden]{display:none !important},
   the show/hide contract, deliberately left untouched. */
.mb-watch .mb-w-chat > .eos-chat-reply-preview {
  position: relative;
  box-sizing: border-box;
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 9px;
  margin: 0;
  padding: 17px 20px 16px 23px;
  border: 0;
  border-top: 1px solid var(--line2);
  border-radius: 0;
  background: var(--stage);
  font-size: 12.5px;
}

.mb-watch .mb-w-chat > .eos-chat-reply-preview::before {
  content: "";
  position: absolute;
  inset: 9px 10px 8px;
  border: 1px solid var(--line2);
  border-left: 3px solid var(--acc);
  border-radius: 11px;
  background: var(--card);
}

.mb-watch .mb-w-chat > .eos-chat-reply-preview > * { position: relative; }

/* The well draws ONE top hairline, on whichever element opens it. § C10
   already makes that chain for the give row, the quick replies, the composer
   and the sign-in swap; the strip is a fifth member chat.js can insert
   anywhere in it. */
.mb-watch .mb-w-chat > .eos-tg-give-btn ~ .eos-chat-reply-preview,
.mb-watch .mb-w-chat > .eos-qr-row ~ .eos-chat-reply-preview { border-top: 0; }

/* v3.35.0 board catch (judge J2): with the strip open, the form's hairline
   must go — but § 24.4's [05] override declares it with !important (it has
   to, chat-studio.css:327-333 is important), and chat.css's legacy
   .eos-chat-form hairline is important too. Importance beats this rule's
   higher specificity, so a plain zero here measured TWO stacked hairlines.
   Only an important zero reaches both — (0,4,0)!important over our own
   (0,3,0)!important and legacy (0,1,0)!important. The signin arm stays
   plain: its hairline is mambo's own, unimportant. */
.mb-watch .mb-w-chat > .eos-chat-reply-preview ~ .mb-w-composer { border-top: 0 !important; }
.mb-watch .mb-w-chat > .eos-chat-reply-preview ~ .mb-w-chatsignin { border-top: 0; }

.mb-watch .mb-w-chat > .eos-chat-reply-preview .eos-chat-reply-preview__col {
  min-width: 0;
  flex: 1;
}

/* dc.html:569 - "REPLYING TO <NAME>" as a 10.5px/700 uppercase clay label. */
.mb-watch .mb-w-chat > .eos-chat-reply-preview .eos-chat-reply-preview__w {
  display: block;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--acc);
}

/* dc.html:570 */
.mb-watch .mb-w-chat > .eos-chat-reply-preview .eos-chat-reply-preview__t {
  display: block;
  margin-top: 2px;
  font-size: 12.5px;
  line-height: 1.35;
  color: var(--muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* dc.html:572 - the same 26px/7px ghost square as every other close in the
   design. chat.css:449-460 makes it a bare glyph that turns red on hover. */
.mb-watch .mb-w-chat > .eos-chat-reply-preview .eos-chat-reply-preview__x {
  flex: 0 0 auto;
  width: 26px;
  height: 26px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  border-radius: 7px;
  background: transparent;
  color: var(--muted);
  font: inherit;
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
  transition: background var(--dur-micro) ease, color var(--dur-micro) ease;
}

.mb-watch .mb-w-chat > .eos-chat-reply-preview .eos-chat-reply-preview__x:hover {
  background: var(--soft);
  color: var(--ink);
}

.mb-watch .mb-w-chat > .eos-chat-reply-preview .eos-chat-reply-preview__x:focus-visible {
  outline: 2px solid var(--acc);
  outline-offset: 1px;
}

/* chat.css:465-469 squares the form top corners while a preview is open, to
   join the two. Here they are separate cards on one well, so the join is not
   wanted - and § C10 already owns the composer hairline. */
.mb-watch .mb-w-chat > .mb-w-composer.eos-chat-form--has-preview { border-radius: 0; }

/* ---- 24.4  [05] THE COMPOSER ROW, PROTOTYPE-EXACT ------------------------
   dc.html:563/:593 - well: padding 9px 10px 11px, 1px --line2 top hairline,
   --stage ground; row: flex, align-items flex-end, gap 7px.

   The winning legacy rule is chat-studio.css:327-333 - .eos-chat-form at
   (0,1,0) with !important on padding / gap / align-items / background /
   border-top. Importance is compared before specificity, so no selector can
   answer it unaided; the sheet cannot be purged (it carries the live-service
   choreography layer). Only !important can answer !important - it is used
   for exactly the five contested declarations, (0,3,0)!important over
   (0,1,0)!important. The dark arm chat-studio.css:334-336 pins only
   border-top-color at (0,2,0)!important; the shorthand below outranks it and
   --line2 re-tones, so no dark duplicate is needed. */
.mb-watch .mb-w-chat > .mb-w-composer {
  padding: 9px 10px 11px !important;
  gap: 7px !important;
  align-items: flex-end !important;
  background: var(--stage) !important;
  border-top: 1px solid var(--line2) !important;
}

/* ---- 24.5  [07] THE UNIFIED MESSAGE TOOLBAR ------------------------------
   watch-controls.js enhance() builds ONE .eos-cn-mtools bar per message
   (React trigger + quickpop, Reply, Save, More + mmore menu) and inline-hides
   the legacy .eos-chat-actions / .eos-chat-react-bar (v3.31.1, the
   ONE_AFFORDANCE_ONLY contract - this section never declares display on
   either legacy container, and never touches the reveal mechanics:
   opacity / transform / pointer-events / transition stay watch-controls.js
   territory, as does z-index, which is stacking-context tuning, not skin).

   The prototype cluster is dc.html:4794/:4801 - a --card card on a 1px
   --line2 hairline, radius 10, shadow 0 8px 20px -12px rgba(0,0,0,.4),
   top -11px, right 10px (LEFT 10px on your own row - the prototype mirrors
   the cluster with the row), 26px buttons at radius 7, --muted, hover
   --soft / --ink. The popover shell is dc.html:3508 (radius 15, padding 6,
   card on line2) with 32px cells at radius 8 (dc.html:3590).

   Selector altitude: the container rules ride (0,4,0), which outranks the
   watch-controls.css skins at (0,2,0)-(0,3,0) and their dark arms at
   (0,3,1); the button rules ride (0,5,0) to outrank the dark button arms at
   (0,4,1) (html[data-theme="dark"] ... .eos-cn-mbtn). Tokens re-tone, so no
   dark duplicates anywhere. Only two rules carry !important, at the end,
   each annotated with the rule it answers. */
.mb-watch .mb-w-chatstream .eos-chat-msg > .eos-cn-mtools {
  top: -11px;
  right: 10px;
  gap: 2px;
  padding: 3px;
  border-radius: 10px;
  background: var(--card);
  border: 1px solid var(--line2);
  box-shadow: 0 8px 20px -12px rgba(0, 0, 0, .4);
}

/* the prototype mirrors the cluster onto the row’s own side (dc.html:4794
   builds left:10px when mine). MUST stay earlier in the file than the
   right-click pin (.mb-w-ctx > .eos-cn-mtools in § 25) - both are (0,4,0),
   so the pin wins their tie on source order alone. */
.mb-watch .mb-w-chatstream .eos-chat-msg.is-mine > .eos-cn-mtools {
  left: 10px;
  right: auto;
}

/* dc.html:4648 flips the cluster inside when the row is within 16px of the
   stream top - a JS measurement with no CSS equivalent; the first row is the
   only row that can sit there, so :first-child is the faithful static form. */
.mb-watch .mb-w-chatstream .eos-chat-msg:first-child > .eos-cn-mtools {
  top: 2px;
}

/* the triggers enhance() creates. min-width answers watch-controls.css:609
   min-width:30px (plain), which was silently clamping any narrower width. */
.mb-watch .mb-w-chat .mb-w-chatstream .eos-cn-mtools .eos-cn-mbtn {
  width: 26px;
  height: 26px;
  min-width: 26px;
  border-radius: 7px;
  color: var(--muted);
  font-size: 14px;
}
.mb-watch .mb-w-chat .mb-w-chatstream .eos-cn-mtools .eos-cn-mbtn:hover {
  background: var(--soft);
  color: var(--ink);
}

/* the quick-react popover: prototype popover shell + 32px cells. */
.mb-watch .mb-w-chat .mb-w-chatstream .eos-cn-quickpop {
  border-radius: 15px;
  padding: 6px;
  background: var(--card);
  border: 1px solid var(--line2);
  box-shadow: 0 2px 6px rgba(0, 0, 0, .05), 0 26px 60px -26px rgba(0, 0, 0, .42);
}
.mb-watch .mb-w-chat .mb-w-chatstream .eos-cn-quickpop .eos-chat-react-q,
.mb-watch .mb-w-chat .mb-w-chatstream .eos-cn-quickpop .eos-chat-react-more {
  width: 32px;
  height: 32px;
  min-width: 32px;
  border-radius: 8px;
  font-size: 17px;
  color: var(--muted);
}

/* the more-menu: prototype popover shell. Item geometry stays
   watch-controls.css:642-646 (its own !important set, labels visible). */
.mb-watch .mb-w-chat .mb-w-chatstream .eos-cn-mmore {
  border-radius: 15px;
  padding: 6px;
  background: var(--card);
  border: 1px solid var(--line2);
  box-shadow: 0 2px 6px rgba(0, 0, 0, .05), 0 26px 60px -26px rgba(0, 0, 0, .42);
}

/* THE TWO ANSWERED-!important RULES.
   1) In-bar Reply/Save geometry: chat-studio.css:219-230 pins width 28 /
      height 28 / border-radius 6 at (0,1,0)!important, and
      watch-controls.css:261 pins color:inherit at (0,2,1)!important. The
      prototype button is 26px at radius 7 in --muted (dc.html:4801). Only
      the four contested declarations carry !important; min-width answers a
      plain clamp and does not. Scoped to DIRECT children so the mmore menu
      items (watch-controls.css:642-646) are untouched. */
.mb-watch .mb-w-chat .mb-w-chatstream .eos-cn-mtools > .eos-chat-action {
  width: 26px !important;
  height: 26px !important;
  min-width: 26px;
  border-radius: 7px !important;
  color: var(--muted) !important;
}

/* 2) The amber hover: watch-controls.css:262-263 paints every
      .eos-chat-action:hover and .eos-chat-react-q:hover
      rgba(231,178,75,.20)/#7E560F at (0,2,1)!important, with a dark arm at
      :264-265 (0,3,1)!important. The prototype hover is --soft / --ink
      (dc.html:4802). (0,5,1)!important / (0,6,1)!important outrank both
      arms, and the tokens re-tone - one rule, both themes, and it covers
      the mmore items too (the prototype popover rows hover the same way,
      dc.html:3697). */
.mb-watch .mb-w-chat .mb-w-chatstream .eos-cn-mtools .eos-chat-action:hover,
.mb-watch .mb-w-chat .mb-w-chatstream .eos-cn-quickpop .eos-chat-react-q:hover,
.mb-watch .mb-w-chat .mb-w-chatstream .eos-cn-mmore .eos-chat-action:hover {
  background: var(--soft) !important;
  color: var(--ink) !important;
}

/* ---- 24.6  [06] THE MENTION CHIP -----------------------------------------
   dc.html:4750 - a 5px-radius --accsoft chip in --acc, padding 1px 5px,
   weight 650; on your own clay bubble it switches to a white scrim
   (rgba(255,255,255,.22)) with inherited text so it reads on --acc.

   chat-studio.css:436-444 pins display / font-weight / font-size / padding /
   border-radius / background / color at (0,1,0)!important (lilac #534AB7),
   with a dark arm at :445-448 (0,2,0)!important. The five below answer the
   contested visuals at (0,3,0)!important, which outranks both arms, and the
   tokens re-tone in dark - no dark duplicate. display:inline-block and the
   13px size are left standing: sub-visible against the prototype (13.5),
   and every !important here must earn its place. margin is not contested,
   so it is plain. The composer-side atomic chip (chat.js:172) carries the
   same class and gets the same coat. */
.mb-watch .mb-w-chatstream .eos-chat-mention,
.mb-watch .mb-w-composer .eos-chat-mention {
  padding: 1px 5px !important;
  border-radius: 5px !important;
  background: var(--accsoft) !important;
  color: var(--acc) !important;
  font-weight: 650 !important;
  margin: 0 1px;
}

/* your own bubble is --acc; the chip switches to the prototype white scrim.
   (0,5,0)!important over the same two arms. */
.mb-watch .mb-w-chatstream .eos-chat-msg.is-mine .eos-chat-mention {
  background: rgba(255, 255, 255, .22) !important;
  color: inherit !important;
}

/* =============================================================================
   25. THE CHAT READS LIKE A CONVERSATION                            v3.31.0

   Dennis, with two WhatsApp screenshots: "you see how users' text are separated
   on either ends to provide clarity? that's what I want. each hover on user's
   text should be distinct on the user's side and not be a highlight across the
   chat width. also a right click on either chats should show the options for
   reply, reaction emojis etc."

   A DELIBERATE DEPARTURE FROM THE PROTOTYPE, recorded as one. dc.html:4736
   draws an INCOMING message as bare text on the page - only your own message
   gets a fill. Dennis has looked at that and asked for the two-sided treatment
   instead, which is a clarity judgement about his own congregation reading a
   fast-moving stream on a phone. The prototype governs the look; the owner
   governs the product. Everything else here stays in the prototype's language:
   its radii, its tokens, its type.
   ========================================================================== */

/* ---- 25.1 A BUBBLE ON EACH SIDE ----------------------------------------
   Your own message already had one (section 24.1). This gives the other side
   its counterpart: --card on a --line hairline, so it reads as a distinct
   object against the panel without competing with the clay of your own.

   The tail corner mirrors: yours is small at the bottom-RIGHT, nearest your
   avatar on the right; theirs is small at the bottom-LEFT, nearest theirs.

   `inline-block` because chat.css leaves this span inline, and an inline box
   takes neither the vertical padding nor the corner radius a bubble needs. */
.mb-watch .mb-w-chatstream .eos-chat-msg:not(.is-mine) .eos-chat-msg__text {
  display: inline-block;
  padding: 7px 11px;
  border: 1px solid var(--line);
  border-radius: 12px 12px 12px 4px;
  background: var(--card);
  color: var(--body);
}

/* The content column shrink-wraps to the bubble and hugs its own side, so a
   short message is a short bubble. Same mechanism as 24.1, mirrored - and for
   the same reason it must be `align-items`, not `text-align`: this span also
   carries the quoted reply-preview, the verse card and the link preview, and
   text-align would reach inside all of them. */
.mb-watch .mb-w-chatstream .eos-chat-msg:not(.is-mine) .eos-chat-msg__body > .body {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

/* Both sides cap at the prototype's own 84% (dc.html:4665) so neither runs the
   full width of the panel - which is what "separated on either end" means. */
.mb-watch .mb-w-chatstream .eos-chat-msg .eos-chat-msg__body { max-width: 84%; }

/* ---- 25.2 HOVER BELONGS TO THE BUBBLE ----------------------------------
   Was `.eos-chat-msg:hover { background: var(--stage) }` - a band the full
   width of the panel, which is exactly what Dennis objected to. The tint now
   lands on the bubble alone, so the feedback sits on the side that owns the
   message. */
.mb-watch .mb-w-chatstream .eos-chat-msg__text {
  transition: background var(--dur-micro) ease, border-color var(--dur-micro) ease;
}

.mb-watch .mb-w-chatstream .eos-chat-msg:not(.is-mine):hover .eos-chat-msg__text {
  background: var(--soft);
  border-color: var(--line2);
}

.mb-watch .mb-w-chatstream .eos-chat-msg.is-mine:hover .eos-chat-msg__text {
  background: var(--accHover);
}

/* ---- 25.3 THE RIGHT-CLICK MENU -----------------------------------------
   REWRITTEN in v3.31.1 after Dennis showed the result: "there is clumsiness.
   makes sure right click doesn't conflict with hover popup."

   He was right, and the first version was built on a false picture of the page.
   `watch-controls.js:605` runs `enhance()` on every message row and builds a
   UNIFIED toolbar, `.eos-cn-mtools`. It MOVES the quick-emoji buttons into
   `.eos-cn-quickpop`, moves Reply and Save into the bar itself, moves whatever
   remains into `.eos-cn-mmore`, and then sets an inline `display: none` on the
   now-empty `.eos-chat-actions` and `.eos-chat-react-bar`.

   So the first version positioned two EMPTY boxes, and its label rule — which
   had to carry an !important to beat chat-studio — leaked onto the Reply and
   Save buttons that now live in the hover pill, printing their labels on top of
   their icons. That is the collision in his screenshot.

   THE FIX IS TO STOP COMPETING WITH THAT TOOLBAR AND DRIVE IT. Right-click now
   pins the toolbar the page already builds at the pointer and opens its own
   emoji popover, using the same `open` / `is-pop` classes its own buttons use.
   One gesture gives the emoji row, Reply, Save and the more-menu — WhatsApp's
   arrangement, out of the component that already exists.

   Consequences worth stating: the parallel menu is gone, the !important went
   with it, and there is now exactly ONE hover/press affordance on a message
   instead of two fighting for the same corner. */
.mb-watch .mb-w-chatstream .eos-chat-msg.mb-w-ctx { z-index: 6; }

/* The toolbar normally sits in the row's top-right corner and fades in on
   hover. While the context menu is open it is pinned at the pointer instead,
   held visible regardless of hover, and lifted above its neighbours. */
.mb-watch .mb-w-chatstream .eos-chat-msg.mb-w-ctx > .eos-cn-mtools {
  left: var(--mb-ctx-x, auto);
  top: var(--mb-ctx-y, auto);
  right: auto;
  bottom: auto;
  z-index: 7;
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transform: none;
}

/* The click-away scrim. A child of the row rather than a body overlay, because
   the row owns the open state — a body overlay would have to be torn down
   separately if chat.js re-rendered the stream under it. It sits BELOW the
   toolbar's own z-index so the buttons stay clickable. */
.mb-watch .mb-w-chatstream .eos-chat-msg.mb-w-ctx::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 5;
}

/* Nothing here restyles the toolbar's buttons. They are watch-controls.js's
   component, they are already correct, and the labels stay icon-only exactly as
   chat-studio.css intends — which is what removes the overlap. */

/* The bubble hover tint animates; under reduced motion it should simply switch.
   (Lost when 25.3 was rewritten, restored here rather than left implicit.) */
@media (prefers-reduced-motion: reduce) {
  .mb-watch .mb-w-chatstream .eos-chat-msg__text { transition: none; }
}
