/* channel01.tv — design tokens and objects. DESIGN.md is binding.
   Light model: one warm key light upper-left; the screen is a second
   (phosphor) light source glowing into a dim room. Every surface carries
   that model: top edges catch light, bottoms occlude, objects cast shadow. */

:root {
  --ground: oklch(0.22 0.02 60);
  --ground-lit: oklch(0.285 0.028 62);
  --walnut: oklch(0.38 0.06 55);
  --walnut-light: oklch(0.44 0.065 57);
  --walnut-deep: oklch(0.3 0.05 55);
  --walnut-black: oklch(0.22 0.04 55);
  --cream: oklch(0.92 0.03 85);
  --cream-bright: oklch(0.96 0.02 85);
  --cream-shade: oklch(0.84 0.04 85);
  --cream-deep: oklch(0.72 0.045 82);
  --signal-red: oklch(0.55 0.19 30);
  --signal-red-deep: oklch(0.45 0.17 30);
  --phosphor: oklch(0.82 0.17 145);
  --newsprint: oklch(0.95 0.02 90);
  --ink: oklch(0.25 0.01 60);
  --tube-black: oklch(0.16 0.012 60);
  --shadow-ink: oklch(0.08 0.02 60);

  --serif: "Source Serif 4", georgia, serif;
  --grotesk: "Barlow", helvetica, arial, sans-serif;
  --grotesk-narrow: "Barlow Condensed", "Barlow", helvetica, sans-serif;
  --teletext: "VT323", monospace;
  --display: "Rammetto One", "Barlow", sans-serif;

  --out-quint: cubic-bezier(0.22, 1, 0.36, 1);
}

* { box-sizing: border-box; }

[hidden] { display: none !important; }

/* Present for crawlers and screen readers, invisible on the set. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

html, body {
  margin: 0;
  color: var(--cream);
  font-family: var(--grotesk);
}

/* The room: a pool of warm light where the set sits, darker at the walls. */
body {
  background:
    radial-gradient(ellipse 85% 68% at 56% 42%, var(--ground-lit), transparent 72%),
    var(--ground);
  background-attachment: fixed;
}

button {
  font: inherit;
  cursor: pointer;
  border: none;
  background: none;
  color: inherit;
}

:focus-visible {
  outline: 2px solid var(--cream);
  outline-offset: 3px;
}

/* ---------- layout ---------- */

.stage {
  position: relative;
  min-height: 100svh;
  max-width: 1600px;
  margin: 0 auto;
  padding: 36px 32px 72px;
  display: grid;
  grid-template-columns: minmax(240px, 330px) minmax(0, 1fr);
  grid-template-areas: "editorial tv";
  gap: 20px 24px;
  align-items: center;
}

/* Orchestrated page load: the set first, then the words. */
@media (prefers-reduced-motion: no-preference) {
  .editorial, .tv-area { animation: rise 760ms var(--out-quint) backwards; }
  .tv-area { animation-delay: 60ms; }
  .editorial { animation-delay: 220ms; }
  @keyframes rise {
    from { opacity: 0; transform: translateY(22px); }
  }
}

/* ---------- editorial column ---------- */

.editorial {
  grid-area: editorial;
  max-width: 34ch;
}

/* The station ident: mark + wordmark, sat level with the top of the set. */
.brand {
  display: flex;
  align-items: center;
  gap: 12px;
}
.brand-mark {
  width: 44px;
  height: 37px;
  flex: none;
  color: var(--cream);
}
.brand-mark-ch {
  font-family: var(--teletext);
  font-size: 13px;
  fill: var(--phosphor);
}
.brand-name {
  margin: 0;
  font-family: var(--display);
  font-size: clamp(21px, 1.7vw, 25px);
  letter-spacing: 0.01em;
  color: var(--cream-bright);
  text-shadow: 0 1px 0 oklch(0 0 0 / 0.35);
}
.brand-name span { color: var(--cream-shade); }

/* The brand pins to the row top (level with the set); the pitch centers
   in the space that remains. */
.editorial { align-self: stretch; display: flex; flex-direction: column; }
.editorial-body { margin: auto 0; }

.editorial h1 {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(34px, 3.4vw, 52px);
  line-height: 1.16;
  margin: 0 0 20px;
  text-shadow: 0 1px 0 oklch(0 0 0 / 0.3);
}

.lede {
  font-family: var(--grotesk);
  font-size: 15px;
  line-height: 1.6;
  color: var(--cream-shade);
  margin: 0;
}
.lede-holder {
  color: inherit;
  font-weight: 700;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.lede-holder:hover { color: var(--cream-bright); }

/* The one red key outside the set: claim the top spot at today's price. */
.hero-claim {
  margin-top: 20px;
  background: linear-gradient(180deg, oklch(0.6 0.19 30), var(--signal-red) 45%);
  color: var(--cream-bright);
  font-weight: 600;
  font-size: 13px;
  letter-spacing: 0.1em;
  padding: 11px 18px;
  border-radius: 6px;
  white-space: nowrap;
  box-shadow:
    inset 0 1px 0 oklch(1 0 0 / 0.25),
    0 2px 0 var(--signal-red-deep),
    0 5px 8px -3px oklch(0 0 0 / 0.4);
  transition: transform 90ms var(--out-quint), box-shadow 90ms var(--out-quint), filter 150ms;
}
.hero-claim:hover { filter: brightness(1.07); }
.hero-claim:active {
  transform: translateY(2px);
  box-shadow: inset 0 1px 2px oklch(0 0 0 / 0.3), 0 0 0 var(--signal-red-deep);
}

/* Quiet second door to the board, for those who miss the GUIDE key. */
.hero-guide {
  display: block;
  margin-top: 12px;
  padding: 0;
  font-family: var(--grotesk-narrow);
  font-size: 12px;
  letter-spacing: 0.14em;
  color: var(--cream-shade);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.hero-guide:hover { color: var(--cream-bright); }

/* Nielsen-style station ratings: hairline rules, tabular figures. */
.ratings {
  margin: 28px 0 0;
  padding: 14px 0 12px;
  border-top: 1px solid oklch(0.36 0.03 60);
  border-bottom: 1px solid oklch(0.36 0.03 60);
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px 16px;
}
.ratings dt {
  font-family: var(--grotesk-narrow);
  font-size: 11px;
  letter-spacing: 0.14em;
  color: var(--cream-shade);
  margin: 0 0 3px;
}
.ratings dd {
  font-family: var(--serif);
  font-size: clamp(20px, 1.7vw, 27px);
  line-height: 1.1;
  margin: 0;
  color: var(--cream-bright);
  font-variant-numeric: tabular-nums;
}
/* Last bids, stacked like a station log. */
.onair-log { margin-top: 20px; }
.log-title {
  font-family: var(--grotesk-narrow);
  font-size: 11px;
  letter-spacing: 0.14em;
  color: var(--cream-shade);
  margin: 0 0 6px;
}
.log-list {
  list-style: none;
  margin: 0;
  padding: 0;
  font-family: var(--grotesk);
  font-size: 13px;
}
.log-list li {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 6px 0;
  border-bottom: 1px dotted oklch(0.33 0.03 60);
}
.log-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  text-align: left;
  padding: 0;
  color: inherit;
  text-decoration: none;
}
.log-name:hover { color: var(--cream-bright); text-decoration: underline; text-underline-offset: 2px; }
.log-amt { color: var(--cream-bright); margin-left: auto; }
.log-time { color: var(--cream-shade); font-size: 11px; letter-spacing: 0.06em; white-space: nowrap; }
.log-empty { color: var(--cream-shade); letter-spacing: 0.05em; }

/* ---------- the TV ---------- */

.tv-area {
  grid-area: tv;
  min-width: 0;
  justify-self: center;
  width: min(1320px, 100%, calc((100svh - 104px) * 1.52));
}

.tv { position: relative; }

.tv-photo {
  display: block;
  width: 100%;
  height: auto;
  user-select: none;
  filter: drop-shadow(0 22px 28px oklch(0.08 0.02 60 / 0.5));
}

/* Live tube sits in the photographed CRT well. */
  .screen {
    position: absolute;
    left: 10.7%;
    top: 12.7%;
    width: 63.4%;
    height: 73.4%;
  border-radius: 9% / 11%;
  overflow: hidden;
  background: var(--tube-black);
  cursor: pointer;
  outline-offset: 4px;
}

.shot {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top center;
  transition: filter 300ms var(--out-quint);
}
.screen:hover .shot { filter: brightness(1.05) saturate(1.05); }

/* Glass: corner falloff of the tube, diagonal reflection sweep,
   top curvature highlight, scanlines. Never leaves the screen. */
.screen::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(ellipse 145% 132% at 50% 48%, transparent 58%, oklch(0 0 0 / 0.42) 100%),
    linear-gradient(112deg, oklch(1 0 0 / 0.1) 0%, oklch(1 0 0 / 0.03) 16%, transparent 30%),
    radial-gradient(ellipse 110% 80% at 32% 10%, oklch(1 0 0 / 0.09), transparent 52%),
    repeating-linear-gradient(to bottom, oklch(0 0 0 / 0.15) 0 1px, transparent 1px 3px);
  border-radius: inherit;
}

/* CRT power-on: a phosphor beam draws across, blooms, and hands over. */
.poweron {
  position: absolute;
  inset: 0;
  z-index: 6;
  background: var(--tube-black);
  pointer-events: none;
}
.poweron i {
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: 2px;
  margin-top: -1px;
  border-radius: 2px;
  background: oklch(0.95 0.09 145);
  box-shadow: 0 0 22px 5px oklch(0.85 0.15 145 / 0.9);
  transform: scaleX(0);
}
@media (prefers-reduced-motion: no-preference) {
  .poweron { animation: po-fade 1050ms var(--out-quint) 250ms forwards; }
  .poweron i { animation: po-beam 1050ms var(--out-quint) 250ms forwards; }
}
@media (prefers-reduced-motion: reduce) {
  .poweron { display: none; }
}
@keyframes po-beam {
  0% { transform: scaleX(0) scaleY(1); opacity: 1; }
  42% { transform: scaleX(1) scaleY(1); opacity: 1; }
  74% { transform: scaleX(1) scaleY(220); opacity: 0.5; }
  100% { transform: scaleX(1) scaleY(280); opacity: 0; }
}
@keyframes po-fade {
  0%, 55% { opacity: 1; }
  100% { opacity: 0; visibility: hidden; }
}

.static {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  opacity: 0;
}

/* channel change: the tube over-brightens for a beat, then settles */
@media (prefers-reduced-motion: no-preference) {
  .screen.burst { animation: tube-bloom 340ms var(--out-quint); }
  @keyframes tube-bloom {
    0% { filter: brightness(1.65) saturate(0.6); }
    100% { filter: brightness(1) saturate(1); }
  }
}

.osd {
  position: absolute;
  top: 5%;
  right: 6%;
  font-family: var(--teletext);
  font-size: clamp(20px, 2.4vw, 34px);
  color: var(--phosphor);
  text-shadow: 0 0 8px var(--phosphor);
  letter-spacing: 0.06em;
}
@media (prefers-reduced-motion: no-preference) {
  .osd { animation: phosphor-breathe 4.5s ease-in-out infinite; }
  @keyframes phosphor-breathe {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.86; }
  }
}

/* Transient channel feedback lives in the caption strip, where NO SIGNAL
   sits; the label yields while the message is up. */
.osd-msg {
  position: absolute;
  left: 6%;
  bottom: 3.2%;
  right: 6%;
  text-align: center;
  font-family: var(--teletext);
  font-size: clamp(17px, 1.9vw, 26px);
  color: var(--phosphor);
  text-shadow: 0 0 8px var(--phosphor);
}
@media (prefers-reduced-motion: no-preference) {
  .osd-msg { animation: osd-in 240ms var(--out-quint); }
  @keyframes osd-in {
    0% { opacity: 0; transform: translateY(4px); }
    60% { opacity: 1; }
    70% { opacity: 0.6; }
    100% { opacity: 1; transform: none; }
  }
}

/* NO SIGNAL — SMPTE bars */
.nosignal {
  position: absolute;
  inset: 0;
  display: grid;
  grid-template-rows: 1fr auto;
  /* Keep the label clear of the lower-third caption band. */
  padding-bottom: 9%;
  background: var(--tube-black);
}
.bars { display: flex; }
.bars i { flex: 1; }
.bars i:nth-child(1) { background: oklch(0.78 0.02 90); }
.bars i:nth-child(2) { background: oklch(0.75 0.16 100); }
.bars i:nth-child(3) { background: oklch(0.7 0.15 195); }
.bars i:nth-child(4) { background: oklch(0.65 0.18 145); }
.bars i:nth-child(5) { background: oklch(0.55 0.22 330); }
.bars i:nth-child(6) { background: oklch(0.5 0.2 30); }
.bars i:nth-child(7) { background: oklch(0.45 0.19 265); }
.nosignal-label {
  margin: 0;
  padding: 10px 0 14px;
  text-align: center;
  font-family: var(--teletext);
  font-size: clamp(18px, 2vw, 28px);
  color: var(--phosphor);
  background: var(--tube-black);
}

/* X-handle broadcast card */
.handlecard {
  position: absolute;
  inset: 0;
  display: grid;
  place-content: center;
  gap: 10px;
  text-align: center;
  background: var(--tube-black);
}
.handlecard-h {
  margin: 0;
  font-family: var(--teletext);
  font-size: clamp(34px, 4.4vw, 64px);
  color: var(--phosphor);
  text-shadow: 0 0 12px var(--phosphor);
}
.handlecard-sub {
  margin: 0;
  font-family: var(--teletext);
  font-size: clamp(15px, 1.6vw, 22px);
  color: var(--phosphor);
  opacity: 0.75;
  letter-spacing: 0.2em;
}

/* ---------- side panel controls ----------
   The keypad is photographed into the cabinet's side panel. Every control
   is an invisible hit area measured off the image; pressing darkens the
   key itself, like a finger shading the plastic. */

.panel-hits { position: absolute; inset: 0; pointer-events: none; }
.panel-hits button { pointer-events: auto; }

.knob-rotor {
  position: absolute;
  left: 81.67%;
  top: 12.06%;
  width: 11.67%;
  height: 17.77%;
  pointer-events: none;
  user-select: none;
  transition: transform 420ms var(--out-quint);
}
@media (prefers-reduced-motion: reduce) {
  .knob-rotor { transition: none; }
}

.knob-hit {
  position: absolute;
  left: 81.4%;
  top: 12.2%;
  width: 12.8%;
  height: 17%;
  border-radius: 50%;
  background: transparent;
  transition: background 90ms;
}
.knob-hit:hover { background: oklch(1 0 0 / 0.05); }
.knob-hit:active { background: oklch(0 0 0 / 0.14); }

.pad {
  position: absolute;
  left: 81.1%;
  top: 33%;
  width: 12.9%;
  height: 23.5%;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(4, 1fr);
  gap: 2% 4%;
}
.pad-zero { grid-column: 2; }

.rocker {
  position: absolute;
  left: 81.2%;
  top: 56.6%;
  width: 12.5%;
  height: 10.2%;
  display: grid;
  gap: 8%;
}

.remote-row {
  position: absolute;
  left: 81.2%;
  top: 67.7%;
  width: 12.6%;
  height: 5.2%;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 5%;
}

.remote-claim {
  position: absolute;
  left: 81.3%;
  top: 74.2%;
  width: 12.9%;
  height: 6.2%;
}

.panel-hits .pad button,
.panel-hits .rocker button,
.panel-hits .remote-row button,
.panel-hits .remote-claim {
  background: transparent;
  transition: background 80ms;
}
.panel-hits .pad button { border-radius: 50%; margin: 4%; }
/* Focus reads as light on the key, not a printed ring: the hit areas only
   approximate the photographed keys, and a crisp outline betrays the gap. */
.panel-hits button:focus-visible {
  outline: none;
  background: oklch(0.82 0.17 145 / 0.14);
  box-shadow: 0 0 12px 3px oklch(0.82 0.17 145 / 0.5);
}
.panel-hits .rocker button,
.panel-hits .remote-row button { border-radius: 16% / 42%; }
.panel-hits .remote-claim { border-radius: 12% / 30%; }
.panel-hits button:active { background: oklch(0 0 0 / 0.16); }
.remote-row button[aria-pressed="true"] {
  background: oklch(0.82 0.17 145 / 0.12);
  box-shadow: 0 0 10px oklch(0.82 0.17 145 / 0.3);
}

/* Invisible hit over the photographed slide switch. */
.sound-toggle {
  position: absolute;
  left: 82%;
  top: 80.3%;
  width: 10.4%;
  height: 7.6%;
  border-radius: 8%;
  background: transparent;
  transition: background 90ms, box-shadow 160ms;
}
.sound-toggle:active { background: oklch(0 0 0 / 0.14); }
.sound-toggle[aria-pressed="true"] {
  box-shadow: 0 0 12px 2px oklch(0.55 0.19 30 / 0.4);
}

/* ---------- claim menu (diegetic, on the screen) ---------- */

.menu {
  position: absolute;
  inset: 0;
  /* Opaque: the tube behind (NO SIGNAL, lower third) must not bleed through. */
  background: oklch(0.16 0.012 60);
  padding: clamp(14px, 3%, 32px) clamp(18px, 5%, 48px);
  overflow-y: auto;
  font-family: var(--teletext);
  color: var(--phosphor);
}
/* Boots like an OSD menu: unfolds vertically with one flicker. */
@media (prefers-reduced-motion: no-preference) {
  .menu { animation: menu-boot 340ms var(--out-quint); transform-origin: 50% 46%; }
  @keyframes menu-boot {
    0% { opacity: 0; transform: scaleY(0.04); }
    55% { opacity: 1; transform: scaleY(1.01); }
    100% { opacity: 1; transform: scaleY(1); }
  }
}
.menu-title {
  margin: 0 0 12px;
  font-size: clamp(22px, 2.4vw, 34px);
  letter-spacing: 0.12em;
  text-shadow: 0 0 8px var(--phosphor);
}
.menu-label {
  display: block;
  font-size: clamp(14px, 1.3vw, 18px);
  opacity: 0.75;
  margin: 10px 0 4px;
  letter-spacing: 0.08em;
}
.menu-input {
  width: 100%;
  background: oklch(0.22 0.02 145);
  border: 1px solid var(--phosphor);
  color: var(--phosphor);
  font-family: var(--teletext);
  font-size: clamp(17px, 1.7vw, 24px);
  padding: 7px 10px;
  border-radius: 3px;
}
.menu-input:focus { outline: 2px solid var(--phosphor); outline-offset: 1px; }
.menu-input::-webkit-outer-spin-button,
.menu-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.menu-input[type="number"] { -moz-appearance: textfield; appearance: textfield; }
/* The currency is printed on the field; you only type the digits. */
.menu-amount { position: relative; }
.menu-amount-prefix {
  position: absolute;
  left: 10px;
  top: 50%;
  transform: translateY(-50%);
  font-size: clamp(17px, 1.7vw, 24px);
  pointer-events: none;
}
.menu-amount .menu-input { padding-left: calc(10px + 0.5em); }
.menu-quote {
  margin: 12px 0 2px;
  font-size: clamp(16px, 1.6vw, 22px);
  min-height: 1.4em;
}
.menu-note { margin: 2px 0 0; font-size: clamp(13px, 1.2vw, 16px); opacity: 0.65; }
.menu-error { margin: 6px 0 0; font-size: clamp(14px, 1.4vw, 19px); min-height: 1.3em; color: var(--phosphor); }
.menu-error:not(:empty)::before { content: "!! "; }
.menu-actions { display: flex; gap: 12px; margin-top: 12px; }
.menu-pay {
  font-family: var(--teletext);
  font-size: clamp(17px, 1.7vw, 24px);
  background: var(--phosphor);
  color: var(--tube-black);
  padding: 8px 18px;
  border-radius: 3px;
  letter-spacing: 0.06em;
  box-shadow: 0 0 14px oklch(0.82 0.17 145 / 0.35);
  transition: transform 90ms var(--out-quint), box-shadow 90ms var(--out-quint);
}
.menu-pay:active { transform: translateY(1px); box-shadow: 0 0 6px oklch(0.82 0.17 145 / 0.3); }
.menu-cancel {
  font-family: var(--teletext);
  font-size: clamp(15px, 1.5vw, 21px);
  color: var(--phosphor);
  border: 1px solid var(--phosphor);
  padding: 8px 14px;
  border-radius: 3px;
}
.menu-rules { margin: 12px 0 0; font-size: clamp(13px, 1.2vw, 16px); }
.menu-rules-link {
  font-family: var(--teletext);
  font-size: inherit;
  color: var(--phosphor);
  text-decoration: underline;
  text-underline-offset: 2px;
  padding: 0;
}

/* ---------- tube pages: guide and rules render on the CRT ---------- */

.tube-page {
  position: absolute;
  inset: 0;
  z-index: 5;
  background: var(--tube-black);
  color: var(--phosphor);
  font-family: var(--teletext);
  display: flex;
  flex-direction: column;
  padding: clamp(10px, 3%, 26px) clamp(14px, 4%, 40px);
}
@media (prefers-reduced-motion: no-preference) {
  .tube-page { animation: menu-boot 340ms var(--out-quint); transform-origin: 50% 46%; }
  /* Shutting plays the boot in reverse: one flicker, fold to a line. */
  .menu.closing,
  .tube-page.closing {
    animation: menu-shut 240ms var(--out-quint) forwards;
    transform-origin: 50% 46%;
    pointer-events: none;
  }
  @keyframes menu-shut {
    0% { opacity: 1; transform: scaleY(1); }
    100% { opacity: 0; transform: scaleY(0.04); }
  }
}
.tube-head {
  display: flex;
  align-items: baseline;
  gap: 14px;
  margin-bottom: 8px;
}
.tube-title {
  margin: 0;
  flex: 1;
  font-weight: 400; /* VT323 has no bold; keep h2s from synthesizing one */
  font-size: clamp(18px, 2vw, 30px);
  letter-spacing: 0.12em;
  text-shadow: 0 0 8px var(--phosphor);
}
.tube-date { margin: 0; font-size: clamp(11px, 1.1vw, 16px); opacity: 0.6; }
.tube-exit {
  font-family: var(--teletext);
  font-size: clamp(13px, 1.3vw, 18px);
  color: var(--phosphor);
  border: 1px solid var(--phosphor);
  border-radius: 3px;
  padding: 2px 10px;
}
.tube-exit:hover { background: oklch(0.82 0.17 145 / 0.15); }
.tube-list {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: oklch(0.82 0.17 145 / 0.5) transparent;
}
.t-row {
  display: flex;
  align-items: center;
  gap: 10px;
  border-bottom: 1px dotted oklch(0.82 0.17 145 / 0.25);
}
.t-tune {
  flex: 1;
  display: flex;
  gap: 10px;
  align-items: baseline;
  min-width: 0;
  font-family: var(--teletext);
  color: var(--phosphor);
  font-size: clamp(14px, 1.5vw, 21px);
  padding: 4px 0;
  text-align: left;
}
.t-tune:hover .t-name { text-decoration: underline; }
.t-num { opacity: 0.7; }
.t-listing {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: baseline;
  gap: 10px;
}
.t-name {
  flex: 0 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.t-bid, .t-clicks { white-space: nowrap; }
.t-clicks { flex: 0 0 auto; opacity: 0.7; }
.t-raise {
  font-family: var(--teletext);
  font-size: clamp(12px, 1.2vw, 16px);
  color: var(--phosphor);
  opacity: 0.75;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.t-raise:hover { opacity: 1; }
/* An empty board still broadcasts something. */
.t-empty {
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  text-align: center;
}
.t-empty p {
  margin: 0;
  font-size: clamp(14px, 1.5vw, 21px);
  opacity: 0.8;
}
.tube-foot {
  margin: 8px 0 0;
  display: flex;
  gap: 20px;
  font-size: clamp(12px, 1.2vw, 16px);
}
.tube-link {
  font-family: var(--teletext);
  font-size: inherit;
  color: var(--phosphor);
  text-decoration: underline;
  text-underline-offset: 2px;
  opacity: 0.8;
  padding: 0;
}
.tube-link:hover { opacity: 1; }
.tube-rules p {
  margin: 0 0 10px;
  font-size: clamp(13px, 1.4vw, 19px);
  line-height: 1.45;
}

/* ---------- lower third ---------- */

/* Broadcast caption on the tube itself: what's on and what it costs. */
.lower-third {
  position: absolute;
  left: 4.5%;
  right: 4.5%;
  bottom: 2.8%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 6px 14px;
  border-radius: 10px;
  background: oklch(0.11 0.012 145 / 0.85);
  font-family: var(--teletext);
  font-size: clamp(15px, 1.6vw, 22px);
  color: var(--phosphor);
  text-shadow: 0 0 8px var(--phosphor);
}
.lt-line { margin: 0; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.now-dot { margin: 0 2px; opacity: 0.6; }
.lt-outbid {
  font-family: var(--teletext);
  font-size: inherit;
  color: var(--phosphor);
  text-shadow: 0 0 8px var(--phosphor);
  text-decoration: underline;
  text-underline-offset: 3px;
  white-space: nowrap;
}
.lt-outbid:hover { color: oklch(0.96 0.2 145); }
/* AUTO surf fuse: burns along the top of the caption band; when it
   reaches the end the set tunes to the next channel. Duration must
   match AUTO_MS in app.js. */
.lt-progress {
  position: absolute;
  left: 0;
  top: 0;
  height: 3px;
  width: 100%;
  background: var(--phosphor);
  box-shadow: 0 0 6px var(--phosphor);
  transform-origin: left;
  transform: scaleX(0);
}
.screen.autosurf .lt-progress { animation: auto-fill 5s linear forwards; }
@keyframes auto-fill { from { transform: scaleX(0); } to { transform: scaleX(1); } }
/* The caption yields to transient OSD messages, which live in the same strip. */
.screen:has(.osd-msg:not([hidden])) .lower-third { visibility: hidden; }

/* ---------- ticker ---------- */

.ticker {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  background: var(--tube-black);
  overflow: hidden;
  padding: 5px 0;
  border-top: 1px solid oklch(0.3 0.02 60);
  box-shadow: 0 -6px 16px -6px oklch(0.08 0.02 60 / 0.6);
  /* Own compositing layer: Safari otherwise leaves ghost frames of the
     animated track behind when repainting a fixed element. */
  transform: translateZ(0);
}
.ticker-track {
  display: inline-block;
  white-space: nowrap;
  font-family: var(--teletext);
  font-size: 17px;
  color: var(--phosphor);
  text-shadow: 0 0 6px oklch(0.82 0.17 145 / 0.55);
  animation: ticker 45s linear infinite;
  padding-left: 100vw;
  will-change: transform;
}
@keyframes ticker {
  from { transform: translateX(0); }
  to { transform: translateX(-100%); }
}

/* ---------- mobile ---------- */

.mobile-bar { display: none; }

@media (max-width: 900px) {
  .stage {
    grid-template-columns: 1fr;
    grid-template-areas: "editorial" "tv";
    padding: 28px 12px 120px;
    gap: 16px;
    align-items: start;
  }
  .editorial { max-width: none; }
  .editorial h1 { font-size: clamp(30px, 8vw, 40px); }
  .tv-area { width: 100%; }
  /* Relocated below the set by placeRatings(); the grid gap spaces them. */
  .stage > .ratings { margin: 0; }
  .stage > .onair-log { margin-top: 0; }

  .mobile-bar {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 20;
    display: grid;
    grid-template-columns: 1fr auto 1fr 1fr 1fr;
    gap: 8px;
    padding: 10px 12px calc(10px + env(safe-area-inset-bottom));
    background: linear-gradient(180deg, var(--cream-bright), var(--cream) 55%);
    border-top: 1px solid var(--cream-shade);
    box-shadow: 0 -8px 20px -8px oklch(0.08 0.02 60 / 0.5);
  }
  .mobile-bar button {
    min-height: 44px;
    border-radius: 8px;
    background: linear-gradient(180deg, var(--cream-bright), var(--cream-shade));
    color: var(--walnut-deep);
    font-family: var(--grotesk-narrow);
    font-size: 13px;
    letter-spacing: 0.06em;
    box-shadow:
      inset 0 1px 0 oklch(1 0 0 / 0.7),
      0 2px 0 var(--cream-deep);
    transition: transform 80ms var(--out-quint), box-shadow 80ms var(--out-quint);
  }
  .mobile-bar button:active {
    transform: translateY(2px);
    box-shadow: inset 0 1px 3px oklch(0 0 0 / 0.25);
  }
  .m-ch {
    align-self: center;
    font-family: var(--grotesk);
    font-weight: 600;
    font-size: 13px;
    color: var(--walnut-deep);
    padding: 0 6px;
  }
  .mobile-bar .m-claim {
    background: linear-gradient(180deg, oklch(0.6 0.19 30), var(--signal-red) 45%);
    color: var(--cream-bright);
    font-weight: 600;
    box-shadow:
      inset 0 1px 0 oklch(1 0 0 / 0.25),
      0 2px 0 var(--signal-red-deep);
  }
  .ticker { bottom: calc(64px + env(safe-area-inset-bottom)); }

  /* Claim menu and tube pages become a close-up of the tube: a framed
     modal floating in the room, which falls dark behind it. */
  .menu.fullscreen,
  .tube-page.fullscreen {
    position: fixed;
    inset: max(16px, env(safe-area-inset-top)) 12px calc(100px + env(safe-area-inset-bottom)) 12px;
    z-index: 40;
    border-radius: 20px;
    border: 6px solid var(--walnut-deep);
    box-shadow:
      inset 0 0 34px oklch(0 0 0 / 0.55),
      0 0 0 1px var(--walnut-black),
      0 0 0 200vmax oklch(0.08 0.02 60 / 0.7);
  }
}

/* ---------- reduced motion ---------- */

@media (prefers-reduced-motion: reduce) {
  .ticker-track { animation: none; padding-left: 12px; }
  .static { display: none; }
}
