/* Older browsers (e.g. Chrome 77 on Huawei phones, common in China) lack dvh, max()
   and flex gap. Sizes get a plain value first; max()/env() and gap fallbacks live
   in the @supports blocks at the end of this file. */
* { box-sizing: border-box; margin: 0; }

/* Figtree (SIL Open Font License, fonts/OFL.txt) for karaoke's lyric lines,
   Truth or Drink's question and a few headings, served from here: the page
   loads nothing from other sites. One variable file holds every weight. Other
   scripts fall back to the system fonts below. */
@font-face {
  font-family: Figtree;
  font-weight: 300 900;
  font-display: swap;
  src: url(/fonts/figtree-latin.woff2) format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: Figtree;
  font-weight: 300 900;
  font-display: swap;
  src: url(/fonts/figtree-latin-ext.woff2) format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* Barlow Condensed (the same licence, fonts/OFL.txt), just its two heaviest
   italics, latin only, for Happybird's arcade lettering (npm run vendor:fonts). */
@font-face {
  font-family: "Barlow Condensed";
  font-style: italic;
  font-weight: 800;
  font-display: swap;
  src: url(/fonts/barlow-condensed-latin-800-italic.woff2) format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Barlow Condensed";
  font-style: italic;
  font-weight: 900;
  font-display: swap;
  src: url(/fonts/barlow-condensed-latin-900-italic.woff2) format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

html, body {
  height: 100%;
  background: #000;
  color: #eee;
  font: 16px/1.4 system-ui, -apple-system, "PingFang SC", "Microsoft YaHei", sans-serif;
}

[hidden] { display: none !important; }

#join-screen {
  height: 100vh;
  height: 100dvh;
  display: grid;
  place-items: center;
  align-content: center;
  padding: 16px;
}

/* The logo, centred, with your picture (.me-chip) hanging off its right side. */
#brand { position: relative; margin-bottom: 20px; }
#logo { display: block; }

#join-form {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  width: 100%;
  max-width: 360px;
}

#code {
  flex: 1 1 200px;
  padding: 12px 14px;
  border: 1px solid #333;
  border-radius: 10px;
  background: #111;
  color: #fff;
  font-size: 18px;
}

button {
  padding: 12px 18px;
  border: 0;
  border-radius: 10px;
  background: #222;
  color: #fff;
  font-size: 16px;
  cursor: pointer;
}

button:disabled { opacity: 0.5; cursor: default; }
button[aria-pressed="true"] { background: #b3261e; }
#join { background: #fff; color: #000; }
#leave { background: #b3261e; }

#error { flex-basis: 100%; min-height: 1.4em; color: #ff8a80; }

#request-code {
  flex-basis: 100%;
  background: transparent;
  border: 1px solid #333;
}
#request-code:not(:disabled) { border-color: rgba(232, 190, 90, 0.5); padding-block: 10px; font-size: 20px; }

/* Gold lettering: Rent a room and the donation's amount. Condensed italic
   caps with a bright-to-deep gold run top to bottom, like struck metal. */
.gold-type, #request-code:not(:disabled) {
  font-family: "Barlow Condensed", Figtree, sans-serif;
  font-style: italic;
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  background-image: linear-gradient(180deg, #fff4c8 0%, #f6d26a 34%, #c48a24 58%, #f2cb5e 82%, #fff0b8 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

#donate { gap: 10px; background: rgba(9, 8, 12, 0.98); } /* much darker than other popups, its gold the brightest thing on it */
#donate-average { color: #fff; font-weight: 700; }
.dialog #donate-amount { font-size: 56px; line-height: 1; margin-top: 6px; color: transparent; }
#donate-range { width: 100%; accent-color: #e2b148; }
.donate-scale { display: flex; justify-content: space-between; font-size: 13px; color: rgba(235, 230, 245, 0.55); margin-top: -6px; }
.dialog #donate-go { align-self: center; padding: 0 36px; background: linear-gradient(180deg, #f6d26a, #c9932c); color: #2a1c05; white-space: nowrap; }

#human-check { flex-basis: 100%; display: flex; justify-content: center; }

/* Rooms this phone bought, so the code is never lost: a near-black panel with
   rounded top corners, sliding up from the bottom of the screen and running
   down under the home indicator, its contents kept above it. It says how many
   rooms there are; sliding its knob opens them one per page over the dimmed
   door (my-rooms.js). The join screen leaves room for it underneath. */
#my-rooms {
  position: fixed;
  z-index: 2;
  left: 0;
  right: 0;
  bottom: 0;
  max-width: 480px;
  margin: 0 auto;
  padding: 18px 16px calc(18px + env(safe-area-inset-bottom));
  display: flex;
  flex-direction: column;
  gap: 14px;
  border-radius: 24px 24px 0 0;
  background: #0c0c0d;
  box-shadow: inset 0 0.5px 0 rgba(255, 255, 255, 0.14), 0 -10px 30px rgba(0, 0, 0, 0.35); /* a hairline top edge, so it shows on the black page */
  animation: room-panel-rise 0.42s cubic-bezier(0.22, 0.8, 0.3, 1);
}
@keyframes room-panel-rise { from { transform: translateY(100%); } }
@media (prefers-reduced-motion: reduce) { #my-rooms { animation: none; } }
#join-screen[data-room] { padding-bottom: calc(150px + env(safe-area-inset-bottom)); }
#my-rooms-count { font-size: 17px; font-weight: 600; text-align: center; }

#my-rooms-slide {
  --slid: 0;
  position: relative;
  height: 56px;
  border-radius: 999px;
  background: #1a1a1c;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
#my-rooms-slide span {
  font-size: 17px;
  opacity: calc(1 - var(--slid) * 1.6);
  background: linear-gradient(90deg, #8e8e93 0%, #8e8e93 40%, #fff 50%, #8e8e93 60%, #8e8e93 100%) 0 0 / 300% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  animation: slide-shine 2.4s linear infinite;
}
@keyframes slide-shine { from { background-position: 100% 0; } to { background-position: 0 0; } }
#my-rooms-knob {
  position: absolute;
  left: 4px;
  top: 4px;
  width: 48px;
  height: 48px;
  padding: 0;
  border-radius: 50%;
  background: #fff;
  color: #000;
  display: grid;
  place-items: center;
  touch-action: none;
  cursor: grab;
  transition: transform 0.3s cubic-bezier(0.22, 0.8, 0.3, 1);
}
#my-rooms-slide.sliding #my-rooms-knob { transition: none; cursor: grabbing; }
#my-rooms-slide.nudge #my-rooms-knob { animation: knob-nudge 0.6s cubic-bezier(0.22, 0.8, 0.3, 1); }
@keyframes knob-nudge { 35% { transform: translateX(36px); } 60% { transform: translateX(-4px); } }

#my-rooms-dim {
  position: fixed;
  z-index: 2;
  inset: 0;
  background: rgba(0, 0, 0, 0.72);
  animation: room-dim-in 0.3s ease-out;
}
@keyframes room-dim-in { from { opacity: 0; } }

#my-rooms-list {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  margin: 0 -16px;
  animation: room-list-in 0.35s cubic-bezier(0.22, 0.8, 0.3, 1);
}
#my-rooms-list::-webkit-scrollbar { display: none; }
@keyframes room-list-in { from { opacity: 0; transform: translateY(12px); } }
.room-page { flex: 0 0 100%; padding: 0 16px; scroll-snap-align: center; }
.room-page .my-room { padding: 16px; border: 0; border-radius: 16px; background: #1a1a1c; }
.room-page .my-room strong { font-size: 17px; }
.room-page .my-room button:not(.join-mine) { background: #2a2a2d; }
#my-rooms-dots { display: flex; justify-content: center; gap: 6px; }
#my-rooms-dots span { width: 6px; height: 6px; border-radius: 50%; background: #555; transition: background 0.2s; }
#my-rooms-dots span[data-on] { background: #fff; }
@media (prefers-reduced-motion: reduce) {
  #my-rooms-slide span, #my-rooms-dim, #my-rooms-list, #my-rooms-slide.nudge #my-rooms-knob { animation: none; }
}
.my-room { display: flex; align-items: center; gap: 8px; padding: 10px 12px; border: 1px solid #333; border-radius: 10px; }
.my-room p { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.my-room span { color: #aaa; font-size: 14px; }
.my-room button { padding: 8px 14px; }
.my-room .join-mine { background: #fff; color: #000; }
#open-rooms { flex-basis: 100%; display: flex; flex-direction: column; gap: 8px; }
.open-room strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.open-room .open-count { font-variant-numeric: tabular-nums; color: #aaa; }
.open-room .ask-join { background: #fff; color: #000; white-space: nowrap; }

#code-screen {
  height: 100vh;
  height: 100dvh;
  display: grid;
  place-items: center;
  padding: 16px;
}

.code-card { display: flex; flex-direction: column; gap: 10px; text-align: center; width: 100%; max-width: 360px; }
#new-code { font-size: 26px; font-weight: 600; color: #fff; overflow-wrap: anywhere; }
#code-expiry { color: #aaa; }
.code-actions { display: flex; justify-content: center; gap: 8px; margin-top: 6px; }
#join-new-code { background: #fff; color: #000; }

/* --grid-bottom: the room under the tiles (the call buttons; karaoke's lyrics
   band too while it shows), which the game's row and timer line up with.
   --ask-row: a game's own row under everyone else's tiles (two lines of the
   question), lifted 5px to line up with the sheets' bottoms, and its gap.
   --players-row: how tall everyone else's tiles are while one is in a game's
   spotlight (the spotlight takes what's left). */
#call-screen { height: 100vh; height: 100dvh; position: relative; --grid-bottom: 62px; --ask-row: 75px; --players-row: 160px; }

#grid {
  position: relative;
  height: 100%;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr));
  grid-auto-rows: 1fr;
  gap: 4px;
  padding: 4px 4px var(--grid-bottom); /* 62px: the tiles end 7px above the call buttons (7px up, 48px tall) */
}

/* Normal call layout: same-size tiles in --cols x --rows, short last row centred.
   Wide screens: 1, 1x2, 1x3, 2x2, 3+2, 2x3, 4+3, 2x4. Upright phones swap rows and
   columns so tiles stay tall, except 3, which is 2 on top and 1 centred below.
   data-count is set by app.js, so this works in browsers without :has(). */
#grid:not(.spotlight) {
  --cols: 1;
  --rows: 1;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-content: center;
}

#grid:not(.spotlight) > .tile {
  flex: 0 0 calc((100% - (var(--cols) - 1) * 4px) / var(--cols));
  height: calc((100% - (var(--rows) - 1) * 4px) / var(--rows));
}

#grid:not(.spotlight)[data-count="2"] { --cols: 2; --rows: 1; }
#grid:not(.spotlight)[data-count="3"] { --cols: 3; --rows: 1; }
#grid:not(.spotlight)[data-count="4"] { --cols: 2; --rows: 2; }
#grid:not(.spotlight)[data-count="5"],
#grid:not(.spotlight)[data-count="6"] { --cols: 3; --rows: 2; }
#grid:not(.spotlight)[data-count="7"],
#grid:not(.spotlight)[data-count="8"] { --cols: 4; --rows: 2; }

@media (orientation: portrait) {
  #grid:not(.spotlight)[data-count="2"] { --cols: 1; --rows: 2; }
  #grid:not(.spotlight)[data-count="3"],
  #grid:not(.spotlight)[data-count="4"] { --cols: 2; --rows: 2; }
  #grid:not(.spotlight)[data-count="5"],
  #grid:not(.spotlight)[data-count="6"] { --cols: 2; --rows: 3; }
  #grid:not(.spotlight)[data-count="7"],
  #grid:not(.spotlight)[data-count="8"] { --cols: 2; --rows: 4; }
}

/* isolation keeps a tile's layers (the camera-off face, the mic badge) inside it,
   under the call buttons that float over the grid. */
.tile { position: relative; isolation: isolate; background: #000; border-radius: 28px; overflow: hidden; } /* as round as the panels */
/* With the camera off (or none), a generic person over a soft dark backdrop. */
.tile-face {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: none;
  align-items: center;
  justify-content: center;
  background: radial-gradient(circle at 50% 42%, #2b2833 0%, #16151a 70%);
}
.tile.camera-off .tile-face, .tile-face.fake-video { display: flex; } /* the test room's pretend cameras show it too */
/* Mic off: a huge crossed-out mic, no circle, centred over the person's tile,
   half see-through like glass (white, softly lit, a gentle shadow). */
.tile-muted {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 2;
  width: 46%;
  max-width: 200px;
  aspect-ratio: 1;
  display: none;
  align-items: center;
  justify-content: center;
  /* Drawn solid, then faded as one piece, so crossing strokes don't double up. */
  opacity: 0.55;
  pointer-events: none;
}
.tile.mic-off .tile-muted { display: flex; }
/* In a game, someone who has sent a question, skipped, or voted: their tile
   dims (green for answered, brown for drank) and an envelope, a skip icon, a
   thumbs up or a beer outline draws itself in the middle (game-ui.js), over
   the mic badge. It fades in, and fades out (drawn) when it goes. */
.tile-mark {
  position: absolute;
  inset: 0;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(10, 8, 16, 0.62);
  pointer-events: none;
  visibility: hidden;
  opacity: 0;
  transition: opacity 0.3s ease, visibility 0s linear 0.3s;
}
.tile-answered { background: rgba(6, 40, 22, 0.66); }
.tile-drank { background: rgba(46, 26, 6, 0.68); }
.tile.has-asked .tile-asked, .tile.has-skipped .tile-skipped, .tile.has-answered .tile-answered, .tile.has-drank .tile-drank { visibility: visible; opacity: 1; transition: opacity 0.3s ease-out; }
.tile-mark svg { width: 34%; max-width: 72px; fill: none; stroke: #fff; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.tile-answered svg { stroke: #9ff2c4; stroke-width: 1.6; }
.tile-drank svg { stroke: #f3c27a; stroke-width: 1.6; }
/* Each trace starts undrawn (both: through its delay too) and stays drawn
   after, so a mark that's going fades out whole. */
.tile-mark rect, .tile-mark path { stroke-dasharray: 1; stroke-dashoffset: 0; }
.tile.has-asked .tile-asked rect { animation: mark-trace 0.9s ease-in-out 0.15s both; }
.tile.has-asked .tile-asked path { animation: mark-trace 0.5s ease-out 0.9s both; }
.tile.has-skipped .tile-skipped path:first-child { animation: mark-trace 0.9s ease-in-out 0.15s both; }
.tile.has-skipped .tile-skipped path + path { animation: mark-trace 0.4s ease-out 0.9s both; }
.tile.has-answered .tile-answered path, .tile.has-drank .tile-drank path { animation: mark-trace 0.9s ease-in-out 0.15s both; }
@keyframes mark-trace { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
/* Your own vote sweeps over your tile from its wedge's corner (bottom left for
   answered, bottom right for drank) as the wedges shrink away, then traces. */
#tile-local.has-answered .tile-answered { transition: none; animation: sweep-from-left 0.6s cubic-bezier(0.22, 0.8, 0.3, 1) 0.15s both; }
#tile-local.has-drank .tile-drank { transition: none; animation: sweep-from-right 0.6s cubic-bezier(0.22, 0.8, 0.3, 1) 0.15s both; }
#tile-local.has-answered .tile-answered path, #tile-local.has-drank .tile-drank path { animation-delay: 0.55s; }
@keyframes sweep-from-left { from { clip-path: polygon(0 100%, 0 100%, 0 100%); } to { clip-path: polygon(0 100%, 0 -100%, 200% 100%); } }
@keyframes sweep-from-right { from { clip-path: polygon(100% 100%, 100% 100%, 100% 100%); } to { clip-path: polygon(100% 100%, 100% -100%, -100% 100%); } }
@media (prefers-reduced-motion: reduce) {
  .tile-mark, .tile.has-asked .tile-asked, .tile.has-skipped .tile-skipped, .tile.has-answered .tile-answered, .tile.has-drank .tile-drank { transition: none; animation: none; }
  .tile.has-asked .tile-asked rect, .tile.has-asked .tile-asked path, .tile.has-skipped .tile-skipped path, .tile.has-answered .tile-answered path, .tile.has-drank .tile-drank path { animation: none; }
}
.tile-muted svg { width: 100%; height: 100%; fill: none; stroke: #fff; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; filter: drop-shadow(0 0 1px rgba(255, 255, 255, 0.35)) drop-shadow(0 6px 18px rgba(0, 0, 0, 0.35)); }
.tile-face svg { width: 34%; max-width: 120px; fill: rgba(255, 255, 255, 0.28); }
/* Someone who shared their picture (profile-ui.js): with the camera off, their
   picture (or their ink waves) takes the generic person's place, sized to the
   tile. Not while you're joining: your camera hasn't started yet, it isn't off. */
#call-screen:not(.joining) .tile.has-profile .tile-face:not(.fake-video) > svg { display: none; }
#call-screen.joining .tile-avatar { display: none; }
.tile-face .tile-avatar { width: 96px; height: 96px; box-shadow: 0 8px 30px rgba(0, 0, 0, 0.35); }
@supports (width: 1cqmin) {
  .tile-face { container-type: size; }
  .tile-face .tile-avatar { width: min(40cqmin, 160px); height: min(40cqmin, 160px); }
}

/* On wide screens the idfk.app wordmark sits at the bottom left, on the call
   buttons' row (their 48px band, 7px up), in the app icon's lettering. Phones
   don't show it. Taps go through it. */
#call-logo {
  position: absolute;
  z-index: 2;
  left: 20px;
  bottom: 7px;
  height: 48px;
  display: none;
  font-family: system-ui, -apple-system, Helvetica, Arial, sans-serif;
  font-weight: 800;
  font-size: 34px;
  line-height: 48px;
  letter-spacing: -0.04em;
  color: #fff;
  pointer-events: none;
  user-select: none;
}
#call-logo span { font-size: 0.7em; } /* ".app" a size down, on the same baseline */

/* You (profile-ui.js): your picture, a photo or your ink waves, to the right
   of the join page's logo, on the bare background. */
.me-avatar {
  flex: none;
  display: block;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: #0a0a0b center / cover no-repeat;
  user-select: none;
}
/* As tall as the logo's "idfk" (22px of the 72px icon, from 24px down),
   8px past its "k", which ends 60px in; the tap area is 44px around it. */
.me-chip {
  position: absolute;
  left: 68px;
  top: 24px;
  display: flex;
  padding: 0;
  border-radius: 50%;
  background: none;
}
.me-chip::after { content: ""; position: absolute; inset: -11px; border-radius: 50%; }
.me-chip .me-avatar { width: 22px; height: 22px; }

/* The popup to change your name and picture: tap the picture to pick a new one. */
#profile-form { display: flex; flex-direction: column; align-items: center; gap: 12px; }
#profile-form[hidden] { display: none; }
#profile-form > .dialog-actions { align-self: stretch; }
#profile-photo { position: relative; margin: 4px 0; cursor: pointer; border-radius: 50%; }
#profile-photo .me-avatar { width: 96px; height: 96px; }
#profile-photo:hover .profile-camera { background: #fff; color: #1a1622; }
#profile-form:has(#profile-file:focus-visible) #profile-photo { outline: 2px solid #fff; outline-offset: 3px; }
.profile-camera {
  position: absolute;
  right: -2px;
  bottom: -2px;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(60, 54, 72, 0.98);
  box-shadow: 0 0 0 3px rgba(26, 22, 35, 1);
  color: #fff;
}
.profile-camera svg { width: 17px; height: 17px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
#profile-remove-photo { min-height: 0; padding: 4px 10px; background: none; box-shadow: none; color: rgba(235, 230, 245, 0.7); font-size: 14px; font-weight: 500; }
#profile-name {
  align-self: stretch;
  padding: 12px 14px;
  border: 1px solid #333;
  border-radius: 12px;
  background: #111;
  color: #fff;
  font-size: 17px;
  text-align: center;
}
#profile-error { min-height: 0; color: #ff8a80; }
#profile-error:empty { display: none; }
#profile-save { background: #fff; color: #1a1622; }

/* Cropping a new picture: the circle is what's kept; outside it is dimmed. */
#profile-crop { display: flex; flex-direction: column; align-items: center; gap: 14px; }
#profile-crop[hidden] { display: none; }
#profile-crop > .dialog-actions { align-self: stretch; }
#crop-frame {
  position: relative;
  width: 240px;
  height: 240px;
  overflow: hidden;
  border-radius: 16px;
  background: #0a0a0b;
  cursor: grab;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
}
#crop-frame:active { cursor: grabbing; }
#crop-frame:focus { outline: none; }
#crop-frame:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }
#crop-image { position: absolute; top: 0; left: 0; max-width: none; transform-origin: 0 0; pointer-events: none; }
.crop-ring { position: absolute; inset: 0; border-radius: 50%; box-shadow: 0 0 0 200px rgba(10, 8, 14, 0.62), inset 0 0 0 1.5px rgba(255, 255, 255, 0.8); pointer-events: none; }
#crop-zoom-row { align-self: stretch; display: flex; align-items: center; gap: 10px; color: rgba(235, 230, 245, 0.7); }
#crop-zoom-row svg { flex: none; width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }
#crop-done { background: #fff; color: #1a1622; }
.visually-hidden { position: absolute; width: 1px; height: 1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

#controls {
  position: absolute;
  z-index: 4; /* over a game's cheer (#game-cheer) */
  left: 0;
  right: 0;
  bottom: 7px; /* the same gap below the buttons as above them */
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 6px;
  padding: 0 8px;
  pointer-events: none; /* the bar spans the screen; its empty space lets taps through to what's under it (the DBG button) */
}
#controls > * { pointer-events: auto; }

/* Round icon buttons; Mute and Camera show their "off" icon while pressed. */
#controls { gap: 12px; }
#controls button { width: 48px; height: 48px; padding: 0; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; }
#controls button[hidden] { display: none; }
#controls svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.3)); }
#controls button[aria-pressed="true"] .when-off, #controls button:not([aria-pressed="true"]) .when-on { display: none; }
/* The Watch button wears the icon of the mode you're in (karaoke-ui.js sets data-mode). */
#karaoke:not([data-mode="karaoke"]) .when-karaoke, #karaoke:not([data-mode="theater"]) .when-theater,
#karaoke[data-mode="karaoke"] .when-watch, #karaoke[data-mode="theater"] .when-watch { display: none; }
/* The call buttons float over the video as dark frosted glass, like iOS in dark
   mode: a smoky tint with a hint of purple, the video blurred behind, a hairline edge and a faint top
   highlight (inset shadows, so the buttons keep their size). Red ones are
   tinted glass. */
#controls button { background: rgba(32, 28, 40, 0.9); box-shadow: inset 0 0 0 0.5px rgba(230, 220, 255, 0.16), inset 0 1px 0 rgba(240, 232, 255, 0.09), 0 4px 16px rgba(0, 0, 0, 0.3); }
#controls button[aria-pressed="true"], #controls #leave { background: rgba(179, 38, 30, 0.9); }
@supports ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  #controls button {
    background: rgba(34, 28, 46, 0.5);
    -webkit-backdrop-filter: blur(24px) saturate(160%);
    backdrop-filter: blur(24px) saturate(160%);
  }
  #controls button[aria-pressed="true"], #controls #leave { background: rgba(200, 30, 30, 0.6); }
}
/* Joining the call (app.js): the buttons are there as ever, but only Mute and
   Camera answer until you're in; your own tile shows full size as it does with
   the camera off (no mic badge: the mic isn't off, just not on yet); others'
   tiles that arrive early wait, then come in as if they'd just joined. */
#call-screen.joining #games, #call-screen.joining #karaoke, #call-screen.joining #leave { pointer-events: none; }
#call-screen.joining #grid > .tile:not(#tile-local) { display: none; }
#call-screen.joining #grid > #tile-local { flex-basis: 100%; height: 100%; }
#call-screen.joining .tile-muted { display: none; }
/* A button whose sheet is open (Games) turns bright glass with a dark icon. */
#controls button[aria-expanded="true"] { background: rgba(255, 255, 255, 0.9); color: #1a1622; }
#controls button[aria-expanded="true"] svg { filter: none; }
/* With more than one mic (an iPhone with AirPods in, a laptop with a headset), a
   white chevron on the Mute button's top right corner opens the list of mics above it. */
#mic-wrap { position: relative; display: inline-flex; }
#controls #mic-pick { position: absolute; top: -4px; right: -4px; width: 22px; height: 22px; background: rgba(255, 255, 255, 0.92); color: #1a1622; }
#controls #mic-pick svg { width: 13px; height: 13px; stroke-width: 2.5; filter: none; }
#mic-list {
  position: absolute;
  bottom: calc(100% + 10px);
  left: 0;
  display: flex;
  flex-direction: column;
  min-width: 200px;
  max-width: calc(100vw - 32px);
  padding: 6px;
  border-radius: 16px;
  background: rgba(32, 28, 40, 0.96);
  box-shadow: inset 0 0 0 0.5px rgba(230, 220, 255, 0.16), 0 10px 30px rgba(0, 0, 0, 0.45);
  animation: volume-out 0.2s ease-out;
}
#mic-list[hidden] { display: none; }
#controls #mic-list button { width: auto; height: auto; min-height: 44px; padding: 0 12px; gap: 10px; justify-content: flex-start; border-radius: 10px; background: none; box-shadow: none; -webkit-backdrop-filter: none; backdrop-filter: none; color: #fff; font: inherit; font-size: 15px; text-align: left; white-space: nowrap; }
#controls #mic-list button[aria-checked="true"] { background: rgba(255, 255, 255, 0.12); }
#controls #mic-list svg { width: 16px; height: 16px; flex: none; }
#controls #mic-list button[aria-checked="false"] svg { visibility: hidden; }
@media (prefers-reduced-motion: reduce) { #mic-list { animation: none; } }
/* In a karaoke or theater session with its panel shut: violet glass with a
   lavender edge and glow, so the button stands out as the one you're in (open,
   it turns white like any open sheet's). */
#controls #karaoke:is([data-mode="karaoke"], [data-mode="theater"]):not([aria-expanded="true"]) {
  background: rgba(124, 82, 255, 0.62);
  box-shadow: inset 0 0 0 0.5px rgba(201, 182, 255, 0.55), inset 0 1px 0 rgba(240, 232, 255, 0.18), 0 4px 18px rgba(124, 82, 255, 0.45);
}

/* Overlays on the call screen: banner, notices, games list, test panel. */
.panel {
  background: #111;
  border: 1px solid #333;
  border-radius: 10px;
}

/* Only shown in the test room: adds and removes pretend people. */
/* The test room's tools open from a small debug button in the bottom left
   corner, beside the call buttons: faint amber, monospace and dashed, so it
   reads as a developer's switch, not part of the app. */
#debug-toggle {
  position: absolute;
  z-index: 2;
  left: 8px;
  bottom: 17px; /* centred on the call buttons' row */
  width: 30px;
  height: 28px;
  padding: 0;
  border: 1px dashed rgba(255, 196, 0, 0.7);
  border-radius: 6px;
  background: rgba(0, 0, 0, 0.35);
  box-shadow: none;
  color: rgba(255, 196, 0, 0.9);
  font: 700 9px/1 ui-monospace, Menlo, Consolas, monospace;
  letter-spacing: 0.04em;
  opacity: 0.5;
}
#debug-toggle[hidden] { display: none; }
#debug-toggle:hover, #debug-toggle[aria-expanded="true"] { opacity: 1; }
#test-panel {
  position: absolute;
  left: 50%;
  bottom: 80px;
  transform: translateX(-50%);
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 12px;
  max-width: calc(100% - 16px);
  padding: 6px;
  white-space: nowrap;
}

#test-panel button { width: 40px; padding: 8px 0; font-size: 20px; line-height: 1; }
#test-panel #pretend-add, #test-panel #pretend-invite { width: auto; padding: 8px 10px; font-size: 14px; }

#people-count { min-width: 5.5em; text-align: center; }

/* Games */

/* The spotlight tile is lifted out of the grid to fill the top; everyone else
   shares one row of small tiles just above the call controls. */
#grid.spotlight {
  grid-template-columns: none;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  grid-template-rows: 1fr var(--players-row);
  padding-bottom: calc(var(--grid-bottom) + var(--ask-row)); /* the game's row under everyone else's tiles */
}

#grid.spotlight > .tile { grid-row: 2; }

/* grid-area: auto so it's positioned against the whole grid, not row 2. */
/* It ends the grid's 4px gap above the row of everyone else, and moves with
   it when karaoke lyrics take a band under the call (the row keeps its size). */
#grid.spotlight > .tile.is-spotlight {
  grid-area: auto;
  position: absolute;
  top: 4px;
  left: 4px;
  right: 4px;
  bottom: calc(var(--grid-bottom) + var(--ask-row) + var(--players-row) + 4px);
  transition: bottom 0.45s cubic-bezier(0.22, 0.8, 0.3, 1);
}
@media (prefers-reduced-motion: reduce) { #grid.spotlight > .tile.is-spotlight, #game-row, #game-timer, #game-start, #game-banner, #game-votes { transition: none; } }

/* A game's words sit just above the seam between the spotlight and everyone
   else: what to do now, over the countdown (or the spotlight's Start). They
   grow upward. */
#game-banner {
  position: absolute;
  z-index: 3;
  left: 50%;
  bottom: calc(var(--grid-bottom) + var(--ask-row) + var(--players-row) + 2px + 26px + 10px); /* the seam, half the countdown, a gap */
  transform: translateX(-50%);
  width: calc(100% - 32px);
  max-width: 420px;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  pointer-events: none;
  transition: bottom 0.45s cubic-bezier(0.22, 0.8, 0.3, 1);
}
#game-banner[hidden] { display: none; }
/* While they answer there's no countdown: the words sit just over the seam. */
#game-banner[data-phase="answering"] { bottom: calc(var(--grid-bottom) + var(--ask-row) + var(--players-row) + 2px + 12px); }
#game-role { padding: 6px 12px; border-radius: 14px; background: rgba(20, 16, 28, 0.72); color: #fff; font-size: 14px; font-weight: 600; }
#game-role[hidden] { display: none; }
/* The question drawn: the call buttons' dark glass, in white Figtree (the
   lyrics' face) at a medium weight. Two lines tall, in the row under everyone
   else's tiles; the question box before it is the same size. A longer
   question grows upward. */
#question {
  width: calc(100% - 24px);
  max-width: 420px;
  min-height: 66px;
  margin: 0;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  text-wrap: balance; /* two even lines, not one long and one short */
  border-radius: 22px;
  background: rgba(32, 28, 40, 0.9);
  box-shadow: inset 0 0 0 0.5px rgba(230, 220, 255, 0.16), inset 0 1px 0 rgba(240, 232, 255, 0.09), 0 4px 16px rgba(0, 0, 0, 0.3);
  color: #fff;
  font: 500 17px/22px Figtree, system-ui, -apple-system, sans-serif;
  letter-spacing: 0.005em;
}
@supports ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  #question {
    background: rgba(34, 28, 46, 0.5);
    -webkit-backdrop-filter: blur(24px) saturate(160%);
    backdrop-filter: blur(24px) saturate(160%);
  }
}
#question { padding: 11px 20px; }

/* Truth or Drink's row under everyone else's tiles: a box to write the
   spotlight a question, then the question drawn in its place, centred. Both
   share one spot, so one can paint out as the other paints in. */
#game-row {
  position: absolute;
  z-index: 2;
  left: 4px;
  right: 4px;
  bottom: calc(var(--grid-bottom) + 5px); /* 12px over the call buttons, like the sheets' bottoms */
  height: 66px;
  display: grid;
  justify-items: center;
  align-items: end;
  transition: bottom 0.45s cubic-bezier(0.22, 0.8, 0.3, 1);
}
#game-row > * { grid-area: 1 / 1; }
#game-row[hidden], #game-ask[hidden], #game-votes[hidden], #question[hidden] { display: none; }
/* The box and the bubble paint themselves in with a diagonal wipe from the top
   left to the bottom right, sliding a little the same way, and paint out the
   same way (data-leaving, game-ui.js); the bubble follows the box out. Other
   words and marks that go fade out. */
#game-ask, #question { animation: paint-in 0.45s cubic-bezier(0.22, 0.8, 0.3, 1) both; }
#question { animation-delay: 0.15s; }
#game-ask[data-leaving], #question[data-leaving] { animation: paint-out 0.4s ease-in both; pointer-events: none; }
#game-role[data-leaving], #game-timer[data-leaving], #game-votes[data-leaving] { animation: fade-out 0.3s ease both; pointer-events: none; }
#game-votes[data-leaving] .game-vote { pointer-events: none; }
@keyframes paint-in {
  from { clip-path: polygon(0 0, 0 0, 0 0); transform: translate(-12px, -6px); }
  to { clip-path: polygon(0 0, 200% 0, 0 200%); transform: none; }
}
@keyframes paint-out {
  from { clip-path: polygon(100% 100%, 100% -100%, -100% 100%); transform: none; }
  to { clip-path: polygon(100% 100%, 100% 100%, 100% 100%); transform: translate(12px, 6px); }
}
@keyframes fade-out { to { opacity: 0; } }
@media (prefers-reduced-motion: reduce) { #game-ask, #question { animation: none; } }
/* The question box: the bubble's size (two lines, wrapping), karaoke's
   search's look (.sheet fields) but with a white edge (solid while typing),
   with its button inside the right end. The button says Submit (white) with
   something typed, otherwise Skip (glass, the same white edge). */
#game-ask { position: relative; width: calc(100% - 24px); max-width: 420px; height: 66px; }
#game-question { box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.45); }
#game-question:focus { box-shadow: inset 0 0 0 1.5px #fff; }
#game-question { display: block; width: 100%; height: 100%; box-sizing: border-box; padding-right: 118px; resize: none; font-family: inherit; line-height: 22px; }
#game-send { position: absolute; top: 11px; right: 11px; min-width: 92px; height: 44px; padding: 0 18px; border-radius: 14px; background: #fff; color: #1a1622; font-size: 15px; font-weight: 600; }
#game-send[data-kind="skip"] { background: rgba(255, 255, 255, 0.08); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.45); color: #fff; }
/* Sent: a tick until they change it. */
#game-ask[data-sent] #game-send { background: rgba(201, 182, 255, 0.9); }
/* The vote: two wedges in the spotlight tile's bottom corners, a thumbs up
   (they answered) on the left and a beer (they drank) on the right, each tinted
   like the mark on a voter's own tile, with its outline icon. A wedge's diagonal edge is square to the
   line from its corner to the tile's centre, --r from the corner: its legs are
   --r times the tile's diagonal over its width (--sx) and over its height
   (--sy), which game-ui.js measures. Its icon sits at the wedge's centroid.
   Until you vote, they pulse their colour, brighter and back. Once you tap
   one, both shrink into their corners and yours sweeps over your own tile
   from its corner (.tile-mark). */
#game-votes {
  --sx: 1.6;
  --sy: 1.3;
  position: absolute;
  z-index: 3;
  top: 4px;
  left: 4px;
  right: 4px;
  bottom: calc(var(--grid-bottom) + var(--ask-row) + var(--players-row) + 4px); /* the spotlight tile */
  border-radius: 28px;
  overflow: hidden;
  pointer-events: none; /* taps outside the wedges reach the tile */
  transition: bottom 0.45s cubic-bezier(0.22, 0.8, 0.3, 1);
}
.game-vote {
  --r: 92px;
  --icon: 30px;
  position: absolute;
  inset: 0;
  isolation: isolate; /* the pulse sits over the tint, under the icon */
  width: auto;
  height: auto;
  padding: 0;
  border-radius: 0;
  box-shadow: none;
  pointer-events: auto; /* only inside the wedge: clip-path clips taps too */
  transition: clip-path 0.45s cubic-bezier(0.22, 0.8, 0.3, 1);
  /* The button is the whole tile, cut to a wedge: iPhones' tap flash and a
     tap's focus ring would show the whole tile's box. */
  -webkit-tap-highlight-color: transparent;
}
.game-vote:focus:not(:focus-visible) { outline: none; }
#game-yes { background: rgba(6, 40, 22, 0.66); clip-path: polygon(0 100%, 0 calc(100% - var(--r) * var(--sy)), calc(var(--r) * var(--sx)) 100%); }
#game-drink { background: rgba(46, 26, 6, 0.68); clip-path: polygon(100% 100%, 100% calc(100% - var(--r) * var(--sy)), calc(100% - var(--r) * var(--sx)) 100%); }
.game-vote svg {
  position: absolute;
  bottom: calc(var(--r) * var(--sy) / 3);
  width: var(--icon);
  height: var(--icon);
  overflow: visible;
  fill: none;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: left 0.45s cubic-bezier(0.22, 0.8, 0.3, 1), right 0.45s cubic-bezier(0.22, 0.8, 0.3, 1), bottom 0.45s cubic-bezier(0.22, 0.8, 0.3, 1), width 0.45s cubic-bezier(0.22, 0.8, 0.3, 1), height 0.45s cubic-bezier(0.22, 0.8, 0.3, 1);
}
#game-yes svg { stroke: #9ff2c4; left: calc(var(--r) * var(--sx) / 3); transform: translate(-50%, 50%); }
#game-drink svg { stroke: #f3c27a; right: calc(var(--r) * var(--sx) / 3); transform: translate(50%, 50%); }
#game-yes:active svg { transform: translate(-50%, 50%) scale(0.9); }
#game-drink:active svg { transform: translate(50%, 50%) scale(0.9); }
/* The pulse: the wedge's own colour, saturated, slowly up and back. */
.game-vote::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  opacity: 0;
  pointer-events: none;
  animation: vote-pulse 3.2s ease-in-out infinite;
}
#game-yes::before { background: #1ed672; }
#game-drink::before { background: #f29a1f; }
@keyframes vote-pulse { 50% { opacity: 0.18; } }
#game-votes[data-choice] .game-vote { --r: 0px; --icon: 0px; pointer-events: none; }
#game-votes[data-choice] .game-vote::before { animation: none; }
@media (prefers-reduced-motion: reduce) { .game-vote::before { animation: none; } .game-vote, .game-vote svg { transition: none; } }
/* The two icons, filled and chunky, on the buttons and in the cheer. */
.vote-fill { fill: #6fe39d; stroke: #1d6b42; stroke-width: 1.2; stroke-linejoin: round; }
.vote-shine { fill: none; stroke: rgba(255, 255, 255, 0.75); stroke-width: 1.4; stroke-linecap: round; }
.mug-handle { fill: none; stroke: #e9a849; stroke-width: 2.2; stroke-linecap: round; }
.mug-body { fill: #e9a849; stroke: #8a5414; stroke-width: 1.1; }
.mug-stripe { fill: none; stroke: rgba(255, 244, 220, 0.55); stroke-width: 1.3; stroke-linecap: round; }
.mug-foam { fill: #fff6e2; stroke: #d9c6a4; stroke-width: 0.8; stroke-linejoin: round; }

/* A vote won: its icon floats up in a crowd over a tint rising from the bottom
   of the call, behind the call buttons, as the next turn starts (game-ui.js). */
#game-cheer {
  position: absolute;
  inset: 0;
  z-index: 3;
  overflow: hidden;
  pointer-events: none;
  animation: cheer-tint 2.6s ease-out forwards;
}
#game-cheer[hidden] { display: none; }
#game-cheer[data-outcome="answered"] { background: linear-gradient(to top, rgba(40, 160, 92, 0.55), rgba(40, 160, 92, 0) 65%); }
#game-cheer[data-outcome="drank"] { background: linear-gradient(to top, rgba(196, 122, 30, 0.55), rgba(196, 122, 30, 0) 65%); }
.cheer-icon {
  position: absolute;
  bottom: -60px;
  width: var(--size);
  height: var(--size);
  opacity: 0;
  animation: cheer-rise 1.7s cubic-bezier(0.2, 0.7, 0.3, 1) forwards;
}
.cheer-icon svg { width: 100%; height: 100%; overflow: visible; filter: drop-shadow(0 3px 6px rgba(0, 0, 0, 0.4)); }
@keyframes cheer-rise {
  0% { opacity: 0; transform: translate(0, 0) scale(0.6) rotate(-8deg); }
  15% { opacity: 1; }
  70% { opacity: 1; }
  100% { opacity: 0; transform: translate(var(--drift), -62vh) scale(1.05) rotate(8deg); }
}
@keyframes cheer-tint { 0% { opacity: 0; } 15% { opacity: 1; } 70% { opacity: 1; } 100% { opacity: 0; } }

/* The seconds left to write a question, on the seam between the spotlight and
   the row of everyone else. */
#game-timer {
  position: absolute;
  z-index: 3;
  left: 50%;
  bottom: calc(var(--grid-bottom) + var(--ask-row) + var(--players-row) + 2px);
  width: 52px;
  height: 52px;
  transform: translate(-50%, 50%);
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: #1a1622;
  box-shadow: 0 0 0 3px #c9b6ff, 0 6px 18px rgba(0, 0, 0, 0.45);
  color: #fff;
  font-family: Figtree, system-ui, -apple-system, sans-serif;
  font-size: 22px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  transition: bottom 0.45s cubic-bezier(0.22, 0.8, 0.3, 1);
}
#game-timer[hidden], #game-start[hidden] { display: none; }
/* Waiting for the spotlight's Start: the full time, dimmed. */
#game-timer[data-idle] { box-shadow: 0 0 0 3px rgba(201, 182, 255, 0.35), 0 6px 18px rgba(0, 0, 0, 0.45); color: rgba(255, 255, 255, 0.5); }
/* The spotlight's Start, where the countdown will be. */
#game-start {
  position: absolute;
  z-index: 3;
  left: 50%;
  bottom: calc(var(--grid-bottom) + var(--ask-row) + var(--players-row) + 2px);
  height: 52px;
  padding: 0 26px;
  transform: translate(-50%, 50%);
  border-radius: 26px;
  background: #fff;
  box-shadow: 0 0 0 3px #c9b6ff, 0 0 22px 6px rgba(160, 118, 255, 0.6), 0 6px 18px rgba(0, 0, 0, 0.45);
  color: #1a1622;
  font-family: Figtree, system-ui, -apple-system, sans-serif;
  font-size: 18px;
  font-weight: 800;
  transition: bottom 0.45s cubic-bezier(0.22, 0.8, 0.3, 1);
  animation: start-glow 1.8s ease-in-out infinite;
}
/* Start (the game's first turn only) glows: its purple ring breathes out into
   a vivid purple haze and back until it's tapped. */
@keyframes start-glow {
  50% { box-shadow: 0 0 0 3px #d9c9ff, 0 0 36px 12px rgba(168, 120, 255, 0.95), 0 6px 18px rgba(0, 0, 0, 0.45); }
}
@media (prefers-reduced-motion: reduce) { #game-start { animation: none; } }
#game-timer[data-low] { box-shadow: 0 0 0 3px #ff6b5e, 0 6px 18px rgba(0, 0, 0, 0.45); }

/* Short notices: someone joined or left, the room ending soon. */
#toast {
  position: absolute;
  top: 16px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 2;
  padding: 8px 14px;
  white-space: nowrap;
}

/* Popups: "Are you still there?" in a call, "You left the room" after. The huge
   shadow dims everything behind. */
.dialog {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 4;
  width: calc(100% - 32px);
  max-width: 320px;
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  text-align: center;
  box-shadow: 0 0 0 100vmax rgba(0, 0, 0, 0.6);
}
/* Popups wear the sheets' dark, purple-hinted glass: big round corners, a
   hairline edge, pill buttons. The main action is white; leaving is red. */
.dialog.panel {
  padding: 22px 18px 18px;
  border: 0;
  border-radius: 28px;
  color: #fff;
  background: rgba(24, 21, 31, 0.96);
  box-shadow: inset 0 0 0 0.5px rgba(230, 220, 255, 0.16), inset 0 1px 0 rgba(240, 232, 255, 0.09), 0 18px 48px rgba(0, 0, 0, 0.45), 0 0 0 100vmax rgba(0, 0, 0, 0.5);
}
@supports ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  .dialog.panel {
    background: rgba(26, 22, 35, 0.94);
    -webkit-backdrop-filter: blur(30px) saturate(170%);
    backdrop-filter: blur(30px) saturate(170%);
  }
}
.dialog p:not(.dialog-title) { font-size: 15px; line-height: 21px; color: rgba(235, 230, 245, 0.75); }
.dialog button { min-height: 48px; border-radius: 999px; background: rgba(255, 255, 255, 0.1); box-shadow: inset 0 0 0 0.5px rgba(255, 255, 255, 0.12); color: #fff; font-weight: 600; }

/* Karaoke's lyrics sit in a band of their own between the video and the call
   buttons: while they show (lyrics-docked, karaoke-ui.js), the tiles' bottom
   edge slides up to clear them. The band is one fixed height for the whole
   song, so the video never moves with the words: on phones, a sung line of two
   rows, the gap and one row of the next line (wide screens give four rows),
   with 16px under the video and 8px to spare over the floor (62px up, just over
   the call buttons). The sung line always starts at the band's top; the lines
   ahead take the room left under it, down to the last whole row that fits
   (karaoke-ui.js). */
#call-screen {
  --lyric-line: 28px;
  --lyrics-floor: 62px;
  --lyrics-band: calc(16px + 3 * var(--lyric-line) + 14px + 8px);
}
/* Behind it all while a song is on (paused too), the song's cover, faint over
   the black, so the band under the video is still dark but tinted by the song. */
#karaoke-backdrop {
  position: absolute;
  inset: 0;
  background: #000 center / cover no-repeat;
  opacity: 0;
  transition: opacity 0.6s ease;
  pointer-events: none;
}
#call-screen.karaoke-backdrop-on #karaoke-backdrop { opacity: 0.45; }
#grid { transition: padding-bottom 0.45s cubic-bezier(0.22, 0.8, 0.3, 1); }
#call-screen.lyrics-docked { --grid-bottom: calc(var(--lyrics-floor) + var(--lyrics-band)); }
@media (prefers-reduced-motion: reduce) { #grid { transition: none; } }
/* Large white centred lines, no shadow. Taps pass through to the call. */
#karaoke-lyrics {
  position: absolute;
  z-index: 2;
  left: 16px;
  right: 16px;
  top: calc(100% - var(--lyrics-floor) - var(--lyrics-band));
  height: var(--lyrics-band);
  padding: 16px 0 8px;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  pointer-events: none;
  text-align: center;
  color: #fff;
}
/* The lines, set like Spotify's lyrics (Figtree standing in for its own
   geometric face): bold, tightly spaced, all one size, the sung line on top in
   white and the ones ahead dimmer. */
#lyrics-current, #lyrics-next, .lyrics-leaving {
  font-family: Figtree, system-ui, -apple-system, "PingFang SC", "Microsoft YaHei", sans-serif;
  font-weight: 700;
  letter-spacing: -0.02em;
}
#karaoke-lyrics[hidden] { display: none; }
#lyrics-current, .lyrics-leaving { font-size: 22px; line-height: 28px; }
#lyrics-current { flex: none; }
.lyrics-leaving { position: absolute; left: 0; right: 0; }
/* The lines ahead fill the rest of the band, cut at a whole row (karaoke-ui.js). */
#lyrics-next { font-size: 22px; line-height: 28px; opacity: 0.45; margin-top: 14px; flex: 1 1 0; min-height: 0; overflow: hidden; }
#lyrics-next span { display: block; }
#lyrics-next span + span { margin-top: 14px; }
/* The lyrics ignore taps (the hidden player sits under them); their buttons
   don't. They sit above the sung line, the lines below it being out of sight. */
#lyrics-actions { position: absolute; left: 0; right: 0; bottom: 100%; margin-bottom: 20px; pointer-events: auto; text-shadow: none; display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 8px; }
#lyrics-actions[hidden], #lyrics-actions [hidden] { display: none; }
#lyrics-actions button { font-size: 14px; padding: 8px 12px; }
#lyrics-hand { margin: 0; display: flex; align-items: center; gap: 8px; font-size: 14px; opacity: 0.85; }
#lyrics-hand button[aria-pressed="true"] { background: #fff; color: #000; }
#lyrics-sync-sheet {
  position: fixed; z-index: 7; left: 50%; bottom: 16px; transform: translateX(-50%);
  width: calc(100% - 32px); max-width: 420px; max-height: 70vh; padding: 14px;
  display: flex; flex-direction: column; gap: 10px;
}
#lyrics-sync-sheet[hidden] { display: none; }
#lyrics-sync-lines { list-style: none; margin: 0; padding: 0; overflow-y: auto; flex: 1; min-height: 120px; }
#lyrics-sync-lines button { display: block; width: 100%; text-align: left; padding: 8px 10px; margin-bottom: 4px; background: transparent; color: #ddd; }
#lyrics-sync-lines button[aria-current="true"] { background: rgba(255, 255, 255, 0.18); color: #fff; font-weight: 700; }


/* "Are you still there?" has a countdown, so it sits above the watch popups. */
#still-there { z-index: 5; }

.dialog-title { font-size: 20px; font-weight: 700; letter-spacing: -0.3px; color: #fff; }
.dialog-actions { display: flex; gap: 8px; }
.dialog-actions button { flex: 1; }
.dialog #im-here, .dialog #left-rejoin, .dialog #watch-ask-yes, .dialog #watch-invited-yes { background: #fff; color: #1a1622; }
.dialog #leave-ask-yes, .dialog #session-end-yes { background: #c62828; }
.dialog #knock-yes { background: #fff; color: #1a1622; }

#game-notice {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  padding: 10px 14px;
  white-space: nowrap;
}

/* Bottom sheets (Games, Watch, Add a song, Add a video): dark glass just above
   the call buttons, one at a time, with a grab handle that closes them. They
   grow open and shrink shut (sheet-motion.js). */
.sheet {
  position: absolute;
  z-index: 3;
  left: 8px;
  right: 8px;
  bottom: 67px; /* the call buttons' 7px + 48px, and a 12px gap */
  max-width: 480px;
  max-height: calc(100% - 67px - 16px);
  overflow-y: auto;
  margin: 0 auto;
  padding: 14px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  border-radius: 28px;
  color: #fff;
  background: rgba(24, 21, 31, 0.94);
  box-shadow: inset 0 0 0 0.5px rgba(230, 220, 255, 0.16), inset 0 1px 0 rgba(240, 232, 255, 0.09), 0 18px 48px rgba(0, 0, 0, 0.45);
}
.sheet[hidden] { display: none; }
/* Dragged down or flung shut: the top edge comes down over contents pinned to
   the bottom (sheet-motion.js). */
.sheet[data-shrinking] { overflow: hidden; justify-content: flex-end; }
.sheet[data-shrinking] > * { flex-shrink: 0; }
@supports ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  .sheet {
    background: rgba(26, 22, 35, 0.84);
    -webkit-backdrop-filter: blur(30px) saturate(170%);
    backdrop-filter: blur(30px) saturate(170%);
  }
}
/* The grab bar floats in the top padding, so the contents sit as far from the
   top edge as from the bottom. */
.sheet-handle { position: absolute; z-index: 1; top: 0; left: 0; right: 0; margin: 0 auto; width: 44px; height: 14px; padding: 0; background: transparent; box-shadow: none; }
.sheet-handle::before { content: ""; position: absolute; left: 4px; right: 4px; top: 5px; height: 4px; border-radius: 2px; background: rgba(255, 255, 255, 0.28); }
.sheet .sheet-title { font-family: Figtree, system-ui, -apple-system, sans-serif; font-size: 22px; font-weight: 800; letter-spacing: -0.4px; text-align: center; }
/* Every sheet's title sits in a 40px row, centred: the Karaoke and Theater
   titles share theirs with round 40px buttons, and Watch and Games match them,
   so a title is the same height from the top in every sheet. */
#watch-title, #games-title { min-height: 40px; display: flex; align-items: center; justify-content: center; }
/* Under a panel's title while it shows results: what they are. */
.sheet-crumb { display: block; font-family: system-ui, -apple-system, sans-serif; font-size: 12px; font-weight: 600; letter-spacing: 0.02em; color: #c9b6ff; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sheet-crumb:empty { display: none; }
.showing-results #queue-shelf, .showing-results #watch-invite, .showing-results #karaoke-volume-row, .showing-results #karaoke-boost-row, .showing-results #karaoke-boost-note { display: none; }
/* Karaoke's own volume, a speaker and theater's slider, on the panel's home. */
#karaoke-volume-row, .boost-row { display: flex; align-items: center; gap: 12px; }
.boost-row[hidden] { display: none; }
#karaoke-volume-row svg, .boost-row svg { width: 20px; height: 20px; flex: none; fill: none; stroke: rgba(235, 230, 245, 0.7); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
/* Drag the bar or the title down to close (sheet-motion.js). */
.sheet-handle, .sheet .sheet-title { touch-action: none; }
.sheet-handle { cursor: grab; }
/* Inside a sheet: soft glass buttons and fields; chosen ones go white. */
:where(.sheet) button { border-radius: 14px; background: rgba(255, 255, 255, 0.08); box-shadow: inset 0 0 0 0.5px rgba(255, 255, 255, 0.1); }
:where(.sheet) input[type="search"], :where(.sheet) input[type="text"], :where(#game-question) {
  padding: 11px 13px;
  border: 0;
  border-radius: 14px;
  background: rgba(255, 255, 255, 0.08);
  box-shadow: inset 0 0 0 0.5px rgba(255, 255, 255, 0.12);
  color: #fff;
  font-size: 16px;
}
:where(.sheet) input::placeholder, :where(#game-question)::placeholder { color: rgba(235, 230, 245, 0.35); }
:where(.sheet) input:focus, :where(#game-question):focus { outline: none; box-shadow: inset 0 0 0 1.5px rgba(206, 180, 255, 0.6); }
#games-store { display: flex; flex-direction: column; gap: 12px; }
#games-store[hidden], #studio[hidden], #game-setup[hidden] { display: none; }
/* Game tiles, like Watch's: big squares, two to a row, the name centred over a
   large, faint icon. */
#game-list { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
#game-list[hidden] { display: none; }
.game-card {
  position: relative;
  overflow: hidden;
  aspect-ratio: 1;
  padding: 12px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  border-radius: 22px;
  color: #fff;
  text-align: center;
}
button.game-card:not(:disabled):active { transform: scale(0.98); }
.game-card svg { position: absolute; left: 50%; top: 50%; width: 78%; height: 78%; transform: translate(-50%, -50%); opacity: 0.09; fill: none; stroke: currentColor; stroke-width: 1.4; stroke-linecap: round; stroke-linejoin: round; }
.game-name { position: relative; font-size: 19px; font-weight: 700; line-height: 23px; }
/* Too few people: the tile looks the same, with a pill at its bottom centre
   saying what it needs (the name stays centred). */
.game-play {
  position: absolute;
  left: 50%;
  bottom: 12px;
  transform: translateX(-50%);
  padding: 4px 10px;
  border-radius: 999px;
  background: #d12f2f;
  box-shadow: inset 0 0 0 0.5px rgba(255, 255, 255, 0.2), 0 2px 8px rgba(0, 0, 0, 0.25);
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
  color: #fff;
}
.game-play:empty { display: none; }
button.game-card:disabled { opacity: 1; cursor: default; }
/* The custom game form: a back arrow, three plain fields, one button. */
#studio, #game-setup { display: flex; flex-direction: column; gap: 12px; }
/* Truth or Drink's setup, laid out like the karaoke panel: its head (a round
   back button, the big title), then the game modes as three covers like
   "Recently played" (art, name, and what it means, wrapping), the chosen one
   ringed in white and the others dimmed; then the timer's presets, which slide
   shut when there's no writing; then Start game, a plain sheet button like
   karaoke's Invite everyone. */
#setup-back { width: 40px; height: 40px; padding: 0; border-radius: 50%; display: flex; align-items: center; justify-content: center; }
#setup-back svg { width: 20px; height: 20px; fill: none; stroke: #fff; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
.setup-group { margin: 0; padding: 0; border: 0; min-width: 0; display: flex; flex-direction: column; gap: 8px; }
.setup-group .setup-head { padding: 0 0 8px; text-align: left; } /* left, like "Recently played" */
.mode-cards { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }
.mode-card { position: relative; display: flex; flex-direction: column; gap: 2px; min-width: 0; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.mode-card input { position: absolute; opacity: 0; pointer-events: none; }
.mode-cover {
  display: grid;
  place-items: center;
  aspect-ratio: 1;
  margin-bottom: 6px;
  border-radius: 12px;
  box-shadow: inset 0 0 0 0.5px rgba(255, 255, 255, 0.14);
  opacity: 0.55;
  transition: opacity 0.2s ease, box-shadow 0.2s ease;
}
.mode-cover[data-mode="custom"] { background: linear-gradient(135deg, #8a6bff, #3a1f8c); }
.mode-cover[data-mode="premade"] { background: linear-gradient(135deg, #ff8a5c, #9e2350); }
.mode-cover[data-mode="mix"] { background: linear-gradient(135deg, #35cfae, #1d4f8a); }
.mode-cover svg { width: 46%; height: 46%; fill: none; stroke: #fff; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.3)); }
.mode-card input:checked + .mode-cover { opacity: 1; box-shadow: 0 0 0 2px #fff; }
.mode-card input:focus-visible + .mode-cover { outline: 2px solid rgba(206, 180, 255, 0.8); outline-offset: 4px; }
.mode-card b { font-size: 13px; font-weight: 600; }
.mode-card small { font-size: 12px; line-height: 16px; color: rgba(235, 230, 245, 0.66); }
/* The banks: covers like karaoke's "Recently played", in a row that scrolls
   sideways to the sheet's edges; each a gradient with its theme's icon, faint,
   and its name and size over a shade at the bottom. Chosen ones are ringed in
   white with a check; the rest dim. */
#setup-banks-row > div { margin: 0 -14px; padding: 0 14px; }
.bank-cards {
  margin: 0 -14px;
  padding: 2px 14px;
  display: flex;
  gap: 12px;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scroll-padding: 0 14px;
  scrollbar-width: none;
}
.bank-cards::-webkit-scrollbar { display: none; }
.bank-card { position: relative; flex: none; width: 112px; scroll-snap-align: start; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.bank-card input { position: absolute; opacity: 0; pointer-events: none; }
.bank-cover {
  position: relative;
  display: block;
  width: 112px;
  height: 112px;
  overflow: hidden;
  border-radius: 12px;
  box-shadow: inset 0 0 0 0.5px rgba(255, 255, 255, 0.14);
  opacity: 0.5;
  transition: opacity 0.2s ease, box-shadow 0.2s ease;
}
.bank-cover::after { content: ""; position: absolute; inset: 0; background: linear-gradient(to top, rgba(0, 0, 0, 0.55), rgba(0, 0, 0, 0) 60%); }
.bank-cover[data-bank="classic"] { background: linear-gradient(135deg, #8a6bff, #c2417a); }
.bank-cover[data-bank="deep"] { background: linear-gradient(135deg, #3a9be0, #173a7a); }
.bank-cover[data-bank="deeper"] { background: linear-gradient(135deg, #2c4bb5, #0f1a4f); }
.bank-cover[data-bank="deepest"] { background: linear-gradient(135deg, #252a5e, #05060f); }
.bank-cover[data-bank="dark"] { background: linear-gradient(135deg, #5c1414, #0b0b0b); }
.bank-cover[data-bank="nasty"] { background: linear-gradient(135deg, #ff4d6d, #8a1240); }
.bank-cover > svg { position: absolute; top: 12px; left: 50%; width: 54px; height: 54px; transform: translateX(-50%); fill: none; stroke: rgba(255, 255, 255, 0.55); stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.bank-name, .bank-count { position: absolute; z-index: 1; left: 10px; right: 10px; color: #fff; text-shadow: 0 1px 3px rgba(0, 0, 0, 0.4); }
.bank-name { bottom: 25px; font: 800 17px/20px Figtree, system-ui, -apple-system, sans-serif; letter-spacing: -0.2px; }
.bank-count { bottom: 9px; font-size: 12px; font-weight: 600; color: rgba(255, 255, 255, 0.8); }
.bank-plays { position: absolute; z-index: 1; top: 7px; left: 7px; padding: 3px 7px; border-radius: 999px; background: rgba(0, 0, 0, 0.38); color: #fff; font-size: 11px; font-weight: 700; line-height: 14px; }
.bank-plays[hidden] { display: none; }
.bank-check { position: absolute; z-index: 1; top: 7px; right: 7px; width: 22px; height: 22px; border-radius: 50%; background: #fff; display: grid; place-items: center; transform: scale(0); transition: transform 0.2s cubic-bezier(0.22, 0.8, 0.3, 1); }
.bank-check svg { width: 14px; height: 14px; fill: none; stroke: #1a1622; stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; }
.bank-card input:checked + .bank-cover { opacity: 1; box-shadow: inset 0 0 0 2px #fff; }
.bank-card input:checked + .bank-cover .bank-check { transform: none; }
.bank-card input:focus-visible + .bank-cover { outline: 2px solid rgba(206, 180, 255, 0.8); outline-offset: 2px; }
.setup-timer { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 11px 14px; border-radius: 16px; background: rgba(255, 255, 255, 0.06); box-shadow: inset 0 0 0 0.5px rgba(255, 255, 255, 0.1); }
.setup-option-text { flex: 1; display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.setup-option-name { font-size: 15px; font-weight: 600; color: #fff; }
.setup-hint { font-size: 13px; line-height: 18px; color: rgba(235, 230, 245, 0.55); }
.setup-timer { cursor: default; }
/* The timer's presets: small pills in a tray, the chosen one white. */
.setup-chips { flex: none; display: flex; gap: 2px; padding: 3px; border-radius: 12px; background: rgba(0, 0, 0, 0.25); }
.setup-chips label { position: relative; }
.setup-chips input { position: absolute; opacity: 0; pointer-events: none; }
.setup-chips span { display: flex; align-items: center; justify-content: center; min-width: 42px; height: 32px; padding: 0 6px; border-radius: 9px; font-size: 14px; font-weight: 600; color: rgba(235, 230, 245, 0.75); cursor: pointer; transition: background 0.2s ease, color 0.2s ease; -webkit-tap-highlight-color: transparent; }
.setup-chips input:checked + span { background: #fff; color: #1a1622; }
.setup-chips input:focus-visible + span { outline: 2px solid rgba(206, 180, 255, 0.8); outline-offset: 1px; }
/* Sliding shut: the row's height goes to nothing (taking the gap above it
   along) as it fades, and the sheet shrinks with it. */
.setup-collapse { display: grid; grid-template-rows: 1fr; transition: grid-template-rows 0.3s cubic-bezier(0.22, 0.8, 0.3, 1), opacity 0.2s ease, margin-top 0.3s cubic-bezier(0.22, 0.8, 0.3, 1); }
.setup-collapse > div { min-height: 0; overflow: hidden; }
.setup-collapse[data-gone] { grid-template-rows: 0fr; opacity: 0; margin-top: -12px; }
@media (prefers-reduced-motion: reduce) { .setup-collapse { transition: none; } }
/* "Design your own game" (studio-ui.js): a chat with Studio that reads like
   prompting an agent (a › at your messages, Studio's in plain text under a
   small glyph, monospace asides, a glowing composer), then the game being
   built (a big percentage, a glowing bar, stages, what's happened), then
   ready. The game list shows it as a tile with a ring of its progress. */
#studio-back { width: 40px; height: 40px; padding: 0; border-radius: 50%; display: flex; align-items: center; justify-content: center; }
#studio-back svg { width: 20px; height: 20px; fill: none; stroke: #fff; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
#studio-chat, #studio-progress, #studio-intro { display: flex; flex-direction: column; gap: 12px; }
#studio-chat[hidden], #studio-progress[hidden], #studio-ready[hidden], #studio-intro[hidden], #studio-log[hidden], #studio-plan-actions[hidden], #studio-composer[hidden] { display: none; }
.studio-mono { margin: 0; font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace; font-size: 11px; color: rgba(235, 230, 245, 0.55); }
.studio-glyph { flex: none; display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 22px; border-radius: 7px; background: #2a2140; box-shadow: inset 0 0 0 1px rgba(201, 182, 255, 0.35); color: #c9b6ff; font: 500 10px/1 ui-monospace, "SF Mono", Menlo, monospace; }
.studio-brand { margin: 0; display: flex; align-items: center; gap: 10px; color: #c9b6ff; font: 12px ui-monospace, "SF Mono", Menlo, monospace; letter-spacing: 0.02em; }
.studio-brand .studio-glyph { width: 34px; height: 34px; border-radius: 10px; font-size: 14px; }
.studio-heading { margin: 0; font: 800 28px/32px Figtree, system-ui, -apple-system, sans-serif; letter-spacing: -0.6px; }
.studio-lede { margin: 0; font-size: 15px; line-height: 21px; color: rgba(235, 230, 245, 0.72); }
.studio-try { margin: 4px 0 -4px; font-size: 13px; font-weight: 600; color: rgba(235, 230, 245, 0.62); }
.studio-ideas { display: flex; flex-direction: column; gap: 8px; }
.studio-idea { display: flex; align-items: center; gap: 10px; padding: 12px 14px; text-align: left; font-size: 14px; font-weight: 500; line-height: 19px; }
.studio-idea svg { flex: none; width: 16px; height: 16px; fill: none; stroke: #c9b6ff; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
/* The chat: it scrolls inside the sheet, newest at the bottom. */
#studio-log { display: flex; flex-direction: column; gap: 16px; max-height: min(48vh, 420px); overflow-y: auto; overscroll-behavior: contain; }
.studio-you { display: flex; gap: 10px; padding: 12px 14px; border-radius: 14px; background: rgba(255, 255, 255, 0.06); }
.studio-you p { margin: 0; font-size: 15px; line-height: 21px; overflow-wrap: anywhere; }
.studio-prompt { color: #c9b6ff; font: 16px/21px ui-monospace, "SF Mono", Menlo, monospace; }
.studio-agent { display: flex; flex-direction: column; gap: 8px; }
.studio-agent-head { display: flex; align-items: center; gap: 8px; font-size: 13px; }
.studio-message { margin: 0; font-size: 15px; line-height: 22px; color: rgba(245, 242, 250, 0.92); overflow-wrap: anywhere; }
.studio-thinking .studio-mono { color: #c9b6ff; font-size: 12px; }
.studio-dots { display: inline-flex; gap: 4px; }
.studio-dots i { width: 5px; height: 5px; border-radius: 50%; background: #c9b6ff; animation: studio-dot 1.2s ease-in-out infinite; }
.studio-dots i:nth-child(2) { animation-delay: 0.2s; }
.studio-dots i:nth-child(3) { animation-delay: 0.4s; }
@keyframes studio-dot { 0%, 100% { opacity: 0.25; } 50% { opacity: 1; } }
.studio-questions { display: flex; flex-direction: column; gap: 10px; padding: 12px 14px; border-radius: 16px; background: #221c2e; box-shadow: inset 0 0 0 0.5px rgba(255, 255, 255, 0.12); }
.studio-question { margin: 0; font-size: 14px; line-height: 19px; font-weight: 600; }
.studio-question + .studio-choices + .studio-question { margin-top: 2px; }
.studio-choices { display: flex; flex-wrap: wrap; gap: 6px; }
:where(.sheet) .studio-choice { padding: 7px 12px; border-radius: 999px; font-size: 13px; font-weight: 600; line-height: 16px; box-shadow: inset 0 0 0 0.5px rgba(255, 255, 255, 0.14); }
.studio-choice[aria-pressed="true"] { background: #fff; color: #1a1622; }
.studio-choice:disabled { opacity: 0.6; }
/* The plan, and the game's art wherever it shows. */
.studio-plan { display: flex; flex-direction: column; gap: 14px; padding: 16px; border-radius: 20px; background: #221c2e; box-shadow: inset 0 0 0 0.5px rgba(255, 255, 255, 0.12); }
.studio-game { display: flex; align-items: center; gap: 12px; }
.studio-game-text { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.studio-game-title { margin: 0; font: 800 19px/23px Figtree, system-ui, -apple-system, sans-serif; letter-spacing: -0.2px; }
.studio-plan .studio-mono { color: #c9b6ff; }
.studio-art { position: relative; flex: none; display: flex; align-items: center; justify-content: center; width: 54px; height: 54px; border-radius: 14px; background: linear-gradient(135deg, #ff6b8b, #5b2a9e); }
.studio-art svg { width: 50%; height: 50%; fill: none; stroke: #fff; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.studio-plan-rows { margin: 0; display: grid; grid-template-columns: 88px minmax(0, 1fr); gap: 12px; font-size: 14px; line-height: 19px; }
.studio-plan-rows dt { color: rgba(235, 230, 245, 0.6); font-weight: 600; }
.studio-plan-rows dd { margin: 0; }
#studio-plan-actions { display: flex; flex-direction: column; gap: 8px; }
:where(.sheet) #studio-build, :where(.sheet) #studio-play { background: #fff; box-shadow: none; color: #1a1622; font-weight: 700; }
/* The composer: one box that glows, a › before what you type, send at the corner. */
#studio-composer { display: flex; flex-direction: column; gap: 10px; padding: 14px 14px 10px; border-radius: 20px; background: #221c2e; box-shadow: inset 0 0 0 1px rgba(201, 182, 255, 0.32), 0 0 0 4px rgba(143, 107, 255, 0.1), 0 0 28px rgba(143, 107, 255, 0.22); }
.studio-compose-row { display: flex; gap: 10px; align-items: flex-start; }
#studio-input { flex: 1; min-width: 0; padding: 0; border: 0; background: transparent; box-shadow: none; resize: none; outline: none; color: #fff; font: 400 16px/22px Figtree, system-ui, -apple-system, sans-serif; }
#studio-input::placeholder { color: rgba(235, 230, 245, 0.4); }
.studio-compose-foot { display: flex; align-items: center; justify-content: space-between; }
#studio-send { width: 36px; height: 36px; padding: 0; border-radius: 50%; background: #fff; box-shadow: none; display: flex; align-items: center; justify-content: center; }
#studio-send svg { width: 18px; height: 18px; fill: none; stroke: #1a1622; stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round; }
#studio-error { margin: -4px 0 0; font-size: 13px; color: #ffb4a8; text-align: center; }
#studio-error:empty { display: none; }
.studio-privacy { margin: -4px 0 0; font-size: 11px; line-height: 15px; text-align: center; color: rgba(235, 230, 245, 0.5); }
/* Building. */
.studio-meter { display: flex; align-items: baseline; justify-content: space-between; }
#studio-percent { font: 800 40px/44px Figtree, system-ui, -apple-system, sans-serif; letter-spacing: -1px; }
#studio-stage-now { color: #c9b6ff; font-size: 12px; }
.studio-bar { height: 10px; border-radius: 5px; background: rgba(255, 255, 255, 0.08); overflow: hidden; }
.studio-bar > div { height: 100%; border-radius: 5px; background: linear-gradient(90deg, #8f6bff, #c9b6ff); box-shadow: 0 0 14px rgba(160, 118, 255, 0.7); transition: width 0.6s ease; }
.studio-bar-done { width: 100%; }
.studio-bar-done > div { width: 100%; background: linear-gradient(90deg, #3fc47d, #6fe39d); box-shadow: 0 0 14px rgba(111, 227, 157, 0.6); }
#studio-stages { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 10px; font-size: 14px; line-height: 19px; color: rgba(235, 230, 245, 0.5); }
#studio-stages li { display: flex; align-items: center; gap: 10px; }
#studio-stages li.is-done { color: #fff; }
#studio-stages li.is-now { color: #fff; font-weight: 700; }
.studio-stage-mark { flex: none; width: 20px; height: 20px; box-sizing: border-box; border-radius: 50%; box-shadow: inset 0 0 0 1.5px rgba(235, 230, 245, 0.3); display: flex; align-items: center; justify-content: center; }
.is-done .studio-stage-mark { background: #6fe39d; box-shadow: none; }
.is-done .studio-stage-mark svg { width: 12px; height: 12px; fill: none; stroke: #0f2a1b; stroke-width: 3.4; stroke-linecap: round; stroke-linejoin: round; }
.is-now .studio-stage-mark { box-shadow: inset 0 0 0 2px rgba(201, 182, 255, 0.25); border-top: 2px solid #c9b6ff; animation: studio-spin 1s linear infinite; }
@keyframes studio-spin { to { transform: rotate(360deg); } }
.studio-activity { display: flex; flex-direction: column; gap: 6px; padding: 12px 14px; border-radius: 14px; background: #120f18; box-shadow: inset 0 0 0 0.5px rgba(255, 255, 255, 0.08); font: 11.5px/16px ui-monospace, "SF Mono", Menlo, monospace; color: rgba(235, 230, 245, 0.75); }
.studio-activity-head, .studio-activity-time { color: rgba(235, 230, 245, 0.42); }
.studio-activity-now { color: #c9b6ff; }
.studio-note { margin: 0; font-size: 12px; line-height: 16px; text-align: center; color: rgba(235, 230, 245, 0.6); }
/* Ready. */
#studio-ready { display: flex; flex-direction: column; align-items: center; gap: 14px; padding-top: 8px; text-align: center; }
#studio-ready > button { align-self: stretch; }
.studio-art-big { width: 120px; height: 120px; border-radius: 32px; box-shadow: 0 0 0 3px rgba(111, 227, 157, 0.9), 0 0 40px rgba(111, 227, 157, 0.35); margin-bottom: 6px; }
.studio-check { position: absolute; right: -10px; bottom: -10px; width: 38px; height: 38px; border-radius: 50%; background: #6fe39d; box-shadow: 0 0 0 4px #1a1623; display: flex; align-items: center; justify-content: center; }
.studio-check svg { width: 22px; height: 22px; fill: none; stroke: #0f2a1b; stroke-width: 3.2; stroke-linecap: round; stroke-linejoin: round; }
.studio-ready-tag { color: #6fe39d; font-size: 12px; }
/* The game list's tile while it's built: a ring of its progress. */
.studio-tile[hidden] { display: none; }
.studio-tile { box-shadow: inset 0 0 0 1px rgba(201, 182, 255, 0.35); }
.studio-tile .game-name { font-size: 14px; line-height: 17px; }
.studio-tile .studio-mono { color: #c9b6ff; }
.studio-ring { position: relative; width: 64px; height: 64px; display: flex; align-items: center; justify-content: center; }
.studio-ring svg { position: absolute; inset: 0; left: 0; top: 0; width: 100%; height: 100%; opacity: 1; transform: rotate(-90deg); fill: none; stroke: rgba(255, 255, 255, 0.1); stroke-width: 6; } /* not .game-card's faint backdrop icon */
.studio-ring .studio-ring-fill { stroke: #c9b6ff; stroke-linecap: round; }
.studio-tile.is-ready .studio-ring-fill { stroke: #6fe39d; }
.studio-ring-text { font-size: 16px; font-weight: 800; }
@media (prefers-reduced-motion: reduce) { .studio-dots i, .is-now .studio-stage-mark { animation: none; } }
#end-game { border-radius: 999px; background: rgba(200, 30, 30, 0.6); font-weight: 600; }
#happybird-return { border-radius: 999px; font-weight: 600; }
/* A mode panel's head: Exit (a back chevron) left of the title, Spotify on the right. */
.panel-head { display: grid; grid-template-columns: 64px 1fr 64px; align-items: center; gap: 8px; margin-bottom: 8px; } /* 20px to the contents with the sheet's gap */
.panel-side { display: flex; }
.panel-side:last-child { justify-content: flex-end; }
#session-exit, #spotify-button { width: 40px; height: 40px; padding: 0; border-radius: 50%; display: flex; align-items: center; justify-content: center; }
#session-exit svg { width: 20px; height: 20px; fill: none; stroke: #fff; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
/* On the panel's home it's a red Exit pill (leaving the session); in results
   it's a back chevron. */
:where(.sheet) #session-exit { width: auto; padding: 0 16px; border-radius: 20px; background: #c62828; box-shadow: none; color: #fff; font-size: 15px; font-weight: 600; }
#session-exit svg, .showing-results #session-exit .exit-word { display: none; }
.showing-results #session-exit { width: 40px; padding: 0; background: rgba(255, 255, 255, 0.08); box-shadow: inset 0 0 0 0.5px rgba(255, 255, 255, 0.1); }
.showing-results #session-exit svg { display: block; }
/* Spotify's own logo in its colours: green with black sound waves. */
#spotify-button .spotify-logo { width: 24px; height: 24px; fill: #1ed760; }

#spotify-button[hidden] { display: none; }
#spotify-button:disabled .spotify-logo { filter: grayscale(1); } /* greyed with the dimming every disabled button gets */

.sheet-title { font-weight: 600; text-align: center; }

/* Happybird (happybird-ui.js): the call's tiles give way to the game (the
   sheets, notices and call buttons stay over it; the voices carry on), in
   heavy italic caps, slanted edges and the four seat colours, like an
   arcade's select screen. The lobby is a card: the start screen, or choosing
   a bird once seated. A race is a dark square as big as fits above the call
   buttons (the page sizes it); a tap anywhere on the screen flaps, so in a
   race nothing scrolls, zooms on a quick double tap or selects. */
#call-screen:has(#happybird-arena:not([hidden])) {
  touch-action: manipulation;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
}
#happybird {
  --hb-ink: #0d0b11;
  --hb-fg: #f4f1f8;
  --hb-tile: #221f2b;
  --hb-panel: #15131b;
  --hb-violet: #a98bff;
  --hb-display: "Barlow Condensed", "Arial Narrow", Impact, sans-serif;
  --hb-bar: calc(56px + env(safe-area-inset-top));
  position: absolute;
  isolation: isolate;
  top: 0;
  left: 0;
  right: 0;
  bottom: var(--grid-bottom);
  display: flex;
  align-items: center;
  justify-content: center;
  padding-top: var(--hb-bar);
  overflow: hidden;
  background: #000;
  color: var(--hb-fg);
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
  -webkit-tap-highlight-color: transparent;
}
/* The seat colours (happybird-ui.js has them too, for the race): --c, a dark
   one for gradients, a soft one for the results. */
#happybird [data-seat="0"] { --c: #ffc94d; --c-dark: #66501f; --c-soft: rgba(255, 201, 77, 0.3); }
#happybird [data-seat="1"] { --c: #ff8f7a; --c-dark: #663931; --c-soft: rgba(255, 143, 122, 0.3); }
#happybird [data-seat="2"] { --c: #6fd6b0; --c-dark: #2c5646; --c-soft: rgba(111, 214, 176, 0.3); }
#happybird [data-seat="3"] { --c: #a98bff; --c-dark: #443866; --c-soft: rgba(169, 139, 255, 0.3); }
.hb-caps { font-family: var(--hb-display); font-style: italic; font-weight: 900; text-transform: uppercase; letter-spacing: 0.01em; }
#happybird button { padding: 0; border-radius: 0; font-family: var(--hb-display); }
/* Slanted buttons clip an outline away, so focus shows inside them. */
#happybird button:focus-visible { outline: none; box-shadow: inset 0 0 0 3px var(--hb-ink), inset 0 0 0 5px var(--hb-fg); }

/* Above the game: Back to the call on the left, the mode in the middle
   (from bird select on), sound on or off (remembered on this phone) on the
   right. */
.hb-bar {
  position: absolute;
  z-index: 4;
  top: 0;
  left: 0;
  right: 0;
  height: var(--hb-bar);
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  padding: 0 max(12px, env(safe-area-inset-right)) 8px max(12px, env(safe-area-inset-left));
}
#happybird .hb-round {
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--hb-tile);
  box-shadow: inset 0 0 0 1px #2c2836;
  color: var(--hb-fg);
}
.hb-round svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
#happybird-back svg { width: 22px; height: 22px; stroke-width: 2.4; }
.hb-modechip {
  align-self: center;
  margin-top: auto;
  margin-bottom: 7px;
  padding: 4px 16px 2px;
  background: var(--hb-tile);
  box-shadow: inset 0 -3px 0 #ff8f7a;
  font-size: 20px;
  line-height: 1;
  clip-path: polygon(8px 0, 100% 0, calc(100% - 8px) 100%, 0 100%);
}
.hb-modechip[data-mode="story"] { box-shadow: inset 0 -3px 0 #6fd6b0; }
.hb-modechip[hidden] { display: none; }
.hb-mute .hb-sound-off, .hb-mute[aria-pressed="true"] .hb-sound-on { display: none; }
.hb-mute[aria-pressed="true"] .hb-sound-off { display: block; }

/* The lobby's card, centred under the row, scrolling on a short screen. */
.hb-screen {
  position: absolute;
  top: var(--hb-bar);
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  flex-direction: column;
  padding: 8px;
  overflow-y: auto;
  touch-action: pan-y;
}
.hb-card {
  position: relative;
  overflow: hidden;
  flex: none;
  width: 100%;
  max-width: 560px;
  margin: auto;
  display: grid;
  grid-gap: 14px;
  gap: 14px;
  align-content: start;
  padding: 18px 14px;
  border-radius: 28px; /* as round as the race */
  background: radial-gradient(120% 70% at 50% 0%, #1d1a26 0%, #07060a 70%);
  box-shadow: 0 0 0 0.5px rgba(230, 220, 255, 0.14);
}
.hb-card > * { position: relative; z-index: 1; }
/* Rays behind the bird select, turning slowly. */
.hb-card > .hb-rays {
  position: absolute;
  z-index: 0;
  top: -40%;
  left: -40%;
  right: -40%;
  bottom: -40%;
  pointer-events: none;
  opacity: 0.5;
  background: repeating-conic-gradient(from 0deg at 50% 50%, rgba(255, 255, 255, 0.045) 0deg 7deg, transparent 7deg 18deg);
  animation: hb-spin 60s linear infinite;
}
@keyframes hb-spin { to { transform: rotate(360deg); } }
.hb-band {
  justify-self: start;
  padding: 6px 28px 4px 18px;
  background: var(--hb-fg);
  color: var(--hb-ink);
  font-size: 34px;
  line-height: 1;
  white-space: nowrap;
  clip-path: polygon(0 0, 100% 0, calc(100% - 18px) 100%, 0 100%);
  box-shadow: inset 0 -5px 0 #ff8f7a;
}
.hb-card > .hb-band { margin-left: -14px; }

/* The start screen: the logo with birds flying behind, a chip per seat (lit
   once someone's in it), the two modes and JOIN. Sized by the screen's height
   (cqh), so on a phone it fits between the bar and the call's buttons. */
#happybird-splash { container-type: size; }
#happybird-splash .hb-card { min-height: 540px; min-height: min(540px, 100cqh); align-content: space-between; justify-items: center; padding: 32px 14px 28px; padding: clamp(12px, 5cqh, 32px) 14px clamp(10px, 4cqh, 28px); grid-gap: clamp(8px, 2cqh, 14px); gap: clamp(8px, 2cqh, 14px); text-align: center; }
#happybird-splash .hb-logo { margin-top: clamp(0px, 20cqh - 70px, 96px); font-size: clamp(50px, min(22vw, 13cqh), 124px); }
#happybird-splash .hb-card .hb-press { font-size: clamp(30px, 7cqh, 40px); }
.hb-card > .hb-sky { position: absolute; z-index: 0; top: 0; left: 0; width: 100%; height: 100%; }
.hb-logo { margin-top: 96px; font-size: 96px; font-size: clamp(76px, 22vw, 124px); line-height: 0.82; text-shadow: 0 6px 0 var(--hb-ink); transform: rotate(-4deg); }
.hb-logo span { display: block; color: #ffc94d; }
.hb-lineup { display: flex; flex-wrap: wrap; justify-content: center; margin: -3px; }
.hb-chip {
  max-width: 9em;
  margin: 3px;
  padding: 5px 12px 4px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 16px;
  font-weight: 800;
  background: var(--hb-tile);
  color: rgba(244, 241, 248, 0.3);
  clip-path: polygon(8px 0, 100% 0, calc(100% - 8px) 100%, 0 100%);
}
.hb-chip[data-in] { background: var(--c); color: var(--hb-ink); }
/* The start screen's seats are tiles a camera fills, with no label over it. */
#happybird-lineup .hb-chip { position: relative; display: inline-grid; place-items: center; width: 68px; height: 46px; max-width: none; padding: 0; }
#happybird-lineup .hb-chip .hb-feed { display: none; position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover; }
#happybird-lineup .hb-chip[data-video] .hb-feed { display: block; }
#happybird-lineup .hb-chip[data-video] > span { visibility: hidden; }
#happybird-lineup .hb-chip[data-mirror] .hb-feed { transform: scaleX(-1); }
#happybird .hb-press {
  padding: 10px 56px 6px;
  background: var(--hb-fg);
  color: var(--hb-ink);
  font-size: 40px;
  line-height: 1.2;
  clip-path: polygon(16px 0, 100% 0, calc(100% - 16px) 100%, 0 100%);
  animation: hb-pulse 1.4s ease-in-out infinite;
}
#happybird .hb-press:disabled { animation: none; opacity: 0.3; }
@keyframes hb-pulse { 50% { transform: scale(1.06); } }
/* The modes side by side: each a clip of a race in it under its name, lit
   in the colour of the seat you'd take once you pick it to vote for, with a
   thumbs up per vote. */
.hb-modes { justify-self: stretch; display: grid; grid-template-columns: 1fr 1fr; grid-gap: 8px; gap: 8px; padding: 0 4px; }
#happybird .hb-mode {
  position: relative;
  display: flex;
  align-items: flex-end;
  aspect-ratio: 3 / 2;
  padding: 0;
  overflow: hidden;
  background: #17151d;
  color: var(--hb-fg);
  text-align: left;
  clip-path: polygon(6% 0, 100% 0, 94% 100%, 0 100%);
}
#happybird .hb-mode:disabled { opacity: 1; }
#happybird .hb-mode:disabled:not([data-mine])[data-votes="0"] { opacity: 0.6; }
.hb-mode .hb-feed { position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover; transition: opacity 0.2s; }
.hb-mode:not([data-mine])[data-votes="0"] .hb-feed { opacity: 0.5; }
.hb-mode-name {
  position: relative;
  margin: 0 0 7% 5%;
  padding: 4px 16px 2px 8px;
  font-size: 28px;
  line-height: 1;
  background: rgba(13, 11, 17, 0.82);
  clip-path: polygon(0 0, 100% 0, calc(100% - 10px) 100%, 0 100%);
}
.hb-mode[data-mine] .hb-mode-name { background: var(--c); color: var(--hb-ink); }
/* The votes' glow, over the clip. */
#happybird .hb-mode::after { content: ""; position: absolute; top: 0; left: 0; right: 0; bottom: 0; pointer-events: none; }
#happybird .hb-mode .hb-tokens { left: 9%; }
/* Votes: a thumbs up each along the card's top. Two make the card glow and
   the thumbs bob; three or more (the most it styles for) light it gold and
   set it cheering. */
.hb-thumb { width: 24px; height: 24px; margin-right: 2px; fill: var(--hb-fg); filter: drop-shadow(0 2px 0 var(--hb-ink)); }
#happybird .hb-mode[data-votes="2"]::after { box-shadow: inset 0 0 0 3px rgba(255, 201, 77, 0.6), inset 0 0 28px rgba(255, 201, 77, 0.28); }
#happybird .hb-mode[data-votes="2"] .hb-thumb { width: 28px; height: 28px; fill: #ffe39a; animation: hb-thumb 1.2s ease-in-out infinite; }
#happybird .hb-mode[data-votes="3"] { animation: hb-cheer 1.4s ease-in-out infinite; }
#happybird .hb-mode[data-votes="3"]::after { box-shadow: inset 0 0 0 4px #ffc94d, inset 0 0 44px rgba(255, 176, 40, 0.5); }
#happybird .hb-mode[data-votes="3"] .hb-thumb { width: 32px; height: 32px; fill: #ffc94d; animation: hb-thumb 0.8s ease-in-out infinite; }
#happybird .hb-mode .hb-thumb:nth-child(2) { animation-delay: 0.15s; }
#happybird .hb-mode .hb-thumb:nth-child(3) { animation-delay: 0.3s; }
#happybird .hb-mode .hb-thumb:nth-child(4) { animation-delay: 0.45s; }
@keyframes hb-thumb { 50% { transform: translateY(-4px) rotate(-10deg); } }
@keyframes hb-cheer { 50% { transform: scale(1.03); } }
@media (prefers-reduced-motion: reduce) {
  #happybird .hb-mode[data-votes], #happybird .hb-mode .hb-thumb { animation: none; }
}

/* Selecting a bird: SELECT, the roster (each seated player's numbered token
   on their bird), a big slanted panel per seat, and START. */
#happybird-select .hb-band, #happybird-maps .hb-band { justify-self: center; margin-left: 0; padding: 6px 30px 4px; clip-path: polygon(14px 0, 100% 0, calc(100% - 14px) 100%, 0 100%); }
.hb-roster { display: grid; grid-template-columns: repeat(4, 1fr); grid-gap: 5px; gap: 5px; padding: 0 6px; }
#happybird .hb-pick {
  position: relative;
  height: 96px;
  display: grid;
  grid-template-rows: 1fr auto;
  background: linear-gradient(165deg, #2e2a39, #17151d 70%);
  color: var(--hb-fg);
  clip-path: polygon(10% 0, 100% 0, 90% 100%, 0 100%);
}
@supports (aspect-ratio: 1) { #happybird .hb-pick { height: auto; aspect-ratio: 1 / 1.08; } }
#happybird .hb-pick[data-mine] { background: linear-gradient(165deg, var(--c), var(--c-dark) 75%); }
#happybird .hb-pick[data-roll] { background: linear-gradient(165deg, #f4f1f8, #8d86a0 75%); }
/* The random bird: a round ? at the band's right. */
#happybird .hb-card > .hb-random { position: absolute; top: 18px; right: 18px; width: 38px; height: 38px; font-size: 24px; line-height: 1; }
#happybird .hb-random:disabled { opacity: 0.4; }
#happybird .hb-pick:disabled { opacity: 0.55; }
#happybird .hb-pick[data-mine]:disabled { opacity: 1; }
.hb-pick canvas { display: block; width: 100%; height: 100%; min-height: 0; }
.hb-pick-name { padding: 4px 0 3px; background: var(--hb-ink); font-size: 17px; line-height: 1; text-align: center; }
.hb-pick[data-mine] .hb-pick-name { background: var(--c); color: var(--hb-ink); }
.hb-tokens { position: absolute; top: 4px; left: 12%; display: flex; }
.hb-token {
  width: 26px;
  height: 26px;
  margin-right: 2px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--c);
  color: var(--hb-ink);
  font-size: 14px;
  line-height: 1;
  box-shadow: 0 2px 0 var(--hb-ink), 0 0 0 2px var(--hb-ink);
}
.hb-panels { display: grid; grid-template-columns: repeat(4, 1fr); grid-gap: 4px; gap: 4px; margin-top: 4px; }
.hb-panel {
  position: relative;
  height: 196px;
  overflow: hidden;
  display: grid;
  grid-template-rows: 1fr auto;
  background: linear-gradient(172deg, var(--c) 0%, var(--c-dark) 100%);
  clip-path: polygon(12% 0, 100% 0, 88% 100%, 0 100%);
}
.hb-panel[data-empty] { background: linear-gradient(172deg, #1b1922, #0e0d12); }
.hb-num { position: absolute; left: 6%; bottom: 22px; font-size: 92px; line-height: 0.8; color: rgba(0, 0, 0, 0.22); }
.hb-panel[data-empty] .hb-num { color: rgba(255, 255, 255, 0.06); }
.hb-panel canvas { position: relative; grid-row: 1; grid-column: 1; display: block; width: 100%; height: 100%; min-height: 0; }
/* Their camera, once it's on, behind their number and bird. Your own is
   mirrored, as on your tile. */
.hb-panel .hb-feed { grid-row: 1; grid-column: 1; display: none; width: 100%; height: 100%; min-height: 0; object-fit: cover; }
.hb-panel[data-video] .hb-feed { display: block; }
.hb-panel[data-video] .hb-num { color: var(--c); text-shadow: 0 4px 0 var(--hb-ink); }
.hb-panel[data-mirror] .hb-feed { transform: scaleX(-1); }
.hb-crown { width: 0.9em; height: 0.7em; margin-right: 0.2em; vertical-align: -0.02em; fill: #ffc94d; stroke: var(--hb-ink); stroke-width: 1.5; stroke-linejoin: round; }
.hb-plate { position: relative; min-height: 31px; padding: 6px 4px 5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; background: var(--hb-ink); font-size: 20px; line-height: 1; text-align: center; }
#happybird .hb-go {
  width: 100%;
  padding: 12px 0 9px;
  background: var(--hb-fg);
  color: var(--hb-ink);
  font-size: 34px;
  line-height: 1;
  clip-path: polygon(14px 0, 100% 0, calc(100% - 14px) 100%, 0 100%);
}
#happybird .hb-go:disabled { opacity: 1; }

/* Selecting the map: a tile per map with its moving preview, lit in the seat
   colour of whoever's looking once it's the one picked, and START. */
.hb-maplist { display: grid; grid-template-columns: 1fr 1fr; grid-gap: 8px; gap: 8px; padding: 0 6px; }
#happybird .hb-map {
  position: relative;
  height: 150px;
  display: grid;
  grid-template-rows: 1fr auto;
  overflow: hidden;
  background: #17151d;
  color: var(--hb-fg);
  clip-path: polygon(6% 0, 100% 0, 94% 100%, 0 100%);
}
#happybird .hb-map canvas { display: block; width: 100%; height: 100%; min-height: 0; }
#happybird .hb-map[data-mine] { box-shadow: inset 0 0 0 4px var(--c); }
#happybird .hb-map[data-mine] .hb-pick-name { background: var(--c); color: var(--hb-ink); }
#happybird .hb-map:disabled { opacity: 1; }
#happybird .hb-map .hb-tokens { left: 9%; }
/* How hard a map is: three pips at its top right, the first one to three lit. */
.hb-pips { position: absolute; top: 8px; right: 9%; display: flex; }
.hb-pips i { width: 9px; height: 9px; margin-left: 4px; border-radius: 50%; background: rgba(244, 241, 248, 0.22); box-shadow: 0 0 0 2px var(--hb-ink); }
.hb-pips i[data-on] { background: #ffc94d; }

/* Loading: the logo, Waiting for everyone… and each flyer's chip, lit once
   their phone is ready. */
#happybird-loading .hb-card { min-height: 420px; align-content: center; justify-items: center; grid-gap: 22px; gap: 22px; text-align: center; }
#happybird-loading .hb-logo { margin-top: 0; }
.hb-waiting { font-size: 26px; line-height: 1; opacity: 0.85; animation: hb-breathe 1.6s ease-in-out infinite; }
@keyframes hb-breathe { 50% { opacity: 0.45; } }

/* Between screens, the next one wipes in on a slant over the last, which
   slides away (happybird-ui.js's showScreen; WIPE_MS there). */
.hb-screen[data-enter], #happybird-arena[data-enter] { z-index: 2; animation: hb-wipe-in 450ms cubic-bezier(0.2, 0.8, 0.2, 1) both; }
.hb-screen[data-leave], #happybird-arena[data-leave] { z-index: 1; pointer-events: none; animation: hb-wipe-out 450ms ease-in both; }
@keyframes hb-wipe-in {
  from { clip-path: polygon(110% 0, 160% 0, 130% 100%, 80% 100%); }
  to { clip-path: polygon(-60% 0, 160% 0, 130% 100%, -90% 100%); }
}
@keyframes hb-wipe-out { to { transform: translateX(-12%); opacity: 0; } }
#happybird-arena[data-enter] { animation-name: hb-zoom-in; }
@keyframes hb-zoom-in { from { transform: scale(0.86); opacity: 0; } }

/* START: READY TO FLY swoops across, then the race counts down. */
.hb-banner {
  position: absolute;
  z-index: 3;
  top: 42%;
  left: -10%;
  right: -10%;
  padding: 12px 0 8px;
  transform: rotate(-6deg);
  background: linear-gradient(90deg, #ffc94d, #ff8f7a, #a98bff, #6fd6b0);
  box-shadow: 0 0 0 6px var(--hb-ink), 0 0 0 9px var(--hb-fg);
  color: var(--hb-ink);
  font-size: 56px;
  font-size: clamp(46px, 13vw, 70px);
  line-height: 1;
  text-align: center;
  pointer-events: none;
  animation: hb-swoop 380ms cubic-bezier(0.2, 0.9, 0.3, 1.2);
}
@keyframes hb-swoop { from { transform: translateX(-110%) rotate(-6deg); } }

/* The race: the square, its band over its top left corner (the stage, violet
   for the last; how it went at the end), and the results once it's over; the
   last picture of the race stays behind them. */
#happybird-arena { position: relative; flex: none; }
#happybird-canvas {
  position: relative;
  display: block;
  width: 100%;
  height: 100%;
  border-radius: 28px; /* as round as the tiles */
  box-shadow: 0 0 0 0.5px rgba(230, 220, 255, 0.14);
}
/* Behind the race, the seated players' cameras (in seat order: one fills the
   square, two side by side, three as two over one, four two by two), shown
   as they are; a seat whose camera is off leaves the dark sky. Your own is mirrored, as on your tile. */
.hb-cams {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
  display: grid;
  grid-template-columns: 1fr;
  grid-auto-rows: 1fr;
  border-radius: 28px;
  background: radial-gradient(circle at 50% 38%, #1c1927 0%, #110f18 62%, #0b0a10 100%);
}
.hb-cams[data-count="2"], .hb-cams[data-count="3"], .hb-cams[data-count="4"] { grid-template-columns: 1fr 1fr; }
.hb-cam { position: relative; min-width: 0; min-height: 0; overflow: hidden; }
.hb-cam[hidden] { display: none; }
.hb-cam[data-wide] { grid-column: 1 / -1; }
.hb-cam .hb-feed { display: block; width: 100%; height: 100%; object-fit: cover; transition: filter 0.3s ease; }
/* A player whose bird is down, waiting to fly again; the skull that pops up
   as it goes down (happybird-ui.js animates it), over its camera. */
.hb-cam[data-down] .hb-feed { filter: grayscale(1); }
.hb-skull {
  position: absolute;
  z-index: 1;
  top: 50%;
  left: 50%;
  width: 34%;
  max-width: 140px;
  opacity: 0;
  transform: translate(-50%, -50%);
  pointer-events: none;
  fill: var(--hb-ink);
  filter: drop-shadow(0 4px 0 rgba(13, 11, 17, 0.6));
}
.hb-skull-bone { fill: var(--hb-fg); stroke: var(--hb-ink); stroke-width: 3; }
.hb-skull-teeth { fill: none; stroke: var(--hb-ink); stroke-width: 3; stroke-linecap: round; }
.hb-cam[data-mirror] .hb-feed { transform: scaleX(-1); }
/* Where videos are painted (happybird-ui.js, PAINT_VIDEOS), each stays
   playing but unseen, so Chrome doesn't slow the page to its frame rate. */
#happybird .hb-feed-source { position: absolute; top: 0; left: 0; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
#happybird-arena[data-stage="2"] #happybird-canvas { box-shadow: 0 0 0 3px var(--hb-violet); }
/* JOIN NEXT RACE, for anyone watching, at the square's top right. */
#happybird .hb-joinnext {
  position: absolute;
  z-index: 1;
  top: 16px;
  right: -6px;
  padding: 7px 20px 5px;
  background: var(--hb-fg);
  color: var(--hb-ink);
  font-size: 22px;
  line-height: 1;
  clip-path: polygon(10px 0, 100% 0, calc(100% - 10px) 100%, 0 100%);
}
/* Rivals' spells, a row under the square (happybird-ui.js keeps room for it:
   SPELL_ROW, its 52px buttons and the 8px over them): each a slanted tile
   with its picture, the totems held or its price in gold, and on a computer
   its key; lit in fire when it can be cast, dim when it can't, and a bar
   along its foot running down while it's up. */
.hb-spells {
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  right: 0;
  height: 52px;
  display: flex;
  justify-content: center;
  gap: 12px;
  touch-action: none;
}
.hb-spells[hidden] { display: none; }
#happybird .hb-spell {
  position: relative;
  width: 128px;
  height: 52px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 0 14px;
  background: linear-gradient(165deg, #ff9a3d, #b8321a 80%);
  color: var(--hb-ink);
  clip-path: polygon(10px 0, 100% 0, calc(100% - 10px) 100%, 0 100%);
  transition: opacity 0.15s ease;
}
#happybird .hb-spell[data-spell="dash"] { background: linear-gradient(165deg, #9fe8ff, #3a7bd5 80%); }
#happybird .hb-spell:disabled { opacity: 0.45; }
#happybird .hb-spell[data-up] { opacity: 0.85; }
.hb-spell-icon { width: 34px; height: 42px; flex: none; }
.hb-spell[data-spell="dash"] .hb-spell-icon { width: 38px; height: 38px; }
.hb-spell-count { display: flex; align-items: center; gap: 4px; font-size: 30px; line-height: 1; }
.hb-coin { display: inline-block; width: 18px; height: 18px; border-radius: 50%; background: radial-gradient(circle, #d99a18 0 32%, #ffcc33 36%); box-shadow: inset 0 0 0 2px #c98a10; }
.hb-spell kbd { position: absolute; top: 4px; right: 14px; font-size: 13px; line-height: 1; opacity: 0.6; }
@media (pointer: coarse) { .hb-spell kbd { display: none; } }
.hb-spell-left { position: absolute; left: 10px; bottom: 0; height: 5px; width: var(--left, 0%); background: var(--hb-fg); }
#happybird-band { position: absolute; z-index: 3; top: 16px; left: -6px; font-size: 26px; font-size: calc(var(--hb-size, 600px) * 0.06); pointer-events: none; }
/* Racing, the band has nothing to say and doesn't show. */
#happybird-band:empty { display: none; }
#happybird-over {
  position: absolute;
  z-index: 2;
  top: 50%;
  left: 50%;
  width: 300px;
  width: min(340px, calc(100% - 32px));
  display: grid;
  grid-gap: 12px;
  gap: 12px;
  padding: 14px;
  transform: translate(-50%, -50%);
  border-radius: 22px;
  background: rgba(13, 11, 17, 0.9);
  box-shadow: inset 0 0 0 0.5px rgba(230, 220, 255, 0.16), 0 18px 48px rgba(0, 0, 0, 0.45);
}
.hb-results { list-style: none; padding: 0; display: grid; grid-gap: 6px; gap: 6px; }
.hb-results li {
  display: grid;
  grid-template-columns: auto 44px minmax(0, 1fr) auto;
  align-items: center;
  grid-gap: 10px;
  gap: 10px;
  padding: 3px 18px 1px 10px;
  background: linear-gradient(90deg, var(--c-soft), transparent), var(--hb-panel);
  clip-path: polygon(10px 0, 100% 0, calc(100% - 10px) 100%, 0 100%);
}
.hb-results li:first-child { background: var(--c); color: var(--hb-ink); }
/* Rivals: each place home, before their bird; story has none. */
.hb-result-place { min-width: 1.6em; font-size: 22px; line-height: 1; }
.hb-results[data-mode="story"] li { grid-template-columns: 44px minmax(0, 1fr) auto; }
.hb-results[data-mode="story"] .hb-result-place { display: none; }
/* Story's team, over its birds: its points, and its best or NEW BEST!. */
.hb-team { display: flex; align-items: baseline; justify-content: center; margin: 0; padding: 4px 0 0; font-size: 24px; line-height: 1; }
.hb-team[hidden] { display: none; }
.hb-team b { margin: 0 10px 0 8px; font-size: 44px; color: #ffc94d; font-variant-numeric: tabular-nums; }
.hb-team-more { font-size: 15px; opacity: 0.8; }
.hb-team-more .hb-record { opacity: 1; }
.hb-results canvas { display: block; width: 44px; height: 44px; }
.hb-result-who { min-width: 0; display: grid; padding: 3px 0 2px; }
.hb-result-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 24px; line-height: 1; }
.hb-result-more { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13px; line-height: 1.2; opacity: 0.75; }
.hb-result-more:empty { display: none; }
.hb-record { display: inline-block; margin-right: 6px; padding: 1px 6px 0; background: #ffc94d; color: var(--hb-ink); font-style: italic; transform: rotate(-3deg); }
.hb-results li:first-child .hb-record { background: var(--hb-ink); color: #ffc94d; }
/* REMATCH (the same birds and map) beside NEXT RACE. */
.hb-again { display: grid; grid-template-columns: 1fr 1fr; grid-gap: 8px; gap: 8px; }
.hb-again[hidden] { display: none; }
#happybird .hb-again #happybird-again { background: var(--hb-tile); color: var(--hb-fg); }
.hb-result-score { font-size: 32px; line-height: 1; font-variant-numeric: tabular-nums; }

@media (max-width: 430px) {
  .hb-card { padding: 16px 10px; }
  .hb-card > .hb-band { margin-left: -10px; font-size: 28px; }
  .hb-pick-name { font-size: 14px; }
  .hb-token { width: 21px; height: 21px; font-size: 12px; }
  .hb-panel { height: 164px; }
  .hb-num { font-size: 64px; }
  .hb-plate { font-size: 15px; }
}
@media (prefers-reduced-motion: reduce) { .hb-card > .hb-rays, #happybird .hb-press, .hb-banner, .hb-waiting { animation: none; } }

/* Karaoke */

/* Full view (no game running): the video fills the top, like the spotlight
   tile, and every video tile shares the row above the controls. Overrides the
   normal call layout, which is flex. */
#call-screen.karaoke-full #grid {
  display: grid;
  grid-template-columns: none;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  grid-template-rows: 1fr 110px;
}

#call-screen.karaoke-full #grid > .tile { grid-row: 2; height: auto; }

#karaoke-stage {
  position: absolute;
  z-index: 1;
  background: #000;
  border-radius: 8px;
  overflow: hidden;
}

#karaoke-screen { position: relative; width: 100%; height: 100%; }
#karaoke-video { display: block; width: 100%; height: 100%; border: 0; }

/* Expand / Collapse / X: over the video's top-right corner in the big views,
   a row above the video in the mini-player. */
#karaoke-tools { position: absolute; z-index: 1; top: 6px; right: 6px; display: flex; gap: 6px; }
#karaoke-tools button { padding: 6px 12px; font-size: 14px; }

/* Taps on the video go to the room (see videoTapAction), not to YouTube. */
#karaoke-touch { position: absolute; top: 0; right: 0; bottom: 0; left: 0; width: 100%; padding: 0; border: 0; border-radius: 0; background: transparent; }

/* The games sheet and game notices must stay above the karaoke video. */
#game-notice { z-index: 3; }

.karaoke-full #karaoke-stage { top: 4px; left: 4px; right: 4px; bottom: calc(80px + 110px + 4px); }

/* Under a game: a small player in the corner of the spotlight area. */
.karaoke-corner #karaoke-stage {
  right: 8px;
  bottom: calc(80px + 110px + 12px);
  width: 34%;
  min-width: 160px;
  aspect-ratio: 16 / 9;
  box-shadow: 0 0 0 1px #333;
}

/* The mini-player: a panel in the bottom-left corner holding the video at
   YouTube's smallest allowed size, 200×200, under its Expand and X buttons.
   On phones it sits above the bottom bar (the corner is under Mute and
   Camera); wide screens get the true corner (below). */
.karaoke-chip #karaoke-stage {
  left: 8px;
  bottom: 80px;
  width: 216px;
  padding: 8px;
  background: #111;
  border-radius: 12px;
  box-shadow: 0 0 0 1px #333;
}
.karaoke-chip #karaoke-tools { position: static; justify-content: flex-end; margin-bottom: 8px; }
.karaoke-chip #karaoke-screen { width: 200px; height: 200px; border-radius: 6px; overflow: hidden; }


/* A hint, not a button: the tap has to land on YouTube's own play button. */
#karaoke-tap {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  margin: 0;
  padding: 8px;
  background: rgba(0, 0, 0, 0.75);
  color: #fff;
  font-size: 14px;
  text-align: center;
  pointer-events: none;
}

/* The queue above the song search: a row of covers that scrolls sideways,
   Spotify-style, running to the sheet's edges. */
#queue-shelf { display: flex; flex-direction: column; gap: 8px; }
#queue-shelf[hidden] { display: none; }
#queue-head { text-align: left; }
#karaoke-queue {
  list-style: none;
  margin: 0 -14px;
  padding: 2px 14px;
  display: flex;
  gap: 12px;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scroll-padding: 0 14px;
  scrollbar-width: none;
}
#karaoke-queue::-webkit-scrollbar { display: none; }
.queue-card { position: relative; flex: none; width: 112px; scroll-snap-align: start; }
.queue-face { display: flex; flex-direction: column; gap: 2px; width: 100%; padding: 0; text-align: left; color: inherit; font: inherit; }
:where(.sheet) button.queue-face { background: transparent; box-shadow: none; border-radius: 0; }
.queue-cover {
  position: relative;
  display: block;
  width: 112px;
  height: 112px;
  margin-bottom: 6px;
  overflow: hidden;
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.08);
  box-shadow: inset 0 0 0 0.5px rgba(255, 255, 255, 0.1);
}
.queue-cover img { display: block; width: 100%; height: 100%; object-fit: cover; }
.queue-face b, .queue-face small { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.queue-face b { font-size: 13px; font-weight: 600; }
.queue-face small { font-size: 12px; color: rgba(235, 230, 245, 0.66); }
button.queue-face:hover .queue-cover img, button.queue-face:active .queue-cover img { opacity: 0.8; }
/* The song playing now is ringed and tagged. */
.now-playing .queue-cover { box-shadow: 0 0 0 2px #c9b6ff; }
.now-playing .queue-cover em {
  display: flex;
  align-items: center;
  gap: 5px;
  position: absolute;
  left: 6px;
  bottom: 6px;
  padding: 3px 7px;
  border-radius: 8px;
  background: rgba(20, 16, 28, 0.82);
  color: #c9b6ff;
  font-size: 11px;
  font-style: normal;
  font-weight: 700;
}
/* Three bars bouncing out of step beside "Now playing", like Spotify's. */
.playing-bars { display: flex; align-items: flex-end; gap: 1.5px; height: 10px; }
.playing-bars i { width: 2.5px; height: 100%; border-radius: 1px; background: currentColor; transform-origin: 50% 100%; animation: playing-bar 0.9s ease-in-out infinite alternate; }
.playing-bars i:nth-child(2) { animation-duration: 0.7s; animation-delay: -0.35s; }
.playing-bars i:nth-child(3) { animation-duration: 1.1s; animation-delay: -0.6s; }
@keyframes playing-bar { from { transform: scaleY(0.25); } to { transform: scaleY(1); } }
@media (prefers-reduced-motion: reduce) { .playing-bars i { animation: none; transform: scaleY(0.6); } }
/* Over the song playing now: pause (or play) for everyone. */
.queue-play {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 44px;
  height: 44px;
  margin: -22px 0 0 -22px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: rgba(20, 16, 28, 0.62);
  box-shadow: inset 0 0 0 0.5px rgba(255, 255, 255, 0.2);
}
.queue-play svg { width: 20px; height: 20px; fill: #fff; }
button.queue-face:active .queue-play { transform: scale(0.92); }
/* Any waiting song comes off with the red X inside its cover's top right
   corner (the card is the cover's width, so 6px in from both edges). */
:where(.sheet) .queue-remove {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 28px;
  height: 28px;
  padding: 0;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: #c62828;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.35);
}
.queue-remove svg { width: 14px; height: 14px; fill: none; stroke: #fff; stroke-width: 2.5; stroke-linecap: round; }

/* Karaoke and theater notices show at the top, clear of the panels that slide
   up from the bottom. */
#karaoke-notice {
  position: absolute;
  z-index: 4;
  left: 50%;
  top: 16px;
  transform: translateX(-50%);
  width: max-content;
  max-width: calc(100% - 32px);
  padding: 10px 14px;
  text-align: center;
  pointer-events: none; /* just a message: taps reach the controls under it */
}

.karaoke-hint { font-size: 13px; color: #aaa; text-align: center; }
.karaoke-hint:empty { display: none; }
/* One box that searches or takes a pasted link, under a small label. */
.find { display: flex; flex-direction: column; gap: 6px; }
.find-head { font-size: 13px; font-weight: 600; color: rgba(235, 230, 245, 0.7); text-align: left; } /* left, like "Recently played" */
.find-row { display: flex; gap: 8px; }
/* Submit is a small round arrow, the white of a chosen button. */
.find-go { flex-shrink: 0; width: 44px; height: 44px; align-self: center; padding: 0; border-radius: 50%; background: #fff; display: flex; align-items: center; justify-content: center; }
.find-go svg { width: 20px; height: 20px; fill: none; stroke: #1a1622; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }

/* The box with its own round clear button (the browser's is hidden). */
.find-box { position: relative; flex: 1; min-width: 0; display: flex; }
#picker-query, #video-query { flex: 1; min-width: 0; padding-right: 38px; }
#picker-query::-webkit-search-cancel-button, #video-query::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; display: none; }
.find-clear { position: absolute; right: 8px; top: 50%; transform: translateY(-50%); width: 22px; height: 22px; padding: 0; border-radius: 50%; background: rgba(255, 255, 255, 0.28); box-shadow: none; display: flex; align-items: center; justify-content: center; }
.find-clear[hidden] { display: none; }
.find-clear svg { width: 12px; height: 12px; fill: none; stroke: #1a1622; stroke-width: 3; stroke-linecap: round; }

#picker-link { display: flex; flex-direction: column; gap: 8px; text-align: center; }
#picker-results { display: flex; flex-direction: column; gap: 4px; }
#picker-results:empty { display: none; } /* no empty row (and gap) under the box */
/* Search results scroll in a box about 4½ rows tall on phones (6½ on wide
   screens, below), the half row showing there's more. Playlists don't scroll. */
/* Song results: five rows of 56px and their gaps on phones (six on wide
   screens), scrolling for more; the thin bar on the right (song-picker.js draws
   it, as phones hide theirs until you scroll) says there are more. */
#picker-results[data-view="search"] { max-height: 296px; overflow-y: auto; overscroll-behavior: contain; scrollbar-width: none; }
#picker-results[data-view="search"]::-webkit-scrollbar { display: none; }
.scroll-bar { position: absolute; right: 16px; width: 3px; border-radius: 2px; background: rgba(255, 255, 255, 0.08); pointer-events: none; }
.scroll-bar[hidden] { display: none; }
.scroll-bar i { position: absolute; left: 0; right: 0; top: 0; border-radius: 2px; background: rgba(255, 255, 255, 0.4); }
#picker-results[aria-busy] { overflow: hidden; } /* the placeholders fill it; nothing to scroll yet */
.picker-row { display: flex; align-items: center; gap: 10px; padding: 8px; text-align: left; background: transparent; }
.picker-row { border-radius: 12px; box-shadow: none; }
.picker-row:hover { background: rgba(255, 255, 255, 0.06); }
/* Placeholder rows while results load: a cover and two text bars, shimmering. */
.picker-row.skeleton { pointer-events: none; }
.skeleton .sk-art { width: 40px; height: 40px; border-radius: 4px; flex: none; }
.skeleton-wide .sk-art { width: 64px; height: 36px; }
.skeleton .sk-text { flex: 1; display: flex; flex-direction: column; gap: 7px; }
.skeleton .sk-line { height: 12px; width: 62%; border-radius: 6px; }
.skeleton .sk-short { width: 38%; height: 10px; }
.skeleton .sk-art, .skeleton .sk-line {
  display: block;
  background: linear-gradient(90deg, rgba(255, 255, 255, 0.07) 0%, rgba(255, 255, 255, 0.16) 50%, rgba(255, 255, 255, 0.07) 100%) 0 0 / 200% 100%;
  animation: shimmer 1.2s linear infinite;
}
@keyframes shimmer { from { background-position: 100% 0; } to { background-position: -100% 0; } }
@media (prefers-reduced-motion: reduce) { .skeleton .sk-art, .skeleton .sk-line { animation: none; } }
.picker-row img { width: 40px; height: 40px; border-radius: 4px; object-fit: cover; flex: none; }
.picker-row span { min-width: 0; }
.picker-row b, .picker-row small { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.picker-row small { color: #aaa; }

#watch-modes { display: grid; grid-template-columns: 1fr 1fr; grid-gap: 10px; }
/* Karaoke and Theater: big square tiles, the name centred over a large, faint
   icon. */
#watch-modes button {
  position: relative;
  overflow: hidden;
  aspect-ratio: 1;
  padding: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 22px;
  font-size: 19px;
  font-weight: 700;
}
#watch-modes span { position: relative; }
#watch-modes svg { position: absolute; left: 50%; top: 50%; width: 78%; height: 78%; transform: translate(-50%, -50%); opacity: 0.09; fill: none; stroke: currentColor; stroke-width: 1.4; stroke-linecap: round; stroke-linejoin: round; }
#watch-modes button[aria-pressed="true"] { background: #fff; color: #1a1622; }
#watch-modes button:disabled { opacity: 0.4; }

/* Theater, Spotify-style: near-black, the video's thumbnail glowing down from
   the top, a top bar, the video, then its controls; people's tiles fill the
   rest, down to the call buttons. Nothing lies over the player (YouTube's rules), so the video's
   own Collapse and X move to the top bar. Bold type is Figtree; the rest stays
   in the system font (only Figtree's bold weights are served).
   --t-video: the video's height, 16:9 across the screen less its margins.
   --t-bar-end: where the controls end, from the top (theater-ui.js). */
#call-screen { --t-safe-top: 0px; --t-safe-left: 0px; --t-safe-right: 0px; --t-video: calc((100vw - 32px) * 9 / 16); --t-accent: #9b7bff; }
#call-screen.theater-page { background: #121212; }
#theater-ambient { position: absolute; inset: 0; overflow: hidden; opacity: 0; transition: opacity 0.6s ease; pointer-events: none; }
#theater-ambient::before {
  content: "";
  position: absolute;
  left: -10%;
  right: -10%;
  top: -10%;
  height: 75%;
  background: var(--thumb) center / cover no-repeat;
  filter: blur(50px) saturate(1.5);
  -webkit-mask-image: linear-gradient(#000 30%, transparent);
  mask-image: linear-gradient(#000 30%, transparent);
}
#call-screen.theater-page #theater-ambient.is-on { opacity: 0.6; }

.t-icon { fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.t-icon text { font: 800 7.4px Figtree, system-ui, -apple-system, sans-serif; fill: currentColor; stroke: none; text-anchor: middle; }
.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* The top bar: the landscape layout (turned), what's on, leave. */
#theater-top {
  position: absolute;
  z-index: 2;
  left: var(--t-safe-left);
  right: var(--t-safe-right);
  top: var(--t-safe-top);
  height: 52px;
  padding: 8px 8px 0;
  display: grid;
  grid-template-columns: 44px 1fr 44px;
  align-items: center;
  color: #fff;
}
#theater-top button { width: 44px; height: 44px; padding: 0; border-radius: 50%; background: transparent; color: #fff; display: flex; align-items: center; justify-content: center; }
#theater-top svg { width: 26px; height: 26px; }
#theater-landscape { grid-column: 1; }
#theater-upright { display: none; } /* only while turned (see the side-by-side rules) */
#theater-landscape svg, #theater-upright svg { width: 22px; height: 22px; }
#theater-leave { grid-column: 3; }
#theater-leave svg { width: 22px; height: 22px; }
/* What's on: the video's title, and its channel · added by you under it. */
#theater-heading { grid-column: 2; min-width: 0; text-align: center; line-height: 1.3; }
#theater-heading b, #theater-heading small { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#theater-heading b { font-size: 15px; font-weight: 700; }
#theater-heading small { font-size: 12px; color: #b3b3b3; }
#theater-heading small:empty { display: none; }

/* The video, under the top bar; its own buttons would lie over it, so they go. */
.watch-theater.karaoke-full #karaoke-stage {
  top: calc(var(--t-safe-top) + 60px);
  left: 16px;
  right: 16px;
  bottom: auto;
  height: var(--t-video);
  border-radius: 10px;
  box-shadow: 0 14px 44px rgba(0, 0, 0, 0.55);
}
.watch-theater.karaoke-full #karaoke-tools { display: none; }
/* The wordmark would sit under the controls. */
#call-screen.theater-page #call-logo { display: none; }

/* People under the controls, filling the rest of the screen, laid out as in a
   normal call: 2 stacked, 3 as two over one centred, 2x2, then 2 across (the
   same on phones and in the side column of wide screens). */
#call-screen.theater-page #grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-content: center;
  grid-template-columns: none;
  grid-template-rows: none;
  gap: 4px;
  padding: calc(var(--t-bar-end, 60%) + 12px + var(--t-upnext)) 16px calc(var(--grid-bottom) + 6px);
  transition: padding-top 0.35s cubic-bezier(0.22, 0.8, 0.3, 1);
}
@media (prefers-reduced-motion: reduce) { #call-screen.theater-page #grid { transition: none; } }

/* Up next (theater-ui.js): in a video's last 20 s with another waiting, a card
   comes in between the controls and the people, who move down for it
   (--t-upnext: its height and gap). Wide screens put it atop the people's column. */
#call-screen { --t-upnext: 0px; }
#call-screen.theater-upnext-on { --t-upnext: 72px; }
#theater-upnext {
  position: absolute;
  z-index: 2;
  left: 16px;
  right: 16px;
  top: calc(var(--t-bar-end, 60%) + 12px);
  height: 60px;
  padding: 10px;
  border-radius: 10px;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 12px;
  background: rgba(255, 255, 255, 0.07);
  color: #fff;
  text-align: left;
  opacity: 0;
  transform: translateY(-8px);
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.3s ease, transform 0.35s cubic-bezier(0.22, 0.8, 0.3, 1), visibility 0s linear 0.35s;
}
#call-screen.theater-upnext-on #theater-upnext { opacity: 1; transform: none; visibility: visible; pointer-events: auto; transition-delay: 0s; }
#call-screen:not(.theater-page) #theater-upnext { display: none; }
@media (prefers-reduced-motion: reduce) { #theater-upnext { transition: none; } }
#theater-upnext .theater-thumb { width: 72px; height: 40px; border-radius: 5px; }
.theater-upnext-text { flex: 1; min-width: 0; }
.theater-upnext-text small { display: block; font-size: 11px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; color: #b3b3b3; }
.theater-upnext-text b { display: block; margin-top: 2px; font-size: 14px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#theater-upnext:active { transform: scale(0.98); }
#call-screen.theater-page #grid > .tile {
  grid-row: auto;
  flex: 0 0 calc((100% - (var(--cols) - 1) * 4px) / var(--cols));
  height: calc((100% - (var(--rows) - 1) * 4px) / var(--rows));
}
#call-screen.theater-page #grid[data-count="2"] { --cols: 1; --rows: 2; }
#call-screen.theater-page #grid[data-count="3"], #call-screen.theater-page #grid[data-count="4"] { --cols: 2; --rows: 2; }
#call-screen.theater-page #grid[data-count="5"], #call-screen.theater-page #grid[data-count="6"] { --cols: 2; --rows: 3; }
#call-screen.theater-page #grid[data-count="7"], #call-screen.theater-page #grid[data-count="8"] { --cols: 2; --rows: 4; }

/* The controls, between the video and the people, as tall as what's in them. */
#theater-bar {
  position: absolute;
  z-index: 3; /* its volume bar comes out over Up next */
  left: 0;
  right: 0;
  top: calc(var(--t-safe-top) + 60px + var(--t-video));
  bottom: auto;
  padding: 18px 16px 0;
  display: flex;
  flex-direction: column;
  overflow: visible; /* the volume bar comes out under its button */
  color: #fff;
}
:where(#theater-bar) button { padding: 0; border-radius: 50%; background: transparent; color: inherit; display: flex; align-items: center; justify-content: center; flex: none; }
/* On phones the title and its line are in the top bar instead (#theater-heading). */
.theater-meta { display: none; }
.theater-info { flex: 1; min-width: 0; }
#theater-title { font-family: Figtree, system-ui, -apple-system, sans-serif; font-size: 22px; font-weight: 800; letter-spacing: -0.01em; line-height: 1.25; }
#theater-byline { margin-top: 2px; font-size: 14px; color: #b3b3b3; }
#theater-title, #theater-byline { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#theater-byline:empty { display: none; }

/* Sliders: a thin track, white (or violet, for the video) up to a white dot. */
:where(#theater-bar, #karaoke-volume-row, .boost-row, #crop-zoom-row) input[type="range"] {
  -webkit-appearance: none;
  appearance: none;
  display: block;
  width: 100%;
  height: 20px;
  margin: 0;
  padding: 0;
  background: transparent;
  cursor: pointer;
  --fill: 0%;
  --fill-colour: #fff;
}
#theater-progress { --fill-colour: var(--t-accent) !important; }
:is(#theater-bar, #karaoke-volume-row, .boost-row, #crop-zoom-row) input[type="range"]::-webkit-slider-runnable-track {
  height: 4px;
  border-radius: 2px;
  background: linear-gradient(to right, var(--fill-colour) var(--fill), rgba(255, 255, 255, 0.22) var(--fill));
}
:is(#theater-bar, #karaoke-volume-row, .boost-row, #crop-zoom-row) input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 12px;
  height: 12px;
  margin-top: -4px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.45);
}
:is(#theater-bar, #karaoke-volume-row, .boost-row, #crop-zoom-row) input[type="range"]::-moz-range-track { height: 4px; border-radius: 2px; background: rgba(255, 255, 255, 0.22); }
:is(#theater-bar, #karaoke-volume-row, .boost-row, #crop-zoom-row) input[type="range"]::-moz-range-progress { height: 4px; border-radius: 2px; background: var(--fill-colour); }
:is(#theater-bar, #karaoke-volume-row, .boost-row, #crop-zoom-row) input[type="range"]::-moz-range-thumb { width: 12px; height: 12px; border: 0; border-radius: 50%; background: #fff; }
:is(#theater-bar, #karaoke-volume-row, .boost-row, #crop-zoom-row) input[type="range"]:focus { outline: none; }
:is(#theater-bar, #karaoke-volume-row, .boost-row, #crop-zoom-row) input[type="range"]:focus-visible::-webkit-slider-thumb { box-shadow: 0 0 0 3px rgba(155, 123, 255, 0.6); }
.theater-progress { margin-top: 0; } /* first under the video on phones, the title being up top */
.theater-times { display: flex; justify-content: space-between; margin-top: 2px; font-size: 12px; font-weight: 500; color: #b3b3b3; font-variant-numeric: tabular-nums; }

/* Volume, back 10 s, play or pause (big and white), forward 10 s, Next. */
.theater-transport { display: flex; align-items: center; justify-content: space-between; margin: 2px -10px 0; }
#theater-back, #theater-fwd { width: 56px; height: 56px; }
#theater-back svg, #theater-fwd svg { width: 34px; height: 34px; stroke-width: 1.8; }
#theater-play { width: 64px; height: 64px; background: #fff; color: #121212; box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35); }
#theater-play svg { width: 28px; height: 28px; fill: currentColor; }
#theater-play[data-paused="true"] .when-playing, #theater-play:not([data-paused="true"]) .when-paused { display: none; }
#theater-next, #theater-volume-button { width: 48px; height: 48px; }
#theater-next svg { width: 28px; height: 28px; fill: currentColor; }
/* Volume: a speaker (crossed out while muted); tapped, a bar under it, on dark
   glass over whatever is below (theater-ui.js hides it 5 s after it's last used). */
.theater-volume { position: relative; flex: none; }
#theater-volume-button svg { width: 26px; height: 26px; }
#theater-volume-button[data-muted="true"] .when-sound, #theater-volume-button:not([data-muted="true"]) .when-muted { display: none; }
#theater-volume-button[aria-expanded="true"] { background: rgba(255, 255, 255, 0.12); }
#theater-volume-pop {
  position: absolute;
  z-index: 3;
  top: calc(100% + 6px);
  left: 0;
  width: 200px;
  padding: 12px 16px;
  border-radius: 14px;
  background: rgba(32, 28, 40, 0.96);
  box-shadow: inset 0 0 0 0.5px rgba(230, 220, 255, 0.16), 0 10px 30px rgba(0, 0, 0, 0.45);
  animation: volume-out 0.2s ease-out;
}
#theater-volume-pop[hidden] { display: none; }
/* The mic boost (iPhones, mic-lift.js): a slider like the volume's, notched at
   every step (10x to 100x); in theater's volume pop it sits over the volume, lined up. */
.boost-track { position: relative; flex: 1; min-width: 0; }
.boost-notches { position: absolute; left: 6px; right: 6px; top: calc(50% + 5px); display: flex; justify-content: space-between; pointer-events: none; }
.boost-notches i { width: 1px; height: 5px; background: rgba(255, 255, 255, 0.35); }
#theater-volume-pop:has(.boost-row:not([hidden])) { width: 240px; display: flex; flex-direction: column; gap: 12px; }
#theater-volume-pop:has(.boost-row:not([hidden]))[hidden] { display: none; }
#theater-volume-pop:has(.boost-row:not([hidden])) #theater-volume { margin-left: 32px; width: calc(100% - 32px); }
.boost-row.boost-off { opacity: 0.4; }
.boost-row.boost-off input { pointer-events: none; }
.boost-note { margin: -4px 0 0 32px; font-size: 13px; color: rgba(235, 230, 245, 0.7); }
.boost-note[hidden] { display: none; }
@keyframes volume-out { from { opacity: 0; } }
@media (prefers-reduced-motion: reduce) { #theater-volume-pop { animation: none; } }
#theater-bar button:not(:disabled):active { transform: scale(0.94); }

/* Shorter screens: the controls get tighter, leaving the people room. */
@media (orientation: portrait) and (max-height: 680px) {
  #theater-play { width: 56px; height: 56px; }
}
@media (orientation: portrait) and (max-height: 600px) {
  #theater-bar { padding-top: 12px; }
}

/* A video in a list: its thumbnail (length in the corner), title and a line under. */
.theater-row { display: flex; align-items: center; gap: 12px; min-height: 68px; color: #fff; }
.theater-thumb { position: relative; flex: none; width: 88px; height: 50px; overflow: hidden; border-radius: 6px; background: rgba(255, 255, 255, 0.08); }
.theater-thumb img { display: block; width: 100%; height: 100%; object-fit: cover; }
.theater-thumb em { position: absolute; right: 4px; bottom: 4px; padding: 1px 4px; border-radius: 3px; background: rgba(0, 0, 0, 0.78); font-size: 10px; font-style: normal; font-weight: 700; font-variant-numeric: tabular-nums; }
.theater-thumb em.is-live { background: #e5484d; letter-spacing: 0.06em; }
.theater-row-text { flex: 1; min-width: 0; }
.theater-row-text b, .theater-row-text small { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.theater-row-text b { font-size: 15px; font-weight: 600; }
.theater-row-text small { margin-top: 3px; font-size: 13px; color: #b3b3b3; }

/* Theater's panel looks like the Karaoke panel (.panel-head with Exit, the
   queue, .find, rows like .picker-row: a video's thumbnail with its length, its
   title and channel; a tap adds it). A link pasted into the box adds that video. */
#video-results { display: flex; flex-direction: column; gap: 4px; max-height: 296px; overflow-y: auto; overscroll-behavior: contain; scrollbar-width: none; }
#video-results::-webkit-scrollbar { display: none; }
#video-results:empty { display: none; }
#video-results[aria-busy] { overflow: hidden; }
.video-row .theater-thumb { width: 71px; height: 40px; border-radius: 4px; }
.video-row .theater-thumb em { right: 3px; bottom: 3px; font-size: 9px; padding: 0 3px; }
.video-row .theater-row-text b { font-size: 16px; font-weight: 700; }
.video-row .theater-row-text small { margin-top: 0; font-size: 13px; color: #aaa; }
#video-results .skeleton-wide .sk-art { width: 71px; height: 40px; }

/* Sideways, side by side: the playback buttons standing in a column on the
   left (Next at the top, then +10 s, play/pause, −10 s, volume at the bottom), the
   video as large as it can be, down to its progress bar at the bottom, and the
   call buttons standing on the right. The people's tiles are hidden (their
   voices carry on). No top bar and no title: the Theater panel (the Watch
   button) has Exit. It's for screens wider than tall, and for a phone held
   upright that's been turned (theater-side and theater-turned, theater-ui.js). */
#call-screen { --t-floor: 7px; }
#call-screen.theater-page.theater-side #theater-top { display: none; }
#call-screen.watch-theater.karaoke-full.theater-side #karaoke-stage {
  top: calc(var(--t-safe-top) + 16px);
  left: calc(var(--t-safe-left) + 72px);
  right: calc(var(--t-safe-right) + 72px);
  bottom: calc(var(--t-floor) + 44px + var(--t-upnext));
  height: auto;
}
#call-screen.theater-page.theater-side #grid { visibility: hidden; }
/* Up next: under the video, over its progress bar; the video makes room. */
#call-screen.theater-side #theater-upnext { top: auto; bottom: calc(var(--t-floor) + 44px); left: calc(var(--t-safe-left) + 72px); right: auto; width: 320px; }
#call-screen.theater-page.theater-side #controls { left: auto; right: calc(var(--t-safe-right) + 16px); top: calc(var(--t-safe-top) + 16px); bottom: var(--t-floor); width: 48px; padding: 0; gap: 12px; flex-direction: column; flex-wrap: nowrap; justify-content: center; align-items: center; }
/* The controls: a layer over the screen holding the playback column and the
   progress bar; its empty space lets taps through to the video and people. */
#call-screen.theater-side #theater-bar {
  top: calc(var(--t-safe-top) + 16px);
  left: calc(var(--t-safe-left) + 16px);
  right: calc(var(--t-safe-right) + 16px);
  bottom: var(--t-floor);
  padding: 0;
  display: block;
  pointer-events: none;
}
#call-screen.theater-side #theater-bar > * { pointer-events: auto; }
#call-screen.theater-side .theater-meta { display: none; }
#call-screen.theater-side .theater-progress { position: absolute; left: 56px; right: 56px; bottom: 0; margin: 0; }
#call-screen.theater-side .theater-transport { position: absolute; left: 0; top: 0; bottom: 0; width: 48px; margin: 0; flex-direction: column; justify-content: center; gap: 14px; }
#call-screen.theater-side #theater-next { order: 1; }
#call-screen.theater-side #theater-fwd { order: 2; }
#call-screen.theater-side #theater-play { order: 3; }
#call-screen.theater-side #theater-back { order: 4; }
#call-screen.theater-side .theater-volume { order: 5; }
/* The volume bar comes out to the right of its button, over the video. */
#call-screen.theater-side #theater-volume-pop { top: 50%; left: calc(100% + 8px); transform: translateY(-50%); }
#call-screen.theater-side #mic-list { bottom: auto; top: 0; left: auto; right: calc(100% + 10px); }
#call-screen.theater-side #theater-back, #call-screen.theater-side #theater-fwd, #call-screen.theater-side #theater-next, #call-screen.theater-side #theater-volume-button { width: 44px; height: 44px; }
#call-screen.theater-side #theater-back svg, #call-screen.theater-side #theater-fwd svg { width: 28px; height: 28px; }
#call-screen.theater-side #theater-play { width: 52px; height: 52px; }
#call-screen.theater-side #theater-play svg { width: 22px; height: 22px; }
#call-screen.theater-side #theater-next svg, #call-screen.theater-side #theater-volume-button svg { width: 24px; height: 24px; }
/* Turned, the top of the left column turns it back upright. */
#call-screen.theater-turned #theater-upright { display: flex; order: 0; width: 44px; height: 44px; margin-bottom: 10px; }
/* Turned: the call screen a quarter turn round, filling the upright phone, to
   watch with the phone on its side. */
#call-screen.theater-page.theater-turned {
position: fixed;
top: 0;
left: 100vw;
width: 100vh;
width: 100dvh;
height: 100vw;
transform-origin: top left;
transform: rotate(90deg);
}

/* Keep controls clear of notches and home bars, only where max() works: Chrome < 79
   accepts max(…, env(…)) and then fails it, which pushed the controls off-screen. */
@supports (bottom: max(1px, 2px)) {
  #controls { bottom: calc(max(0px, env(safe-area-inset-bottom)) + 7px); }
  #call-screen { --grid-bottom: calc(max(0px, env(safe-area-inset-bottom)) + 62px); }
  #call-screen { --t-safe-top: max(0px, env(safe-area-inset-top)); --t-safe-left: max(0px, env(safe-area-inset-left)); --t-safe-right: max(0px, env(safe-area-inset-right)); --t-floor: calc(max(0px, env(safe-area-inset-bottom)) + 7px); }
  #call-screen { --t-video: min(calc((100vw - 32px) * 9 / 16), 42vh); }
  #call-screen { --lyrics-floor: calc(max(0px, env(safe-area-inset-bottom)) + 62px); }
  #call-logo { bottom: calc(max(0px, env(safe-area-inset-bottom)) + 7px); }
  .sheet { bottom: calc(max(0px, env(safe-area-inset-bottom)) + 67px); max-height: calc(100% - max(0px, env(safe-area-inset-bottom)) - 67px - max(16px, env(safe-area-inset-top))); }
  #toast { top: max(16px, env(safe-area-inset-top)); }
  #karaoke-notice { top: max(16px, env(safe-area-inset-top)); }
  .karaoke-chip #karaoke-stage { bottom: calc(max(0px, env(safe-area-inset-bottom)) + 80px); }
  #test-panel { bottom: calc(max(0px, env(safe-area-inset-bottom)) + 80px); }
  #debug-toggle { bottom: calc(max(0px, env(safe-area-inset-bottom)) + 17px); }
}

/* Wide screens: the mini-player clears the bottom bar, so it takes the true corner. */
@media (min-width: 840px) {
  #picker-results[data-view="search"], #video-results { max-height: 356px; } /* 6 rows */
  #call-logo { display: block; }
  #debug-toggle { left: 20px; bottom: 63px; } /* over the wordmark, which has the corner */
  #call-screen.karaoke-chip #karaoke-stage { bottom: 8px; }
  #karaoke-lyrics { left: 12%; right: 12%; }
  #call-screen { --lyric-line: 38px; --lyrics-band: calc(16px + 4 * var(--lyric-line) + 3 * 14px + 8px); }
  #lyrics-current, #lyrics-next, .lyrics-leaving { font-size: 30px; line-height: 38px; }
}

/* Flex gap needs Chrome 84; older browsers get margins instead (aspect-ratio support
   arrived just after flex gap, so its absence marks browsers without it). */
@supports not (aspect-ratio: 1 / 1) {
  #code { margin-right: 8px; }
  #request-code, #human-check, #error, #open-rooms { margin-top: 8px; }
  #my-rooms > * + *, #open-rooms > * + * { margin-top: 8px; }
  .my-room > * + * { margin-left: 8px; }
  #profile-form > * + * { margin-top: 12px; }
  #profile-crop > * + * { margin-top: 14px; }
  #crop-zoom-row > * + * { margin-left: 10px; }
  .code-card > * + *, #games-sheet > * + * { margin-top: 10px; }
  #game-list > * + * { margin-top: 8px; }
  #lyrics-actions > * + *, #lyrics-hand > * + * { margin-left: 8px; }
  #lyrics-sync-sheet > * + * { margin-top: 10px; }
  .code-actions > * + *, #game-ask > * + * { margin-left: 8px; }
  #controls > * + * { margin-left: 12px; }
  #test-panel > * + * { margin-left: 12px; }
  .dialog > * + * { margin-top: 12px; }
  .dialog-actions > * + * { margin-left: 8px; }
  #picker-link > * + * { margin-top: 8px; }
  #karaoke-sheet > * + *, #song-picker > * + * { margin-top: 10px; }
  #karaoke-sheet > .sheet-handle + *, #song-picker > .sheet-handle + *, #video-picker > .sheet-handle + *, #games-sheet > .sheet-handle + * { margin-top: 0; }
  #picker-results > * + * { margin-top: 4px; }
  #karaoke-queue > * + *, .find-row > * + * { margin-left: 8px; }
  #queue-shelf > * + * { margin-top: 8px; }
  .find > * + * { margin-top: 6px; }
  .picker-row > * + * { margin-left: 10px; }
  .theater-meta > * + *, .theater-row > * + *, .video-find > * + * { margin-left: 10px; }
  #karaoke-tools > * + * { margin-left: 6px; }
  #video-picker > * + * { margin-top: 10px; }
  /* No aspect-ratio either: 34% wide at 16:9 is about 19% of the screen width tall. */
  .karaoke-corner #karaoke-stage { height: 19.125vw; min-height: 90px; }
}

/* Karaoke never shows its player: it plays fully transparent behind the call.
   Once it plays, it takes theater's size: YouTube picks the stream for the
   player's size, and a small player's sound came out muffled. */
#call-screen.karaoke-hidden-player #karaoke-stage { opacity: 0; z-index: -1; pointer-events: none; }
#call-screen.karaoke-hidden-player.karaoke-started:not(.karaoke-needs-tap):not(.karaoke-warm):not(.karaoke-borrow) #karaoke-stage { width: auto; padding: 0; }
#call-screen.karaoke-hidden-player.karaoke-started:not(.karaoke-needs-tap):not(.karaoke-warm):not(.karaoke-borrow) #karaoke-screen { width: calc(var(--t-video) * 16 / 9); height: var(--t-video); }

/* Some phones (iPhones, and browsers that block autoplay) start the music only
   when a tap lands inside YouTube's player. Then the still-invisible player lies
   exactly over this card, so tapping the card is tapping the player. The card is
   only the middle band of the 200×200 player, around its play button: the
   player's top strip (title and channel) links to youtube.com, and a tap there
   left the call for the YouTube app. */
#karaoke-start {
  position: fixed;
  z-index: 5;
  left: 50%;
  top: 50%;
  width: 200px;
  height: 88px;
  margin: -44px 0 0 -100px;
  padding: 8px;
  border-radius: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  font-size: 18px;
  font-weight: 600;
  color: #fff;
}
#call-screen.karaoke-needs-tap #karaoke-stage {
  position: fixed;
  z-index: 6;
  left: 50%;
  top: 50%;
  right: auto;
  bottom: auto;
  width: 200px;
  height: 88px;
  margin: -44px 0 0 -100px;
  padding: 0;
  background: transparent;
  box-shadow: none;
  opacity: 0.01;
  pointer-events: auto;
}
#call-screen.karaoke-needs-tap #karaoke-tools,
#call-screen.karaoke-needs-tap #karaoke-tap { display: none; }
/* The player keeps its 200×200 and is cut to its middle 88px (56 to 144). */
#call-screen.karaoke-needs-tap #karaoke-screen { width: 200px; height: 200px; margin-top: -56px; border-radius: 0; }

/* Before any song, a warm-up video waits in the invisible player for this
   phone's first tap (see drawBorrow in karaoke-ui.js). While the Watch sheet
   offers Start or Join karaoke, or an invite offers Join, the player lies over
   that button, cut to the button's size around the middle of the 200×200
   player, so the tap meant for the button starts the player. Above the invite
   (4); "Are you still there?" (5, later in the page) stays on top. */
#call-screen.karaoke-warm #karaoke-stage {
  position: fixed;
  left: 0;
  top: 0;
  right: auto;
  bottom: auto;
  width: 200px;
  height: 200px;
  margin: 0;
  padding: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  opacity: 0;
  z-index: -1;
  pointer-events: none;
}
#call-screen.karaoke-warm #karaoke-tools,
#call-screen.karaoke-warm #karaoke-tap,
#call-screen.karaoke-warm #karaoke-touch { display: none; }
#call-screen.karaoke-warm #karaoke-screen { width: 200px; height: 200px; border-radius: 0; }
#call-screen.karaoke-borrow #karaoke-stage {
  left: var(--borrow-left);
  top: var(--borrow-top);
  width: var(--borrow-width);
  height: var(--borrow-height);
  opacity: 0.01;
  z-index: 5;
  pointer-events: auto;
}
#call-screen.karaoke-borrow #karaoke-screen {
  margin: calc((var(--borrow-height) - 200px) / 2) 0 0 calc((var(--borrow-width) - 200px) / 2);
}
