  :root{
    --table:#1E0B47; --panel:#3B1E86; --slot:#6C4FC0; --label:#B9A6F5;
    --accent:#FFD400; --accentInk:#1E0B47; --key:#fff; --shadow:rgba(0,0,0,.55);
  }
  *{box-sizing:border-box; -webkit-tap-highlight-color:transparent;}
  html,body{margin:0; background:var(--table); color:#fff;
    font-family:'Archivo Black',system-ui,sans-serif; overflow-x:hidden;}
  #app{max-width:460px; margin:0 auto; min-height:100dvh; padding:22px 22px 40px;
    display:flex; flex-direction:column; gap:16px;}
  /* A build or a showdown is one phone tall: the tray and the verdict stay on
     screen, and a travelling card can't paint past the glass. */
  #app:has(#slots), #app:has(#sd){height:100dvh; max-height:100dvh; min-height:0; overflow:hidden;}
  .sticker{border:4px solid var(--key); box-shadow:6px 6px 0 var(--shadow);}
  .chip{display:inline-block; padding:8px 14px; border-radius:8px; color:var(--accentInk);
    background:#fff; font-size:18px;}
  h1.word{font-size:clamp(40px,13vw,64px); margin:0; color:#0D2B18; background:#16C46A;
    display:inline-block; padding:10px 20px; border-radius:14px; transform:rotate(-2.5deg);}
  .label{color:var(--label); font-size:17px; letter-spacing:.08em;}   /* 17px is the type floor */
  .big{font-size:34px;}
  input.field{width:100%; font-family:inherit; font-size:28px; text-align:center;
    color:#fff; background:var(--panel); border:3px solid var(--slot); border-radius:14px;
    padding:12px; text-transform:uppercase; outline:none; caret-color:var(--accent);}
  /* iOS draws the caret through the middle of a centred placeholder (YOUR|NAME). */
  input.field:focus::placeholder{color:transparent;}
  button.btn, a.btn{width:100%; font-family:inherit; font-size:30px; border:5px solid var(--key);
    border-radius:24px; padding:20px; background:#fff; color:var(--accentInk);
    box-shadow:8px 8px 0 var(--shadow); transform:rotate(-1deg); cursor:pointer;}
  button.btn.accent, a.btn.accent{background:var(--accent);}
  /* HOST YOUR OWN NIGHT is a link, tilted off the button under it */
  a.btn{display:block; text-align:center; text-decoration:none; transform:rotate(1deg); text-wrap:balance;}
  .btn.compact{font-size:20px; padding:14px;}                      /* …and quieter mid-party */
  .hostnote{text-align:center;}
  button.btn:disabled{background:var(--panel); color:var(--slot); border-color:var(--slot);
    box-shadow:none; transform:none; cursor:default;}
  button.btn:active, a.btn:active{box-shadow:3px 3px 0 var(--shadow); translate:5px 5px;}
  .spacer{flex:1;}
  /* rows */
  .row{display:flex; align-items:center; gap:10px; padding:12px 18px; border-radius:14px;
    min-height:60px;}
  .row .name{font-size:34px; flex:1; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
  .row .rchip{font-size:17px; padding:5px 9px; border-radius:6px;}
  .row .count{font-size:46px;}
  .row .awaychip{background:#fff; color:var(--accentInk);}
  /* code boxes */
  .codeboxes{display:flex; gap:10px; justify-content:center;}
  .codebox{width:66px; height:90px; border-radius:10px; display:flex; align-items:center;
    justify-content:center; font-size:48px;}
  /* cards */
  .cards{display:flex; gap:6px; flex-wrap:wrap;}
  .card{width:64px; height:90px; border-radius:10px; padding:5px; display:flex;
    flex-direction:column; justify-content:space-between; cursor:pointer; flex:0 0 auto;
    touch-action:none; user-select:none; -webkit-user-select:none;
    border:3px solid var(--key); box-shadow:4px 4px 0 var(--shadow);}   /* every card is a die-cut sticker */
  .card .ci{display:flex; flex-direction:column; align-items:flex-start; line-height:1;}
  .card .r{font-size:22px; line-height:1;}
  .card .cs{font-size:17px; line-height:1;}                 /* corner suit, under the rank */
  .card .s{font-size:22px; text-align:right; line-height:1;}
  .card:not(.big) .s{display:none;}                          /* slot cards: corner index only */
  .card.big{width:80px; height:112px;}
  .card.big .r{font-size:30px;}
  .card.big .cs{font-size:20px;}
  .card.big .s{font-size:30px;}
  .card.wild{align-items:center; justify-content:center; text-align:center;}
  .card.dragclone{position:fixed; z-index:50; pointer-events:none; margin:0;
    border:4px solid #fff; box-shadow:6px 6px 0 var(--shadow);}
  .dropok{outline:4px solid var(--accent); outline-offset:3px;}
  .slotrow{display:flex; gap:10px; align-items:flex-start; flex-wrap:wrap;}
  /* slots hold five cards on one line; the tray is a fanned hand that fits the width */
  .slotgroup .cards{gap:5px; flex-wrap:nowrap;}
  .slotgroup .card, .slotgroup .empty{width:60px; height:84px;}
  #slots{display:flex; flex-direction:column; gap:8px; min-width:0; min-height:0;}
  #tray{flex-wrap:nowrap; column-gap:0; row-gap:10px; padding:8px 14px 14px; max-width:100%;}   /* padding holds tilt + shadow */
  .slotgroup{display:flex; flex-direction:column; gap:6px; padding:8px; border-radius:14px; max-width:100%; min-width:0;}
  .slotgroup.active{background:var(--accent);}
  .slotgroup .gl{font-size:17px; letter-spacing:.1em; display:flex; align-items:center; flex-wrap:wrap; row-gap:4px; max-width:100%; min-width:0;}
  /* Short phones: four hands plus the tray have to finish above the glass.
     Heights track SHOWDOWN-style budget: header and padding leave the rest for five rows of cards. */
  #app:has(#slots){container-type:size; padding:12px 16px 16px; gap:8px;}
  #app:has(#slots) #slots{flex:1 1 auto; gap:6px;}
  #app:has(#slots) .slotgroup{padding:6px; gap:4px;}
  #app:has(#slots) .slotgroup .cards{width:100%; min-width:0;}
  #app:has(#slots) .slotgroup .card, #app:has(#slots) .slotgroup .empty{
    flex:0 0 auto;
    width:min(56px, calc((100% - 20px) / 5));
    height:min(78px, calc((100cqh - 330px) / 5));}
  #app:has(#slots) #tray .card{
    width:min(58px, calc((100cqh - 330px) / 5.4));
    height:auto; aspect-ratio:64 / 90;}
  #foot{flex:0 0 auto; min-width:0; max-width:100%;}
  .readout{font-size:18px; background:var(--accent); color:var(--accentInk); border:3px solid #fff;
    padding:1px 9px; border-radius:999px; margin-left:8px; letter-spacing:0;}
  .empty{width:64px; height:90px; border:4px dashed var(--slot); border-radius:10px; flex:0 0 auto;}
  .empty.on{border-color:var(--accentInk);}
  /* showdown: one sticker row per player; the loser's floods pink with a LOSES stamp */
  .sdrow{position:relative; padding:6px 8px; border-radius:14px; display:flex; flex-direction:column; gap:6px;
    background:var(--panel); border:4px solid var(--key); box-shadow:5px 5px 0 var(--shadow);}
  .sdrow.lose{background:#FF3D7F;}
  .sdhead{display:flex; align-items:center; gap:10px;}
  .sdhead{flex-wrap:wrap; row-gap:6px;}
  .sdhead .stamp.losetag{margin-left:auto;}
  .sdrow .cards{gap:5px; flex-wrap:nowrap;}
  .sdrow .flip{width:48px; height:68px;}                    /* everyone's hand, at the app's reveal size */
  .sdrow .card .r{font-size:20px;} .sdrow .card .cs{font-size:17px;}
  .namechip, .tagchip{display:inline-block; font-size:18px; padding:3px 10px; border-radius:8px;
    border:3px solid var(--key); box-shadow:4px 4px 0 var(--shadow); white-space:nowrap;}
  .chips{display:flex; flex-wrap:wrap; gap:12px;}
  .namechip.away{background:var(--panel); color:var(--label);}
  /* lobby name chips tilt like the app's (Metric.nameChipTilts): neighbours never share one */
  .chips .namechip:nth-child(6n+1){rotate:-2deg;} .chips .namechip:nth-child(6n+2){rotate:3deg;}
  .chips .namechip:nth-child(6n+3){rotate:-1deg;} .chips .namechip:nth-child(6n+4){rotate:2deg;}
  .chips .namechip:nth-child(6n+5){rotate:-3deg;} .chips .namechip:nth-child(6n+6){rotate:1deg;}
  .gamecard{position:relative; padding:16px 18px; border-radius:14px; display:flex; flex-direction:column; gap:6px;
    rotate:-2deg;}
  .gamecard .gtitle{font-size:34px; line-height:1.05;}
  .gamecard .gblurb{font-size:17px; line-height:1.25;}
  /* the tag (.tagchip: accent fill, keyline) overhangs the card's top-right corner at its own tilt;
     a tagged card makes room for it above, and drops its title clear of it */
  .gamecard .gtag{position:absolute; top:-14px; right:14px; rotate:6deg;}
  .gamecard.tagged{margin-top:8px; padding-top:26px;}
  .colorkey{display:flex; align-items:center; justify-content:center; flex-wrap:wrap; gap:8px 10px;}
  .colorkey .keyword{font-size:20px; color:var(--label); margin-left:8px;}
  .colorkey .keyface{display:inline-flex; align-items:center; justify-content:center; width:40px; height:52px;
    font-size:24px; border:3px solid var(--key); border-radius:8px; box-shadow:3px 3px 0 var(--shadow);}
  .tagchip{background:var(--accent); color:var(--accentInk);}
  /* stamps: slapped on — they land by scale, never by fade */
  .stamp{display:inline-block; padding:8px 18px; border:4px solid var(--key); border-radius:14px;
    box-shadow:7px 7px 0 var(--shadow); text-align:center; line-height:1.05; white-space:nowrap;}
  .stamp.wrap{white-space:normal;}
  .land{animation:land .24s cubic-bezier(.3,1.5,.5,1) both;}
  .land.late{animation-delay:.4s;}
  @keyframes land{from{scale:1.18;} to{scale:1;}}
  @media (prefers-reduced-motion: reduce){ .land{animation:none;} }
  /* guess: the card in play, big, with its verdict stamped across its foot */
  .card.small{width:48px; height:68px;}
  .card.small .r{font-size:20px;}
  .card.hero, .flip.hero{width:124px; height:174px;}
  .card.hero .r{font-size:36px;} .card.hero .cs{font-size:26px;} .card.hero .s{display:block; font-size:52px;}
  .guess-hero{position:relative; height:196px; display:flex; justify-content:center;}
  .guess-hero .stamp{position:absolute; bottom:0; left:50%; translate:-50% 0;}
  .prompt{font-size:20px; text-align:center;}
  .givegrid{display:grid; gap:10px;}
  .givegrid button{font-family:inherit; min-height:60px; border:4px solid var(--key); border-radius:14px;
    box-shadow:6px 6px 0 var(--shadow); cursor:pointer; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
  .givegrid button:active{box-shadow:2px 2px 0 var(--shadow); translate:4px 4px;}
  .flip{width:64px; height:90px; flex:0 0 auto; perspective:600px;}
  .flip-inner{position:relative; width:100%; height:100%; transform-style:preserve-3d;
    transition:transform .34s ease; transform:rotateY(180deg);}
  .flip.up .flip-inner{transform:rotateY(0deg);}
  .flip.settled .flip-inner{transition:none;}               /* a re-render of a card already turned */
  .flip .face{position:absolute; inset:0; backface-visibility:hidden; -webkit-backface-visibility:hidden;}
  .flip .front{transform:rotateY(0deg);}
  .flip .back{transform:rotateY(180deg); display:flex; align-items:center; justify-content:center;
    background:var(--panel); color:var(--slot); border-radius:10px; font-size:30px;
    border:3px solid var(--key); box-shadow:4px 4px 0 var(--shadow);}
  /* verdict. The phone bands match SHOWDOWN in table.js: tight <=700, roomy >=900.
     The inline font-size is showdownLayout(); these rules keep the sticker's
     keyline, hard shadow and tilt inside that budget. */
  .verdict{font-size:clamp(40px,22vw,104px); background:#FF3D7F; color:#2A0011;
    border:5px solid #fff; border-radius:20px; padding:6px 18px; transform:rotate(-3deg);
    box-shadow:10px 10px 0 var(--shadow); text-align:center; line-height:.9;}
  .loseverb{font-size:32px; background:var(--accent); color:var(--accentInk); border:5px solid #fff;
    border-radius:12px; padding:4px 16px; transform:rotate(2deg); box-shadow:8px 8px 0 var(--shadow);
    margin-top:8px;}
  /* Padding keeps each row's hard shadow inside the scrollport, so a short
     column scrolls to a whole sticker instead of slicing the last border. */
  #sd{display:flex; flex-direction:column; gap:6px; overflow-y:auto; flex:1; min-height:0; padding:2px 8px 8px 2px;}
  #app:has(#sd){container-type:size; padding:12px 16px 26px; gap:8px;}
  #app:has(#sd) .sdrow{padding:4px 6px; gap:4px;}
  #app:has(#sd) .sdrow .flip{width:44px; height:60px;}
  #app:has(#sd) .sdverdict{flex:0 0 auto; gap:0;}
  @media (max-height:700px){
    #app:has(#sd){padding:10px 14px 22px; gap:6px;}
    /* Four hands have to finish above the verdict. Card height tracks the
       phone (SHOWDOWN.tight): 44px on a 659 journey, a hair taller on 667. */
    #app:has(#sd) .sdrow{gap:2px;}
    #app:has(#sd) .sdrow .flip{
      width:auto; aspect-ratio:32 / 44;
      height:clamp(44px, calc((100cqh - 484px) / 4), 48px);}
    #app:has(#sd) .sdrow .card{padding:2px 3px;}
    #app:has(#sd) .sdrow .card .r,
    #app:has(#sd) .sdrow .card .cs{font-size:17px;}
    #app:has(#sd) .verdict{padding:4px 14px; box-shadow:8px 8px 0 var(--shadow);}
    #app:has(#sd) .loseverb{font-size:22px; margin-top:6px; padding:4px 14px; box-shadow:6px 6px 0 var(--shadow);}
  }
  @media (min-height:900px){
    .verdict{font-size:clamp(64px,26vw,120px); border-width:6px; padding:8px 24px; box-shadow:14px 14px 0 var(--shadow);}
    .loseverb{font-size:44px; padding:6px 22px; margin-top:14px;}
    #app:has(#sd){padding:22px 22px 40px; gap:16px;}
    #sd{gap:10px;}
    #app:has(#sd) .sdrow{padding:6px 8px; gap:6px;}
    #app:has(#sd) .sdrow .flip{width:48px; height:68px;}
  }
  .center{display:flex; flex-direction:column; align-items:center; justify-content:center; gap:12px; flex:1;}
  /* modal */
  #modal{position:fixed; inset:0; background:rgba(10,4,30,.85); display:none;
    align-items:center; justify-content:center; padding:20px; z-index:10;}
  #modal .sheet{background:var(--table); border:4px solid #fff; border-radius:20px; padding:20px;
    max-width:420px; width:100%; display:flex; flex-direction:column; gap:14px;}
  .pick{display:flex; flex-wrap:wrap; gap:6px;}
  .pick button{font-family:inherit; font-size:20px; width:46px; height:46px; border-radius:8px;
    border:none; background:var(--panel); color:var(--label); cursor:pointer;}
  .pick button.sel{background:var(--accent); color:var(--accentInk);}
  .suitpick button{width:56px; height:56px; font-size:26px; border:4px solid transparent;}
  .suitpick button.sel{border-color:#fff;}
  /* connection banner (conn-ui.js): a sticker strip pinned over the game */
  .connbanner{display:flex; justify-content:space-between; gap:12px; padding:10px 14px;
    border-radius:14px; background:var(--accent); color:var(--accentInk); font-size:20px; rotate:-1deg;}
  /* blocked taps: dashed keyline + label swap, never a fade */
  button.btn.wait{border-style:dashed; background:var(--panel); color:var(--label); border-color:var(--label);}
  /* Beats button.btn:disabled (slot on panel, one wrapping line). */
  button.btn.locked:disabled{background:var(--panel); color:#fff; border-color:#fff;
    box-shadow:none; transform:none; display:flex; flex-direction:column; align-items:center;
    justify-content:center; gap:2px; line-height:1.1; padding:14px 16px; cursor:default;}
  button.btn.locked:disabled .lockready{color:var(--label); font-size:17px; letter-spacing:.04em;}
  .tally{display:flex; flex-wrap:wrap; gap:12px; padding:8px 2px 12px;}
  button.wait{border-style:dashed; background:var(--panel); color:var(--label); border-color:var(--label);}   /* the Guess give grid too */
  /* replay (replay.html): a shared Flips hand — the board peels, the sweat chart draws,
     one sticker row per seat with its live win %; stamps land at the end */
  .rhead{min-height:76px; display:flex; flex-direction:column; align-items:flex-start; justify-content:center; gap:8px;}
  .rboard{display:flex; gap:6px;}
  .rboard .flip{width:min(64px, calc((100% - 24px) / 5)); height:auto; aspect-ratio:64 / 90;}
  .rboard .card, .rseat .card{cursor:default; touch-action:auto;}   /* nothing to drag: let the page scroll */
  .rchart svg{display:block; overflow:visible;}
  .rchart text{font-family:inherit; font-size:17px; fill:var(--label);}
  .rchart .grid{stroke:var(--slot); stroke-width:1;}
  .rchart .seg{fill:none; stroke-linecap:round; stroke-linejoin:round;}
  .rchart .seg.grow{stroke-dasharray:var(--len); stroke-dashoffset:var(--len); animation:draw .6s ease-out forwards;}
  @keyframes draw{to{stroke-dashoffset:0;}}
  @media (prefers-reduced-motion: reduce){ .rchart .seg.grow{animation:none; stroke-dashoffset:0;} }
  .rseats{display:flex; flex-direction:column; gap:12px;}
  .rseat{padding:8px 10px; border-radius:14px; display:flex; flex-direction:column; gap:8px;
    background:var(--panel); border:4px solid var(--key); box-shadow:5px 5px 0 var(--shadow);}
  .rseat:nth-child(odd){rotate:-.6deg;} .rseat:nth-child(even){rotate:.6deg;}
  .rseat .rtop{display:flex; align-items:center; gap:10px; flex-wrap:wrap;}
  .rseat .pct{margin-left:auto; font-size:28px;}
  .rseat .cards{gap:5px; flex-wrap:nowrap;}
  .rseat > .stamp{align-self:flex-start;}
