/* Little Computer People viewer. Warm 80s evening palette; the stage keeps its 800x570 aspect and everything else flows around it. */

:root {
  --bg: #1a1220;
  --bg2: #241a2c;
  --panel: #2b2034;
  --line: #3d2f48;
  --ink: #f4ecd0;
  --ink2: #b9aeb8;
  --amber: #e8a33d;
  --red: #e5534b;
  --green: #52f08e;
  --teal: #2f8f83;
  --radius: 12px;
  --ease: cubic-bezier(0.3, 0.7, 0.2, 1);
  color-scheme: dark;
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: 15px/1.4 ui-rounded, "Avenir Next", "Segoe UI", system-ui, sans-serif;
  -webkit-text-size-adjust: 100%;
}

body {
  min-height: 100dvh;
  padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
}

[hidden] {
  display: none !important;
}

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

/* ---- top bar ---------------------------------------------------------------------------------------------------- */

.top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 16px;
  border-bottom: 1px solid var(--line);
  background: var(--bg2);
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0;
  font-size: 18px;
  letter-spacing: 0.02em;
  min-width: 0;
}

.brand span:last-child {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.brand-mark {
  flex: none;
  width: 22px;
  height: 18px;
  border-radius: 4px;
  background: linear-gradient(#0d2b1a, #0d2b1a) padding-box;
  border: 3px solid #cbbf9f;
  box-shadow: inset 0 0 6px #52f08e66;
}

.top-status {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: none;
}

.badge {
  font: 700 11px/1 ui-monospace, "SF Mono", Menlo, monospace;
  letter-spacing: 0.12em;
  padding: 5px 8px;
  border-radius: 999px;
  background: var(--red);
  color: #fff;
}

.badge[data-mode="rerun"] {
  background: var(--amber);
  color: #2a1a10;
}

.badge[data-mode="card"],
.badge[data-mode="idle"],
.badge[data-mode="starting"] {
  background: #5b5266;
}

.viewers {
  color: var(--ink2);
  font-size: 12px;
}

.conn {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #5b5266;
}

.conn[data-state="open"] {
  background: var(--green);
  box-shadow: 0 0 6px var(--green);
}

.conn[data-state="lost"] {
  background: var(--red);
  animation: blink 1s steps(2) infinite;
}

.btn {
  font: inherit;
  font-size: 13px;
  color: var(--ink);
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 6px 12px;
  cursor: pointer;
  min-height: 32px;
}

.btn:hover,
.btn:focus-visible {
  border-color: var(--amber);
  outline: none;
}

.btn[aria-pressed="true"] {
  background: var(--teal);
  border-color: var(--teal);
}

.offline {
  text-align: center;
  padding: 6px 12px;
  background: #5b2a2a;
  font-size: 13px;
}

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

.layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 320px;
  gap: 16px;
  max-width: 1280px;
  margin: 0 auto;
  padding: 16px;
}

.stage-col {
  min-width: 0;
  container-type: inline-size;
  container-name: stagecol;
}

.side {
  display: flex;
  flex-direction: column;
  gap: 14px;
  min-width: 0;
}

.panel {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 12px 14px;
}

.panel h2 {
  margin: 0 0 8px;
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink2);
}

/* ---- stage ------------------------------------------------------------------------------------------------------ */

.stage {
  position: relative;
  aspect-ratio: 800 / 570;
  width: 100%;
  overflow: hidden;
  border-radius: var(--radius);
  border: 2px solid #000;
  background: #000;
  box-shadow: 0 8px 30px #0008;
  container-type: inline-size;
  container-name: stage;
}

#stage-svg {
  display: block;
  width: 100%;
  height: 100%;
}

#stage-svg text {
  font-family: ui-rounded, "Avenir Next", system-ui, sans-serif;
}

.bug,
.kind-bug,
.plate {
  position: absolute;
  font: 700 clamp(9px, 2.1cqw, 14px) / 1 ui-monospace, "SF Mono", Menlo, monospace;
  letter-spacing: 0.12em;
  padding: 0.5em 0.8em;
  border-radius: 6px;
  background: #000a;
  color: #fff;
  pointer-events: none;
}

.bug {
  z-index: 3; /* over the credits and the slate: RERUN lights before a rerun's first line */
  top: 2.2cqw;
  left: 2.2cqw;
  display: flex;
  align-items: center;
  gap: 0.6em;
}

.bug .dot {
  width: 0.8em;
  height: 0.8em;
  border-radius: 50%;
  background: var(--red);
  animation: pulse 1.6s ease-in-out infinite;
}

.bug[data-mode="rerun"] .dot {
  background: var(--amber);
  animation: none;
}

.bug[data-mode="card"] .dot,
.bug[data-mode="idle"] .dot,
.bug[data-mode="starting"] .dot {
  background: #8d8398;
  animation: none;
}

.kind-bug {
  top: calc(2.2cqw + 3em);
  left: 2.2cqw;
  background: var(--amber);
  color: #2a1a10;
  animation: pop 0.35s var(--ease);
}

.plate {
  top: 2.2cqw;
  right: 2.2cqw;
  font-family: Georgia, "Times New Roman", serif;
  font-weight: 700;
  letter-spacing: 0.04em;
  background: #f4ecd0ee;
  color: #2a1a10;
  max-width: 55%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  animation: pop 0.35s var(--ease);
}

.plate:empty {
  display: none;
}

.lower-third {
  position: absolute;
  left: 4cqw;
  bottom: 4cqw;
  max-width: 70%;
  animation: slide-in 0.4s var(--ease);
  pointer-events: none;
}

.lt-top {
  display: inline-block;
  padding: 0.35em 0.9em;
  background: #c0392b;
  color: #fff;
  font: 700 clamp(8px, 1.7cqw, 12px) / 1 ui-monospace, Menlo, monospace;
  letter-spacing: 0.18em;
}

.lt-main {
  padding: 0.5em 0.9em;
  background: #f4ecd0;
  color: #16305c;
  font: 700 clamp(11px, 2.8cqw, 20px) / 1.1 Georgia, serif;
}

.slate {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 6cqw;
  text-align: center;
  background: radial-gradient(ellipse at center, #2c2a5af2, #0a0612f8);
  animation: fade-in 0.4s ease;
}

.slate-box {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.6em;
}

.slate-title {
  font: 700 clamp(18px, 5cqw, 38px) / 1.15 Georgia, serif;
  color: var(--ink);
}

.slate-sub {
  font-size: clamp(11px, 2.2cqw, 16px);
  color: var(--ink2);
}

.slate-sub:empty {
  display: none;
}

/* The stand-by slate (WS28 Part B). `plain`: the slate above. `slate`: a period slate box over the dimmed house.
   `bars`: the same box over colour bars drawn in CSS (an original arrangement, no marks). */
.slate-bars,
.slate-head,
.slate-gag,
.slate-rerun,
.slate-clock {
  display: none;
}

.slate[data-style="slate"],
.slate[data-style="bars"] {
  background: #000c;
}

.slate[data-style="bars"] {
  padding: 0;
}

.slate[data-style="bars"] .slate-bars {
  position: absolute;
  inset: 0;
  display: grid;
  grid-template-columns: repeat(7, 1fr);
}

.slate-bars i:nth-child(1) {
  background: linear-gradient(#bfbfbf 0 70%, #1c1a8f 70% 78%, #f2f2f2 78%);
}

.slate-bars i:nth-child(2) {
  background: linear-gradient(#c8c43c 0 70%, #111 70% 78%, #0d2d63 78%);
}

.slate-bars i:nth-child(3) {
  background: linear-gradient(#3ec0c2 0 70%, #b03ab0 70% 78%, #f2f2f2 78%);
}

.slate-bars i:nth-child(4) {
  background: linear-gradient(#3cba45 0 70%, #111 70% 78%, #3c1a6a 78%);
}

.slate-bars i:nth-child(5) {
  background: linear-gradient(#b23cb5 0 70%, #3ec0c2 70% 78%, #111 78%);
}

.slate-bars i:nth-child(6) {
  background: linear-gradient(#c33c35 0 70%, #111 70% 78%, #1b1b1b 78%);
}

.slate-bars i:nth-child(7) {
  background: linear-gradient(#2a3cb8 0 70%, #bfbfbf 70% 78%, #0b0b0b 78%);
}

.slate[data-style="slate"] .slate-box,
.slate[data-style="bars"] .slate-box {
  position: relative;
  max-width: 78%;
  padding: 1.1em 1.6em 1em;
  border: 3px double #f4ecd0;
  border-radius: 8px;
  background: #120c1aee;
  box-shadow: 0 6px 30px #000a;
  gap: 0.45em;
}

.slate[data-style="slate"] .slate-head,
.slate[data-style="bars"] .slate-head {
  display: block;
  font: 700 clamp(9px, 1.9cqw, 13px) / 1 ui-monospace, Menlo, monospace;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--amber);
}

.slate[data-style="slate"] .slate-title,
.slate[data-style="bars"] .slate-title {
  font-size: clamp(16px, 4.2cqw, 32px);
}

.slate[data-style="slate"] .slate-gag:not(:empty),
.slate[data-style="bars"] .slate-gag:not(:empty) {
  display: block;
  font: italic clamp(11px, 2.3cqw, 17px) / 1.3 Georgia, serif;
  color: var(--ink);
  opacity: 0.85;
}

.slate[data-style="slate"] .slate-clock:not(:empty),
.slate[data-style="bars"] .slate-clock:not(:empty) {
  display: block;
  font: 700 clamp(10px, 2cqw, 14px) / 1 ui-monospace, Menlo, monospace;
  letter-spacing: 0.14em;
  color: var(--ink2);
}

.slate[data-beat="1"] .slate-rerun:not(:empty) {
  display: block;
  font: 700 clamp(12px, 2.6cqw, 19px) / 1.25 Georgia, serif;
  color: var(--amber);
  animation: fade-in 0.3s ease;
}

/* A name card (WS28 Part B): at the start of a confessional, low on the left like a lower third. */
.char-card {
  position: absolute;
  left: 4cqw;
  bottom: 4cqw;
  max-width: 72%;
  display: flex;
  align-items: stretch;
  pointer-events: none;
  animation: slide-in 0.45s var(--ease);
  box-shadow: 0 4px 18px #0008;
}

.cc-head {
  flex: none;
  width: clamp(38px, 9cqw, 68px);
  background: #2c2a5a;
}

.cc-head svg {
  display: block;
  width: 100%;
  height: 100%;
}

.cc-head .tag,
.cr-fig .tag {
  display: none;
}

.cc-text {
  padding: 0.45em 0.9em 0.55em;
  background: #f4ecd0;
  color: #2a1a10;
  min-width: 0;
}

.cc-tag {
  font: 700 clamp(8px, 1.6cqw, 11px) / 1 ui-monospace, Menlo, monospace;
  letter-spacing: 0.2em;
  color: #b5473a;
}

.cc-name {
  font: 700 clamp(15px, 4cqw, 30px) / 1.1 Georgia, serif;
}

.cc-sub {
  font: italic clamp(10px, 2.1cqw, 15px) / 1.2 Georgia, serif;
  color: #5a4636;
}

.cc-tag:empty,
.cc-sub:empty,
.lt-top:empty {
  display: none;
}

/* The opening credits (WS28 Part B): one step at a time over the stage, in the gap before an episode's first line. */
.credits {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  padding: 5cqw;
  text-align: center;
  background: radial-gradient(ellipse at center, #2a1d3cfa, #08040efd);
  animation: fade-in 0.5s ease;
  pointer-events: none;
}

.cr-step {
  display: none;
  grid-area: 1 / 1;
  max-width: 100%;
}

.credits[data-step="title"] [data-for="title"],
.credits[data-step="cast"] [data-for="cast"],
.credits[data-step="closing"] [data-for="closing"],
.credits[data-step="episode"] [data-for="episode"] {
  display: block;
  animation: credit-in 0.7s var(--ease);
}

.cr-show {
  font: 700 clamp(22px, 7.4cqw, 58px) / 1.05 Georgia, serif;
  color: var(--amber);
  text-shadow: 0 3px 0 #0008;
}

.cr-lines p,
.cr-closing {
  margin: 0.7em 0 0;
  font: italic clamp(12px, 2.8cqw, 21px) / 1.3 Georgia, serif;
  color: var(--ink);
}

.cr-cast {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 1.4cqw 1.8cqw;
}

.cr-cast li {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: clamp(56px, 12.5cqw, 110px);
}

.cr-fig {
  width: 70%;
  aspect-ratio: 60 / 116;
}

.cr-cast b {
  font: 700 clamp(10px, 2.2cqw, 16px) / 1.15 Georgia, serif;
  color: var(--ink);
}

.cr-cast small {
  font: italic clamp(8px, 1.6cqw, 12px) / 1.2 Georgia, serif;
  color: var(--ink2);
}

.cr-rerun {
  display: inline-block;
  margin-bottom: 0.7em;
  padding: 0.35em 0.8em;
  border-radius: 6px;
  background: var(--amber);
  color: #2a1a10;
  font: 700 clamp(9px, 1.9cqw, 13px) / 1 ui-monospace, Menlo, monospace;
  letter-spacing: 0.2em;
}

.cr-ep {
  font: 700 clamp(18px, 5.4cqw, 42px) / 1.15 Georgia, serif;
  color: var(--ink);
}

@container stage (max-width: 520px) {
  .credits {
    padding: 3cqw;
  }

  .cr-cast li {
    width: 30%;
  }

  .cr-fig {
    width: 36%;
  }

  .char-card {
    max-width: 88%;
  }
}

/* The place plate is redundant on the News Desk, and on a narrow stage it moves down so it never meets the bug. */
.stage[data-look="news"] .plate {
  display: none;
}

@container stage (max-width: 520px) {
  .plate {
    top: auto;
    bottom: 2.2cqw;
    right: 2.2cqw;
    max-width: 62%;
  }
}

/* ---- house and rooms -------------------------------------------------------------------------------------------- */

.room .shade {
  opacity: 0.38;
  transition: opacity 0.6s var(--ease);
}

.room.active .shade {
  opacity: 0;
}

.room.lit .shade {
  opacity: 0.1;
}

.room.active .frame {
  stroke: var(--amber);
}

.room .frame {
  transition: stroke 0.6s;
}

.room-label {
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  fill: #f4ecd0;
  opacity: 0.55;
}

.address {
  font-size: 12px;
  letter-spacing: 0.3em;
  fill: #f4ecd0;
  opacity: 0.55;
}

.console-glow {
  animation: flicker 3s steps(2) infinite;
}

.window-glow {
  animation: breathe 6s ease-in-out infinite;
}

.stars circle {
  animation: twinkle 4s ease-in-out infinite;
}

.stars circle:nth-child(3n) {
  animation-delay: -1.3s;
}

.stars circle:nth-child(3n + 1) {
  animation-delay: -2.6s;
}

/* ---- the town map (WS28) ------------------------------------------------------------------------------------------ */

.map-label {
  font-size: 12px;
  font-weight: 700;
  fill: #2a1a10;
  paint-order: stroke;
  stroke: #f4ecd0;
  stroke-width: 3px;
}

.map-name {
  font: 700 20px Georgia, serif;
  letter-spacing: 0.04em;
  fill: #2a1a10;
}

/* `?knobs=1`: the active viewer knobs in a corner of the stage */
.knobs-corner {
  position: absolute;
  right: 6px;
  bottom: 6px;
  z-index: 5;
  max-height: 80%;
  margin: 0;
  padding: 6px 8px;
  overflow: auto;
  font: 10px / 1.35 ui-monospace, "SF Mono", Menlo, monospace;
  color: #f4ecd0;
  background: #000c;
  border-radius: 4px;
}

/* ---- cutaway -------------------------------------------------------------------------------------------------- */

.cutaway {
  opacity: 0;
  pointer-events: none;
  transform-origin: 400px 285px;
  transition: opacity 0.4s ease;
}

.cutaway.on {
  opacity: 1;
}

.cutaway-dim {
  opacity: 0;
  transition: opacity 0.4s;
}

.cutaway[data-look="cutaway"].on .cutaway-dim {
  opacity: 0.62;
}

.card-frame {
  stroke: transparent;
  stroke-width: 0;
}

.cutaway[data-look="cutaway"] .card-frame {
  stroke: #f4ecd0;
  stroke-width: 10;
}

.cutaway[data-look="cutaway"] #cutaway-card {
  filter: drop-shadow(0 10px 18px #000a);
}

.cutaway.enter[data-look="cutaway"] {
  animation: cut-in 0.6s var(--ease);
}

.cutaway.enter[data-look="news"] {
  animation: wipe-in 0.55s var(--ease);
}

.cutaway.enter[data-look="confessional"] {
  animation: crt-on 0.5s var(--ease);
}

.crt-lines {
  animation: scan 8s linear infinite;
}

/* ---- the little people ------------------------------------------------------------------------------------------ */

.fig {
  transition:
    transform 1.1s var(--ease),
    opacity 0.45s ease;
}

.fig.gone {
  opacity: 0;
  pointer-events: none;
}

.fig.dim {
  opacity: 0.82;
}

.fig.dim .tag {
  opacity: 0;
}

.fig .tag {
  font-size: 9px;
  letter-spacing: 0.06em;
  fill: #f4ecd0;
  paint-order: stroke;
  stroke: #000a;
  stroke-width: 3px;
  transition: opacity 0.4s;
}

.fig .shadow {
  fill: #0006;
}

.fig .npc-mark {
  stroke: #f4ecd0;
  stroke-width: 1.5;
  stroke-dasharray: 3 3;
  opacity: 0.55;
}

.fig[data-flip="1"] .body {
  scale: -1 1;
}

.fig .body {
  transform-origin: 0 0;
  transition:
    rotate 0.6s var(--ease),
    translate 0.6s var(--ease);
}

.fig .head {
  transform-origin: 0 -72px;
  transition: transform 0.5s var(--ease);
}

.fig .arm {
  transform-origin: 0 0;
  transition: transform 0.45s var(--ease);
}

.fig .crossed {
  display: none;
}

.fig .eyes {
  transition: transform 0.3s;
}

.fig .mouth {
  transform-origin: 0 -78px;
}

.fig.speaking {
  filter: drop-shadow(0 0 5px #ffe9a8aa);
}

/* The speaker's mouth is driven frame by frame from the voice (mouth.js); it is not a CSS loop. */
.fig .mouth-open {
  transition: none;
}

.fig.speaking .head {
  animation: head-talk 0.9s ease-in-out infinite;
}

/* Postures */
.fig[data-posture="upright"] .body {
  translate: 0 -2px;
}

.fig[data-posture="slouch"] .body {
  rotate: 5deg;
  translate: 0 2px;
}

.fig[data-posture="slouch"] .head {
  transform: rotate(-6deg) translateY(3px);
}

.fig[data-posture="lean-in"] .body {
  rotate: 9deg;
}

.fig[data-posture="lean-back"] .body {
  rotate: -8deg;
}

.fig[data-posture="arms-crossed"] .crossed {
  display: block;
}

.fig[data-posture="arms-crossed"] .arm {
  display: none;
}

.fig[data-posture="hands-on-hips"] .arm-l {
  transform: rotate(38deg);
}

.fig[data-posture="hands-on-hips"] .arm-r {
  transform: rotate(-38deg);
}

.fig[data-posture="head-in-hands"] .head {
  transform: translateY(10px) rotate(8deg);
}

.fig[data-posture="head-in-hands"] .arm-l {
  transform: rotate(-150deg);
}

.fig[data-posture="head-in-hands"] .arm-r {
  transform: rotate(150deg);
}

/* Gestures (the right arm does the talking) */
.fig[data-gesture="shrug"] .arm {
  animation: shrug 1.1s ease-in-out infinite;
}

.fig[data-gesture="point"] .arm-r {
  transform: rotate(-95deg);
}

.fig[data-gesture="facepalm"] .arm-r {
  transform: rotate(140deg);
}

.fig[data-gesture="facepalm"] .head {
  transform: rotate(-8deg) translateY(2px);
}

.fig[data-gesture="wave"] .arm-r {
  animation: wave 0.7s ease-in-out infinite alternate;
}

.fig[data-gesture="sip"] .arm-r {
  transform: rotate(125deg);
}

.fig[data-gesture="check-phone"] .arm-r {
  transform: rotate(80deg);
}

.fig[data-gesture="check-phone"] .head {
  transform: rotate(10deg) translateY(2px);
}

.fig[data-gesture="pace"] .body {
  animation: pace 2.4s ease-in-out infinite alternate;
}

.fig[data-gesture="fidget"] .arm-l {
  animation: fidget 0.5s ease-in-out infinite alternate;
}

/* Reactions: short, one-shot */
.fig[data-reaction="nod"] .head {
  animation: nod 0.6s ease-in-out 2;
}

.fig[data-reaction="wince"] .head {
  animation: wince 0.7s ease-out;
}

.fig[data-reaction="eye-roll"] .eyes {
  animation: eye-roll 0.9s ease-in-out;
}

.fig[data-reaction="smirk"] .head {
  transform: rotate(5deg);
}

.fig[data-reaction="gasp"] .body {
  animation: gasp 0.5s var(--ease);
}

.fig[data-reaction="lean-in"] .body {
  rotate: 8deg;
}

.fig[data-reaction="look-away"] .head {
  transform: translateX(-4px) rotate(-10deg);
}

.fig[data-reaction="laugh"] .body {
  animation: laugh 0.3s ease-in-out 4;
}

.fig[data-reaction="facepalm"] .arm-r {
  transform: rotate(140deg);
}

/* ---- caption, now playing --------------------------------------------------------------------------------------- */

.caption {
  margin-top: 12px;
  min-height: 6.4em;
  padding: 12px 16px;
  background: var(--bg2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  transition: opacity 0.3s;
}

.caption[data-style="none"] {
  opacity: 0.35;
}

.caption[data-hold="1"] {
  opacity: 0.8;
}

.cap-who {
  min-height: 1.3em;
  font: 700 12px/1.3 ui-monospace, Menlo, monospace;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--amber);
}

.cap-text {
  margin: 4px 0 0;
  font: clamp(17px, 3.4cqw, 24px) / 1.35 Georgia, "Times New Roman", serif;
  overflow-wrap: anywhere;
}

.cap-text .rest {
  opacity: 0;
}

.caption[data-style="action"] .cap-text {
  font-style: italic;
  color: var(--ink2);
}

.caption[data-style="interlude"] .cap-text {
  font-style: italic;
}

.caption[data-style="interlude"] .cap-who {
  color: var(--ink2);
}

.caption[data-style="sfx"] .cap-text {
  font-variant: small-caps;
  letter-spacing: 0.08em;
  color: var(--ink2);
}

.caption[data-style="confessional"] .cap-text {
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: clamp(15px, 3cqw, 21px);
  color: var(--green);
}

.caption[data-style="confessional"] .cap-who {
  color: var(--green);
}

.cap-influence {
  margin-top: 8px;
  font-size: 12px;
  color: var(--ink2);
  border-left: 3px solid var(--teal);
  padding-left: 8px;
}

.now {
  margin-top: 12px;
}

.now-ep {
  font: 700 17px/1.2 Georgia, serif;
}

.now-scene {
  min-height: 1.4em;
  color: var(--ink2);
  font-size: 13px;
}

.progress {
  margin-top: 8px;
  height: 4px;
  border-radius: 2px;
  background: var(--line);
  overflow: hidden;
}

.progress i {
  display: block;
  height: 100%;
  width: 0;
  background: var(--amber);
  transition: width 0.3s linear;
}

/* ---- side panels ------------------------------------------------------------------------------------------------ */

.roster,
.upnext,
.log {
  list-style: none;
  margin: 0;
  padding: 0;
}

.roster li {
  display: grid;
  grid-template-columns: 34px 1fr auto;
  align-items: center;
  gap: 10px;
  padding: 5px 6px;
  border-radius: 8px;
  transition: background 0.3s;
}

.roster li[data-state="speaking"] {
  background: #e8a33d33;
}

.roster li[data-state="stage"] {
  background: #ffffff10;
}

.avatar {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: #00000040;
}

.roster .who {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.roster .who b {
  font-size: 14px;
}

.roster .who small {
  color: var(--ink2);
  font-size: 11px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.roster .st {
  font-size: 11px;
  color: var(--ink2);
  white-space: nowrap;
}

.roster li[data-state="speaking"] .st {
  color: var(--amber);
}

.upnext li {
  display: flex;
  gap: 10px;
  padding: 4px 0;
  font-size: 13px;
}

.upnext .when {
  flex: none;
  min-width: 3.4em;
  font: 12px ui-monospace, Menlo, monospace;
  color: var(--amber);
}

.upnext .muted,
.muted {
  color: var(--ink2);
}

.log {
  max-height: 260px;
  overflow: auto;
  font-size: 13px;
}

.log li {
  padding: 4px 0;
  border-bottom: 1px dashed var(--line);
  animation: fade-in 0.4s ease;
}

.log li.past {
  opacity: 0.6;
}

.log li[data-kind="action"] span {
  font-style: italic;
  color: var(--ink2);
}

.log li[data-kind="confessional"] span {
  color: var(--green);
}

.log b {
  color: var(--amber);
  font-weight: 600;
}

/* ---- phones and narrow windows ---------------------------------------------------------------------------------- */

@media (max-width: 880px) {
  .layout {
    grid-template-columns: minmax(0, 1fr);
    padding: 10px;
    gap: 12px;
  }

  .side {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  }
}

@media (max-width: 520px) {
  .top {
    padding: 8px 10px;
  }

  .brand {
    font-size: 15px;
  }

  .brand-mark {
    display: none;
  }

  .stage {
    border-radius: 8px;
  }

  .caption {
    padding: 10px 12px;
    min-height: 7em;
  }

  .side {
    grid-template-columns: minmax(0, 1fr);
  }

  .btn {
    min-height: 36px;
  }
}

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

@keyframes pulse {
  50% {
    opacity: 0.35;
  }
}

@keyframes blink {
  50% {
    opacity: 0.2;
  }
}

@keyframes pop {
  from {
    opacity: 0;
    transform: translateY(-6px) scale(0.92);
  }
}

@keyframes fade-in {
  from {
    opacity: 0;
  }
}

@keyframes credit-in {
  from {
    opacity: 0;
    transform: translateY(14px) scale(0.97);
  }
}

@keyframes slide-in {
  from {
    opacity: 0;
    transform: translateX(-24px);
  }
}

@keyframes cut-in {
  from {
    opacity: 0;
    transform: scale(0.86) rotate(-1.5deg);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@keyframes wipe-in {
  from {
    clip-path: inset(0 100% 0 0);
  }
  to {
    clip-path: inset(0 0 0 0);
  }
}

@keyframes crt-on {
  0% {
    opacity: 0;
    transform: scale(1, 0.01);
    filter: brightness(3);
  }
  60% {
    opacity: 1;
    transform: scale(1, 0.06);
  }
  100% {
    transform: none;
    filter: none;
  }
}

@keyframes scan {
  to {
    transform: translateY(12px);
  }
}

@keyframes flicker {
  50% {
    opacity: 0.55;
  }
}

@keyframes breathe {
  50% {
    opacity: 0.12;
  }
}

@keyframes twinkle {
  50% {
    opacity: 0.1;
  }
}

@keyframes head-talk {
  50% {
    transform: translateY(-1.5px) rotate(1.5deg);
  }
}

@keyframes shrug {
  50% {
    transform: rotate(-20deg);
  }
}

@keyframes wave {
  from {
    transform: rotate(-135deg);
  }
  to {
    transform: rotate(-170deg);
  }
}

@keyframes pace {
  from {
    translate: -26px 0;
  }
  to {
    translate: 26px 0;
  }
}

@keyframes fidget {
  from {
    transform: rotate(8deg);
  }
  to {
    transform: rotate(-4deg);
  }
}

@keyframes nod {
  50% {
    transform: translateY(calc(3px * var(--react, 1))) rotate(calc(4deg * var(--react, 1)));
  }
}

@keyframes wince {
  30% {
    transform: translateX(calc(2px * var(--react, 1))) rotate(calc(8deg * var(--react, 1)));
  }
}

@keyframes eye-roll {
  25% {
    transform: translate(-2px, -2px);
  }
  50% {
    transform: translate(0, -3px);
  }
  75% {
    transform: translate(2px, -2px);
  }
}

@keyframes gasp {
  40% {
    transform: scale(calc(1 + 0.06 * var(--react, 1))) translateY(calc(-3px * var(--react, 1)));
  }
}

@keyframes laugh {
  50% {
    transform: translateY(calc(-4px * var(--react, 1)));
  }
}

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

/* Reduced motion: the titles fade in place instead of moving (the camera cuts instead; camera.js). */
@media (prefers-reduced-motion: reduce) {
  .credits [data-for],
  .char-card,
  .slate,
  .slate-rerun {
    animation-name: fade-in !important;
    animation-duration: 0.4s !important;
  }
}
