/* FilmJinx. Mobile-first (spec req 3). Two visual acts:
   front-of-house = pink+cyan neon marquee (home, lobby);
   auditorium = calm dark navy with one cyan action colour (everything past setup).
   Fonts self-hosted (offline-capable, no external calls). */

/* ---- self-hosted fonts ---- */
@font-face{font-family:'Monoton';src:url('/fonts/monoton.woff2') format('woff2');font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:'Marcellus';src:url('/fonts/marcellus.woff2') format('woff2');font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:'Hanken Grotesk';src:url('/fonts/hanken-400.woff2') format('woff2');font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:'Hanken Grotesk';src:url('/fonts/hanken-500.woff2') format('woff2');font-weight:500;font-style:normal;font-display:swap}
@font-face{font-family:'Hanken Grotesk';src:url('/fonts/hanken-600.woff2') format('woff2');font-weight:600;font-style:normal;font-display:swap}
@font-face{font-family:'Space Mono';src:url('/fonts/spacemono-400.woff2') format('woff2');font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:'Space Mono';src:url('/fonts/spacemono-700.woff2') format('woff2');font-weight:700;font-style:normal;font-display:swap}

:root{
  /* front-of-house neon */
  --pink:#F86AB0; --cyan-neon:#3FD3DC; --bulb:#FFE7B0; --bulb-glow:rgba(245,193,71,.8);
  /* auditorium (calm interior) */
  --page:#0b0e1a; --panel:#12162f; --card:#141a2e; --line:#262c48; --line2:#323a63;
  --cream:#E8E6DF; --dim:#8B90A8;
  /* the single action colour + its quiet tint */
  --accent:#40D0DA; --accent-ink:#052a2e;
  --accent-tint:rgba(64,208,218,.13); --accent-tint-line:rgba(64,208,218,.42); --accent-tint-ink:#9be9ef;
  --amber:#E0A94A; --danger:#E23B4E;
  /* UI-uplift R1: anchors take the one action colour, underlined, so no visible
     link falls back to browser-default blue/purple (invisible on the dark card). */
  --link:#40D0DA;
  --font-body:'Hanken Grotesk',system-ui,-apple-system,'Segoe UI',Roboto,sans-serif;
  --font-head:'Marcellus',Georgia,serif;
  --font-mono:'Space Mono',ui-monospace,monospace;
  --font-neon:'Monoton',cursive;
}
*{box-sizing:border-box}
html,body{margin:0;padding:0;color:var(--cream);font-family:var(--font-body);
  background:linear-gradient(180deg,#171d38 0,#171d38 45%,#10142b 100%);
  background-attachment:fixed}
body{animation:page-fade .35s ease-out}
@keyframes page-fade{from{opacity:0}to{opacity:1}}
@media (prefers-reduced-motion:reduce){body{animation:none}}
#app{max-width:480px;margin:0 auto;padding:10px 16px 24px;min-height:80vh}
#app.stage-rating{padding-top:0;padding-bottom:0}

/* ---- topbar: persistent small neon wordmark + Home exit ---- */
#topbar{position:sticky;top:0;z-index:5;display:flex;align-items:center;justify-content:space-between;
  padding:8px 14px;background:rgba(9,12,26,.85);backdrop-filter:blur(6px);border-bottom:1px solid var(--line)}
#topbar.hidden{display:none}
.wordmark{font-family:var(--font-neon);font-size:1.05rem;line-height:1;letter-spacing:.01em}
/* WF3: wordmark is now an inline SVG. Topbar tier: subtle glow (parity with old text). */
.wm-film{fill:#d3fbff;filter:drop-shadow(0 0 6px rgba(64,211,220,.45))}
.wm-jinx{fill:#ffd9ee;filter:drop-shadow(0 0 6px rgba(248,106,176,.5))}
.wordmark .wm-svg{height:1.05rem;width:auto;display:block}
/* flicker now applies in both sites (n and x of Jinx), harmless in the topbar too */
.wm-flicker{animation:neon-flicker 2.2s infinite}
.wm-flicker-alt{animation-duration:3.4s;animation-delay:.9s}
.navbtn{width:auto;margin:0;min-height:34px;padding:5px 12px;font-size:.8rem;color:var(--dim);
  background:var(--card);border:1px solid var(--line);border-radius:999px;font-family:var(--font-mono);letter-spacing:.04em}

/* ---- type ---- */
h1{font-family:var(--font-head);font-weight:400;font-size:1.7rem;line-height:1.12;margin:14px 0 6px}
h2{font-family:var(--font-head);font-weight:400;font-size:1.25rem;margin:10px 0}
p{line-height:1.5}
/* UI-uplift R1.1: every anchor takes the single action colour, underlined. */
a{color:var(--link);text-decoration:underline;text-underline-offset:2px}
.muted{color:var(--dim)}
.version{font-family:var(--font-mono);font-size:.7rem;margin-top:18px;text-align:center;opacity:.7}

/* ---- buttons: hierarchy by fill / tint / ghost / faint, one hue ---- */
button{font:inherit;border:0;border-radius:12px;padding:14px 16px;background:var(--card);color:var(--cream);
  width:100%;margin:6px 0;min-height:48px;cursor:pointer;font-weight:500}
button.primary,button.good{background:var(--accent);color:var(--accent-ink);font-weight:600}
/* UI-uplift R2 (buttons card): the opt-in ambient glow on the ONE flow-advancing
   primary per screen. Wordmark recipe - a tight core shadow on the button plus a
   soft radial cyan wash behind it (a ::before in the button's own stacking
   context), no wide blur so it cannot haze. A modifier class, not the card's
   wrapper div (deviation, recorded), so it also works for a primary inside a flex
   row and can never land on .good (rating buttons share the fill; R2.3/E11). */
button.primary.glow{position:relative;z-index:0;
  box-shadow:0 0 10px rgba(64,208,218,.8),0 0 3px rgba(234,254,255,.6)}
button.primary.glow::before{content:"";position:absolute;left:50%;top:50%;width:110%;height:320%;
  transform:translate(-50%,-50%);border-radius:50%;z-index:-1;pointer-events:none;
  background:radial-gradient(closest-side,rgba(64,208,218,.38),transparent 70%)}
button.tint{background:var(--accent-tint);border:1px solid var(--accent-tint-line);color:var(--accent-tint-ink);font-weight:600}
/* UI-uplift R9.1: tint button with a mono count badge (buttons card). */
button.tint.icon{display:flex;align-items:center;justify-content:center;gap:8px}
.count{font-family:var(--font-mono);font-size:.7rem;font-weight:700;padding:2px 8px;border-radius:999px;
  border:1px solid var(--accent-tint-line);background:rgba(64,208,218,.12)}
button.ghost{background:transparent;border:1px solid var(--line2);color:var(--cream)}
/* WF3: "Seen it" gets real weight (filled tint), still off the yes/no axis
   (RB2: it is a fact, not a desire, so it stays off the green/red colours). */
button.seen-it{background:rgba(63,211,220,.16);border:0;color:var(--cyan-neon);font-weight:600;font-size:.9rem}
button.seen-it:active{background:rgba(63,211,220,.28)}
button.open{background:transparent;border:1px solid var(--accent-tint-line);color:var(--accent-tint-ink);font-weight:600}
button.undo{background:transparent;border:1px solid var(--line);color:var(--dim)}
button:disabled{opacity:.45;cursor:default}
button.back{width:auto;margin:0 0 6px;padding:8px 12px;min-height:36px;font-size:.85rem;border-radius:999px;
  font-family:var(--font-mono);color:var(--dim);background:transparent;border:1px solid var(--line)}

input{font:inherit;width:100%;padding:14px;border-radius:11px;border:1px solid var(--line2);
  background:#141a3a;color:var(--cream);margin:6px 0;min-height:48px}
input::placeholder{color:#6f77a0}
.row{display:flex;gap:8px}
.row>*{flex:1}

/* ---- join screen: segmented OTP-style code entry (W1 Task 4) ---- */
.otp-row{display:flex;gap:10px;justify-content:center;margin:8px 0 4px}
.otp-box{width:48px;height:56px;padding:0;margin:0;text-align:center;font:700 24px var(--font-mono);
  background:transparent;border:2px solid var(--line);border-radius:10px;color:inherit}
.otp-box:focus{outline:none;border-color:var(--accent)}

/* ---- neon marquee sign (home hero) ---- */
.sign{position:relative;border-radius:16px;padding:34px 22px 30px;text-align:center;margin:10px 0 18px}
.sign .wm{font-family:var(--font-neon);font-size:2.4rem;line-height:1}
/* WF3 fix + tester feedback 2026-07-11 item 4: sign tier neon glow is TWO
   tiers per group, a tight full-colour core (8px) plus one wide faded bloom
   (22px at .65 alpha) to bring back the neon spill the single-shadow version
   lost. Never chain three full-strength shadows: space-separated filter
   functions compound (each shadows the previous glow) and fill the wordmark's
   bounding box with solid haze. The faded wide pass spreads too thin to box. */
.sign .wm-film{fill:#dcffff;filter:drop-shadow(0 0 8px var(--cyan-neon)) drop-shadow(0 0 22px rgba(63,211,220,.65))}
.sign .wm-jinx{fill:#ffe3f2;filter:drop-shadow(0 0 8px var(--pink)) drop-shadow(0 0 22px rgba(248,106,176,.65))}
.sign .wm-svg{height:2.4rem;width:auto;display:block;margin:0 auto}
.sign .sign-sub{margin:12px 2px 0;color:var(--dim);font-size:.9rem}
.tagline{font-size:0.95em;opacity:0.75;margin:2px 0 14px}
/* Neon stutter on Jinx's 'n' and 'x' only (Film renders steady): two irregular
   dips per cycle on short, non-harmonic durations, deliberately unsynced so the
   pair never reads as a matched, synced flicker. */
@keyframes neon-flicker{0%,8%,10%,36%,39%,100%{opacity:1}9%{opacity:.5}37%{opacity:.75}38%{opacity:.45}}

/* ---- landing: how-it-works numbered strip + button helper lines ---- */
.how{list-style:none;counter-reset:how;margin:0 0 16px;padding:0}
.how li{counter-increment:how;position:relative;padding:7px 0 7px 30px;color:var(--dim);font-size:.9rem;line-height:1.4}
.how li::before{content:counter(how);position:absolute;left:0;top:6px;width:20px;height:20px;border-radius:50%;
  background:var(--accent-tint);border:1px solid var(--accent-tint-line);color:var(--accent-tint-ink);
  font-family:var(--font-mono);font-size:.7rem;display:flex;align-items:center;justify-content:center}
.btn-sub{color:var(--dim);font-size:.78rem;margin:-2px 0 12px;text-align:center}
.auth-pitch{max-width:34ch;margin:0 auto 12px}
.welcome-back{margin:4px 0 10px}
.linklike{background:none;border:none;min-height:auto;padding:6px 0;color:var(--accent);font:inherit}
/* ---- UI-uplift R3: home hamburger menu (buttons card). The three bare home
   utility links move in here; a guest sees only Leave (E2, no empty rows). ---- */
.home-menu-wrap{position:relative;display:flex;justify-content:flex-end;margin:0 0 2px}
.burger{width:44px;min-height:44px;margin:0;padding:0;border-radius:999px;flex:none;
  background:transparent;border:1px solid var(--line);color:var(--dim);
  display:inline-flex;align-items:center;justify-content:center;cursor:pointer}
.burger svg{width:16px;height:16px}
.home-menu{position:absolute;right:0;top:calc(100% + 4px);z-index:6;width:220px;padding:6px;
  border-radius:14px;background:var(--panel);border:1px solid var(--line2);box-shadow:0 12px 30px rgba(0,0,0,.45)}
.home-menu.hidden{display:none}
.home-menu button{width:100%;margin:0;min-height:42px;padding:10px 12px;border-radius:9px;
  background:transparent;border:0;color:var(--cream);text-align:left;font-size:.85rem;cursor:pointer}
.home-menu button.quiet{color:var(--dim);display:flex;align-items:center;gap:9px}
.home-menu button.quiet svg{width:14px;height:14px;flex:none}
.stat-tiles{display:flex;gap:10px;margin:10px 0}
.tile{flex:1;text-align:center;padding:14px 6px;border:1px solid var(--line);border-radius:12px;background:var(--panel)}
/* UI-uplift R12: stats figures in the mono (machinery) face; labels in the mono
   micro-label voice, consistent with the vote table. Presentation only. */
.tile strong{display:block;font-size:1.6em;font-family:var(--font-mono)}
.tile span{color:var(--dim);font-size:.7rem;font-family:var(--font-mono);text-transform:uppercase;letter-spacing:.08em}
.pick-row{margin:6px 0}
.explainer-list{text-align:left;margin:0;padding-left:18px}
.explainer-list li{margin:6px 0}

/* even, corner-anchored marquee bulbs (JS fills these) */
.bulbs{position:absolute;inset:8px;pointer-events:none}
.bulbs i{position:absolute;width:7px;height:7px;border-radius:50%;margin:-3.5px 0 0 -3.5px;
  background:var(--bulb);box-shadow:0 0 6px 2px var(--bulb-glow);animation:chase 1.5s linear infinite}
@keyframes chase{0%,100%{opacity:.2}45%{opacity:1}}
/* UI-uplift R13.2: still the marquee bulbs and the wordmark flicker for phones
   that ask for no motion (the two remaining decorative loops). */
@media (prefers-reduced-motion:reduce){
  .bulbs i{animation:none;opacity:.7}
  .wm-flicker{animation:none}
}

/* ---- lobby: the code hand-off is the hero ---- */
.lobby-hero{position:relative;border-radius:16px;padding:22px 18px 20px;text-align:center;margin:10px 0 16px;overflow:hidden;
  background:linear-gradient(180deg,#141a36,#0b1022);box-shadow:0 0 0 4px #0e1430}
.qr{background:#fff;border-radius:12px;padding:12px;margin:6px auto 12px;width:fit-content;max-width:70%}
.qr svg{display:block;width:196px;height:auto}
.share-code{font-family:var(--font-mono);font-weight:700;font-size:1.9rem;letter-spacing:.28em;text-align:center;
  color:var(--cyan-neon);text-shadow:0 0 14px rgba(63,211,220,.6);padding:6px 0 2px;margin:4px 0}
/* UI-uplift R11: the quiet "Show the code instead" disclosure. Collapsed by
   default; the code and host-entry line live inside it. */
.code-reveal{margin:8px 0 0}
.code-reveal summary{list-style:none;cursor:pointer;color:var(--dim);font-size:.8rem;
  font-family:var(--font-mono);letter-spacing:.04em;text-decoration:underline}
.code-reveal summary::-webkit-details-marker{display:none}
.code-reveal[open] summary{margin-bottom:6px}

/* ---- WF3 R3: ready-screen pick summary ---- */
.pick-summary{margin:12px 0;padding:12px;border-radius:12px;background:rgba(255,255,255,.05)}
.pick-summary p{margin:2px 0}

/* ---- H4: group roster panel (joined names + ready ticks) ---- */
.roster-list{margin:12px 0}
.roster-row{margin:4px 0}

/* ---- mode chooser: cinema tickets ---- */
.mode-list{display:flex;flex-direction:column;gap:12px;margin:16px 0}
/* Tester feedback 2026-07-11 item 1: "or" dividers so the three tickets read
   as alternative doors, not sequential steps. */
.or-div{text-align:center;color:var(--dim);font-family:var(--font-mono);font-size:.6rem;
  letter-spacing:.18em;text-transform:uppercase;margin:-4px 0}
/* FB1 R8 (item 4): a card shadow + pressed state so the tickets read as tappable
   buttons, not an info list. Neutral drop shadow (never an accent glow - ui-uplift
   R2.3/E11 keeps the one-glow-primary-per-screen rule; the tickets stay unglowed). */
.ticket{position:relative;display:flex;align-items:stretch;width:100%;text-align:left;color:var(--cream);
  background:var(--card);border:1px solid var(--line);border-radius:12px;overflow:hidden;margin:0;min-height:auto;padding:0;
  box-shadow:0 2px 10px rgba(0,0,0,.28);transition:transform .08s ease,box-shadow .08s ease}
.ticket:active{transform:translateY(1px);box-shadow:0 1px 4px rgba(0,0,0,.3)}
.ticket .stub{flex:0 0 52px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:7px;
  border-right:2px dashed #333a63;position:relative;background:rgba(64,208,218,.09)}
.ticket .ic{font-size:1.15rem;line-height:1;color:var(--accent);display:flex}
.ticket .ic svg{width:22px;height:22px;display:block}
.ticket .adm{font-family:var(--font-mono);font-size:.5rem;letter-spacing:.14em;color:var(--dim);
  writing-mode:vertical-rl;transform:rotate(180deg)}
.ticket .stub::before,.ticket .stub::after{content:"";position:absolute;right:-7px;width:12px;height:12px;
  border-radius:50%;background:var(--page)}
.ticket .stub::before{top:-7px}.ticket .stub::after{bottom:-7px}
.ticket .tbody{padding:14px 15px}
.ticket .tbody strong{display:block;font-family:var(--font-head);font-weight:400;font-size:1.08rem;margin-bottom:3px}
.ticket .tbody span{color:var(--dim);font-size:.85rem;line-height:1.35}

/* ---- genre chips ---- */
.chips{display:flex;flex-wrap:wrap;gap:9px;margin:14px 0}
.chip{width:auto;padding:9px 14px;border-radius:999px;margin:0;min-height:44px;font-weight:500;
  border:1px solid var(--line2);background:transparent;color:var(--cream)}
.chip.on{background:var(--accent);border-color:var(--accent);color:var(--accent-ink);font-weight:600}
.chip-sub{font-size:.72em;color:var(--dim);font-weight:400;margin-left:4px}

/* ---- host settings panel ---- */
.settings-panel{border:1px solid var(--line);border-radius:12px;padding:12px 14px;margin:16px 0;background:var(--card)}
.settings-panel h3{font-family:var(--font-head);font-weight:400;font-size:1.05rem;margin:0 0 8px}
.setrow{display:flex;align-items:center;justify-content:space-between;gap:10px;margin:10px 0;
  font-family:var(--font-mono);font-size:.72rem;letter-spacing:.12em;text-transform:uppercase;color:var(--dim)}
.setrow select{width:auto;min-width:130px;margin:0;min-height:40px;padding:8px 10px;border-radius:8px;
  font-family:var(--font-body);font-size:.95rem;letter-spacing:normal;text-transform:none;
  border:1px solid var(--line2);background:#141a3a;color:var(--cream)}
.mini{font-size:.78rem;margin:4px 0 0}
/* ---- UI-uplift R7: free-range filter sliders (filters card). Real range
   inputs, >=44px hit target (R7.7), accent track/thumb. ---- */
.sliderow{margin:16px 0}
.sliderow .lab{display:flex;justify-content:space-between;align-items:baseline;
  font-family:var(--font-mono);font-size:.72rem;letter-spacing:.12em;text-transform:uppercase;color:var(--dim)}
.sliderow .val{font-family:var(--font-mono);font-size:.85rem;color:var(--accent-tint-ink);letter-spacing:.04em;text-transform:none}
.sliderow .hint{font-size:.7rem;color:var(--dim);margin:2px 4px 0;display:flex;justify-content:space-between}
input[type=range].rng{-webkit-appearance:none;appearance:none;width:100%;height:44px;min-height:44px;
  background:transparent;margin:0;padding:0;cursor:pointer}
input[type=range].rng:focus{outline:none}
input[type=range].rng::-webkit-slider-runnable-track{height:4px;border-radius:999px;background:var(--line2)}
input[type=range].rng::-moz-range-track{height:4px;border-radius:999px;background:var(--line2)}
input[type=range].rng::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:22px;height:22px;
  margin-top:-9px;border-radius:50%;background:var(--accent);border:2px solid #0b0e1a;box-shadow:0 0 0 1px var(--accent)}
input[type=range].rng::-moz-range-thumb{width:22px;height:22px;border-radius:50%;background:var(--accent);
  border:2px solid #0b0e1a;box-shadow:0 0 0 1px var(--accent)}
input[type=range].rng:focus-visible::-webkit-slider-thumb{box-shadow:0 0 0 3px var(--accent-tint-line)}
input[type=range].rng:focus-visible::-moz-range-thumb{box-shadow:0 0 0 3px var(--accent-tint-line)}
/* R7.3 two-ended range: overlaid inputs (thumbs live), a shared track + fill drawn under. */
.dual{position:relative;height:44px}
.dual-track{position:absolute;left:0;right:0;top:50%;height:4px;transform:translateY(-50%);border-radius:999px;background:var(--line2)}
.dual-fill{position:absolute;top:0;bottom:0;border-radius:999px;background:var(--accent)}
.dual .dual-rng{position:absolute;left:0;top:0;pointer-events:none}
.dual .dual-rng::-webkit-slider-runnable-track{background:transparent}
.dual .dual-rng::-moz-range-track{background:transparent}
.dual .dual-rng::-webkit-slider-thumb{pointer-events:auto}
.dual .dual-rng::-moz-range-thumb{pointer-events:auto}
/* ---- UI-uplift R8: Bridget-mode toggle switch + nested certification subrow. ---- */
.sw2{position:relative;width:46px;height:26px;min-height:26px;border-radius:999px;background:var(--line2);
  border:0;cursor:pointer;flex:0 0 auto;transition:background .15s;padding:0;margin:0}
.sw2::after{content:"";position:absolute;top:3px;left:3px;width:20px;height:20px;border-radius:50%;
  background:var(--cream);transition:transform .15s}
.sw2[aria-pressed="true"]{background:var(--accent)}
.sw2[aria-pressed="true"]::after{transform:translateX(20px)}
.subrow{margin:10px 0 4px 14px;padding-left:14px;border-left:2px solid var(--line2)}
.subrow .setrow{margin:8px 0}
.setblock{margin:10px 0}
.setlabel{display:block;font-family:var(--font-mono);font-size:.72rem;letter-spacing:.12em;
  text-transform:uppercase;color:var(--dim)}
.stream-grid{display:grid;grid-template-columns:1fr 1fr;gap:8px 12px;margin-top:8px}
.streamcheck{display:flex;align-items:center;gap:6px;font-family:var(--font-body);
  font-size:.85rem;letter-spacing:normal;text-transform:none;color:var(--cream)}
.streamcheck input{width:auto;min-height:auto;margin:0}

/* ---- host filters: collapsed expander on the Host setup screen ---- */
.filters{border:1px solid var(--line);border-radius:12px;margin:6px 0 12px;background:var(--card);overflow:hidden}
.filters-toggle{display:flex;align-items:center;justify-content:space-between;width:100%;margin:0;min-height:auto;
  background:transparent;border:0;border-radius:0;padding:13px 15px;color:var(--cream);font-weight:600}
.filters-toggle .chev{color:var(--dim);font-size:.75rem}
.filters-body{padding:4px 15px 14px;border-top:1px solid var(--line)}

/* ---- seed autocomplete ---- */
.seed-results{display:flex;flex-direction:column;gap:6px;margin:4px 0}
.seed-suggest{display:flex;align-items:center;gap:10px;width:100%;text-align:left;padding:8px 10px;margin:0;
  min-height:auto;border:1px solid var(--line);background:var(--card);border-radius:10px}
.seed-suggest img{width:34px;height:51px;object-fit:cover;border-radius:6px}
.noposter{width:34px;height:51px;border-radius:6px;background:var(--line)}
.seed-chosen{display:flex;flex-wrap:wrap;gap:8px;margin:12px 0}
.seed-chip{width:auto;margin:0;padding:8px 12px;border-radius:999px;min-height:40px;font-size:.92rem;
  border:1px solid var(--accent);background:var(--accent-tint);color:var(--accent-tint-ink)}

/* ---- rating card: portrait poster with scrim, title overlaid ---- */
.poster{position:relative;border-radius:14px;overflow:hidden;margin:6px 0;aspect-ratio:3/4;max-height:44vh;background:#12172b}
.poster img{width:100%;height:100%;object-fit:cover;display:block}
.poster-scrim{position:absolute;inset:0;background:linear-gradient(to top,rgba(6,8,16,.9) 0,transparent 44%)}
.poster-title{position:absolute;left:14px;right:14px;bottom:12px;margin:0;font-family:var(--font-head);font-weight:400;
  font-size:1.6rem;line-height:1.05;color:var(--cream);text-shadow:0 2px 12px rgba(0,0,0,.75)}
.cbody{padding:10px 2px 0}
.meta{color:var(--dim);font-size:.85rem;margin:4px 0 8px;line-height:1.7}
.cert-chip{border:1px solid currentColor;border-radius:4px;padding:0 4px;font-size:.85em}
/* UI-uplift R9.2: trailer pill (tint-voice outline, video-badge play icon).
   Wins over the global a{} rule (class beats element), so no underline/link blue. */
.trailer{width:auto;display:inline-flex;align-items:center;gap:8px;margin:8px 0 0;padding:9px 16px 9px 12px;
  min-height:40px;border-radius:999px;background:transparent;border:1px solid var(--accent-tint-line);
  color:var(--accent-tint-ink);font-weight:500;font-size:.85rem;text-decoration:none}
.trailer svg{width:20px;height:14px;flex:none}
.credits-line{margin:6px 0 0;font-size:.85rem}
.scores-line{margin:6px 0 0;font-size:.85rem}
.award-badges{margin:8px 0 0}
.award-badge{display:inline-block;border:1px solid var(--amber);color:var(--amber);border-radius:6px;padding:1px 8px;font-size:.85em;margin:2px 6px 2px 0}
.runtime{display:inline-block;background:#20264a;color:var(--cream);border-radius:6px;padding:1px 8px;font-weight:600;
  font-size:.8rem;font-family:var(--font-mono);margin-right:2px}
.syn{color:var(--dim);font-size:.9rem;line-height:1.45;margin:0 0 10px}
/* "Why you're seeing this" reasons, shown inside the synopsis reveal. */
.why{margin:0 0 11px;padding:9px 12px;background:var(--accent-tint);
  border:1px solid var(--accent-tint-line);border-radius:10px}
.why-label{margin:0 0 6px;font-family:var(--font-mono);font-size:.64rem;letter-spacing:.07em;
  text-transform:uppercase;color:var(--accent-tint-ink)}
.why ul{list-style:none;margin:0;padding:0}
.why li{position:relative;padding-left:16px;color:var(--cream);font-size:.85rem;line-height:1.5;margin:4px 0}
.why li::before{content:"";position:absolute;left:2px;top:.55em;width:6px;height:6px;border-radius:50%;
  background:var(--accent)}
.rate-grid{display:grid;grid-template-columns:1fr 1fr;gap:9px;margin-top:10px}
.rate-grid button{margin:0;min-height:46px;font-size:.85rem;padding:11px 8px}
.progress{font-family:var(--font-mono);font-size:.72rem;color:var(--dim);letter-spacing:.04em;margin:6px 0;text-transform:uppercase}

/* One-screen rating card: flex column sized to the viewport minus the sticky
   topbar; the poster is the only flexible child, so the button cluster is
   always visible without scrolling. Scoped to .ratecard — other screens scroll. */
.ratecard{display:flex;flex-direction:column;height:calc(100dvh - var(--topbar-h, 48px));min-height:0}
.ratecard .poster{flex:1 1 auto;min-height:0;max-height:none;aspect-ratio:auto;margin:6px 0}
.ratecard .poster img{width:100%;height:100%;object-fit:cover}
.ratecard .rateinfo{flex:0 0 auto}
.ratecard .ratebtns{flex:0 0 auto}
.ratecard>.notice,.ratecard>.error{flex:0 0 auto}

/* WF3: card flip region. Front sets the height; back matches and scrolls. The
   .flipped class toggles on the live element so the spin only plays on an
   intentional flip, never on a render() rebuild (WF/F2-safe). */
.flip{flex:1;min-height:0;position:relative;perspective:1200px}
.flip-inner{position:absolute;inset:0;transform-style:preserve-3d;transition:transform .5s ease}
.flip.flipped .flip-inner{transform:rotateY(180deg)}
.flip .face{position:absolute;inset:0;display:flex;flex-direction:column;
  backface-visibility:hidden;-webkit-backface-visibility:hidden}
.flip .face.back{transform:rotateY(180deg);overflow-y:auto}
.flip .face .poster{flex:1;min-height:0}
.flip .back-body{padding:12px 14px 56px}
/* FB1 R6 (item 18): the front "More about this film" pill (.flip-ctl) floats
   absolute over the card bottom; reserve matching clearance below the front meta
   so the pill never covers it, mirroring the back face's 56px. */
.flip .face.front .face-meta{padding-bottom:56px}
/* FB1 R10 (item 10): the muted streaming-availability line under the front meta. */
.provline{font-size:.8rem;margin:2px 0 0;line-height:1.3}
.flip .back-title{margin:0 0 8px}
/* Tester feedback 2026-07-11 item 3: the old full-width bottom strip read as
   poster shadow, not a button (missed across ~20 swipes). Now a floating pill
   that looks pressable: bordered, rounded, centered above the bottom edge. */
.flip-ctl{position:absolute;left:50%;transform:translateX(-50%);bottom:10px;width:auto;min-height:auto;
  margin:0;padding:8px 16px;border:1px solid rgba(255,255,255,.4);border-radius:999px;
  background:rgba(0,0,0,.68);color:#fff;font:inherit;font-size:.88rem;white-space:nowrap;
  cursor:pointer;backdrop-filter:blur(2px);box-shadow:0 2px 10px rgba(0,0,0,.45)}
.flip-ctl .fc-ic{margin-right:2px}
/* night-flow R3/R5/R6: the same "More" control in a static (non-flip) context
   - ranking rows, the single-match confirm screen, Tonight's movie - so it
   sits in normal flow instead of .flip-ctl's absolute-over-the-card position. */
.film-more-ctl{position:static;width:auto;min-height:auto;margin:6px 0 0;padding:7px 14px;
  border:1px solid var(--line);border-radius:999px;background:transparent;color:var(--cream);
  font:inherit;font-size:.82rem;cursor:pointer}
.film-details{margin-top:8px}
@media (prefers-reduced-motion: reduce){
  .flip-inner{transition:none}
}
.undo-link{width:auto;min-height:auto;margin:6px auto 0;display:block;padding:4px 8px;background:transparent;
  border:0;color:var(--dim);font-size:.78rem;text-decoration:underline;opacity:.8}
/* H6 Task 8/req 18a: quiet like Undo, but danger-tinted so it reads as
   distinct and one-way (a two-tap inline confirm, no modal). */
.never-link{width:auto;display:block;margin:2px auto 0;padding:4px 8px;background:none;border:none;
  min-height:auto;color:var(--danger);font-size:.85rem;opacity:.85;text-decoration:underline}

/* G6: rewatch prompt overlays the button cluster without shifting layout.
   .ratebtns-main reserves exactly the height of the 4 main rating buttons
   (.rb-buttons); they never leave the DOM, so that height never changes.
   While the rewatch question is showing, .rw-hidden keeps the buttons (and
   the Undo link) occupying their space via visibility:hidden - not
   display:none, which would collapse the box - and .rw-prompt covers the box
   as an out-of-flow absolute layer that contributes no height of its own. */
.ratebtns-main{position:relative}
.rw-hidden{visibility:hidden}
.rw-prompt{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;
  justify-content:center;gap:10px;text-align:center;background:transparent;border-radius:12px;padding:0 4px}
.rw-prompt p{margin:0}
.rw-prompt button{margin:0;min-height:42px;font-size:.85rem;padding:8px 10px;width:100%}

/* M1: bars + pill share one row so the pill never adds a full extra line to
   the one-screen rating card. */
.progress-row{display:flex;align-items:center;gap:10px;margin:4px 0 2px}
.progressbars{flex:1 1 auto;display:flex;flex-direction:column;gap:4px;margin:0}
.pbar{height:5px;border-radius:999px;background:var(--line);overflow:hidden}
.pbar-fill{height:100%;border-radius:999px;transition:width .25s ease}
/* H4 Task 7: hue is the participant's roster INDEX (stable across phones),
   not their host/guest role. p0/p1 match the old host-pink/guest-cyan couple
   colours; p2-p5 are the new group-mode hues. */
.pbar-p0 .pbar-fill{background:var(--pink)}
.pbar-p1 .pbar-fill{background:var(--cyan-neon)}
.pbar-p2 .pbar-fill{background:var(--amber)}
.pbar-p3 .pbar-fill{background:#B487F0}
.pbar-p4 .pbar-fill{background:#7FE08A}
.pbar-p5 .pbar-fill{background:#F08A5A}
.round-label{font-family:var(--font-mono);font-size:.68rem;letter-spacing:.12em;text-transform:uppercase;
  color:var(--dim);flex:1;text-align:center}

/* M1: tappable match counter, lives in the progress row (not a new one) */
.match-pill{flex:0 0 auto;width:auto;margin:0;border-radius:999px;padding:6px 12px;font-weight:700;
  font-size:.8rem;background:transparent;border:2px solid var(--pink, #ff3d8b);color:inherit;
  min-height:auto;white-space:nowrap}

/* ---- simple card (done / single match) ---- */
.card{background:var(--card);border-radius:14px;overflow:hidden;margin:6px 0}
.card img{width:100%;display:block;max-height:44vh;object-fit:cover}
.card .body{padding:10px 14px}
.card h2{margin:6px 0 4px}
.card .meta{margin:6px 0 8px}
.card .syn{color:var(--dim);font-size:.9rem;line-height:1.45}

.notice{background:#20264a;border:1px solid var(--amber);border-radius:12px;padding:10px 12px;margin:10px 0;font-size:.95rem}
/* WF/F3: compact dismissible line replacing the old .notice thin-pool block. */
.thin-line{font-size:0.85em;margin:4px 0}
.linklike{background:transparent;border:0;padding:0;margin-left:6px;color:var(--dim);
  font-size:inherit;text-decoration:underline;opacity:.8;cursor:pointer;
  width:auto;min-height:auto;display:inline}
.error{background:#2a1720;border:1px solid var(--danger);border-radius:12px;padding:10px 12px;margin:10px 0}

/* ---- match overlay: now proposals-only (the panel styling is below). The
   celebration visuals moved to #splash (Task 5b), which has its own copies;
   .match-title and the curtain-l/curtain-r/match-pop keyframes stay here
   unprefixed because #splash's markup (built in showSplash()) still uses
   them directly. ---- */
#overlay{position:fixed;inset:0;background:rgba(6,8,16,.93);display:flex;align-items:center;justify-content:center;
  padding:20px;z-index:10}
#overlay.hidden{display:none}
.match-title{font-family:var(--font-neon);font-size:1.7rem;line-height:1.1;margin:8px 0 14px;
  color:#ffe3f2;text-shadow:0 0 4px #fff,0 0 12px var(--pink),0 0 26px var(--pink)}
@keyframes curtain-l{to{transform:translateX(-102%)}}
@keyframes curtain-r{to{transform:translateX(102%)}}
@keyframes match-pop{0%{transform:scale(.9);opacity:.4}100%{transform:scale(1);opacity:1}}

/* ---- M1/Task 6: matches panel — the other thing #overlay shows: either the
   pill's full match list, or a live proposal folded into that same list. ---- */
#overlay .panel{max-width:420px;width:100%;max-height:82vh;overflow-y:auto;text-align:left;
  background:var(--card);border-radius:16px;padding:18px 16px;box-shadow:0 12px 44px rgba(0,0,0,.55)}
#overlay .panel h2{margin:0 0 10px;font-family:var(--font-head);text-align:center}
#overlay .panel #panel-close{margin-top:12px}
.match-row{display:flex;flex-wrap:wrap;gap:8px 10px;align-items:center;padding:10px 0;
  border-bottom:1px solid var(--line, #2a3350)}
.match-row img,.match-row .noposter{width:44px;flex:0 0 auto}
.match-row img{border-radius:6px}
.match-row-main{flex:1 1 160px;text-align:left}
.match-row button{width:auto;flex:1 1 auto;margin:0;min-height:40px;padding:9px 12px;font-size:.85rem}

/* ---- C2 coach card: lighter dim so the first poster peeks through ---- */
#coach{position:fixed;inset:0;background:rgba(6,8,16,.72);display:flex;align-items:center;justify-content:center;
  padding:22px;z-index:11}
#coach.hidden{display:none}
.coach-card{position:relative;max-width:360px;width:100%;background:var(--card);border:1px solid var(--line2);
  border-radius:16px;padding:22px 20px 18px;box-shadow:0 12px 44px rgba(0,0,0,.55)}
.coach-card h2{margin:0 0 12px}
.coach-card ul{list-style:none;margin:0 0 16px;padding:0}
.coach-card li{position:relative;padding-left:18px;margin:9px 0;line-height:1.45;font-size:.95rem}
.coach-card li::before{content:"";position:absolute;left:2px;top:.55em;width:6px;height:6px;border-radius:50%;
  background:var(--accent)}
.coach-x{position:absolute;top:6px;right:6px;width:auto;min-height:auto;margin:0;padding:6px 11px;
  background:transparent;border:0;color:var(--dim);font-size:1.2rem;line-height:1}

/* ---- W2/M1 Task 5b: strong-match splash — full-screen celebratory chrome for
   a both-keen match, no buttons, self-dismissing. Reuses the overlay's
   celebration visuals (.celebrate/.curtain/.reveal/.match-title are generic
   classes) but needs its own #splash-scoped rules since the existing ones are
   scoped to #overlay. Sits above #overlay/#coach/#toast (z-index) but never
   blocks the rating card underneath once it clears — it's a dedicated element,
   not the proposal overlay, so it can't be killed or gate anything. ---- */
#splash{position:fixed;inset:0;background:rgba(6,8,16,.93);display:flex;align-items:center;justify-content:center;
  padding:20px;z-index:50}
#splash.hidden{display:none}
#splash .inner{max-width:420px;width:100%;text-align:center;position:relative;overflow:hidden}
#splash img{max-width:58%;border-radius:12px;box-shadow:0 0 30px rgba(248,106,176,.35)}
#splash h2{font-family:var(--font-head)}
#splash .curtain{display:none}
#splash .inner.celebrate .curtain{display:block;position:absolute;top:0;bottom:0;width:52%;z-index:3;
  pointer-events:none;background:linear-gradient(90deg,#5a0c14,#8e1620 55%,#6b0f18);box-shadow:inset 0 0 40px rgba(0,0,0,.55)}
#splash .inner.celebrate .curtain.left{left:0;animation:curtain-l .9s ease-in-out forwards}
#splash .inner.celebrate .curtain.right{right:0;animation:curtain-r .9s ease-in-out forwards}
#splash .inner.celebrate .reveal{animation:match-pop .9s ease-out both}
@media (prefers-reduced-motion:reduce){
  #splash .inner.celebrate .curtain{display:none}
  #splash .inner.celebrate .reveal{animation:none}
}

/* ---- M1: non-blocking match toast, a signal, never a takeover.
   UI-uplift R4 (toast card, Proposal B): the calm-act card - --card ground, a
   1px --pink border and a soft pink outer glow carry the signal, while the
   film title and quip sit on the auditorium surface (eyebrow/title/subtitle
   anatomy) so the eye finds the film name first. ---- */
#toast{position:fixed;top:calc(var(--topbar-h, 48px) + 8px);left:50%;
  transform:translateX(-50%);background:var(--card);color:var(--cream);
  border:1px solid var(--pink);box-shadow:0 0 18px rgba(248,106,176,.28);
  max-width:min(92vw, 420px);width:max-content;padding:12px 16px;
  border-radius:14px;line-height:1.4;z-index:40;
  pointer-events:none;animation:toast-in 200ms ease-out}
#toast.hidden{display:none}
#toast .toast-eyebrow{font-family:var(--font-mono);font-size:.6rem;letter-spacing:.16em;
  text-transform:uppercase;color:var(--pink);margin:0 0 3px}
#toast .toast-title{font-size:.95rem;font-weight:600;color:var(--cream);line-height:1.2;margin:0}
#toast .toast-sub{font-size:.85rem;font-weight:400;font-style:italic;color:var(--dim);line-height:1.4;margin:4px 0 0}
@keyframes toast-in{from{opacity:0;transform:translate(-50%,-8px)}}
@media (prefers-reduced-motion:reduce){#toast{animation:none}}
/* H4 Task 9 / R4.3 / E9: the solo bank toast's own action button. Parent is
   pointer-events:none (a signal, not a takeover); this opts back in. */
#toast .toast-action{display:block;margin-top:8px;min-height:36px;
  border-radius:999px;padding:8px 14px;font-size:.85rem;font-weight:600;border:0;
  background:var(--accent);color:var(--accent-ink);pointer-events:auto;cursor:pointer}

/* ---- ranking ---- */
.rank-item{display:flex;align-items:center;gap:10px;background:var(--card);border-radius:12px;padding:8px;margin:8px 0}
.rank-item img{width:52px;border-radius:8px}
.rank-badge{background:var(--accent);color:var(--accent-ink);min-width:32px;height:32px;border-radius:999px;
  display:flex;align-items:center;justify-content:center;font-weight:700;font-family:var(--font-mono)}
.rank-badge.empty{background:var(--line2);color:transparent}
/* night-flow R3: the title + More control + expanded details column, so the
   badge/poster stay fixed while this side wraps and grows with the panel. */
.rank-item-main{flex:1;min-width:0;display:flex;flex-direction:column;align-items:flex-start;gap:2px}

/* ---- recap table (WF3 R4): per-person icon table. Fits 360px, no page side-scroll.
   H4 Task 10: N>=3 columns (a group's roster) can exceed a narrow phone's width;
   .recap-scroll scrolls the table horizontally instead of squeezing it (mirrors
   the memory table's .mem-table-wrap idiom). At N=2 the table still fits inside
   the wrapper, so couples never see a scrollbar. ---- */
.recap-scroll{overflow-x:auto;margin:0}
/* H4 Task 10b (review fix): table-layout was 'fixed' with per-column widths
   as a %, which always sums to <=100% of the wrapper and so can never
   overflow it (the bug: a 4-person group squeezed the title column to ~12%
   instead of scrolling). Auto layout plus a fixed min-width per column
   (below) makes the table's natural width grow linearly with roster size N
   and reliably overflow into .recap-scroll at N>=3, mirroring the .mem-table
   min-width force-overflow idiom at ~line 470. Fixed layout ignores min-width
   on cells (it only reads 'width' from the first row), which is why this
   fix needs auto layout to work at all. */
.recap-table{width:100%;border-collapse:collapse}
.recap-table th,.recap-table td{padding:8px 6px;text-align:center;vertical-align:top}
.recap-table th:first-child,.recap-table td.recap-film{text-align:left;width:auto;min-width:150px}
/* Two 56px icon columns plus the title's 150px minimum (262px) still fit a
   360px phone (296px inside the wrapper), so couples (N=2) see no premature
   scroll; three or more (318px+) reliably overflow into .recap-scroll. */
.recap-table th:not(:first-child){min-width:56px}
.recap-film{word-break:break-word}
.recap-row{cursor:pointer}
.recap-reveal td{padding:0 6px 8px;text-align:left}
.recap-cell{display:inline-flex;align-items:center;justify-content:center;
  width:26px;height:26px;border-radius:50%;font-size:.95rem;line-height:1}
/* UI-uplift R5.2: shape + colour per level (survives colour-blindness/brightness). */
.recap-cell.lv-would{background:rgba(63,211,220,.18);color:var(--cyan-neon)}
.recap-cell.lv-open{background:rgba(224,169,74,.15);border:1px solid rgba(224,169,74,.4);color:var(--amber)}
.recap-cell.lv-no{background:transparent;border:1px solid var(--line2);color:var(--dim)}
.recap-cell.lv-blank{background:transparent;color:var(--line2)}
/* R5.1: the key leads, above the data, not after it. */
.recap-legend{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin:2px 0 10px}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}

/* ---- UI-uplift R6: the one waiting pill (waiting card). Replaces the old
   animated dots everywhere the app waits on the other person or the server.
   Reduced motion: the ring stops spinning and dims, no motion. ---- */
.wpill{display:inline-flex;align-items:center;gap:10px;background:var(--panel);border:1px solid var(--line2);
  border-radius:999px;padding:10px 18px;font-size:.92rem;color:var(--cream)}
.wpill.small{padding:6px 12px;font-size:.8rem;gap:8px}
.wpill-line{display:flex;justify-content:center;margin:10px 0}
/* FB1 R5 (item 16): the "Building your pool" heading centres so it lines up with
   the centred waiting pill below it (was a left-aligned h1 over a centred pill). */
.building-title{text-align:center}
/* FB1 R14 (item 20b): the memory screen's inline "Add a film" search block. */
.mem-add{margin:8px 0 12px}
/* FB1 R12 (items 1+2): warm-up step labels + the running "In your memory" list. */
.step-label{font-family:var(--font-mono);font-size:.62rem;letter-spacing:.1em;text-transform:uppercase;margin:0 0 2px}
.warmup-mem{margin:10px 0}
.warmup-mem-h{font-family:var(--font-mono);font-size:.62rem;letter-spacing:.08em;text-transform:uppercase;margin:0 0 4px}
.warmup-mem-row{margin:2px 0;font-size:.9rem;color:var(--cream)}
.wspin{width:15px;height:15px;border-radius:50%;border:2px solid var(--line2);border-top-color:var(--accent);
  animation:wspin .8s linear infinite;flex:0 0 auto}
.wpill.small .wspin{width:11px;height:11px}
@keyframes wspin{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){.wspin{animation:none;opacity:.55}}

/* ---- footer attribution (spec req 26) ---- */
#footer{padding:14px 14px 18px;background:var(--page);border-top:1px solid var(--line);
  font-size:.72rem;color:var(--dim);display:flex;flex-direction:column;gap:8px;
  align-items:center;justify-content:center;text-align:center}
/* night-flow R4.5: the softened one-line footer credit - the mark sits inline
   and small (much smaller than the old standalone logo row), quiet by design. */
.credit-line{margin:0;line-height:1.5}
.tmdb-mark{vertical-align:middle;margin-right:4px;opacity:.75}
/* UI-uplift R10: the done screen's curtain line (type card). Marcellus, centred,
   bulb-coloured dots either side; no session code (D4). */
.close-line{font-family:var(--font-head);font-size:1.12rem;text-align:center;color:var(--cream);letter-spacing:.02em;margin:14px 0 6px}
.close-line::before,.close-line::after{content:"·";color:var(--bulb);margin:0 10px;opacity:.85}
.want-list{padding-left:0;list-style:none}
.want-list li{padding:8px 0;border-bottom:1px solid var(--line)}

/* ---- H6 Task 8: "Delete my profile", clearly the destructive action ---- */
button.danger{background:transparent;border:1px solid var(--danger);color:var(--danger)}

/* ---- H6 Task 8: memory table. Scrolls horizontally inside its own wrapper
   rather than squeezing five tick columns unreadably on a narrow phone. ---- */
.mem-table-wrap{overflow-x:auto;margin:8px 0}
.mem-table{border-collapse:collapse;min-width:540px;width:100%}
.mem-table th,.mem-table td{padding:6px 4px;text-align:center;vertical-align:middle;font-size:.85rem}
.mem-table th:first-child,.mem-table td:first-child{width:36px}
.mem-table td.mem-film,.mem-table th:nth-child(2){text-align:left;min-width:120px}
.mem-table td.mem-date{white-space:nowrap;font-size:.78rem}
.mem-poster{width:30px;height:45px;object-fit:cover;border-radius:4px;display:block}
/* UI-uplift R12: memory table headers adopt the mono machinery voice. */
.mem-sort{width:auto;min-height:auto;margin:0;padding:0;background:none;border:0;color:var(--cream);
  font-weight:600;font-size:.72rem;font-family:var(--font-mono);text-transform:uppercase;letter-spacing:.06em;
  text-decoration:underline;cursor:pointer}
th.mem-tick-h{color:var(--dim);font-weight:400;font-size:.68rem;white-space:nowrap;
  font-family:var(--font-mono);text-transform:uppercase;letter-spacing:.06em}
.mem-tick{width:30px;height:30px;min-height:auto;margin:0 auto;padding:0;border-radius:6px;
  background:var(--card);border:1px solid var(--line2);color:var(--accent);font-weight:700}
.mem-tick.on{background:var(--accent-tint);border-color:var(--accent-tint-line);color:var(--accent-tint-ink)}
.mem-tick.mem-never-on{background:rgba(226,59,78,.16);border-color:var(--danger);color:var(--danger)}

/* ---- H6 Task 8: warm-up mini-cards, part one (strip) and part two (search
   follow-up), reusing the seed-picker's row layout (.seed-results/.seed-suggest). ---- */
.warmup-list{display:flex;flex-direction:column;gap:8px;margin:8px 0}
.warmup-card{display:flex;gap:10px;background:var(--card);border-radius:12px;padding:10px;align-items:flex-start}
.warmup-card img,.warmup-card .noposter{width:46px;height:69px;object-fit:cover;border-radius:6px;flex:0 0 auto}
.warmup-card-body{flex:1;min-width:0}
.warmup-title{margin:0 0 6px;font-weight:600}
.warmup-card-body button{margin:4px 0}

