:root {
  --bg: #050806; --fg: #f7faf8; --muted: #aab7af; --accent: #0b7541;
  --accent-bright: #17a35c; --green-deep: #061b10; --green: #074d2b;
  --silver: #a0a0a0; --card: #101713; --line: #294333; --warn: #ffd166;
  --danger: #d83939; --shadow: 0 20px 60px rgba(0,0,0,.35);
}
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; background: var(--bg); color: var(--fg);
  font-family: Inter, ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif; -webkit-text-size-adjust: 100%; }
body { min-height: 100dvh; }
a { color: #7bd9a2; }
.wrap { max-width: 560px; margin: 0 auto; padding: 20px; }
h1 { font-size: 1.5rem; margin: 0 0 8px; }
h2 { font-size: 1.1rem; margin: 18px 0 6px; }
p { line-height: 1.5; color: var(--fg); }
.muted { color: var(--muted); font-size: .92rem; }
.card { background: var(--card); border: 1px solid var(--line); border-radius: 14px; padding: 16px; margin: 14px 0; }
.warn { border-color: var(--warn); }
.warn b { color: var(--warn); }
button, .btn { font: inherit; cursor: pointer; border-radius: 12px; border: 1px solid var(--line);
  background: #1d2330; color: var(--fg); padding: 14px 18px; width: 100%; margin-top: 10px; }
button.primary { background: var(--accent); color: #fff; border-color: var(--accent-bright); font-weight: 800; }
button.ghost { background: transparent; }
/* light-blue (голубой) call-to-action — the "turn on the flashlight" button */
button.accent-blue { background: #fff; color: var(--green-deep); border-color: #fff; font-weight: 800; }
button:disabled { opacity: .5; cursor: default; }
.row { display: flex; gap: 10px; }
.row > * { flex: 1; }
.pill { display: inline-block; padding: 4px 10px; border-radius: 999px; background: #1d2330; color: var(--muted); font-size: .8rem; }
.lang { position: absolute; top: 10px; right: 12px; font-size: .85rem; }
.lang a { margin-left: 8px; cursor: pointer; }
.credit { margin-top: 18px; font-size: .82rem; color: var(--muted); text-align: center; }
.hidden { display: none !important; }

/* full-screen flash layer for the audience */
#flash { position: fixed; inset: 0; background: #000; z-index: 1; transition: none; }
/* #stage scrolls so the consent screen is fully reachable on short/phone viewports;
   it is transparent, so the fixed #flash layer shows through behind it. */
#stage { position: fixed; inset: 0; z-index: 2; overflow-y: auto; -webkit-overflow-scrolling: touch; }
#stage .wrap { min-height: 0; padding-bottom: 40px; }
#stopbtn { position: fixed; top: 12px; right: 12px; z-index: 3; width: auto; margin: 0;
  pointer-events: auto; background: rgba(0,0,0,.55); border-color: rgba(255,255,255,.4); color: #fff; padding: 10px 14px; }
#statuspill { position: fixed; bottom: 12px; left: 50%; transform: translateX(-50%); z-index: 3;
  background: rgba(0,0,0,.5); color: #fff; padding: 6px 12px; border-radius: 999px; font-size: .8rem; pointer-events: none; }
#brightToast { position: fixed; bottom: 52px; left: 50%; transform: translateX(-50%); z-index: 4;
  max-width: 86vw; text-align: center; background: rgba(20,16,4,.92); color: var(--warn);
  border: 1px solid var(--warn); padding: 10px 16px; border-radius: 999px; font-size: .9rem;
  font-weight: 600; pointer-events: none; box-shadow: 0 4px 18px rgba(0,0,0,.5); }
#wave { position: fixed; left: 8px; width: calc(100vw - 16px); bottom: 44px; height: 44px; z-index: 3;
  background: rgba(0,0,0,.5); border-radius: 8px; pointer-events: none; }
#diag { position: fixed; left: 8px; bottom: 12px; z-index: 4; font-size: 11px; color: #9aa3b2;
  background: rgba(0,0,0,.55); padding: 3px 7px; border-radius: 6px; pointer-events: none; font-variant-numeric: tabular-nums; }

/* operator */
table { width: 100%; border-collapse: collapse; }
td, th { text-align: left; padding: 6px 4px; border-bottom: 1px solid var(--line); font-size: .92rem; }
.qrbox { background: #fff; padding: 14px; border-radius: 14px; text-align: center; }
.qrbox img { width: 100%; max-width: 320px; image-rendering: pixelated; }
.big { font-size: 2rem; font-weight: 800; }
.transport button { width: auto; }
#blackout { background: var(--danger); color: #fff; border-color: var(--danger); font-weight: 800; }
.nudge { display: flex; align-items: center; gap: 10px; }
.nudge input { flex: 1; }
input[type=password], input[type=text] { width: 100%; padding: 12px; border-radius: 10px; border: 1px solid var(--line);
  background: #0f131b; color: var(--fg); font: inherit; }

/* Round 10: responsive operator/studio console — use the full width on desktop instead of a
   560px phone-strip. Scoped to .op-console (operator.html ONLY); the audience /join page uses
   bare .wrap and is untouched. Mobile = unchanged single column. Robust to public-mode
   hide/reorder: a 2- then 3-column grid that flows cards; top-level header/welcome/play/status/
   credit span all columns. */
@media (min-width: 980px) {
  .op-console { max-width: 1240px; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 16px; align-items: start; grid-auto-flow: row dense; }
  .op-console > h1, .op-console > #pubWelcome, .op-console > #playSound,
  .op-console > p.muted, .op-console > .credit, .op-console > details { grid-column: 1 / -1; }
  .op-console .card { margin: 0; }
}
@media (min-width: 1440px) {
  .op-console { max-width: 1560px; grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
/* Advanced-controls disclosure (public studio): laid out as its own full-width grid inside */
.op-adv { margin: 14px 0; }
.op-adv > summary { cursor: pointer; padding: 12px 16px; background: var(--card); border: 1px solid var(--line);
  border-radius: 12px; list-style: none; font-weight: 600; color: var(--muted); }
.op-adv[open] > summary { border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
.op-adv > summary::-webkit-details-marker { display: none; }

/* round 11 — progressive disclosure (pt 2): on /studio, only the Start button shows until the first
   Start; .reveal blocks (STOP/BLACKOUT, the cards, presets, QR, share) appear when .pre-start clears. */
.op-console.pre-start .reveal,
.op-console.pre-start #shareBlock { display: none !important; }
/* the Start button's loading spinner (pt 2) — pure CSS, no asset */
.spin { display: inline-block; width: 0.9em; height: 0.9em; vertical-align: -0.1em; margin-left: 6px;
  border: 2px solid rgba(0,0,0,.25); border-top-color: #04222c; border-radius: 50%; animation: cls-spin 0.7s linear infinite; }
@keyframes cls-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .spin { animation: none; } }
/* round 11 (pt 10): the Live-presets card fills its full-width disclosure (not a narrow column) */
#studioCard { width: 100%; }
/* round 11 (pt 19): the audience scrolling marquee — a SEPARATE text overlay above the flash layer
   (z-index 4 > #flash 1 / #stage 2). Text + translucent bg only; a smooth horizontal transform (no
   luminance pulsing) so it can never affect the epilepsy flash-rate cap. Short text simply repeats. */
#marquee { position: fixed; left: 0; right: 0; bottom: env(safe-area-inset-bottom, 0); z-index: 4;
  overflow: hidden; white-space: nowrap; pointer-events: none; background: rgba(0,0,0,.45); color: #fff;
  font: 600 5vw/1.6 system-ui, -apple-system, sans-serif; text-shadow: 0 1px 3px #000; padding: 6px 0; }
#marquee.hidden { display: none; }
#marqueeInner { display: inline-block; padding-left: 100%; animation: cls-marq 12s linear infinite; }
@keyframes cls-marq { from { transform: translateX(0); } to { transform: translateX(-100%); } }

/* round 16 (#1): the SHARE-THIS-SHOW QR on the audience's live (flashing) screen.
   SIZE — a QR is read reliably at roughly 10x its own width, and a friend's camera is 30-50 cm away,
   so it has to be a real object (~3 cm), not a badge: min(44vw, 26vh, 186px) lands at ~29-30 mm on a
   phone, which a modern camera reads comfortably at 30-40 cm while leaving most of the screen to the
   light show. The 26vh term keeps a short/landscape screen from being swallowed by it, and the 186px
   cap stops a tablet painting a billboard. At 600px source / ~180px box a DPR-2/3 phone downsamples
   by <=1.7x, so the modules stay crisp (image-rendering: pixelated, like the console .qrbox).
   PLACE — bottom-centre, ABOVE the waveform strip (which owns 44-88px), clear of the top-right Stop
   button and the bottom marquee. The whole upper screen therefore stays pure colour: the light show
   itself (and photos of it) is unchanged, and the code sits on the edge nearest a person beside you.
   CONTRAST — solid white card with a dark ring: it must still scan over a WHITE flash frame, so the
   card can never be translucent. It is a static image: no luminance change, no effect on the flash-
   rate governor. */
#shareQr { position: fixed; left: 50%; transform: translateX(-50%); z-index: 5;
  bottom: calc(116px + env(safe-area-inset-bottom, 0px));
  display: flex; flex-direction: column; align-items: center; gap: 6px; max-width: 92vw; }
#shareQrCap { background: rgba(0,0,0,.62); color: #fff; font-size: .76rem; font-weight: 600;
  line-height: 1.25; text-align: center; padding: 4px 10px; border-radius: 999px; max-width: 86vw;
  text-shadow: 0 1px 2px #000; pointer-events: none; }
#shareQrBox { position: relative; padding: 8px; line-height: 0; border-radius: 14px; cursor: pointer;
  background: #fff; border: 2px solid rgba(0,0,0,.55); box-shadow: 0 6px 22px rgba(0,0,0,.45); }
#shareQrImg { display: block; width: min(44vw, 26vh, 186px); height: auto; aspect-ratio: 1 / 1;
  image-rendering: pixelated; }
/* The explicit "hide" affordance — a real ✕ beside the card, so nobody has to guess that the card is
   tappable. 44x44 to meet the WCAG 2.5.8 target size, and placed just OUTSIDE the card rather than on
   its corner: overlapping the quiet zone (or the top-right finder pattern behind it) is exactly what
   makes a code fail to scan in a dark room, which is the one job this code has. */
#shareQrHide { position: absolute; top: -6px; right: -52px; width: 44px; height: 44px; margin: 0;
  padding: 0; border-radius: 50%; font-size: 15px; line-height: 1; display: flex; align-items: center;
  justify-content: center; background: rgba(0,0,0,.82); color: #fff; border: 1px solid rgba(255,255,255,.45);
  box-shadow: 0 2px 8px rgba(0,0,0,.5); }
#shareQrPill { position: fixed; right: 12px; z-index: 5; width: auto; margin: 0;
  bottom: calc(116px + env(safe-area-inset-bottom, 0px)); padding: 8px 12px; font-size: .85rem;
  background: rgba(0,0,0,.6); color: #fff; border-color: rgba(255,255,255,.4); }
/* Short screens (a phone in landscape): drop the caption and lean on the WIDTH, which is plentiful
   there — sizing off 30vh gave ~19 mm, well under the ~3 cm this file says a camera needs, so the
   code stopped being scannable exactly where there was room for it. */
@media (max-height: 560px) {
  #shareQrImg { width: min(26vw, 46vh, 168px); }
  #shareQrCap { display: none; }
}

/* round 14: VJ pult faux-fullscreen (when the Fullscreen API is unavailable, e.g. iOS Safari) */
#vjCard.vj-faux-full { position: fixed; inset: 0; z-index: 9999; margin: 0; overflow: auto; border-radius: 0; }
#vjCard:fullscreen { overflow: auto; padding: 18px; }
#vjStage { user-select: none; -webkit-user-select: none; touch-action: none; }
/* round 16.2: the XY pad grew, so its vertical faders grow with it — a 170 px fader next to a 300 px
   pad reads as broken, and the pad itself needs the room to make a hue drag precise. */
#vjStage .vj-fader-track { height: min(52vh, 420px); min-height: 300px; }

/* round 15c: audience /join — grandma-test flow. One big confirm button on the first screen; after it,
   a prominent flashlight join + a quiet screen-only fallback so people reach for the flashlight more. */
.cls-bigcta { width: 100%; padding: 18px 16px; font-size: 1.15rem; font-weight: 800; margin-top: 12px; border-radius: 12px; }
#joinScreen.cls-quiet { background: transparent; color: #9aa3b2; border: 1px solid rgba(255,255,255,.16); box-shadow: none; font-weight: 600; padding: 11px 14px; font-size: .96rem; margin-top: 10px; }
.cls-how { margin-top: 16px; }
.cls-how > summary { cursor: pointer; color: #8b93a7; font-size: .9rem; padding: 6px 0; }
.cls-how p { margin-top: 8px; }
.cls-jointip { margin-top: 16px; font-size: .96rem; text-align: center; }

/* Bobcat Light Show identity: a high-contrast game-night working surface. */
.landing-page,
.operator-page {
  background:
    radial-gradient(circle at 15% 0%, rgba(17, 123, 68, .30), transparent 34rem),
    linear-gradient(145deg, #050806 0%, #07130c 48%, #030504 100%);
}

.landing-page::before,
.operator-page::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: .12;
  background-image:
    linear-gradient(rgba(255,255,255,.08) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,.08) 1px, transparent 1px);
  background-size: 44px 44px;
  mask-image: linear-gradient(to bottom, black, transparent 75%);
}

.bobcat-shell {
  width: min(1120px, calc(100% - 32px));
  min-height: 100dvh;
  margin: 0 auto;
  padding: clamp(24px, 5vw, 64px) 0 28px;
  display: flex;
  flex-direction: column;
}

.brand-lockup {
  display: flex;
  align-items: center;
  gap: clamp(16px, 3vw, 30px);
}

.brand-logo {
  width: clamp(90px, 15vw, 154px);
  height: clamp(90px, 15vw, 154px);
  object-fit: contain;
  filter: drop-shadow(0 14px 24px rgba(0,0,0,.38));
}

.brand-lockup h1 {
  margin: 2px 0 1px;
  font-size: clamp(2rem, 5vw, 5rem);
  line-height: .92;
  letter-spacing: -.055em;
  text-transform: uppercase;
  text-wrap: balance;
}

.brand-kicker,
.eyebrow {
  margin: 0;
  color: #75d49f;
  font-size: .75rem;
  font-weight: 900;
  letter-spacing: .18em;
  text-transform: uppercase;
}

.brand-line { margin: 10px 0 0; color: var(--silver); font-weight: 700; }

.launch-panel {
  margin: clamp(42px, 8vw, 94px) 0 42px;
  padding: clamp(24px, 5vw, 54px);
  border: 1px solid rgba(137, 181, 153, .28);
  border-left: 7px solid var(--accent-bright);
  border-radius: 6px 24px 24px 6px;
  background: linear-gradient(135deg, rgba(15,32,21,.96), rgba(7,16,10,.92));
  box-shadow: var(--shadow);
}

.launch-panel h2 {
  max-width: 850px;
  margin: 16px 0;
  font-size: clamp(2.25rem, 7vw, 6.6rem);
  line-height: .94;
  letter-spacing: -.06em;
  text-wrap: balance;
}

.launch-copy {
  max-width: 700px;
  margin: 0;
  color: #c8d5cd;
  font-size: clamp(1rem, 2.1vw, 1.3rem);
}

.launch-button {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  width: min(100%, 560px);
  margin: 30px 0 16px;
  padding: 20px 22px;
  border: 1px solid #2fc878;
  border-radius: 12px;
  background: linear-gradient(135deg, #0b7541, #07552f);
  color: #fff;
  font-size: clamp(1.05rem, 2vw, 1.25rem);
  font-weight: 900;
  text-decoration: none;
  box-shadow: 0 14px 34px rgba(11,117,65,.28);
}

.launch-button:hover { filter: brightness(1.13); transform: translateY(-1px); }
.launch-button span { font-size: 1.5em; line-height: 0; }

.status-dot {
  display: inline-block;
  width: 9px;
  height: 9px;
  flex: 0 0 auto;
  border-radius: 50%;
  background: #27d978;
  box-shadow: 0 0 0 4px rgba(39,217,120,.13), 0 0 18px rgba(39,217,120,.9);
}

.status-dot-warn {
  background: var(--warn);
  box-shadow: 0 0 0 4px rgba(255,209,102,.12);
}

.system-readout {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 24px;
  color: #b7c5bc;
  font-size: .9rem;
  font-weight: 700;
}

.join-steps {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
  margin-top: 34px;
}

.join-steps > div {
  min-width: 0;
  padding: 16px;
  border: 1px solid rgba(255,255,255,.09);
  border-radius: 12px;
  background: rgba(255,255,255,.035);
}

.join-steps span {
  display: block;
  color: #6ec996;
  font-size: .72rem;
  font-weight: 900;
  letter-spacing: .14em;
}

.join-steps b { display: block; margin: 8px 0 4px; font-size: .98rem; }
.join-steps small { display: block; color: var(--muted); line-height: 1.4; }

.landing-footer {
  margin-top: auto;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  color: #79877f;
  font-size: .79rem;
}

.landing-footer a { color: #a9b8af; }

/* Audience join */
.audience-page { background: #000; }

.audience-wrap {
  width: min(calc(100% - 24px), 580px);
  margin: 14px auto;
  padding: 22px;
  border: 1px solid rgba(145,180,157,.26);
  border-top: 5px solid var(--accent-bright);
  border-radius: 18px;
  background: linear-gradient(155deg, rgba(14,30,19,.98), rgba(5,10,7,.98));
  box-shadow: var(--shadow);
}

.audience-brand { display: flex; align-items: center; gap: 12px; margin-bottom: 26px; }
.audience-brand img { width: 62px; height: 62px; object-fit: contain; }
.audience-brand span {
  display: block;
  color: #7ed7a5;
  font-size: .66rem;
  font-weight: 900;
  letter-spacing: .16em;
  text-transform: uppercase;
}
.audience-brand strong {
  display: block;
  margin-top: 3px;
  font-size: 1.05rem;
  text-transform: uppercase;
  letter-spacing: .025em;
}
.audience-wrap h1 {
  margin-top: 8px;
  font-size: clamp(2.1rem, 10vw, 3.6rem);
  line-height: .95;
  letter-spacing: -.045em;
}
.audience-lead { margin: 12px 0 18px; color: #c7d3cb; font-size: 1.05rem; }
.safety-card { margin-top: 18px; background: rgba(255,209,102,.06); }
.safety-card p { margin-bottom: 0; font-size: .91rem; }
.audience-credit {
  margin-top: 26px;
  padding-top: 18px;
  border-top: 1px solid rgba(255,255,255,.08);
  line-height: 1.55;
}
.audience-credit span { color: #75827a; }
.audience-live {
  padding-top: 74px;
  text-align: center;
  color: #fff;
  text-shadow: 0 2px 9px rgba(0,0,0,.9);
}
.audience-live h1 { font-size: clamp(1.7rem, 8vw, 3rem); }
.audience-live p { color: #fff; font-weight: 700; }
.live-badge {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 8px 12px;
  border: 1px solid rgba(255,255,255,.35);
  border-radius: 999px;
  background: rgba(0,0,0,.55);
  font-size: .74rem;
  font-weight: 900;
  letter-spacing: .09em;
  text-transform: uppercase;
}
.audience-left { padding-top: 90px; text-align: center; }
.left-logo { width: 140px; max-width: 45vw; }
.back-link { display: block; margin-top: 18px; color: #b9c8bf; }

/* Crowd messages are large enough to read across the bleachers. */
#marquee {
  top: auto;
  bottom: env(safe-area-inset-bottom, 0);
  padding: 12px 0 14px;
  border-top: 5px solid var(--accent-bright);
  background: rgba(0, 10, 5, .88);
  color: #fff;
  font: 900 clamp(2rem, 12vw, 5.4rem)/1.1 Inter, ui-sans-serif, system-ui, sans-serif;
  letter-spacing: -.03em;
  text-shadow: 0 3px 10px #000;
}

#marqueeInner { padding-left: 100%; animation-duration: 11s; }

/* Operator dashboard */
.operator-page { min-height: 100dvh; }
.op-console { max-width: 1240px; padding: 26px 18px 60px; }

.operator-masthead {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 14px 0 20px;
  border-bottom: 1px solid rgba(255,255,255,.10);
}

.operator-masthead img {
  width: 82px;
  height: 82px;
  object-fit: contain;
  filter: drop-shadow(0 9px 16px rgba(0,0,0,.35));
}

.operator-masthead > div:nth-child(2) { min-width: 0; }
.operator-masthead span {
  color: #79d5a2;
  font-size: .68rem;
  font-weight: 900;
  letter-spacing: .15em;
  text-transform: uppercase;
}
.operator-masthead h1 {
  margin: 3px 0 0;
  font-size: clamp(1.65rem, 4vw, 2.8rem);
  line-height: .95;
  letter-spacing: -.04em;
  text-transform: uppercase;
}
.operator-masthead p {
  margin: 5px 0 0;
  color: var(--silver);
  font-size: .78rem;
  font-weight: 800;
  letter-spacing: .12em;
  text-transform: uppercase;
}

.operator-badge {
  margin-left: auto;
  padding: 7px 10px;
  border: 1px solid rgba(118,207,157,.35);
  border-radius: 999px;
  color: #a9dcbc;
  background: rgba(10,93,50,.18);
  font-size: .68rem;
  font-weight: 800;
  white-space: nowrap;
}

.operator-statusbar {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 24px;
  padding: 12px 14px;
  border: 1px solid rgba(255,255,255,.09);
  border-radius: 10px;
  background: rgba(0,0,0,.24);
  color: var(--muted);
  font-size: .83rem;
}

.operator-statusbar > span { display: inline-flex; align-items: center; gap: 7px; }
.operator-statusbar b { color: #fff; }

.operator-page .card {
  border-radius: 12px;
  border-color: rgba(103,153,120,.26);
  background: rgba(15,24,18,.95);
  box-shadow: 0 14px 30px rgba(0,0,0,.18);
}

.operator-page .card > h2:first-child { margin-top: 0; }
.step-number {
  display: inline-block;
  margin-right: 7px;
  color: #58bc83;
  font-size: .7em;
  font-weight: 900;
  letter-spacing: .1em;
  vertical-align: .12em;
}

.message-card {
  border: 1px solid rgba(35,180,99,.62) !important;
  border-left: 6px solid var(--accent-bright) !important;
  background: linear-gradient(135deg, rgba(9,44,25,.98), rgba(13,22,16,.98)) !important;
}

.card-heading { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.card-heading > div { display: flex; align-items: baseline; }
.card-heading h2 { margin: 0; font-size: clamp(1.15rem, 2.4vw, 1.55rem); }
.safe-label {
  padding: 5px 8px;
  border: 1px solid rgba(255,255,255,.12);
  border-radius: 999px;
  color: #9ac8ad;
  font-size: .68rem;
  font-weight: 800;
  white-space: nowrap;
}

.message-entry {
  display: grid;
  grid-template-columns: minmax(220px, 1fr) auto auto;
  gap: 8px;
  align-items: stretch;
}

.message-entry input {
  min-height: 51px;
  border-color: rgba(48,180,104,.48);
  background: rgba(0,0,0,.42);
  font-size: 1rem;
}

.message-entry button { width: auto; min-height: 51px; margin: 0; }
.quick-messages { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 10px; }
.quick-messages button {
  width: auto;
  margin: 0;
  padding: 9px 11px;
  border-color: rgba(126,203,155,.24);
  background: rgba(255,255,255,.055);
  color: #d9e8de;
  font-size: .74rem;
  font-weight: 800;
}
.quick-messages button:hover { border-color: #46b978; background: rgba(19,123,65,.26); }
.message-status { min-height: 1.3em; margin: 8px 0 0; color: #8ee0b0; font-weight: 700; }

.operator-page button:hover { filter: brightness(1.14); }
.operator-page button:focus-visible,
.landing-page a:focus-visible,
.audience-page button:focus-visible { outline: 3px solid #fff; outline-offset: 3px; }
.operator-page input[type=file] {
  width: 100%;
  padding: 11px;
  border: 1px dashed rgba(126,203,155,.32);
  border-radius: 10px;
  background: rgba(0,0,0,.23);
  color: var(--muted);
}
.operator-page input[type=range] { accent-color: var(--accent-bright); }
.operator-page .pill {
  background: rgba(16,117,63,.24);
  color: #b8e1c7;
  border: 1px solid rgba(70,185,120,.25);
}
.operator-page .qrbox { border: 8px solid #fff; border-radius: 10px; }
.operator-page .op-adv > summary {
  border-color: rgba(103,153,120,.28);
  background: rgba(15,24,18,.97);
  color: #e9f1ec;
}

@media (min-width: 980px) {
  .op-console > .operator-masthead,
  .op-console > .operator-statusbar,
  .op-console > .message-card { grid-column: 1 / -1; }
  .message-card { padding: 24px; }
}

@media (max-width: 680px) {
  .bobcat-shell { width: min(calc(100% - 22px), 1120px); padding-top: 18px; }
  .brand-logo { width: 86px; height: 86px; }
  .brand-lockup h1 { font-size: clamp(1.9rem, 10vw, 2.8rem); }
  .brand-line { font-size: .8rem; }
  .launch-panel { margin-top: 34px; padding: 23px 18px; border-left-width: 5px; }
  .join-steps { grid-template-columns: 1fr; }
  .landing-footer { justify-content: center; text-align: center; }
  .operator-masthead { align-items: flex-start; }
  .operator-masthead img { width: 60px; height: 60px; }
  .operator-badge { display: none; }
  .operator-statusbar { justify-content: space-between; }
  .card-heading { align-items: flex-start; flex-direction: column; }
  .message-entry { grid-template-columns: 1fr 1fr; }
  .message-entry input { grid-column: 1 / -1; }
  .message-entry #mqSend { grid-column: 1; }
  .message-entry #mqClear { grid-column: 2; }
  .nudge { flex-wrap: wrap; }
}

@media (prefers-reduced-motion: reduce) {
  .launch-button { transition: none; }
  #marqueeInner { animation-duration: 18s; }
}
