.stb{--night:#1a0f2b;--night2:#22143a;--stb-card:#2c1b49;--stb-card2:#372357;--rose:#f378a0;--rose-deep:#c0355f;--peach:#f6b782;--ruby:#d24b73;--cream:#f6ecf1;--muted:#b6a4c7;--dim:#8b7aa0;--line:rgba(255,255,255,.09);--good:#7fd0a6;--gate:#e05a86;--grad:linear-gradient(135deg,#f378a0,#f6b782);--radius:14px}
.stb *{box-sizing:border-box;margin:0;padding:0}
.stb{max-width:576px;margin:0 auto;position:relative;background:var(--night);color:var(--cream);font-family:'Inter',system-ui,sans-serif;border-radius:16px;overflow:hidden;box-sizing:border-box}
.stb .screen{display:none;padding:22px 20px 40px;animation:fade .35s ease}
.stb .screen.active{display:block}
@keyframes fade{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
.stb h1, .stb h2, .stb h3{font-family:'Fraunces',serif}
.stb .top{display:flex;align-items:center;gap:10px;margin-bottom:8px;min-height:24px}
.stb .back{background:none;border:none;color:var(--muted);font-size:22px;cursor:pointer;line-height:1;padding:4px}
.stb .back:hover{color:var(--cream)}
/* V670: A BACK BUTTON THAT LOOKS LIKE A BUTTON. His words: "place 'Back' button
   with a click button shape", and "Give a <Back button (clickable)". The control
   it replaces was a bare '‹' -- no border, no label, 22px of glyph in a 30px box.
   Three things this fixes at once: it reads as a control, it says where it goes,
   and it is a 44px tap target, which the chevron never was.
   `--muted` on the card ground, not `--dim`: 3.96:1 is the pair this stylesheet
   has tripped on three times now (V662, V664, and the V669 pass rule). */
.stb .backbtn{display:inline-flex;align-items:center;gap:6px;background:var(--stb-card);
  border:1px solid var(--line);color:var(--muted);border-radius:10px;
  padding:9px 14px;font:inherit;font-size:13px;font-weight:600;cursor:pointer;
  min-height:44px;line-height:1;letter-spacing:.02em;transition:.15s;flex:0 0 auto}
.stb .backbtn:hover{color:var(--cream);border-color:var(--rose)}
.stb .backbtn:active{transform:scale(.97)}
.stb .backbtn:focus-visible{outline:2px solid var(--rose);outline-offset:2px}
.stb .kicker{font-size:12px;letter-spacing:2px;text-transform:uppercase;color:var(--dim)}
.stb .muted{color:var(--muted)}
.stb .hero{text-align:center;padding:8px 0 18px;position:relative}
.stb .hero .glow{position:absolute;inset:-30px 0 auto;height:150px;background:radial-gradient(circle at 50% 20%,rgba(246,183,124,.28),transparent 62%);filter:blur(6px);pointer-events:none}
.stb .hero h1{font-size:30px;font-weight:600;position:relative}
.stb .hero h1 em{font-style:italic;color:var(--peach)}
.stb .hero p{color:var(--muted);margin-top:8px;font-size:14px;position:relative}
.stb .section-lbl{font-size:12px;letter-spacing:1.5px;text-transform:uppercase;color:var(--dim);margin:22px 0 12px;display:flex;align-items:center;justify-content:space-between}
.stb .prow{display:flex;align-items:center;gap:10px;background:var(--stb-card);border:1px solid var(--line);border-radius:12px;padding:7px 12px;margin-bottom:9px}
.stb .prow .idx{width:28px;height:28px;border-radius:50%;flex:none;display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:500}
.stb .prow input{flex:1;background:transparent;border:none;color:var(--cream);font-family:inherit;font-size:var(--fld-fs,14.5px);padding:7px 2px;outline:none}
/* V671: 232x30 measured. The 44px floor in line_escape.css covers `button` and a
   handful of named controls -- it never covered <input>. This one is typed into by
   three to twelve people in a row at a party, so it earns the height.
   THE ROW GETS 14px TALLER and that is the visible cost he approved: with twelve
   players, 168px more scrolling on the setup screen. Height only -- the field is
   already `flex: 1` and must stay so, or the ✕ beside it loses its place. */
@media (pointer: coarse) {
  .stb .prow input { min-height: 44px; padding: 0 2px; }
}
.stb .prow .rm{background:none;border:none;color:var(--dim);font-size:20px;cursor:pointer;line-height:1;padding:2px 6px}
.stb .prow .rm:hover{color:var(--gate)}
.stb .prow .rm:disabled{opacity:.25;cursor:default}
.stb .addp{background:none;border:1px dashed var(--line);border-radius:12px;padding:12px;color:var(--peach);font-size:14px;cursor:pointer;width:100%;font-family:inherit;display:flex;align-items:center;justify-content:center;gap:8px}
.stb .addp:hover{border-color:var(--peach)}
.stb .pcount{font-size:12px;color:var(--dim);text-transform:none;letter-spacing:0}
.stb .chips{display:flex;flex-wrap:wrap;gap:9px}
.stb .chip{background:var(--stb-card);border:1px solid var(--line);border-radius:999px;padding:9px 15px;font-size:13.5px;cursor:pointer;display:inline-flex;align-items:center;gap:7px;transition:.15s;color:var(--cream);font-family:inherit}
.stb .chip .n{font-size:11px;color:var(--dim)}
.stb .chip:hover{border-color:rgba(243,120,160,.45)}
.stb .chip.on{background:var(--grad);color:#3a1226;border-color:transparent;font-weight:500}
.stb .chip.on .n{color:#7a2f45}
.stb .chip.gate{border-color:rgba(224,90,134,.5)}
.stb .chip.gate.on{background:linear-gradient(135deg,#e05a86,#c0355f);color:#fff}
.stb .mixnote{margin-top:12px;font-size:13px;color:var(--peach);display:none;align-items:center;gap:7px}
.stb .mixnote.show{display:flex}
/* V792 --- Prompts source segmented switch (Duo-style) + the iOS deck dropdown. */
.stb .seg3{display:flex;background:var(--stb-card);border:1px solid var(--line);border-radius:11px;overflow:hidden}
.stb .seg3 button{flex:1;background:transparent;border:0;color:var(--muted);padding:9px 8px;font-size:12.5px;font-weight:600;cursor:pointer;font-family:inherit}
.stb .seg3 button.on{background:var(--stb-card2);color:var(--cream)}
.stb .deckdd{position:relative}
.stb .deckdd .ddbtn{width:100%;display:flex;align-items:center;gap:10px;background:var(--stb-card);
  border:1px solid var(--line);border-radius:12px;padding:12px 14px;color:var(--cream);font-size:14px;
  font-weight:600;cursor:pointer;font-family:inherit}
.stb .deckdd .ddbtn .lbl{flex:1 1 auto;text-align:left;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.stb .deckdd .ddbtn .lbl small{color:var(--dim);font-weight:500}
.stb .deckdd .ddbtn .chev{color:var(--dim);font-size:12px;transition:.15s}
.stb .deckdd.open .ddbtn{border-color:var(--peach)}
.stb .deckdd.open .ddbtn .chev{transform:rotate(180deg)}
.stb .deckdd .ddmenu{margin-top:8px;background:var(--stb-card);border:1px solid var(--line);border-radius:14px;
  overflow:hidden;box-shadow:0 10px 26px rgba(0,0,0,.4)}
.stb .deckdd .ddhint{font-size:11px;letter-spacing:.03em;text-transform:uppercase;color:var(--dim);padding:9px 14px 4px}
.stb .deckdd .ddrow{display:flex;align-items:center;gap:12px;padding:12px 14px;cursor:pointer;border-top:1px solid var(--line)}
.stb .deckdd .ddrow:active{background:var(--stb-card2)}
.stb .deckdd .ddrow .rn{flex:1 1 auto;font-size:14px;color:var(--muted)}
.stb .deckdd .ddrow.on .rn{color:var(--cream);font-weight:600}
.stb .deckdd .ddrow .rn .spice{font-size:12.5px}
.stb .deckdd .ddrow .ck{width:20px;flex:0 0 auto;color:var(--rose);font-size:17px;text-align:center;opacity:0}
.stb .deckdd .ddrow.on .ck{opacity:1}
.stb .deckdd .ddfoot{display:flex;justify-content:flex-end;padding:8px 12px;border-top:1px solid var(--line)}
.stb .deckdd .dddone{background:var(--grad);color:#3a1226;border:0;border-radius:9px;padding:7px 16px;font-weight:700;font-size:12.5px;cursor:pointer;font-family:inherit}
/* V793 --- the bottle-type single-select dropdown (reuses the deck dropdown's chrome). */
.stb .botdd{position:relative;flex:1 1 auto;min-width:0}
.stb .botdd .ddbtn{width:100%;display:flex;align-items:center;gap:10px;background:var(--stb-card);
  border:1px solid var(--line);border-radius:12px;padding:11px 13px;color:var(--cream);font-size:13.5px;
  font-weight:600;cursor:pointer;font-family:inherit}
.stb .botdd .ddbtn .lbl{flex:1 1 auto;display:flex;align-items:center;gap:9px;text-align:left;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.stb .botdd .ddbtn .chev{color:var(--dim);font-size:12px;transition:.15s}
.stb .botdd.open .ddbtn{border-color:var(--peach)}
.stb .botdd.open .ddbtn .chev{transform:rotate(180deg)}
.stb .botdd .ddmenu{position:absolute;left:0;right:0;z-index:6;margin-top:6px;background:var(--stb-card);
  border:1px solid var(--line);border-radius:13px;overflow:hidden;box-shadow:0 12px 28px rgba(0,0,0,.5)}
.stb .botdd .ddrow{display:flex;align-items:center;gap:10px;padding:11px 13px;cursor:pointer;border-top:1px solid var(--line)}
.stb .botdd .ddrow:first-child{border-top:0}
.stb .botdd .ddrow:active{background:var(--stb-card2)}
.stb .botdd .ddrow .rn{flex:1 1 auto;font-size:13.5px;color:var(--muted)}
.stb .botdd .ddrow.on .rn{color:var(--cream);font-weight:600}
.stb .botdd .ddrow .ck{width:18px;flex:0 0 auto;color:var(--rose);font-size:16px;text-align:center;opacity:0}
.stb .botdd .ddrow.on .ck{opacity:1}
.stb .botdd .bswatch{width:14px;height:14px;flex:0 0 auto;border-radius:4px;display:inline-block}
.stb .opt{background:var(--stb-card);border:1px solid var(--line);border-radius:var(--radius);padding:15px;margin-bottom:11px}
.stb .opt-head{display:flex;align-items:flex-start;gap:12px}
.stb .opt-head .txt{flex:1}
.stb .opt-head h4{font-size:15px;font-weight:500}
.stb .opt-head p{font-size:12.5px;color:var(--muted);margin-top:3px;line-height:1.45}
.stb .sw{width:46px;height:27px;border-radius:999px;background:#3a2a52;position:relative;cursor:pointer;flex:none;transition:.2s;border:none}
.stb .sw::after{content:"";position:absolute;top:3px;left:3px;width:21px;height:21px;border-radius:50%;background:#fff;transition:.2s}
.stb .sw.on{background:var(--rose)}
.stb .sw.on::after{left:22px}
.stb .subopt{margin-top:13px;padding-top:13px;border-top:1px solid var(--line);display:none}
.stb .subopt.show{display:block}
.stb .radiorow{display:flex;gap:10px;margin-bottom:12px}
.stb .rbtn{flex:1;background:var(--night2);border:1px solid var(--line);border-radius:10px;padding:10px;font-size:13px;cursor:pointer;color:var(--muted);font-family:inherit;text-align:center}
.stb .rbtn.on{border-color:var(--rose);color:var(--cream);background:rgba(243,120,160,.12)}
.stb .linkbtn{background:none;border:1px dashed var(--line);border-radius:10px;padding:10px 14px;color:var(--peach);font-size:13px;cursor:pointer;width:100%;font-family:inherit;display:flex;align-items:center;justify-content:center;gap:7px}
.stb .seg{display:flex;background:var(--stb-card);border:1px solid var(--line);border-radius:12px;padding:4px;gap:4px}
.stb .seg button{flex:1;background:none;border:none;color:var(--muted);padding:10px;border-radius:9px;font-size:13px;cursor:pointer;font-family:inherit}
.stb .seg button.on{background:var(--grad);color:#3a1226;font-weight:500}
.stb .err{color:var(--gate);font-size:13px;margin-top:10px;display:none}
.stb .err.show{display:block}
.stb .note{color:var(--peach);font-size:12.5px;margin-top:10px;display:none}
.stb .note.show{display:block}
.stb .cta{width:100%;background:var(--grad);color:#3a1226;border:none;border-radius:14px;padding:16px;font-size:16px;font-weight:600;cursor:pointer;margin-top:24px;font-family:inherit;box-shadow:0 8px 24px rgba(243,120,160,.22)}
.stb .cta:active{transform:scale(.99)}
.stb .overlay{position:fixed;inset:0;background:rgba(10,5,20,.8);display:none;align-items:center;justify-content:center;z-index:50;padding:24px;backdrop-filter:blur(3px)}
.stb .overlay.show{display:flex}
.stb .modal{background:var(--stb-card);border:1px solid rgba(224,90,134,.4);border-radius:22px;padding:26px 22px;max-width:360px;width:100%;text-align:center}
.stb .modal .lockcirc{width:58px;height:58px;border-radius:50%;background:rgba(224,90,134,.16);display:flex;align-items:center;justify-content:center;margin:0 auto 14px}
.stb .modal .lockcirc svg{width:26px;height:26px}
.stb .modal h3{font-size:22px;font-weight:600;margin-bottom:8px}
.stb .modal p{color:var(--muted);font-size:14px;line-height:1.5;margin-bottom:18px}
.stb .modal input{background:var(--night2);border:1px solid var(--line);border-radius:10px;padding:12px;color:var(--cream);font-size:var(--fld-fs,15px);width:130px;text-align:center;font-family:inherit;margin-bottom:16px}
.stb .modal .merr{color:var(--gate);font-size:12.5px;margin-bottom:10px;min-height:16px}
.stb .modal .mrow{display:flex;gap:10px}
.stb .modal .mrow button{flex:1;border-radius:11px;padding:13px;font-size:14px;cursor:pointer;font-family:inherit;border:none}
.stb .mcancel{background:var(--night2);color:var(--muted);border:1px solid var(--line)!important}
.stb .mok{background:linear-gradient(135deg,#e05a86,#c0355f);color:#fff}
.stb .playwrap{text-align:center;position:relative}
.stb .play-glow{position:absolute;top:40px;left:50%;transform:translateX(-50%);width:300px;height:300px;background:radial-gradient(circle,rgba(246,183,124,.16),transparent 65%);pointer-events:none;filter:blur(4px)}
.stb .play-sub{font-size:12px;color:var(--muted);margin-bottom:12px}
/* V669: the pass rule, on the play screen. Quieter than the line above it --
   it is a standing rule rather than a description of this game -- but it must
   read at a glance, so `--dim` is not used: it measured 3.96:1 against the card in
   V662 and again in V664, which is the pair this stylesheet has tripped on twice.
   The token is `--cream`, one this file declares and all three skins override --
   the first draft of this rule named `--stb-ink2`, which does not exist here, and
   a colour with no declaration is not defaulted, it is DROPPED (V611's lesson). */
.stb .play-sub .passrule{display:inline-block;margin-top:5px;font-size:12.5px;
  color:var(--cream);font-weight:600;letter-spacing:.01em;opacity:.92}

.stb .table{position:relative;width:270px;height:270px;margin:6px auto 0;border-radius:50%;background:radial-gradient(circle,var(--stb-card2),var(--stb-card));border:1px solid var(--line)}
.stb .seat{position:absolute;text-align:center;width:64px}
.stb .seat .av{width:44px;height:44px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-weight:500;margin:0 auto;font-size:15px;transition:box-shadow .3s;border:1px solid rgba(255,255,255,.12)}
.stb .seat .nm{font-size:10.5px;color:var(--muted);margin-top:3px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.stb .bottle{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%) rotate(0deg);transform-origin:center;transition:transform 3.4s cubic-bezier(.17,.67,.28,1)}
.stb .spinbtn{width:100%;background:var(--grad);color:#3a1226;border:none;border-radius:14px;padding:15px;font-size:15px;font-weight:600;cursor:pointer;margin-top:20px;font-family:inherit;display:flex;align-items:center;justify-content:center;gap:9px}
.stb .editp{width:100%;background:none;border:1px solid var(--line);color:var(--muted);border-radius:12px;padding:11px;font-size:13px;cursor:pointer;font-family:inherit;margin-top:10px}
.stb .tod-panel{margin-top:16px;display:none}
.stb .tod-pointed{font-size:16px;margin-bottom:12px}
.stb .tdrow{display:flex;gap:11px}
.stb .tdbtn{flex:1;border-radius:13px;padding:15px;font-size:15px;font-weight:500;cursor:pointer;font-family:inherit;border:1px solid var(--line)}
.stb .tdbtn.truth{background:rgba(243,120,160,.14);color:var(--rose);border-color:rgba(243,120,160,.4)}
.stb .tdbtn.dare{background:rgba(246,183,124,.14);color:var(--peach);border-color:rgba(246,183,124,.4)}
.stb .prompt-card{background:var(--stb-card2);border:1px solid var(--line);border-radius:16px;padding:20px;margin-top:14px;display:none}
.stb .prompt-card .pt{font-size:11px;letter-spacing:2px;text-transform:uppercase;margin-bottom:8px}
.stb .prompt-card .px{font-family:'Fraunces';font-size:18px;font-weight:500;line-height:1.3}
.stb .nextbtn{width:100%;background:var(--stb-card2);border:1px solid var(--line);color:var(--cream);border-radius:12px;padding:13px;font-size:14px;cursor:pointer;font-family:inherit;margin-top:14px;display:none;align-items:center;justify-content:center;gap:7px}
.stb .nextbtn.show{display:flex}
.stb .cchip{display:flex;align-items:center;gap:10px;background:var(--stb-card);border:1px solid var(--line);border-radius:11px;padding:11px 13px;font-size:13.5px}
.stb .freein{width:100%;background:var(--night2);border:1px solid var(--line);border-radius:12px;padding:13px;color:var(--cream);font-family:inherit;font-size:15px;margin-bottom:12px}
.stb .trow{display:flex;align-items:center;justify-content:space-between;background:var(--stb-card);border:1px solid var(--line);border-radius:10px;padding:8px 12px;margin-bottom:7px;font-size:13px}
.stb .trow .who{display:flex;align-items:center;gap:8px}
.stb .trow .dot{width:22px;height:22px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:500;flex:none}
.stb .trow .cnt{color:var(--muted);font-size:12px}
@media(prefers-reduced-motion:reduce){.stb .bottle{transition:transform .1s}}
.stb :focus-visible{outline:2px solid var(--peach);outline-offset:2px}

/* ==========================================================================
   V661 — THE THREE SKINS. His ask: "keep option to keep twilight or use light or
   green as per tool (three options)".

   Only TOKENS are redeclared below; not one rule is repeated. That is the whole
   reason the palette was hoisted into custom properties on the container in the
   first place, and it is why a fourth skin would be eight lines rather than a
   second stylesheet.

   TWILIGHT is the default and is the block at the top of this file, so it needs
   no rule here -- `.stb.skin-twilight` inherits it. Absence is the default,
   the same way games_skin.py stores it as a missing row.

   LIGHT is the same design on warm white. The rose darkens to --rose-deep for
   text-weight use because #f378a0 measures about 2.1:1 on white and this project
   has a 4.5:1 floor it paid for once already (V578).

   GREEN IS NOT A COLOUR, IT IS "FOLLOW THE HOUSE". Every token maps onto the
   site's own (--bg, --panel, --text, --accent ...), so it is dark green on a dark
   site and white on a light one, and it tracks any future change to those tokens
   for free. It is the only one of the three that makes the tool look like the
   rest of the site, which is the reason it is offered.
   ========================================================================== */
.stb.skin-light{
  --night:#fdf7f9;--night2:#f6eef2;--stb-card:#ffffff;--stb-card2:#f4e8ee;
  --rose:#c0355f;--rose-deep:#96234a;--peach:#b96a2a;--ruby:#a52b52;
  --cream:#2a1c26;--muted:#5d4a56;--dim:#6b5766;--line:rgba(42,28,38,.14);
  --good:#1f7a52;--gate:#a52b52;
  --grad:linear-gradient(135deg,#c0355f,#b96a2a)}
.stb.skin-green{
  --night:var(--bg);--night2:var(--panel);--stb-card:var(--panel);--stb-card2:var(--btn);
  --rose:var(--accent);--rose-deep:var(--accent);--peach:var(--accent);--ruby:var(--accent);
  --cream:var(--text);--muted:var(--muted2);--dim:var(--muted3);--line:var(--line2);
  --good:var(--good-line);--gate:var(--bad);
  --grad:linear-gradient(135deg,var(--accent),var(--accent))}

/* The picker itself. Three pills, and it is on the tool's own tokens so it
   repaints with everything else the instant the class changes. */
.stb .skinrow{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin:18px 0 4px}
.stb .spill{background:var(--stb-card);color:var(--muted);border:1px solid var(--line);
  border-radius:999px;padding:6px 14px;font:inherit;font-size:12.5px;cursor:pointer}
.stb .spill:hover{color:var(--cream)}
.stb .spill.on{background:var(--rose);color:var(--night);border-color:var(--rose);font-weight:600}
/* V661: see the note in duo.css -- currentColor, so the icons follow the skin. */
.stb .lockcirc,.stb .lockcirc2{color:var(--gate)}

/* ==========================================================================
   V662 — the spin-duration stepper and the flavour pickers.
   ========================================================================== */
.stb .spinbar{display:flex;align-items:center;justify-content:center;gap:12px;margin-top:12px}
/* V670: THE BOTTLE CHIPS AND THE SPIN STEPPER ON ONE ROW, at his ask, and the
   `<details>` that used to hold the chips is gone rather than opened -- see the
   note in the markup. `margin-top:0` on the nested .spinbar because the row owns
   the spacing now, and leaving the old 12px would have put the stepper half a line
   below the chips it is supposed to sit beside. The gap is 14px rather than the
   chips' 8px: these are two different controls, not four chips.

   THE STEPPER IS A TWO-LINE BLOCK, AND THAT IS WHAT ACTUALLY PUTS IT ON THE ROW.
   The first cut of this rule did not, and only a browser said so. Measured at
   414px: laid out on one line the spinbar wanted 227px (a 128px stepper, a 14px
   gap, a 91px "second spin"), the three bottle chips wanted 233px at their
   narrowest useful width, and 460 does not fit in 374 -- so the browser wrapped
   the spinbar to a line of its own, 84px BELOW the chips it is meant to sit
   beside, and the flex row read exactly like the stack it replaced. His ask was
   "place timer just beside the Bottle names. in same row", and a row with
   permission to wrap had not met it.
   Turning the hint under the stepper takes that block to 128px, which leaves 232px
   for the chips: they wrap to two short lines INSIDE their own box, alongside the
   stepper, and the row is one row. `align-items:flex-start` so the stepper sits
   level with the first line of chips rather than centred against all of them. */
.stb .flavrow{display:flex;flex-wrap:wrap;align-items:flex-start;gap:14px;margin-top:14px;
  text-align:left}
.stb .flavrow .frow{flex:1 1 150px;min-width:0}
.stb .flavrow .spinbar{margin-top:0;flex:0 0 auto;flex-direction:column;
  align-items:flex-start;gap:5px}
/* Under 340px it stacks. The stepper keeps its 38px buttons -- shrinking a tap
   target to keep a row on one line is the wrong trade on the screen somebody uses
   every turn -- so below that width there is no room and two lines is the honest
   answer. 400px was the first threshold and it was too generous: it stacked a
   414px phone that had 232px going spare. */
@media (max-width:340px){
  .stb .flavrow{gap:10px}
  .stb .flavrow .frow,.stb .flavrow .spinbar{flex:1 1 100%}
}
.stb .stepper{display:flex;align-items:center;gap:2px;background:var(--stb-card);
  border:1px solid var(--line);border-radius:999px;padding:4px}
.stb .stepbtn{width:38px;height:38px;border:none;background:transparent;color:var(--rose);
  font-size:21px;line-height:1;font-family:inherit;cursor:pointer;border-radius:999px}
.stb .stepbtn:hover{background:var(--stb-card2);color:var(--cream)}
.stb .stepbtn:active{transform:scale(.94)}
.stb .stepval{min-width:40px;text-align:center;font-size:20px;font-weight:600;
  font-family:'Fraunces',serif;color:var(--cream);font-variant-numeric:tabular-nums}
.stb .stephint{font-size:13px;color:var(--muted)}

/* V670: THE `<details>` IS GONE, and its rules with it -- his ask, "this Bottle
   design should be always shown". V662's reason for the box is worth keeping on
   the record because it was a real argument: "the pickers are a once-a-session
   decision sitting on the screen somebody uses every turn". What overrules it is
   that he uses them per turn, not per session -- the spin length especially --
   and a control he reaches for every round should not be behind a click.
   `.flavrow` above is what replaced it. The V662 contrast lesson that lived in
   this block is NOT lost: it is `--muted` and not `--dim` on a card ground, and
   it is stated where it still applies, on `.stb .stephint` and in the V664 note
   further down this file. */
.stb .frow{display:flex;flex-wrap:wrap;gap:8px}
.stb .fchip{background:var(--stb-card2);color:var(--muted);border:1px solid var(--line);
  border-radius:999px;padding:7px 13px;font:inherit;font-size:12.5px;cursor:pointer;
  display:inline-flex;align-items:center;gap:7px}
.stb .fchip:hover{color:var(--cream)}
.stb .fchip.on{background:var(--rose);color:var(--night);border-color:var(--rose);font-weight:600}
.stb .bchip i{width:11px;height:11px;border-radius:999px;display:inline-block;
  box-shadow:0 0 0 1px rgba(0,0,0,.25) inset}
/* The spin button is disabled while the bottle is moving. Saying so beats a tap
   that silently does nothing. */
.stb .spinbtn:disabled{opacity:.5;cursor:default}
/* V662: 480 -> 576 (his "make the area 20% extra (horizontally)"), and the setup
   header loses half its vertical space -- it holds a back arrow and one line of
   kicker text and was reserving 32px plus 16px below it. The card still centres
   and still has `box-sizing:border-box`, so nothing inside needed touching. */

/* ==========================================================================
   V664 — THE SKIN REACHES THE PAGE. The reasoning is written once, in duo.css:
   the tokens go on <body> rather than a background, because the toolbar's own
   controls are built from the SITE tokens and a background alone leaves the Admin
   chip gold on a purple page. Green gets no block on purpose — it means "follow
   the house", so the site tokens must stay untouched.

   THE VALUES ARE THE SAME because the two tools share one palette and one skin
   setting per person; if they ever diverge, they diverge here and not by accident.
   ========================================================================== */

/* THE CHROME TOKEN, AND WHY IT NEEDS SAYING SEPARATELY.

   `--chrome-accent` exists precisely so a tool overriding `--accent` inside itself
   does NOT repaint the Home button sitting in its own subtree -- line_escape.css's
   own note explains that it was added because RaffleHub's product blue landed on the
   house green at 1.67:1. So it is declared at :root ONLY, on purpose.

   His ask here is the deliberate exception: he wants the chrome to follow the tool.
   That is why this is set on `body.stbskin-*` and not inside `.stb` -- the point of the
   token is that a tool's own subtree cannot reach it, and the page-level class is the
   one scope entitled to. Green still leaves it alone, so "follow the house" keeps the
   house's gold. */
body.stbskin-twilight{
  --chrome-accent:#f9a0bd;
  --bg:#1a0f2b; --panel:#2c1b49; --btn:#372357;
  --line:rgba(255,255,255,.10); --line2:rgba(255,255,255,.16);
  --text:#f6ecf1; --muted:#cbbcd8; --muted2:#c3b3d2; --muted3:#b6a4c7;
  --accent:#f378a0; --accent-fg:#2a0d1a;
  --backdrop:rgba(14,7,24,.74); --backdrop2:rgba(14,7,24,.85);
}
body.stbskin-light{
  --chrome-accent:#a4274d;
  --bg:#fdf7f9; --panel:#ffffff; --btn:#f4e8ee;
  --line:rgba(42,28,38,.14); --line2:rgba(42,28,38,.20);
  --text:#2a1c26; --muted:#5d4a56; --muted2:#5d4a56; --muted3:#6b5766;
  --accent:#a4274d; --accent-fg:#ffffff;
  --backdrop:rgba(42,28,38,.42); --backdrop2:rgba(42,28,38,.55);
}
body.stbskin-twilight .stb, body.stbskin-light .stb{box-shadow:none}

/* ---- V664: the two things a token swap alone does not reach --------------- */

/* Same two, for Spin the Bottle. Reasoning in duo.css.
   1. THE WHITE BAND UNDER A SHORT PAGE. `background` on <body> only reaches the
      canvas when <html> has none, and this site paints html (line_escape.css sets
      `html, body`). On the Duo home screen the body is ~590px inside a 940px
      window, so html's own colour showed as a band below the content -- which is
      the "not just this area" complaint again, one element further out. */
body.stbskin-twilight, body.stbskin-light{min-height:100vh}

/* 2. THE FLOATING MENU IS A HARDCODED GOLD GRADIENT. It is the site's identity and
      it is deliberately not a token, so a token swap cannot touch it -- and it sits
      on top of the tool as the single most off-theme thing on the page. Repainted
      from the skin's own accents here, and NOWHERE ELSE: on all thirty other tools
      it stays gold, because this rule needs `body.stbskin-*` to apply. */
body.stbskin-twilight #shell-open{
  background:linear-gradient(180deg,#f9a0bd 0%,#e8628f 100%);
  border-color:rgba(90,20,45,.55); color:#2a0d1a;
  box-shadow:0 4px 14px rgba(0,0,0,.45), 0 0 0 1px rgba(255,200,220,.35) inset}
body.stbskin-twilight #shell-open:hover, body.stbskin-twilight #shell-open:focus,
body.stbskin-twilight #shell-open.fab-drag{border-color:rgba(90,20,45,.8)}
body.stbskin-light #shell-open{
  background:linear-gradient(180deg,#c0355f 0%,#96234a 100%);
  border-color:rgba(70,12,30,.5); color:#fff;
  box-shadow:0 4px 14px rgba(42,28,38,.28), 0 0 0 1px rgba(255,255,255,.22) inset}
body.stbskin-light #shell-open:hover, body.stbskin-light #shell-open:focus,
body.stbskin-light #shell-open.fab-drag{border-color:rgba(70,12,30,.75)}

/* ==========================================================================
   V664 — the online room's own furniture.
   ========================================================================== */
.stb .codebox{text-align:center;padding:18px 14px;background:var(--stb-card);
  border:1px dashed color-mix(in srgb, var(--rose) 45%, transparent);
  border-radius:14px;margin:14px 0 12px}
.stb .codebox .clbl{font-size:10px;letter-spacing:.18em;text-transform:uppercase;
  /* V664: --muted, NOT --dim. Identical to the V662 flavbox fix and caught by the
     same ratchet: --dim is chosen against the PAGE and this label sits on the
     CARD, where it measures 3.96:1 against a 4.5 floor. I wrote that lesson down
     three releases ago and reached for --dim again anyway -- which is the argument
     for the ratchet rather than the note. */
  color:var(--muted)}
.stb .codebox .cval{font-family:'Fraunces',serif;font-size:44px;font-weight:600;
  letter-spacing:.16em;color:var(--peach);line-height:1.1;margin:6px 0 4px;
  font-variant-numeric:tabular-nums}
.stb .codebox .chint{font-size:11.5px;color:var(--muted)}
.stb .cta.ghost{background:none;border:1px solid var(--line);color:var(--muted);font-weight:600}
/* One row per player. `.me` is the only decoration -- on a shared screen the
   thing you need first is which one is you. */
.stb .prow2{display:flex;align-items:center;gap:9px;padding:9px 11px;
  background:var(--stb-card);border:1px solid var(--line);border-radius:11px;
  margin-bottom:7px;font-size:13.5px}
.stb .prow2 .av{width:25px;height:25px;border-radius:999px;flex:0 0 auto;
  background:var(--grad);color:var(--night);font-size:11px;font-weight:700;
  display:grid;place-items:center}
.stb .prow2 .who{flex:1;font-weight:500}
.stb .prow2.me{border-color:color-mix(in srgb, var(--rose) 55%, transparent)}
.stb .ptag{font-size:9px;font-weight:700;letter-spacing:.09em;text-transform:uppercase;
  padding:3px 7px;border-radius:999px;flex:0 0 auto}
.stb .ptag.host{background:color-mix(in srgb, var(--peach) 20%, transparent);color:var(--peach)}
.stb .ptag.me{background:color-mix(in srgb, var(--rose) 20%, transparent);color:var(--rose)}
.stb .ptag.guest{background:rgba(128,128,128,.14);color:var(--dim)}
.stb .ptag.turn{background:var(--rose);color:var(--night)}
.stb .kickb{background:none;border:none;color:var(--dim);font-size:17px;cursor:pointer;
  line-height:1;padding:2px 5px}
.stb .kickb:hover{color:var(--gate)}
/* The 18+ rule, said out loud. It is a statement of fact about the room, not a
   warning, so it is not painted like an error. */
.stb .adultnote{display:none;margin:10px 0 4px;padding:10px 12px;border-radius:11px;
  font-size:12.5px;line-height:1.45;background:color-mix(in srgb, var(--peach) 10%, transparent);
  border:1px solid color-mix(in srgb, var(--peach) 32%, transparent);color:var(--muted)}
.stb .adultnote.show{display:block}
.stb .adultnote b{color:var(--cream)}
/* Waiting for somebody else. Never a dead screen: it always names who. */
.stb .waitrow{text-align:center;font-size:13px;color:var(--muted);padding:12px;
  background:rgba(128,128,128,.07);border-radius:12px;margin-top:12px}
.stb .waitrow b{color:var(--cream)}
/* V667 — compact page-theme switcher on the play screen. Sits under the top bar,
   smaller pills so it does not crowd the table. The setup row keeps its size. */
.stb .skinrow-play{margin:6px 0 2px;gap:6px}
.stb .skinrow-play .spill{padding:4px 10px;font-size:12px}

/* ==========================================================================
   V672 — FULL SCREEN, his ask: "give a full screen mode for spinning the bottle:
   with above screen and truth and date section"
   ==========================================================================
   `.playwrap` is the element that goes full screen (see the note in bottle.html for
   why the button is inside it). Four things have to be true in that mode and none of
   them is true by default:

   (1) IT PAINTS ITS OWN GROUND. A full-screen element composites over the browser's
       backdrop, which is BLACK — not this tool's skin. `.playwrap` had no background
       at all, because on the page it inherits the section's. In full screen that
       reads as a black page with floating text, and on the `light` skin it is
       unreadable. So the ground is painted here, from the same token the page uses.
   (2) IT CENTRES. The wrap is a text-align:center column inside a narrow tool
       column; full screen hands it a 1920px-wide box, and left-aligned-to-the-top
       content in the middle of a projector is not a party screen.
   (3) THE CIRCLE GROWS. `min(58vh, 88vw)` square — the smaller of the two, so it
       fits a phone in landscape and a 4K projector without a second rule. The seats
       are placed in JS from the table's MEASURED size (see placeSeats), which is why
       this can be a viewport unit at all.
   (4) THE BETWEEN-GAMES CONTROLS GO. Edit players, the Tally heading and the tally
       itself are hidden: this mode is for the turn in front of you, and a tally of
       who has done what is read between games, on the page, where it stays.

   The bottle/spin-length row STAYS. V670's note is explicit that the bottle design
   and the spin length are the every-turn decision and belong on the screen somebody
   uses every turn — full screen is that screen, more so than the page is. */
.stb .stb-fs {
  position: absolute; top: 0; right: 0; z-index: 5;
  width: 34px; height: 34px; border-radius: 50%;
  background: var(--stb-card2); border: 1px solid var(--line);
  color: var(--muted); font-size: 15px; line-height: 1; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  font-family: inherit; padding: 0;
}
/* `--gate` is the token, not `--stb-gate` -- my typo, and the fallback hid it: the rule
   worked, it just fell back to `--line` and the hover did nothing. v578's contrast suite
   catches exactly this, which is why it asserts every fallback names a real token. */
.stb .stb-fs:hover { color: var(--cream); border-color: var(--gate); }
/* The site's touch floor, the invisible way: padding out to 44 and pulled back by an
   equal negative margin, so the 34px circle and the corner it sits in do not move.
   V672's own lesson applies -- `width` is set above, so `box-sizing` has to give. */
@media (pointer: coarse) {
  .stb .stb-fs { box-sizing: content-box; padding: 5px; margin: -5px; }
}

.stb .playwrap:fullscreen {
  /* `--night` IS THIS TOOL'S GROUND, and all three skins override it (twilight's
     literal, light's #fdf7f9, green's `var(--bg)`), so one token here follows the
     skin the player picked. NOT `var(--bg)`: that is the site's ground, which on the
     light skin would paint the house dark green under pink cards. A colour with no
     declaration is DROPPED rather than defaulted -- V611's lesson, recorded 60 lines
     up this same file about `--stb-ink2`. */
  background: var(--night);
  padding: clamp(10px, 3vh, 34px) clamp(12px, 4vw, 60px);
  display: flex; flex-direction: column; align-items: center;
  /* `flex-start`, NOT `center`, and this cost a measurement to learn: a centred flex
     column whose content is taller than the box overflows in BOTH directions, and the
     part above the top edge cannot be scrolled to. Measured with a prompt revealed at
     1280x800 -- content 886 tall, and the consent line ("Anyone may pass") sat at
     y = -62 with no way to reach it. The circle is sized so a full turn fills most of
     a tall screen anyway; on a short one the wrap scrolls and everything is reachable,
     which is the trade that keeps the mode honest on a laptop. */
  justify-content: flex-start;
  gap: clamp(6px, 1.4vh, 18px);
  overflow: auto;
}
/* THE COLUMN'S WIDTH IS SET ON THE BLOCKS THAT NEED IT, NOT ON `> *`, and the first
   cut did use `> *`. It hit the two children that must not be stretched: the table,
   which became 680 wide against a 462 height and drew the circle as an ELLIPSE with
   the seats off it, and the ⛶ button, which became a 680px flex item. Seen in a
   screenshot; the numbers all looked right. */
.stb .playwrap:fullscreen .play-sub,
.stb .playwrap:fullscreen .spinbtn,
.stb .playwrap:fullscreen .flavrow,
.stb .playwrap:fullscreen .tod-panel { width: min(680px, 100%); }
.stb .playwrap:fullscreen .table {
  /* THE CIRCLE YIELDS, AND STAYS A CIRCLE. Two mistakes were made here before this
     shape was found, and both are worth keeping.

     (1) The first cut let the flex column shrink it with the default
         `flex-shrink: 1`. A declared 462 square rendered about 462x200 once a prompt
         was revealed -- and `border-radius: 50%` on a squashed box is an ELLIPSE,
         with the seats, placed from the measured WIDTH, sitting outside it.
     (2) So the second cut pinned it with `flex: 0 0 auto`. Now it kept its shape and
         pushed the prompt off the bottom of a 1080p projector -- measured: content
         1206 tall in 1080, with the TRUTH card starting at y=1030. The thing he asked
         to see better was the thing that went off screen.

     `aspect-ratio` is what resolves it: HEIGHT is the flexible dimension in a column,
     so the item shrinks on height and the width follows the ratio. It is round at
     every size, as big as the screen allows, and the prompt stays on it. `min-height`
     stops it collapsing to nothing on a phone in landscape with a long prompt -- past
     that point the wrap scrolls, which is the honest answer rather than a 40px table.

     placeSeats() is called again whenever this can change size -- entering and leaving
     the mode, a resize, and a prompt being revealed or cleared -- because the seats
     are placed in pixels from the measured box.

     MEASURED, with a prompt revealed, everything on screen and no sideways scroll:
       1920x1080 projector   circle 435, content 1080 in 1080 -- exact
       1280x800  laptop      circle 243, content  800 in  800 -- exact
       390x844   phone       circle at its 168 floor, content 935 -- IT SCROLLS.
     A phone cannot hold a circle, a spin button, the truth/dare pair and a prompt at
     44px each in 844 pixels, and the honest answer is a scroll rather than a 40px
     table or a hidden consent line. The mode is for the laptop or the projector at a
     party, which is what he asked it for. */
  flex: 0 1 auto;
  aspect-ratio: 1 / 1;
  height: min(52vh, 86vw); width: auto; min-height: 168px;
  margin: 0 auto;
}
.stb .playwrap:fullscreen .play-sub { font-size: clamp(13px, 1.9vh, 20px); }
.stb .playwrap:fullscreen .tod-pointed { font-size: clamp(16px, 2.6vh, 30px); }
.stb .playwrap:fullscreen .prompt-card .pt { font-size: clamp(15px, 2.4vh, 28px); }
.stb .playwrap:fullscreen .spinbtn { margin-top: clamp(8px, 1.6vh, 20px); }
/* Between-games controls, hidden with `!important` because `#tally` carries an inline
   `text-align` from the template and the tally rows are built by JS -- an author rule
   without it is a rule the next builder can silently outrank. */
.stb .playwrap:fullscreen .editp,
.stb .playwrap:fullscreen .section-lbl,
.stb .playwrap:fullscreen #tally { display: none !important; }
/* The toggle keeps its corner in the mode. `fixed` rather than `absolute` so it stays
   put while the wrap scrolls, and it is taken out of the flex flow by being positioned
   at all -- as a flex item it was being sized and placed by the column. */
.stb .playwrap:fullscreen .stb-fs {
  position: fixed; top: clamp(10px, 2vh, 26px); right: clamp(12px, 2.4vw, 34px);
  width: 34px; height: 34px;
}
/* AND THE TOP LINE KEEPS CLEAR OF IT. The consent line ("Anyone may pass") is centred
   in a 680px column and the button sits in the corner; at 1280px they overlapped. A
   right padding on that one block is enough and moves nothing else. */
.stb .playwrap:fullscreen .play-sub { padding-right: 52px; padding-left: 52px; }

/* V802 — invite-by-username in the Spin lobby + the standing-invite banner. */
.stb .stb-invbox .invrow{display:flex;gap:8px;margin-top:6px}
.stb .ol-hit{display:flex;justify-content:space-between;align-items:center;width:100%;background:rgba(255,255,255,.05);border:1px solid rgba(255,255,255,.14);color:inherit;border-radius:9px;padding:9px 12px;margin-top:6px;font:inherit;font-size:14px;cursor:pointer}
.stb .ol-inviteb{background:var(--accent,#e0aa3e);color:#1a1200;border-radius:6px;padding:3px 10px;font-size:12px;font-weight:800}
.stb .ol-banner{display:flex;justify-content:space-between;align-items:center;gap:10px;flex-wrap:wrap;background:rgba(224,170,62,.14);border:1px solid var(--accent,#e0aa3e);border-radius:12px;padding:11px 13px;margin:0 0 12px}
.stb .ol-bantxt{font-size:14px}
.stb .ol-banbtns{display:flex;align-items:center;gap:8px}
.stb .ol-banbtns .linkbtn{background:none;border:none;color:inherit;opacity:.7;text-decoration:underline;font-size:13px;cursor:pointer;padding:6px}
