/* The signed-in app: a studio. The preview of what the stream will show sits in the middle, the
   sources that feed it sit under it, and setup, style and past sessions share one panel beside it.
   One ground, one accent (purple), red only for being on air. */

/* ---------- Top bar ---------- */
.top { padding: 10px 20px; }
.mode-switch { display: none; }
body.signed-in .mode-switch { display: inline-flex; gap: 2px; padding: 3px; margin-right: auto; margin-left: 28px;
  background: var(--raised); border: 1px solid var(--line); border-radius: 10px; }
.mode-switch button { height: 30px; padding: 0 14px; border: 0; border-radius: 7px; background: transparent;
  color: var(--muted); font-size: 13px; font-weight: 500; }
.mode-switch button.on { background: var(--surface); color: var(--text); box-shadow: 0 1px 0 rgba(255, 255, 255, .06) inset, 0 1px 3px rgba(0, 0, 0, .4); }
.mode-switch button:hover:not(.on) { color: var(--text); }
.mode-switch.locked button:not(.on) { opacity: .35; pointer-events: none; }

/* Invite guests: in the top bar whenever podcast guests join by link, with a count of who is in. */
.guests-btn { display: none; height: 36px; padding: 0 16px; font-size: 14px; font-weight: 600; gap: 8px; align-items: center; }
body.signed-in.podcast.links .guests-btn { display: inline-flex; }
.guests-btn .count { min-width: 20px; height: 20px; padding: 0 6px; border-radius: 99px; background: var(--accent); color: #fff; font-size: 12px; display: inline-grid; place-items: center; }
#guests-dialog { width: min(560px, calc(100vw - 32px)); }
#guests-dialog .link-box input { font-size: 12.5px; }
#guest-list:empty { display: none; }

/* ---------- Shell ---------- */
.app.studio { max-width: 1560px; margin: 0 auto; padding: 18px 20px 32px;
  display: grid; grid-template-columns: minmax(0, 1fr) 380px; gap: 18px; align-items: start; }
.stage-col { display: grid; gap: 14px; min-width: 0; }
.stage-col > .msg { margin: 0; }

/* ---------- While live: the numbers, in one quiet row above the preview ---------- */
.metrics { display: flex; gap: 8px; margin: 0; flex-wrap: wrap; }
.metrics div { flex: 1; min-width: 104px; padding: 8px 12px; background: var(--surface); border: 1px solid var(--line); border-radius: 10px; }
.metrics dt { font-size: 11px; color: var(--faint); text-transform: uppercase; letter-spacing: .05em; }
.metrics dd { margin: 1px 0 0; font-weight: 600; font-size: 14px; font-variant-numeric: tabular-nums; }

/* ---------- Stage: what the stream will show ---------- */
.stage { position: relative; aspect-ratio: 16 / 9; display: grid; grid-template-columns: 1fr 1fr; gap: 2px;
  background: var(--line); border: 1px solid var(--line); border-radius: 16px; overflow: hidden;
  box-shadow: 0 30px 80px rgba(0, 0, 0, .45); }
body.podcast .stage { grid-template-columns: 1fr; }
.pane { position: relative; min-width: 0; background: radial-gradient(120% 90% at 50% 20%, #17171c, #0a0a0c); container-type: inline-size; }
.pane-tag { position: absolute; top: 12px; left: 12px; z-index: 2; display: inline-flex; align-items: center; gap: 10px;
  padding: 5px 11px; border-radius: 8px; background: rgba(0, 0, 0, .55); backdrop-filter: blur(6px);
  font-size: 12.5px; font-weight: 600; }
/* A caption strip sits where the OBS source goes: along the bottom of that side's video. */
.pane .strip { position: absolute; left: 3%; right: 3%; bottom: 3%; }
/* One wide pane in a podcast: the strip keeps a real strip's width rather than filling it. */
body.podcast .pane .strip { left: 20%; right: 20%; }

/* Podcast guests on a link: everyone's camera fills the preview above the strip. */
.call-tiles { position: absolute; inset: 52px 3% 34% 3%; display: grid; gap: 10px; align-content: center;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr)); }
.call-tiles[data-n="0"] { display: none; }
.call-tiles[data-n="1"] { grid-template-columns: minmax(0, 60%); justify-content: center; }
.tile { position: relative; aspect-ratio: 16 / 9; border-radius: 10px; overflow: hidden; background: #000; }
.tile video { width: 100%; height: 100%; object-fit: cover; display: block; }
.tile[data-id="host"] video { transform: scaleX(-1); }
.tile-name { position: absolute; left: 8px; bottom: 8px; padding: 2px 9px; border-radius: 6px; background: rgba(0, 0, 0, .6); font-size: 12px; font-weight: 600; }
.tile.off video { visibility: hidden; }
/* Whoever is talking gets a ring, camera or not. */
.tile::before { content: ""; position: absolute; inset: 0; z-index: 1; border-radius: inherit; pointer-events: none; transition: box-shadow .12s; }
.tile.talk::before { box-shadow: inset 0 0 0 3px var(--ok); }
.tile.off::after { content: attr(data-initial); position: absolute; inset: 0; display: grid; place-items: center; font-size: 34px; font-weight: 700; color: var(--faint); }

/* The caption preview: the same 960 × 260 shape, look and sizing rules as the OBS source. */
.strip { position: relative; aspect-ratio: 960 / 260; border-radius: 10px; overflow: hidden; container-type: inline-size;
  background: rgba(0, 0, 0, .28); outline: 1px dashed rgba(255, 255, 255, .09); outline-offset: -1px; }
.cap { position: absolute; inset: 0; padding: 1.2cqw 1.5cqw; overflow: hidden; text-align: center; line-height: 1.5; font-weight: 600;
  font-family: var(--font, "Geist", "IBM Plex Sans Arabic", "IBM Plex Sans Hebrew", "Segoe UI", Arial, sans-serif); }
.cap:empty::before { content: attr(data-empty); color: var(--faint); font-weight: 500; font-size: 3cqw; }
.cap .roll { display: flex; flex-direction: column; justify-content: flex-end; overflow: hidden; }
.cap .box { color: var(--fg, #fff); text-shadow: var(--shadow, none); font-weight: var(--weight, 600); font-style: var(--italic, normal);
  paint-order: stroke fill; -webkit-box-decoration-break: clone; box-decoration-break: clone; white-space: pre-line; }
.cap[data-style="box"] .box { background: var(--box, #0c0c0e); padding: .06em .4em; border-radius: .22em; }
.cap .new { color: var(--hl, #ffd54a); }
.cap .draft { opacity: .55; }
.cap .nm { color: var(--c); }

/* ---------- Tray: the sources that feed the preview ---------- */
.tray { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; align-items: start; }
body.podcast .tray { grid-template-columns: 1.4fr 1fr; }
.src { background: var(--surface); border: 1px solid var(--line); border-radius: 14px; overflow: hidden; }
.src-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 12px 16px;
  border-bottom: 1px solid var(--line); cursor: pointer; user-select: none; }
.src-name { display: inline-flex; align-items: center; gap: 9px; font-weight: 600; font-size: 14px; }
.src-name::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--line-strong); }
.src > :not(.src-head) { transition: opacity .18s; }
.src:has(.src-head input:not(:checked)) > :not(.src-head) { opacity: .4; }
/* On air: a side that is listening turns the red every streamer already reads as recording. */
body.is-live:not(.is-paused) .src:has(.src-head input:checked) .src-name::before { background: var(--live); box-shadow: 0 0 0 4px rgba(255, 61, 61, .16); animation: pulse 1.6s infinite; }
body.is-live:not(.is-paused) .src-head .switch input:checked + span { background: var(--live); }
.row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 16px; min-height: 52px; }
.row + .row { border-top: 1px solid var(--line); }
.row-label { display: grid; font-size: 13.5px; font-weight: 500; min-width: 0; }
.row-sub { font-size: 12px; font-weight: 400; color: var(--faint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.row-sub.set { color: var(--muted); }
.row select { width: auto; max-width: 240px; height: 34px; padding: 0 10px; font-size: 13px; }
#voice-lang { min-width: 170px; } /* fits "Match the stranger" */
.src-ctl { display: flex; align-items: center; gap: 8px; flex: none; min-width: 0; }
.src-ctl select { max-width: 200px; }
.small-btn { height: 34px; font-size: 13px; padding: 0 12px; flex: none; }
.invite { width: 200px; height: 34px; font: 500 12px var(--mono); color: var(--muted); }
.live-only { display: none !important; }
body.is-live:not(.podcast) .row.live-only { display: flex !important; }

/* Speaker names, podcast mode: a colour, a name box, and the last thing each voice said. */
.speakers { gap: 0; border-top: 1px solid var(--line); }
.spk { display: grid; grid-template-columns: 10px 140px 1fr; align-items: center; gap: 10px; padding: 8px 16px; }
.spk + .spk { border-top: 1px solid var(--line); }
.spk-dot { width: 10px; height: 10px; border-radius: 50%; background: var(--c, var(--faint)); }
.spk input { height: 32px; padding: 0 10px; font-size: 13px; }
.spk-said { font-size: 12px; color: var(--muted); overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }

/* ---------- Side panel ---------- */
.side { position: sticky; top: 72px; max-height: calc(100vh - 90px); display: flex; flex-direction: column;
  background: var(--surface); border: 1px solid var(--line); border-radius: 16px; overflow: hidden; }
.tabs { display: flex; flex: none; border-bottom: 1px solid var(--line); padding: 0 8px; }
.tabs button { flex: 1; height: 46px; padding: 0; border: 0; border-radius: 0; background: none; color: var(--muted);
  font-size: 13.5px; font-weight: 500; border-bottom: 2px solid transparent; margin-bottom: -1px; }
.tabs button:hover { color: var(--text); }
.tabs button.on { color: var(--text); border-bottom-color: var(--accent); }
.tab { overflow: auto; padding: 16px; display: grid; gap: 12px; align-content: start; }

/* Which streaming app: every OBS fork has a Browser Source, so only the OBS Studio extras differ. */
.apps { display: flex; gap: 2px; padding: 3px; background: var(--raised); border: 1px solid var(--line); border-radius: 10px; }
.apps button { flex: 1; height: 30px; padding: 0 8px; font-size: 12.5px; border: 0; border-radius: 7px; background: transparent; color: var(--muted); }
.apps button.on { background: var(--surface); color: var(--text); font-weight: 600; box-shadow: 0 1px 3px rgba(0, 0, 0, .4); }
.apps button:hover:not(.on) { color: var(--text); }
.slobs-only, .syard-only, .scene-only, .link-only, .pod-only { display: none; }
body.slobs .obs-only { display: none; }
body.slobs .slobs-only, body.syard .syard-only { display: grid; }
body.syard .obs-only, body.syard .slobs-only, body.syard #setup-guest { display: none; }
body.podcast .pod-only { display: grid; }
body.podcast .no-pod { display: none !important; }
body.podcast.links .row.link-only { display: flex; }
body.podcast.links .call-tiles.link-only { display: grid; }
body.podcast.links .scene-only { display: grid; }
body.podcast.links .tab-row, body.podcast.links #setup-viewer .obs-only, body.podcast.links #setup-viewer .slobs-only { display: none !important; }

/* A setup card per caption source: folds to a bar once that source is in OBS. */
.card { border: 1px solid var(--line); border-radius: 12px; background: var(--raised); }
.setup-bar { display: flex; align-items: center; justify-content: space-between; width: 100%; height: auto; padding: 12px 14px;
  background: transparent; border: 0; border-radius: 12px; font-size: 13.5px; font-weight: 500; color: var(--text); text-align: left; }
.done-title { display: flex; align-items: center; gap: 9px; }
.tick { width: 16px; height: 16px; border-radius: 50%; background: var(--line-strong); position: relative; flex: none; }
.tick::after { content: ""; position: absolute; left: 5.5px; top: 3px; width: 3.5px; height: 7px;
  border-right: 1.5px solid var(--faint); border-bottom: 1.5px solid var(--faint); transform: rotate(45deg); }
.card.ready .tick { background: rgba(62, 207, 142, .16); }
.card.ready .tick::after { border-color: var(--ok); }
.chev { width: 7px; height: 7px; flex: none; border-right: 1.5px solid var(--faint); border-bottom: 1.5px solid var(--faint);
  transform: rotate(45deg); margin-bottom: 3px; transition: transform .18s; }
.card.open .chev { transform: rotate(-135deg); margin: 3px 0 0; }
.card-body { padding: 2px 14px 14px; }
/* A setup card holding up the stream pulses until its source arrives. */
.card.needs { border-color: rgba(248, 113, 113, .55); animation: needs 1.6s ease-in-out infinite; }
@keyframes needs { 0%, 100% { box-shadow: 0 0 0 0 rgba(248, 113, 113, 0); } 50% { box-shadow: 0 0 0 5px rgba(248, 113, 113, .16); } }

.side .steps { gap: 12px; margin: 0 0 14px; font-size: 13.5px; }
.side .steps li { padding-left: 34px; line-height: 1.7; }
.side .steps li::before { width: 22px; height: 22px; font-size: 11px; }
.side .steps:last-child, .side .manual:last-child { margin-bottom: 0; }
.side .drag { margin: 8px 0 2px; }
.side .link-box input { height: 36px; font-size: 11.5px; }
.side .link-box button { height: 36px; min-width: 70px; }
.side .wait { font-size: 13px; }
.scene-opts { display: flex; gap: 10px; flex-wrap: wrap; }
.scene-opts label { display: flex; align-items: center; gap: 8px; }
.scene-opts select { width: auto; height: 34px; font-size: 13px; }
.test-btn { justify-self: start; margin: 0; }

/* Style: the caption look, applied to every preview and source as it changes. */
.look-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0 10px; }
.side .field { gap: 5px; margin-bottom: 10px; }
.side .label { font-size: 12px; }
.side .field select { height: 36px; padding: 0 10px; font-size: 13.5px; }
.colors, .checks { display: flex; flex-wrap: wrap; gap: 8px 16px; }
.checks { padding-top: 12px; border-top: 1px solid var(--line); }
.colors label, .checks label { display: flex; align-items: center; gap: 7px; font-size: 13px; cursor: pointer; }
.colors input[type="color"] { width: 30px; height: 24px; padding: 2px; border-radius: 6px; cursor: pointer; }
.checks input { accent-color: var(--accent); width: 15px; height: 15px; }
.colors #reset-colors { margin: 0; height: 26px; padding: 0 8px; font-size: 12px; }

/* Sessions: the last few, kept in this browser. */
.tab-acts { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.tab-acts .small { margin: 0; color: var(--bad); }
#tab-sessions .logs { margin: 0; border-top: 1px solid var(--line); }

/* ---------- Narrower screens ---------- */
@media (max-width: 1180px) {
  .app.studio { grid-template-columns: 1fr; }
  .side { position: static; max-height: none; }
}
@media (max-width: 760px) {
  .app.studio { padding: 12px 12px 24px; }
  .tray, body.podcast .tray { grid-template-columns: 1fr; }
  body.signed-in .mode-switch { margin-left: 0; }
  .stage { grid-template-columns: 1fr; aspect-ratio: auto; }
  .pane { aspect-ratio: 16 / 9; }
}
