  /* Robn glass design system.
     Web glassmorphism approximation (not Apple's native Liquid Glass).
     Brand locked: lime #c8f135 accent, court-green darks, Syne + DM Sans.
     Radius system: sheets 28px (top), cards 20px, controls 12px, chips/pills 999px.
     Blur budget: backdrop-filter only on major surfaces (live cards, dock,
     sheets, overlays). Repeated small cards use translucent fills, no blur. */
  *,*::before,*::after{box-sizing:border-box;margin:0;padding:0;}
  /* author `display` rules outrank the UA sheet's [hidden]{display:none} */
  [hidden]{display:none !important;}
  :root{
    --court:#1a472a;--court-light:#2d6a42;--lime:#c8f135;--white:#f5f5f0;--muted:#93a48e;--dark:#0b100a;--card:#1e2b1f;
    --glass:rgba(255,255,255,.055);
    --glass-strong:rgba(255,255,255,.085);
    --glass-brd:rgba(255,255,255,.10);
    --glass-edge:rgba(255,255,255,.14);
    --glass-green:rgba(45,106,66,.26);
    --lime-tint:rgba(200,241,53,.12);
    --ink:rgba(8,12,7,.35);
    --ease:cubic-bezier(.32,.72,0,1);
    --r-sheet:28px;--r-card:20px;--r-btn:14px;--r-ctl:12px;--r-chip:8px;--r-pill:999px;
    /* Spacing scale, read off what the app already does rather than imposed on
       it: 14px and 10px account for over a third of every margin and padding in
       here, with 18, 7, 9 and 22 behind them. Before this the system had radii
       and colours but no spacing at all, so every gap was a fresh number and one
       relationship drifted to 26 / 28 / 30px across three pages. Pick from here;
       add a step rather than inventing a value between two. Rules written before
       this still carry their literals — retrofitting all 600-odd of them would
       move every screen, so the scale is what new and edited code reaches for
       and a step with no caller yet is documentation, not dead weight. */
    --s-1:4px;--s-2:7px;--s-3:10px;--s-4:14px;--s-5:18px;--s-6:22px;--s-7:28px;--s-8:36px;--s-9:48px;
    /* Page shell. The run-in above a page's title used to be 12px on results,
       28px on the viewer and 36px on setup, help and journal. */
    --page-pad-x:16px;--page-pad-top:36px;
    /* Line heights. There were seventeen distinct values in use, eight of them
       between 1.3 and 1.65 — near-identical numbers doing the same job. Four
       steps now; 1 and 0 stay literal because they are resets, not rhythm. */
    --lh-display:1.1;--lh-heading:1.25;--lh-snug:1.4;--lh-body:1.6;
    --fs-body:13.5px;--fs-sm:12px;
    --brand-size:30px;
  }
  html{overflow-x:hidden;touch-action:manipulation;}
  body{background:var(--dark);color:var(--white);font-family:'DM Sans',sans-serif;font-size:16px;line-height:var(--lh-body);min-height:100vh;overflow-x:hidden;padding:env(safe-area-inset-top) env(safe-area-inset-right) calc(80px + env(safe-area-inset-bottom)) env(safe-area-inset-left);-webkit-tap-highlight-color:transparent;touch-action:manipulation;}
  /* ambient court-green mesh the glass refracts; fixed + inert so it never repaints on scroll */
  body::before{content:'';position:fixed;inset:0;z-index:-1;pointer-events:none;background:
    radial-gradient(120% 90% at 85% -10%,rgba(45,106,66,.55),transparent 60%),
    radial-gradient(90% 70% at -15% 30%,rgba(26,71,42,.65),transparent 55%),
    radial-gradient(70% 60% at 70% 105%,rgba(200,241,53,.07),transparent 60%),
    var(--dark);}

  /* SHARED SURFACES & CONTROLS — the idioms every screen reaches for, declared
     once. Each rule holds only what every member declares alike; sizes, radii
     that differ, spacing and transitions stay with the member in its own
     section below, where a later declaration of the same property wins as
     usual. Selector lists rather than utility classes, because the markup
     already names things by what they do — .lime-btn is the one hook for
     markup with no name of its own (help.html). The viewer's selectors sit in
     these lists too: styles.css is the sheet every surface loads, so
     viewer.css keeps nothing but the TV's scale. */
  /* the solid lime action */
  .lime-btn,.setup-next,.setup-start,.confirm-btn,.round-continue-btn,.cm-go,.play-again-btn,.board-shuffle,.roster-add-btn,.ce-btn,.photo-modal-cta,.ks-go{background:var(--lime);color:var(--dark);border:none;border-radius:var(--r-ctl);font-family:'Syne',sans-serif;font-weight:800;text-transform:uppercase;cursor:pointer;}
  .setup-start:hover,.confirm-btn:hover,.photo-modal-cta:hover{opacity:.9;}
  .setup-start:active,.confirm-btn:active,.round-continue-btn:active,.play-again-btn:active,.board-shuffle:active,.photo-modal-cta:active{transform:scale(.98);}
  /* the quiet glass action beside it */
  .setup-back,.modal-cancel,.end-btn,.copy-btn{background:var(--glass);color:var(--muted);border:1px solid var(--glass-brd);font-family:'Syne',sans-serif;font-size:13px;font-weight:700;text-transform:uppercase;cursor:pointer;}
  /* the blurred glass card: a live court, the leaderboard, the points table, the TV's court */
  .game-card,.pts-bar,.final-table-wrap,.v-court{background:var(--glass);border:1px solid var(--glass-brd);border-radius:var(--r-card);overflow:hidden;backdrop-filter:blur(20px) saturate(1.5);-webkit-backdrop-filter:blur(20px) saturate(1.5);box-shadow:inset 0 1px 0 rgba(255,255,255,.10),0 16px 44px var(--ink);}
  /* and its labelled head */
  .pts-bar-head,.final-table-head,.game-log-head,.v-court-head{background:var(--glass-green);border-bottom:1px solid var(--glass-brd);font-family:'Syne',sans-serif;font-weight:700;text-transform:uppercase;color:var(--lime);}
  /* the small flat glass card: a name row, a court number, a podium slot, an award tile, a stat */
  .name-row,.court-id,.pod,.bt,.stat-card{background:var(--glass);border:1px solid var(--glass-brd);border-radius:var(--r-ctl);box-shadow:inset 0 1px 0 rgba(255,255,255,.07);}
  /* the bottom sheet */
  .modal-box,.round-box,.board-box{border:1px solid var(--glass-edge);border-bottom:none;border-radius:var(--r-sheet) var(--r-sheet) 0 0;width:100%;max-width:600px;backdrop-filter:blur(24px) saturate(1.6);-webkit-backdrop-filter:blur(24px) saturate(1.6);box-shadow:inset 0 1px 0 rgba(255,255,255,.14),0 -18px 60px rgba(0,0,0,.45);}
  /* the × on a sheet's head */
  .aw-close,.board-close{background:transparent;border:none;color:var(--muted);line-height:1;cursor:pointer;padding:0 4px;}
  /* the tables: live leaderboard, round report, points table */
  table.lb-table,table.round-lb,table.final-table{width:100%;border-collapse:collapse;}
  table.lb-table th,table.round-lb th,table.final-table th{text-transform:uppercase;color:var(--muted);text-align:left;border-bottom:1px solid var(--glass-brd);}
  table.lb-table td,table.round-lb td,table.final-table td{border-bottom:1px solid rgba(255,255,255,.05);}
  table.lb-table tr:last-child td,table.round-lb tr:last-child td,table.final-table tr:last-child td{border-bottom:none;}
  table.lb-table th:not(:first-child),table.round-lb th:not(:first-child),table.final-table th:not(:first-child),table.lb-table td:not(:first-child),table.round-lb td:not(:first-child),table.final-table td:not(:first-child){text-align:center;}
  /* the VS chip between two sides */
  .vs-center,.cm-vs,.v-vs{font-family:'Syne',sans-serif;font-size:12px;font-weight:800;color:var(--lime);background:rgba(8,14,8,.45);border:1px solid var(--glass-brd);border-radius:9px;padding:6px 8px;}
  /* the side you tap to say who won: a team on a court, a player at the table */
  .win-btn,.catan-player-btn{background:rgba(8,14,8,.4);border:1px solid var(--glass-brd);color:var(--white);cursor:pointer;display:flex;align-items:center;box-shadow:inset 0 1px 0 rgba(255,255,255,.06);}
  .win-btn:hover:not(:disabled),.catan-player-btn:hover:not(:disabled){background:var(--glass-green);border-color:var(--glass-edge);}
  .win-btn:disabled,.catan-player-btn:disabled{cursor:default;}
  .win-btn.selected,.catan-player-btn.selected{background:var(--lime-tint);border-color:var(--lime);}
  .win-btn.unselected,.catan-player-btn.unselected{background:rgba(8,14,8,.3);border-color:rgba(255,255,255,.04);opacity:.4;}
  /* the score box: points on a court, victory points at the table */
  .score-inp,.vp-inp{width:100%;background:rgba(8,14,8,.4);border:1px solid var(--glass-brd);color:var(--white);font-family:'Syne',sans-serif;font-weight:800;text-align:center;outline:none;transition:border-color .2s var(--ease);}
  .score-inp:focus,.vp-inp:focus{border-color:var(--lime);}
  .score-inp.winning-inp,.vp-inp.winning-inp{border-color:var(--glass-edge);}
  /* a name as a chip: remembered players, the custom-match pool, the finish-time presets */
  .name-chip,.cm-chip,.fb-chip{background:var(--glass);border:1px solid var(--glass-edge);color:var(--white);font-family:'DM Sans',sans-serif;font-size:14px;font-weight:600;border-radius:var(--r-pill);padding:8px 16px;cursor:pointer;}
  .name-chip:hover,.cm-chip:hover,.fb-chip:hover{border-color:var(--lime);}
  .name-chip:active,.cm-chip:active,.fb-chip:active{transform:scale(.95);}
  /* the two small controls on the live label row share its chip shape */
  .fx-toggle,.roster-btn{margin-left:auto;background:rgba(8,14,8,.45);border:1px solid var(--glass-brd);border-radius:var(--r-chip);padding:5px 9px;cursor:pointer;}
  /* the quiet underlined link that skips or discards */
  .skip-btn,.end-discard-btn{background:none;border:none;cursor:pointer;text-decoration:underline;transition:color .2s var(--ease);}
  .skip-btn:hover,.end-discard-btn:hover{color:#e08080;}

  /* SETUP */
  #setup-screen{padding:var(--page-pad-top) var(--page-pad-x) 60px;}
  .setup-inner{max-width:600px;margin:0 auto;}
  /* Step one is the app's front door and holds still: it sizes itself to the
     viewport minus the dock and does not scroll, so the two sports fill the
     height the marketing footer used to take rather than leaving half a screen
     of dead green under the Next button. `.fit` is hung on the screen only
     while step one is showing — twelve name fields cannot be made to fit and
     must keep scrolling, so every later step returns to ordinary flow. */
  #setup-screen.fit{height:calc(100dvh - 80px - env(safe-area-inset-top) - env(safe-area-inset-bottom));padding-bottom:var(--s-4);display:flex;flex-direction:column;overflow:hidden;}
  /* column all the way down, so `flex:1` sizes heights rather than widths and
     the `min-height:0` chain actually lets the cards give way on a short screen */
  #setup-screen.fit .setup-inner,#setup-screen.fit #step-body{flex:1;display:flex;flex-direction:column;min-height:0;width:100%;}
  #setup-screen.fit .brand-tagline,#setup-screen.fit .step-labels{margin-bottom:var(--s-5);}
  #setup-screen.fit .setup-title{margin-bottom:var(--s-4);}
  #setup-screen.fit .game-list{flex:1;min-height:0;justify-content:center;margin-bottom:var(--s-5);}
  body.setup-locked{overflow-y:hidden;}
  /* On a short phone the chrome is what gets trimmed, not the figures: the
     wordmark, the stepper and the card padding all give way first, and below
     680px the tagline goes too, because the sport you are picking says more
     than a line describing the app does. */
  @media (max-height:760px){
    #setup-screen.fit{padding-top:var(--s-6);}
    #setup-screen.fit .brand{font-size:26px;}
    #setup-screen.fit .brand-tagline{font-size:13px;margin-bottom:var(--s-4);}
    #setup-screen.fit .step-labels{margin-bottom:var(--s-4);}
    #setup-screen.fit .setup-title{font-size:18px;margin-bottom:var(--s-3);}
    #setup-screen.fit .game-list{margin-bottom:var(--s-4);}
    #setup-screen.fit .game-row{padding:var(--s-4);gap:var(--s-3);}
  }
  @media (max-height:680px){
    #setup-screen.fit .brand-tagline{display:none;}
  }
  /* A phone on its side has no height to hold a front door at any size, so it
     goes back to scrolling rather than clipping Next off the bottom edge. */
  @media (max-height:520px){
    #setup-screen.fit{height:auto;overflow:visible;padding-bottom:60px;}
    #setup-screen.fit .game-list{flex:none;}
    body.setup-locked{overflow-y:auto;}
  }
  /* One wordmark. It was declared three times over — identically in CSS but
     divergently in markup, so setup shouted RO-BN while help and journal
     whispered ro-b-n. Uppercased here rather than in the markup so no page can
     opt out of it by typing the letters differently. */
  .brand{text-align:center;font-family:'Syne',sans-serif;font-size:var(--brand-size);font-weight:800;letter-spacing:.02em;line-height:var(--lh-display);text-transform:uppercase;margin:0 0 var(--s-1);}
  .brand span{color:var(--lime);}
  .brand-tagline{text-align:center;color:var(--muted);font-size:14px;line-height:var(--lh-body);margin:0 0 var(--s-7);}
  .step-track{display:flex;align-items:center;justify-content:center;margin-bottom:6px;}
  .step-dot{width:28px;height:28px;border-radius:50%;border:1.5px solid var(--glass-brd);background:var(--glass);color:var(--muted);font-family:'Syne',sans-serif;font-size:12px;font-weight:800;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:all .25s var(--ease);}
  .step-dot.active{border-color:var(--lime);color:var(--lime);background:var(--lime-tint);box-shadow:inset 0 1px 0 rgba(255,255,255,.12);}
  .step-dot.done{border-color:var(--lime);color:var(--dark);background:var(--lime);}
  .step-bar{flex:1;height:2px;background:var(--glass-brd);max-width:70px;transition:background .25s var(--ease);}
  .step-bar.done{background:var(--lime);}
  .step-labels{display:flex;justify-content:space-between;padding:0 4px;font-size:11px;color:var(--muted);letter-spacing:.06em;text-transform:uppercase;margin-bottom:28px;}
  /* a seventh step's worth of labels does not fit a 375px phone at 11px */
  .step-labels.tight{font-size:9.5px;letter-spacing:.01em;padding:0;}
  .setup-title{font-family:'Syne',sans-serif;font-size:20px;font-weight:800;text-align:center;margin-bottom:20px;}
  .game-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:9px;margin-bottom:28px;}
  .game-card-s{display:flex;flex-direction:column;align-items:center;justify-content:flex-start;min-width:0;background:var(--glass);border:1px solid var(--glass-brd);border-radius:16px;padding:18px 7px;text-align:center;cursor:pointer;transition:border-color .25s var(--ease),background .25s var(--ease),transform .18s var(--ease);user-select:none;-webkit-tap-highlight-color:transparent;box-shadow:inset 0 1px 0 rgba(255,255,255,.08),0 8px 24px var(--ink);}
  .game-card-s:hover{border-color:var(--glass-edge);background:var(--glass-strong);}
  .game-card-s:active{transform:scale(.97);}
  .game-card-s.selected{border-color:var(--lime);background:var(--lime-tint);}
  .game-icon{margin-bottom:8px;display:flex;justify-content:center;align-items:center;height:42px;}
  .game-icon svg{display:block;max-width:100%;}
  .game-name{font-family:'Syne',sans-serif;font-weight:800;font-size:13.5px;letter-spacing:-.01em;line-height:var(--lh-display);}
  .game-desc{font-size:11px;color:var(--muted);margin-top:5px;line-height:var(--lh-heading);min-height:2.6em;display:flex;align-items:center;justify-content:center;text-wrap:balance;}
  @media(max-width:380px){.game-card-s{padding:16px 5px;}.game-name{font-size:12px;}.game-desc{font-size:10.5px;}}
  @media(max-width:340px){.game-name{font-size:11px;letter-spacing:-.02em;}}
  /* Game picker: two cards that share whatever height step one has left, with
     the figure standing in the middle of its own square rather than pinned to
     a 46px chip at the left edge. The figure is sized off the viewport and set
     to shrink, so it takes the room a tall phone gives it and gives it back on
     a short one instead of pushing Next off the bottom. */
  .game-list{display:flex;flex-direction:column;gap:var(--s-3);margin-bottom:var(--s-7);}
  .game-row{position:relative;flex:1;min-height:0;max-height:420px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--s-4);width:100%;text-align:center;background:var(--glass);border:1px solid var(--glass-brd);border-radius:var(--r-card);padding:var(--s-6) var(--s-5);cursor:pointer;color:var(--white);font-family:inherit;transition:border-color .25s var(--ease),background .25s var(--ease),transform .18s var(--ease);user-select:none;-webkit-tap-highlight-color:transparent;box-shadow:inset 0 1px 0 rgba(255,255,255,.08),0 8px 24px var(--ink);}
  .game-row:hover{border-color:var(--glass-edge);background:var(--glass-strong);}
  .game-row:active{transform:scale(.99);}
  .game-row.selected{border-color:var(--lime);background:var(--lime-tint);}
  .game-row-ic{flex:0 1 auto;min-height:0;height:clamp(72px,15vh,160px);aspect-ratio:1;display:flex;align-items:center;justify-content:center;background:rgba(8,14,8,.5);border:1px solid var(--glass-brd);border-radius:var(--r-card);transition:border-color .25s var(--ease),background .25s var(--ease);}
  /* 64% of the tile, so the padding around the figure grows with the tile */
  .game-row-ic svg{display:block;width:64%;height:64%;}
  .game-row.selected .game-row-ic{border-color:rgba(200,241,53,.32);background:rgba(200,241,53,.07);}
  .game-row-txt{flex:0 0 auto;min-width:0;display:flex;flex-direction:column;gap:var(--s-1);}
  .game-row-name{font-family:'Syne',sans-serif;font-weight:800;font-size:clamp(18px,5vw,24px);letter-spacing:-.01em;line-height:var(--lh-display);}
  .game-row-desc{font-size:13px;color:var(--muted);line-height:var(--lh-heading);}
  .game-row-mark{position:absolute;top:var(--s-4);right:var(--s-4);width:22px;height:22px;border-radius:50%;border:2px solid var(--glass-edge);transition:border-color .25s var(--ease),background .25s var(--ease);}
  .game-row.selected .game-row-mark{border-color:var(--lime);background:var(--lime);}
  .game-row.selected .game-row-mark::after{content:'';position:absolute;left:6px;top:2.5px;width:6px;height:11px;border:solid var(--dark);border-width:0 2.5px 2.5px 0;transform:rotate(45deg);}
  .count-control{display:flex;align-items:center;justify-content:center;gap:28px;margin:24px 0 12px;}
  .count-btn{width:52px;height:52px;border-radius:50%;background:var(--glass-strong);border:1px solid var(--glass-edge);color:var(--white);font-size:26px;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:border-color .2s var(--ease),transform .15s var(--ease);box-shadow:inset 0 1px 0 rgba(255,255,255,.14),0 6px 18px var(--ink);}
  .count-btn:hover:not(:disabled){border-color:var(--lime);}
  .count-btn:active:not(:disabled){transform:scale(.94);}
  .count-btn:disabled{opacity:.3;cursor:default;}
  .count-num{font-family:'Syne',sans-serif;font-size:72px;font-weight:800;color:var(--lime);line-height:1;min-width:80px;text-align:center;text-shadow:0 0 40px rgba(200,241,53,.25);}
  .count-note{text-align:center;color:var(--muted);font-size:14px;min-height:20px;margin-bottom:28px;}
  .flow-note{font-size:13px;line-height:var(--lh-body);margin-top:-10px;}
  .name-list{display:flex;flex-direction:column;gap:10px;margin-bottom:10px;}
  .name-row{display:flex;align-items:center;gap:12px;padding:10px 16px;transition:border-color .2s var(--ease);}
  .name-row:focus-within{border-color:var(--glass-edge);background:var(--glass-strong);}
  .name-num{font-family:'Syne',sans-serif;font-weight:800;font-size:13px;color:var(--muted);min-width:18px;}
  .name-inp{flex:1;min-width:0;background:transparent;border:none;color:var(--white);font-size:16px;font-family:'DM Sans',sans-serif;font-weight:500;outline:none;}
  .name-inp::placeholder{color:#4c5c4e;}
  .name-error{font-size:12px;color:#e08080;text-align:center;min-height:18px;margin-bottom:10px;}
  /* Court numbers: the same glass row as a name, but the value is short and is
     the thing being read, so it takes the display face and the label shrinks. */
  .court-id-list{display:grid;grid-template-columns:repeat(auto-fit,minmax(132px,1fr));gap:var(--s-3);margin-bottom:var(--s-3);}
  .court-id{display:flex;align-items:center;gap:var(--s-3);padding:var(--s-3) var(--s-4);transition:border-color .2s var(--ease),background .2s var(--ease);}
  .court-id:focus-within{border-color:var(--glass-edge);background:var(--glass-strong);}
  .court-id-lbl{font-family:'Syne',sans-serif;font-weight:800;font-size:10px;letter-spacing:.12em;text-transform:uppercase;color:var(--muted);}
  .court-id-inp{flex:1;min-width:0;background:transparent;border:none;color:var(--white);font-family:'Syne',sans-serif;font-weight:800;font-size:20px;line-height:var(--lh-display);outline:none;}
  .lineup-list{display:flex;flex-wrap:wrap;gap:10px;justify-content:center;margin-bottom:20px;}
  .lineup-chip{background:var(--lime-tint);border:1.5px solid var(--lime);color:var(--lime);font-family:'DM Sans',sans-serif;font-size:15px;font-weight:600;border-radius:var(--r-pill);padding:10px 18px;cursor:pointer;transition:all .2s var(--ease);box-shadow:inset 0 1px 0 rgba(255,255,255,.1);}
  .lineup-chip:active{transform:scale(.96);}
  .lineup-chip.benched{background:var(--glass);border-color:var(--glass-brd);color:var(--muted);text-decoration:line-through;box-shadow:none;}
  .serve-line{display:flex;align-items:center;justify-content:center;gap:8px;background:rgba(8,14,8,.45);border:1px solid var(--glass-brd);border-radius:10px;padding:7px 12px;margin:10px 0 0;font-size:14px;color:var(--white);}
  .serve-line .serve-tag{font-family:'Syne',sans-serif;font-size:10px;font-weight:800;letter-spacing:.1em;text-transform:uppercase;color:var(--dark);background:var(--lime);border-radius:6px;padding:3px 7px;}
  .serve-line b{color:var(--lime);font-weight:700;}
  .setup-nav{display:flex;flex-direction:column;gap:10px;}
  .setup-nav.two{flex-direction:row;}
  .setup-next{font-size:14px;padding:14px;flex:1;letter-spacing:.06em;transition:opacity .2s var(--ease),transform .15s var(--ease);box-shadow:0 8px 24px rgba(200,241,53,.18);}
  .setup-next:disabled{opacity:.3;cursor:default;box-shadow:none;}
  .setup-next:not(:disabled):hover{opacity:.9;}
  .setup-next:not(:disabled):active{transform:scale(.98);}
  .setup-back{border-radius:var(--r-ctl);font-size:clamp(12px,3.4vw,14px);padding:14px 10px;flex:1;white-space:nowrap;transition:border-color .2s var(--ease),transform .15s var(--ease);}
  .setup-back:hover{border-color:var(--glass-edge);}
  .setup-back:active{transform:scale(.98);}
  /* fluid + balanced so "Start Tournament 🏆" never breaks the trophy onto its own line */
  .setup-start{font-size:clamp(12.5px,3.6vw,15px);padding:16px 12px;flex:2;letter-spacing:.03em;text-wrap:balance;line-height:var(--lh-heading);transition:opacity .2s var(--ease),transform .15s var(--ease);box-shadow:0 8px 24px rgba(200,241,53,.18);}
  .setup-context{display:flex;align-items:center;justify-content:center;gap:7px;margin:0 auto 22px;background:var(--glass);border:1px solid var(--glass-brd);border-radius:var(--r-pill);padding:6px 15px;font-size:13px;font-weight:600;width:fit-content;box-shadow:inset 0 1px 0 rgba(255,255,255,.08);}
  .setup-context svg{display:block;}
  .setup-context .ctx-sep{color:#4c5c4e;}
  .setup-context .ctx-val{color:var(--lime);}
  .courts-note{line-height:var(--lh-snug);}
  .courts-note .warn{color:#e0b070;}
  .courts-note .ok{color:var(--muted);}
  /* The lime chip — a court tag, an Up Next court number, a viewer tag. It was
     written out three times across two files, alike but for the font size, so
     the viewer's copy was free to drift away from the app's. One rule, sizes
     below. The viewer selectors live here rather than in viewer.css because
     styles.css is the sheet every surface loads. */
  .court-tag,.upnext-game,.v-upnext-court,.v-upnext-tag{font-family:'Syne',sans-serif;font-weight:800;letter-spacing:.1em;text-transform:uppercase;color:var(--lime);background:rgba(8,14,8,.45);border:1px solid var(--glass-brd);border-radius:var(--r-chip);padding:var(--s-1) 9px;}
  .court-tag{font-size:11px;}
  .upnext-game,.v-upnext-court,.v-upnext-tag{font-size:10px;}
  .upnext-game,.v-upnext-court,.v-upnext-tag{white-space:nowrap;flex-shrink:0;}
  /* the courts column and the Up Next divider, shared with the viewer for the
     same reason */
  #courts-container,#v-courts{display:flex;flex-direction:column;gap:var(--s-4);}
  .upnext-row+.upnext-row,.v-upnext-row+.v-upnext-row{border-top:1px solid rgba(255,255,255,.06);}
  .waiting-line{margin-top:14px;text-align:center;font-size:12px;color:var(--muted);}
  .waiting-line .name{color:#c0b080;font-weight:600;}
  .waiting-line .wait-eta{white-space:nowrap;}

  /* UP NEXT — the on-deck round, drawn the moment the current one starts.
     Dashed border reads as "not live yet"; the live cards keep the solid glass. */
  .upnext-wrap,.v-upnext{margin-top:14px;background:rgba(17,26,17,.5);border:1.5px dashed rgba(200,241,53,.32);border-radius:var(--r-card);}
  .upnext-wrap{padding:12px 16px 13px;}
  .upnext-head,.v-upnext-head{display:flex;align-items:center;font-family:'Syne',sans-serif;font-weight:800;letter-spacing:.15em;text-transform:uppercase;color:var(--lime);margin-bottom:4px;}
  .upnext-head{gap:7px;font-size:11px;}
  .upnext-head .upnext-sub{margin-left:auto;font-family:'DM Sans',sans-serif;font-size:11px;font-weight:500;letter-spacing:.04em;color:var(--muted);text-transform:none;}
  /* when the round starts — right-aligned on its own, trailing the game range
     when there is one, gone entirely when no court is running a clock */
  .upnext-head .upnext-eta,.v-upnext-eta{margin-left:auto;font-family:'DM Sans',sans-serif;font-weight:500;letter-spacing:.04em;color:var(--white);text-transform:none;white-space:nowrap;}
  .upnext-head .upnext-eta{font-size:11px;}
  .upnext-head .upnext-sub+.upnext-eta{margin-left:0;}
  .upnext-head .upnext-eta:empty{display:none;}
  .upnext-row,.v-upnext-row{display:flex;align-items:center;}
  .upnext-row{gap:12px;padding:9px 0;}
  .upnext-match,.v-upnext-match{display:flex;align-items:center;flex-wrap:wrap;font-weight:600;color:var(--white);line-height:var(--lh-snug);}
  .upnext-match{gap:9px;font-size:14.5px;}
  .upnext-team{white-space:nowrap;}
  .upnext-vs,.v-upnext-vs{font-family:'Syne',sans-serif;font-weight:800;color:var(--lime);opacity:.85;}
  .upnext-vs{font-size:10px;}
  .upnext-sits,.v-upnext-sits{margin-top:6px;border-top:1px solid rgba(255,255,255,.06);color:var(--muted);}
  .upnext-sits{padding-top:9px;font-size:12px;}
  .upnext-sits .name{color:#c0b080;font-weight:600;}

  /* court finished, waiting for the round to close */
  .live-card.done{border-color:rgba(200,241,53,.22);}
  .done-body{padding:14px;display:flex;flex-direction:column;gap:11px;}
  .done-result{font-size:14.5px;color:var(--white);}
  .done-result b{color:var(--lime);}
  .done-check{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;border-radius:50%;background:var(--lime);color:var(--dark);font-size:12px;font-weight:800;margin-right:9px;vertical-align:-4px;}
  .done-score{color:var(--muted);margin-left:7px;font-weight:600;}
  .done-upnext,.v-done-next{background:rgba(8,14,8,.4);border:1.5px dashed rgba(200,241,53,.3);border-radius:var(--r-ctl);}
  .done-upnext{padding:11px 13px;}
  .done-upnext-label{font-family:'Syne',sans-serif;font-size:9.5px;font-weight:800;letter-spacing:.13em;text-transform:uppercase;color:var(--lime);margin-bottom:6px;}
  .done-upnext-match{display:flex;align-items:center;gap:9px;flex-wrap:wrap;font-size:15px;font-weight:600;color:var(--white);line-height:var(--lh-snug);}
  .done-wait{display:flex;align-items:center;gap:8px;font-size:12px;color:var(--muted);flex-wrap:wrap;}
  /* the estimate leads, the measured elapsed sits behind it — the model can be
     wrong but the clock never is, so the verifiable number stays on screen */
  .done-wait-main{color:var(--white);font-weight:500;}
  .done-wait-sub{color:var(--muted);opacity:.72;}
  .done-wait-sub::before{content:'\00b7';margin-right:6px;opacity:.6;}
  .done-wait-dot{width:7px;height:7px;border-radius:50%;background:#c0b080;animation:pulse 1.2s ease-in-out infinite;flex-shrink:0;}

  /* GAME SCREEN */
  #game-screen{padding:28px 16px 80px;}
  header{text-align:center;margin-bottom:28px;}
  .eyebrow{font-size:11px;letter-spacing:.2em;text-transform:uppercase;color:var(--lime);font-weight:600;margin-bottom:10px;}
  h1{font-family:'Syne',sans-serif;font-size:clamp(1.8rem,7vw,3rem);font-weight:800;line-height:1;letter-spacing:-.02em;}
  h1 span{color:var(--lime);}
  .subtitle{margin-top:8px;color:var(--muted);font-size:14px;}
  .live-wrap{max-width:600px;margin:0 auto 20px;}
  .live-label{display:flex;align-items:center;gap:8px;font-size:11px;letter-spacing:.15em;text-transform:uppercase;color:var(--lime);font-weight:700;margin-bottom:10px;}
  .fx-toggle{font-size:15px;line-height:1;}
  .fx-toggle[aria-pressed="false"]{opacity:.45;filter:grayscale(1);}
  .live-dot{width:8px;height:8px;border-radius:50%;background:var(--lime);animation:pulse 1.2s ease-in-out infinite;}
  @keyframes pulse{0%,100%{opacity:1;transform:scale(1);}50%{opacity:.4;transform:scale(.7);}}
  /* primary glass surface: the live game card, from the shared rule above */
  .live-card{border-color:var(--glass-edge);}
  .game-header{display:flex;align-items:center;justify-content:space-between;padding:10px 18px;background:var(--glass-green);border-bottom:1px solid var(--glass-brd);}
  .game-header-left{display:flex;flex-direction:column;gap:2px;}
  .game-num{font-family:'Syne',sans-serif;font-size:12px;font-weight:700;letter-spacing:.15em;text-transform:uppercase;color:var(--lime);}
  .round-indicator{font-size:10px;color:var(--muted);letter-spacing:.04em;}
  .sitout-tag{font-size:11px;color:var(--muted);}
  .sitout-tag .name{color:#c0b080;font-weight:600;}
  .winner-row{display:grid;grid-template-columns:1fr auto 1fr;align-items:center;gap:10px;padding:14px;}
  .win-btn{border-radius:var(--r-btn);padding:14px 10px;flex-direction:column;gap:4px;transition:background .2s var(--ease),border-color .2s var(--ease),transform .18s var(--ease);width:100%;}
  .win-btn:hover:not(:disabled){transform:translateY(-1px);}
  .win-btn:active:not(:disabled){transform:scale(.98);}
  .win-btn:disabled{transform:none;}
  .team-label-btn{font-size:9px;letter-spacing:.12em;text-transform:uppercase;color:var(--muted);}
  .player-names-btn{font-size:15px;font-weight:600;line-height:var(--lh-snug);text-align:center;}
  .win-badge{display:none;font-size:10px;font-weight:700;letter-spacing:.1em;color:var(--lime);text-transform:uppercase;margin-top:2px;}
  .win-btn.selected .win-badge{display:block;}
  .vs-center{white-space:nowrap;text-align:center;}

  /* CATAN */
  .catan-who-won{padding:14px 14px 8px;}
  .catan-section-label{font-size:10px;letter-spacing:.15em;text-transform:uppercase;color:var(--muted);font-weight:700;margin-bottom:10px;}
  .catan-players{display:flex;flex-wrap:wrap;gap:8px;}
  .catan-player-btn{border-radius:var(--r-ctl);padding:10px 12px;font-size:14px;font-weight:600;gap:6px;flex:1;min-width:80px;justify-content:center;transition:background .2s var(--ease),border-color .2s var(--ease),transform .15s var(--ease);}
  .catan-player-btn:active:not(:disabled){transform:scale(.97);}
  .cp-check{display:none;color:var(--lime);font-weight:800;font-size:12px;}
  .catan-player-btn.selected .cp-check{display:inline;}
  .vp-section{padding:0 14px 4px;}
  .vp-label{font-size:10px;letter-spacing:.12em;text-transform:uppercase;color:var(--muted);margin-bottom:8px;display:flex;align-items:center;gap:6px;}
  .vp-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;}
  @media(max-width:360px){.vp-grid{grid-template-columns:repeat(2,1fr);}}
  .vp-cell{display:flex;flex-direction:column;align-items:center;gap:5px;}
  .vp-pname{font-size:11px;color:var(--muted);text-align:center;}
  .vp-pname.winning{color:var(--lime);}
  .vp-inp{border-radius:10px;font-size:22px;padding:8px 0;}

  /* SCORE */
  .score-section{padding:0 14px 4px;display:none;}
  .score-section.visible{display:block;}
  .score-label{font-size:10px;letter-spacing:.12em;text-transform:uppercase;color:var(--muted);margin-bottom:8px;display:flex;align-items:center;gap:6px;}
  .score-optional{font-size:10px;color:#66766a;}
  .score-inputs{display:grid;grid-template-columns:1fr auto 1fr;align-items:center;gap:8px;}
  .score-side{display:flex;flex-direction:column;align-items:center;gap:6px;}
  .score-team-name{font-size:11px;color:var(--muted);text-align:center;line-height:var(--lh-heading);}
  .score-team-name.winning{color:var(--lime);}
  .score-inp{border-radius:var(--r-ctl);font-size:26px;padding:10px 0;}
  .score-dash{font-family:'Syne',sans-serif;font-size:20px;color:var(--muted);text-align:center;}
  .confirm-wrap{padding:10px 14px 14px;display:none;}
  .confirm-wrap.visible{display:block;}
  .confirm-btn{width:100%;font-size:14px;letter-spacing:.08em;padding:12px;transition:opacity .2s var(--ease),transform .15s var(--ease);box-shadow:0 8px 24px rgba(200,241,53,.18);}
  .skip-wrap{display:flex;align-items:center;justify-content:center;gap:6px;flex-wrap:wrap;padding:0 14px 14px;text-align:center;}
  .skip-btn{color:#5a6a5c;font-size:11px;text-underline-offset:2px;padding:4px 8px;letter-spacing:.02em;}
  .cm-open-btn{background:rgba(8,14,8,.45);border:1px solid var(--glass-brd);color:var(--lime);font-family:'DM Sans',sans-serif;font-size:11px;font-weight:600;border-radius:var(--r-pill);padding:5px 12px;cursor:pointer;transition:border-color .2s var(--ease),transform .15s var(--ease);}
  .cm-open-btn:hover{border-color:var(--lime);}
  .cm-open-btn:active{transform:scale(.96);}
  .custom-tag{display:inline-block;margin-left:6px;font-family:'DM Sans',sans-serif;font-size:9px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--dark);background:var(--lime);border-radius:5px;padding:2px 5px;vertical-align:middle;}
  .skip-confirm{display:flex;align-items:center;justify-content:center;gap:10px;font-size:12px;color:var(--muted);}
  .skip-yes{background:rgba(90,25,25,.35);color:#e08080;border:1px solid rgba(224,128,128,.25);border-radius:var(--r-chip);padding:5px 14px;cursor:pointer;font-size:12px;font-weight:600;}
  .skip-no{background:transparent;color:var(--muted);border:1px solid var(--glass-brd);border-radius:var(--r-chip);padding:5px 14px;cursor:pointer;font-size:12px;}

  /* LEADERBOARD (frosted dock) */
  .pts-bar{max-width:600px;margin:20px auto 0;}
  .pts-bar-head{padding:10px 18px;font-size:11px;letter-spacing:.15em;}
  table.lb-table th{font-size:10px;letter-spacing:.08em;padding:8px 8px;}
  table.lb-table td{padding:9px 8px;font-size:13px;vertical-align:middle;}
  .lb-pts{font-family:'Syne',sans-serif;font-weight:800;color:var(--lime);font-size:16px;}
  .lb-w{color:var(--lime);font-weight:600;}.lb-l{color:var(--muted);}.lb-gp{color:#6a9a75;}
  .lb-wr{color:#8aba78;font-size:12px;}
  .lb-pd.pos{color:#8aba78;font-size:12px;}.lb-pd.neg{color:#c07070;font-size:12px;}.lb-pd.neu{color:var(--muted);font-size:12px;}
  .lb-pos{font-family:'Syne',sans-serif;font-weight:800;font-size:11px;color:var(--muted);margin-right:4px;}
  .streak-badge{display:inline-block;margin-left:5px;font-size:10px;background:var(--lime-tint);color:var(--lime);border-radius:5px;padding:1px 4px;font-weight:700;vertical-align:middle;}

  /* HISTORY */
  .history-wrap{max-width:600px;margin:20px auto 0;}
  .section-label{font-size:11px;letter-spacing:.15em;text-transform:uppercase;color:var(--muted);font-weight:700;margin-bottom:10px;display:flex;align-items:center;justify-content:space-between;}
  .undo-btn{font-size:11px;color:#e08080;background:rgba(90,25,25,.35);border:1px solid rgba(224,128,128,.25);border-radius:var(--r-chip);padding:3px 10px;cursor:pointer;font-weight:600;transition:opacity .2s var(--ease),transform .15s var(--ease);}
  .undo-btn:hover{opacity:.8;}
  .undo-btn:active{transform:scale(.96);}
  .history-list{display:flex;flex-direction:column;gap:8px;}
  .end-wrap{max-width:600px;margin:24px auto 0;}
  .end-btn{border-radius:var(--r-btn);letter-spacing:.08em;padding:14px;width:100%;transition:border-color .2s var(--ease),color .2s var(--ease);}
  .end-btn:hover{border-color:#d06060;color:#d06060;}

  /* MODALS (floating glass sheets) */
  /* The sheet sits a hair in from each edge so its rounded corners and its
     border are whole rather than sliced off by the screen — and clears a
     landscape notch, which `position:fixed` does not inherit from body. */
  .modal-overlay{display:none;position:fixed;inset:0;overflow:hidden;background:rgba(5,9,5,.55);backdrop-filter:blur(8px) saturate(1.2);-webkit-backdrop-filter:blur(8px) saturate(1.2);z-index:100;align-items:flex-end;justify-content:center;padding:0 calc(10px + env(safe-area-inset-right)) 0 calc(10px + env(safe-area-inset-left));}
  .modal-overlay.open{display:flex;}
  /* overflow-y:auto alone would make overflow-x auto as well, and a sheet must
     never scroll sideways on a phone — a native time input or a long name is
     clipped, not panned to */
  .modal-box{background:rgba(24,36,25,.78);padding:28px 24px calc(36px + env(safe-area-inset-bottom));max-height:100%;overflow-y:auto;overflow-x:hidden;animation:slideUp .3s var(--ease);}
  @keyframes slideUp{from{transform:translateY(60px);opacity:0;}to{transform:translateY(0);opacity:1;}}
  .modal-title{font-family:'Syne',sans-serif;font-size:20px;font-weight:800;margin-bottom:8px;}
  .modal-sub{color:var(--muted);font-size:13px;margin-bottom:24px;line-height:var(--lh-body);}
  .modal-btns{display:grid;grid-template-columns:1fr 1fr;gap:12px;}
  .modal-cancel{border-radius:var(--r-ctl);padding:14px;transition:border-color .2s var(--ease),transform .15s var(--ease);}
  .modal-cancel:active{transform:scale(.98);}
  .modal-confirm{background:#c0392b;color:var(--white);border:none;border-radius:var(--r-ctl);font-family:'Syne',sans-serif;font-size:13px;font-weight:800;padding:14px;cursor:pointer;text-transform:uppercase;transition:transform .15s var(--ease);}
  .modal-confirm:active{transform:scale(.98);}
  .end-discard-btn{display:block;width:100%;margin-top:14px;color:#7a8a75;font-size:12px;text-underline-offset:3px;padding:6px;}
  /* the same quiet link doing a reversible job — red would over-signal it */
  .end-discard-btn.quiet:hover{color:var(--lime);}

  /* CUSTOM MATCH SHEET */
  .cm-teams{display:grid;grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);align-items:center;gap:8px;margin-bottom:18px;}
  .cm-team{min-width:0;}
  .cm-team-head{font-size:9.5px;letter-spacing:.12em;text-transform:uppercase;color:var(--muted);font-weight:700;text-align:center;margin-bottom:7px;}
  .cm-slots{display:flex;flex-direction:column;gap:6px;}
  .cm-slot{display:block;width:100%;min-width:0;border-radius:10px;padding:11px 8px;font-family:'DM Sans',sans-serif;font-size:13.5px;font-weight:600;text-align:center;line-height:var(--lh-heading);overflow-wrap:anywhere;}
  .cm-slot.filled{background:var(--lime-tint);border:1.5px solid var(--lime);color:var(--lime);cursor:pointer;}
  .cm-slot.filled:active{transform:scale(.97);}
  .cm-slot.empty{background:rgba(8,14,8,.4);border:1.5px dashed var(--glass-brd);color:#5a6a5c;font-size:12px;font-weight:500;}
  .cm-vs{align-self:center;margin-top:20px;}
  .cm-pool-label{font-size:11px;letter-spacing:.04em;color:var(--muted);text-align:center;margin-bottom:10px;}
  .cm-pool{display:flex;flex-wrap:wrap;gap:8px;justify-content:center;margin-bottom:22px;min-height:38px;}
  .cm-chip{transition:border-color .2s var(--ease),transform .15s var(--ease);box-shadow:inset 0 1px 0 rgba(255,255,255,.08);}
  .cm-empty{font-size:12px;color:#5a6a5c;align-self:center;}
  .cm-go{font-size:13px;padding:14px 10px;letter-spacing:.04em;line-height:var(--lh-heading);text-wrap:balance;transition:opacity .2s var(--ease),transform .15s var(--ease);}
  .cm-go:disabled{opacity:.3;cursor:default;}
  .cm-go:not(:disabled):active{transform:scale(.98);}
  .round-box{background:rgba(24,36,25,.82);max-height:88vh;display:flex;flex-direction:column;animation:slideUp .32s var(--ease);}
  .round-box-header{padding:22px 22px 16px;background:var(--glass-green);border-bottom:1px solid var(--glass-brd);border-radius:var(--r-sheet) var(--r-sheet) 0 0;text-align:center;flex-shrink:0;}
  .round-badge-emoji{font-size:34px;margin-bottom:6px;}
  .round-badge-title{font-family:'Syne',sans-serif;font-size:21px;font-weight:800;}
  .round-badge-sub{font-size:12px;color:var(--muted);margin-top:4px;}
  .round-body{flex:1;overflow-y:auto;overflow-x:hidden;padding:18px 18px 0;}
  .round-section-title{font-size:10px;letter-spacing:.15em;text-transform:uppercase;color:var(--muted);font-weight:700;margin:14px 0 8px;}
  .round-section-title:first-child{margin-top:0;}
  .round-mvp{background:var(--lime-tint);border:1px solid var(--lime);border-radius:var(--r-btn);padding:14px 16px;display:flex;align-items:center;justify-content:space-between;gap:12px;box-shadow:inset 0 1px 0 rgba(255,255,255,.1);}
  .round-mvp>div:first-child{min-width:0;}
  .round-mvp>div:last-child{flex-shrink:0;}
  .round-mvp-name{font-family:'Syne',sans-serif;font-size:clamp(15px,4.6vw,18px);font-weight:800;margin-bottom:4px;line-height:var(--lh-heading);overflow-wrap:anywhere;}
  .round-mvp-stat{font-size:12px;color:var(--lime);}
  table.round-lb{background:rgba(255,255,255,.04);border-radius:var(--r-ctl);overflow:hidden;}
  table.round-lb th{font-size:10px;letter-spacing:.08em;padding:8px 12px;}
  table.round-lb td{padding:9px 12px;font-size:13px;}
  .rlb-pts{font-family:'Syne',sans-serif;font-weight:800;color:var(--lime);}
  .rlb-pos{font-family:'Syne',sans-serif;font-weight:800;font-size:11px;color:var(--muted);margin-right:7px;}
  .round-footer{padding:14px 18px calc(28px + env(safe-area-inset-bottom));background:rgba(255,255,255,.03);border-top:1px solid var(--glass-brd);flex-shrink:0;}
  .round-continue-btn{width:100%;font-size:14px;letter-spacing:.08em;padding:14px;transition:transform .15s var(--ease);box-shadow:0 8px 24px rgba(200,241,53,.18);}
  .copy-btn{display:block;width:100%;border-radius:var(--r-btn);letter-spacing:.08em;padding:11px;margin-bottom:10px;transition:border-color .2s var(--ease),color .2s var(--ease);}
  .copy-btn:hover,.copy-btn.copied{border-color:var(--lime);color:var(--lime);}

  /* FINAL — tuned for a shareable screenshot: as much signal per screen as
     stays legible, so a single capture tells the whole story. */
  #final-screen{max-width:600px;margin:0 auto;padding:var(--page-pad-top) var(--page-pad-x) 30px;animation:fadeIn .5s var(--ease);}
  /* when the night ran, under the headline meta — quieter, and tabular so the
     times line up between one tournament and the next */
  .final-times{font-size:12px;color:var(--muted);opacity:.8;margin-top:5px;font-variant-numeric:tabular-nums;}
  @keyframes fadeIn{from{opacity:0;transform:translateY(16px);}to{opacity:1;transform:translateY(0);}}
  .final-header{text-align:center;margin-bottom:10px;}
  .trophy{font-size:20px;margin-bottom:0;line-height:1;}
  .final-title{font-family:'Syne',sans-serif;font-size:clamp(1.15rem,4.4vw,1.7rem);font-weight:800;letter-spacing:-.02em;line-height:var(--lh-display);}
  .final-title span{color:var(--lime);}
  .final-sub{color:var(--white);font-size:12.5px;font-weight:600;margin-top:3px;}
  .final-meta{color:#6a7a65;font-size:10.5px;margin-top:3px;line-height:var(--lh-snug);}

  /* PODIUM — one row, winner weighted wider. The full table below carries the
     detail, so this only needs to read as 1/2/3 at a glance. */
  .podium{display:grid;grid-template-columns:1.35fr 1fr 1fr;gap:5px;margin:0 0 8px;}
  .pod{display:flex;flex-direction:column;gap:1px;min-width:0;padding:7px 9px;}
  .pod1{background:var(--lime-tint);border-color:var(--lime);}
  .pod-medal{font-size:13px;line-height:var(--lh-display);}
  .pod-body{min-width:0;display:flex;flex-direction:column;}
  .pod-name{font-family:'Syne',sans-serif;font-weight:800;font-size:12.5px;line-height:var(--lh-display);overflow-wrap:anywhere;}
  .pod1 .pod-name{font-size:14.5px;}
  .pod-line{font-size:9.5px;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
  .pod-pts{font-family:'Syne',sans-serif;font-weight:800;font-size:15px;color:var(--lime);line-height:1;display:flex;align-items:baseline;gap:2px;margin-top:1px;}
  .pod1 .pod-pts{font-size:19px;}
  .pod-pts small{font-size:8px;font-weight:700;color:var(--muted);letter-spacing:.05em;text-transform:uppercase;}

  /* RESULT TABS */
  .rtabs{display:grid;grid-template-columns:1fr 1fr;gap:4px;background:rgba(8,14,8,.45);border:1px solid var(--glass-brd);border-radius:var(--r-pill);padding:4px;margin-bottom:8px;box-shadow:inset 0 1px 0 rgba(255,255,255,.06);}
  .rtab{min-width:0;background:transparent;border:none;color:var(--muted);font-family:'Syne',sans-serif;font-size:clamp(9.5px,2.7vw,12px);font-weight:800;letter-spacing:.02em;text-transform:uppercase;border-radius:var(--r-pill);padding:8px 4px;cursor:pointer;white-space:nowrap;transition:background .2s var(--ease),color .2s var(--ease);}
  .rtab.active{background:var(--lime);color:var(--dark);}
  .empty-note{color:var(--muted);font-size:13px;text-align:center;padding:22px 14px;}

  /* AWARDS — bento mosaic. 6-column base; tiles claim 2 / 3 / 6 tracks by how
     much text they carry, and `dense` backfills the gaps so nothing is wasted. */
  .bento{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:5px;}
  .bt{position:relative;display:flex;flex-direction:column;justify-content:center;gap:1px;min-width:0;text-align:left;padding:8px 9px;color:var(--white);font-family:inherit;}
  .bt-lg{display:grid;grid-template-columns:1fr auto;align-items:center;column-gap:10px;row-gap:1px;}
  .bt.tappable{cursor:pointer;transition:border-color .2s var(--ease),transform .15s var(--ease);}
  .bt.tappable:hover{border-color:var(--glass-edge);}
  .bt.tappable:active{transform:scale(.98);}
  .bt-label{display:flex;align-items:center;gap:4px;min-width:0;font-size:8.5px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:var(--muted);line-height:var(--lh-heading);}
  .bt-ic{font-size:10px;line-height:1;flex-shrink:0;}
  .bt-val{font-family:'Syne',sans-serif;font-weight:800;font-size:19px;color:var(--lime);line-height:var(--lh-display);overflow-wrap:anywhere;}
  .bt-sm .bt-val{font-size:16px;}
  .bt-sub{font-size:10px;color:var(--muted);line-height:var(--lh-heading);overflow-wrap:anywhere;}
  /* wide tiles read as a row: label over sub on the left, value pinned right */
  .bt-lg>.bt-label{grid-column:1;grid-row:1;}
  .bt-lg>.bt-sub{grid-column:1;grid-row:2;}
  .bt-lg>.bt-val{grid-column:2;grid-row:1/3;text-align:right;font-size:16px;}
  .bt-more{position:absolute;top:6px;right:7px;width:4px;height:4px;border-radius:50%;background:var(--lime);opacity:.55;}
  .award-details{display:none;}
  .award-note{font-size:11.5px;color:var(--muted);line-height:var(--lh-snug);padding:2px 2px 6px;}

  /* award detail sheet */
  .aw-box{max-height:82vh;display:flex;flex-direction:column;padding:0;}
  .aw-head{display:flex;align-items:center;gap:11px;padding:18px 18px 14px;background:var(--glass-green);border-bottom:1px solid var(--glass-brd);border-radius:var(--r-sheet) var(--r-sheet) 0 0;flex-shrink:0;}
  .aw-head-ic{font-size:22px;line-height:1;flex-shrink:0;}
  .aw-head-txt{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px;}
  .aw-head-title{font-family:'Syne',sans-serif;font-size:16px;font-weight:800;line-height:var(--lh-heading);}
  .aw-head-val{font-size:13px;font-weight:600;color:var(--lime);overflow-wrap:anywhere;}
  .aw-close{flex-shrink:0;font-size:26px;}
  .aw-body{flex:1;overflow-y:auto;overflow-x:hidden;padding:14px 14px calc(24px + env(safe-area-inset-bottom));display:flex;flex-direction:column;gap:8px;}

  /* MATCH ROW — stacked so long line-ups can never overflow a phone */
  .m-list{display:flex;flex-direction:column;gap:8px;padding:12px;}
  /* reused inside the live history and the round report, which supply their own padding */
  .history-list .m-list,#round-games-content .m-list{padding:0;}
  .m-list.compact{gap:0;padding:0;}

  /* compact game-log row: two lines per match instead of five */
  .gl-row{display:grid;grid-template-columns:30px minmax(0,1fr) auto auto;align-items:center;gap:9px;padding:7px 13px;border-bottom:1px solid rgba(255,255,255,.05);}
  /* how long the game ran, in its own column so the scores stay a clean edge to
     read down; empty for anything that was never clocked */
  .gl-dur{font-family:'Syne',sans-serif;font-size:10px;font-weight:700;color:var(--muted);opacity:.72;font-variant-numeric:tabular-nums;white-space:nowrap;text-align:right;min-width:22px;}
  .gl-row:last-child{border-bottom:none;}
  .gl-g{font-family:'Syne',sans-serif;font-size:10px;font-weight:700;color:var(--muted);letter-spacing:.04em;}
  .gl-tag{color:var(--lime);margin-left:1px;}
  .gl-teams{min-width:0;display:flex;flex-direction:column;gap:1px;font-size:12.5px;line-height:var(--lh-heading);}
  .gl-w{color:var(--lime);font-weight:600;overflow-wrap:anywhere;}
  .gl-l{color:#8a9a86;overflow-wrap:anywhere;}
  .gl-sc{font-family:'Syne',sans-serif;font-size:13px;font-weight:800;color:var(--white);white-space:nowrap;letter-spacing:.02em;}
  .m-list.compact .log-div{padding:3px 13px;background:rgba(255,255,255,.03);}
  .m-list.compact .log-div b{font-size:8.5px;}
  .m-row{background:rgba(8,14,8,.4);border:1px solid var(--glass-brd);border-radius:var(--r-ctl);padding:10px 12px;min-width:0;}
  .m-head{display:flex;align-items:center;gap:7px;flex-wrap:wrap;margin-bottom:7px;}
  .m-num{font-family:'Syne',sans-serif;font-size:10.5px;font-weight:800;letter-spacing:.12em;text-transform:uppercase;color:var(--muted);}
  .m-tag{font-size:9.5px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--muted);background:rgba(255,255,255,.06);border-radius:6px;padding:2px 6px;}
  /* how long the game took, pushed to the end of the head row so the game
     number stays the thing you scan down. Tabular so the column lines up. */
  .m-dur{margin-left:auto;font-size:10.5px;color:var(--muted);opacity:.75;font-variant-numeric:tabular-nums;}
  .m-tag.custom{color:var(--dark);background:var(--lime);}
  .m-side{display:flex;align-items:baseline;gap:8px;min-width:0;padding:3px 0;}
  .m-res{flex-shrink:0;width:38px;font-size:9.5px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--muted);}
  .m-side.win .m-res{color:var(--lime);}
  .m-players{flex:1;min-width:0;font-size:14px;font-weight:600;line-height:var(--lh-snug);overflow-wrap:anywhere;}
  .m-side.win .m-players{color:var(--lime);}
  .m-side.lose .m-players{color:#9fb09a;}
  .m-side .m-score{flex-shrink:0;font-family:'Syne',sans-serif;font-size:12px;font-weight:800;color:var(--white);}
  .mt-amp{color:#5a6a5c;font-weight:400;}
  .m-score-big{font-family:'Syne',sans-serif;font-size:17px;font-weight:800;color:var(--white);letter-spacing:.04em;padding:3px 0 3px 46px;}
  .m-score-big span{color:var(--muted);margin:0 3px;}
  .m-out{font-size:10.5px;color:#6a7a65;margin-top:6px;padding-top:6px;border-top:1px solid rgba(255,255,255,.05);overflow-wrap:anywhere;}
  .log-div{display:flex;align-items:center;gap:10px;padding:4px 2px;}
  .log-div span{flex:1;height:1px;background:var(--glass-brd);}
  .log-div b{font-size:9.5px;letter-spacing:.12em;text-transform:uppercase;color:var(--muted);font-weight:700;white-space:nowrap;}

  .final-table-wrap{margin-bottom:8px;}
  .final-table-head,.game-log-head{padding:6px 13px;font-size:9.5px;letter-spacing:.14em;}
  table.final-table th{font-size:9px;letter-spacing:.05em;padding:5px 6px;}
  table.final-table td{padding:5px 6px;font-size:12.5px;vertical-align:middle;}
  table.final-table tr.top td{background:var(--lime-tint);}
  table.final-table td.ft-name{overflow-wrap:anywhere;}
  table.final-table td:not(:first-child),table.final-table th:not(:first-child){width:1%;white-space:nowrap;}
  @media(max-width:400px){table.final-table th,table.final-table td{padding:7px 5px;font-size:12.5px;}}
  .pts-final{font-family:'Syne',sans-serif;font-weight:800;font-size:14px;color:var(--lime);}
  .f-w{color:var(--lime);font-weight:600;}.f-l{color:var(--muted);}.f-gp{color:#6a9a75;}.f-wr{color:#8aba78;font-size:12px;}
  .f-pd.pos{color:#8aba78;}.f-pd.neg{color:#c07070;}.f-pd.neu{color:var(--muted);}
  .game-log-wrap{background:var(--glass);border:1px solid var(--glass-brd);border-radius:var(--r-card);overflow:hidden;margin-bottom:10px;}

  /* compact stat cards + log rows — also used by the player-profile pages.
     min-width:0 is load-bearing: `1fr` tracks floor at min-content, so without
     it long names blow the grid past the viewport and get clipped by
     html{overflow-x:hidden} with no way to scroll to them. */
  .stat-cards{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:7px;margin-bottom:14px;}
  @media(min-width:520px){.stat-cards{grid-template-columns:repeat(4,minmax(0,1fr));}}
  .stat-card{min-width:0;padding:9px 10px;}
  .stat-card-label{font-size:9px;letter-spacing:.06em;text-transform:uppercase;color:var(--muted);margin-bottom:3px;line-height:var(--lh-heading);}
  .stat-card-val{font-family:'Syne',sans-serif;font-size:16px;font-weight:800;color:var(--lime);line-height:var(--lh-display);overflow-wrap:anywhere;}
  .stat-card-sub{font-size:10.5px;color:var(--muted);margin-top:2px;line-height:var(--lh-heading);overflow-wrap:anywhere;}
  .log-row{display:grid;grid-template-columns:34px minmax(0,1fr) auto minmax(0,1fr);align-items:center;padding:6px 14px;border-bottom:1px solid rgba(255,255,255,.05);font-size:13px;gap:8px;}
  .log-row:last-child{border-bottom:none;}
  .log-row>*{min-width:0;overflow-wrap:anywhere;}
  .log-gnum{color:var(--muted);font-size:11px;}.log-winner{color:var(--lime);font-weight:600;}
  .log-score{font-family:'Syne',sans-serif;font-size:13px;font-weight:800;color:var(--white);text-align:center;white-space:nowrap;}
  .log-loser{color:var(--muted);text-align:right;}
  .play-again-btn{border-radius:var(--r-btn);font-size:15px;letter-spacing:.08em;padding:13px;width:100%;transition:opacity .2s var(--ease),transform .15s var(--ease);box-shadow:0 8px 24px rgba(200,241,53,.18);}
  .play-again-btn:hover{opacity:.88;}

  /* CATAN BOARD GENERATOR */
  #board-gen-wrap{max-width:600px;margin:16px auto 0;}
  .board-gen-btn{width:100%;background:var(--glass);color:var(--lime);border:1px solid var(--glass-edge);border-radius:var(--r-btn);font-family:'Syne',sans-serif;font-size:13px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;padding:13px;cursor:pointer;transition:background .2s var(--ease),transform .15s var(--ease);box-shadow:inset 0 1px 0 rgba(255,255,255,.08);}
  .board-gen-btn:hover{background:var(--glass-strong);}
  .board-gen-btn:active{transform:scale(.98);}
  .board-box{background:rgba(14,20,13,.85);max-height:94vh;display:flex;flex-direction:column;animation:slideUp .32s var(--ease);}
  .board-box-header{display:flex;align-items:center;justify-content:space-between;padding:16px 20px;background:var(--glass-green);border-bottom:1px solid var(--glass-brd);border-radius:var(--r-sheet) var(--r-sheet) 0 0;flex-shrink:0;}
  .board-title{font-family:'Syne',sans-serif;font-size:18px;font-weight:800;}
  .board-edition{display:flex;gap:0;background:rgba(8,14,8,.45);border:1px solid var(--glass-brd);border-radius:var(--r-pill);padding:3px;box-shadow:inset 0 1px 0 rgba(255,255,255,.06);}
  .board-ed-btn{background:transparent;border:none;color:var(--muted);font-family:'Syne',sans-serif;font-size:11px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;border-radius:var(--r-pill);padding:6px 12px;cursor:pointer;transition:background .2s var(--ease),color .2s var(--ease);}
  .board-ed-btn.selected{background:var(--lime);color:var(--dark);}
  @media(max-width:380px){.board-ed-btn{padding:6px 9px;font-size:10px;}}
  .board-close{font-size:24px;}
  .board-canvas{flex:1;overflow:hidden auto;padding:22px 18px;background:radial-gradient(120% 100% at 50% -20%,rgba(30,58,95,.55),transparent 70%),#0a1a2e;display:flex;justify-content:center;align-items:center;min-height:340px;}
  .board-canvas svg{width:100%;height:auto;max-width:560px;}
  .board-opts{padding:16px 18px;border-top:1px solid var(--glass-brd);display:grid;grid-template-columns:1fr 1fr;gap:13px 10px;flex-shrink:0;background:rgba(255,255,255,.02);max-height:34vh;overflow:hidden auto;}
  .board-opt{display:flex;align-items:center;gap:8px;font-size:12.5px;color:var(--white);cursor:pointer;user-select:none;}
  .board-opt input{accent-color:var(--lime);width:17px;height:17px;flex-shrink:0;}
  .board-footer{display:flex;gap:10px;align-items:center;padding:14px 18px calc(18px + env(safe-area-inset-bottom));border-top:1px solid var(--glass-brd);flex-shrink:0;}
  .board-opts-toggle{flex:0 0 auto;background:var(--glass);color:var(--lime);border:1px solid var(--glass-edge);border-radius:var(--r-ctl);font-family:'Syne',sans-serif;font-size:13px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;padding:13px 16px;cursor:pointer;white-space:nowrap;transition:background .2s var(--ease);}
  .board-opts-toggle:hover{background:var(--glass-strong);}
  .board-shuffle{flex:1;font-size:15px;letter-spacing:.06em;padding:14px;transition:transform .15s var(--ease);box-shadow:0 8px 24px rgba(200,241,53,.18);}
  .board-shuffle:hover{opacity:.92;}

  /* SYNC (share pill + conflict banner, injected by sync.js) */
  #sync-pill{display:inline-flex;align-items:center;gap:7px;margin-top:12px;background:var(--glass);border:1px solid var(--glass-brd);border-radius:var(--r-pill);padding:7px 14px;color:var(--white);font-family:'DM Sans',sans-serif;font-size:13px;font-weight:600;cursor:pointer;transition:border-color .2s var(--ease),transform .15s var(--ease);box-shadow:inset 0 1px 0 rgba(255,255,255,.08);}
  #sync-pill:hover{border-color:var(--glass-edge);}
  #sync-pill:active{transform:scale(.97);}
  #sync-pill.copied{border-color:var(--lime);color:var(--lime);}
  #sync-pill .sync-dot{width:7px;height:7px;border-radius:50%;background:#6a7a65;flex-shrink:0;}
  #sync-pill .sync-dot.on{background:var(--lime);}
  #sync-pill .sync-dot.pending{background:#e0b070;}
  #sync-pill .sync-dot.warn{background:#e0b070;animation:pulse 1.8s ease-in-out infinite;}
  #sync-pill.local-only{border-color:rgba(224,176,112,.45);color:#e0b070;}
  #sync-watching{color:var(--muted);font-size:11px;}
  #sync-banner{position:fixed;left:50%;transform:translateX(-50%);bottom:calc(16px + env(safe-area-inset-bottom));display:flex;align-items:center;gap:12px;background:rgba(24,36,25,.9);border:1px solid var(--glass-edge);border-radius:var(--r-btn);padding:12px 16px;font-size:13px;z-index:200;backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);box-shadow:0 12px 40px rgba(0,0,0,.5);max-width:92vw;}
  #sync-banner.wide{flex-direction:column;align-items:stretch;gap:14px;width:min(92vw,420px);bottom:calc(80px + env(safe-area-inset-bottom));line-height:var(--lh-body);}
  #sync-banner.wide b{color:var(--lime);}
  #sync-banner.wide button{width:100%;}
  #sync-banner button{background:var(--lime);color:var(--dark);border:none;border-radius:9px;font-family:'Syne',sans-serif;font-size:12px;font-weight:800;padding:8px 14px;cursor:pointer;text-transform:uppercase;flex-shrink:0;}

  #photo-status{text-align:center;font-size:12px;color:var(--muted);min-height:16px;margin-bottom:10px;}
  #photo-modal{position:fixed;inset:0;overflow:hidden;display:flex;align-items:center;justify-content:center;padding:24px;background:rgba(5,9,5,.55);backdrop-filter:blur(8px) saturate(1.2);-webkit-backdrop-filter:blur(8px) saturate(1.2);z-index:205;}
  .photo-modal-box{background:rgba(24,36,25,.85);border:1px solid var(--glass-edge);border-radius:var(--r-sheet);padding:30px 24px 20px;width:min(92vw,360px);text-align:center;animation:popIn .3s var(--ease);backdrop-filter:blur(24px) saturate(1.6);-webkit-backdrop-filter:blur(24px) saturate(1.6);box-shadow:inset 0 1px 0 rgba(255,255,255,.14),0 18px 60px rgba(0,0,0,.5);}
  @keyframes popIn{from{opacity:0;transform:scale(.94);}to{opacity:1;transform:scale(1);}}
  .photo-modal-emoji{font-size:42px;line-height:1;margin-bottom:12px;}
  .photo-modal-title{font-family:'Syne',sans-serif;font-size:20px;font-weight:800;margin-bottom:8px;}
  .photo-modal-sub{color:var(--muted);font-size:13px;line-height:var(--lh-body);margin-bottom:22px;}
  .photo-modal-cta{width:100%;font-size:14px;padding:16px 12px;letter-spacing:.03em;transition:opacity .2s var(--ease),transform .15s var(--ease);box-shadow:0 8px 24px rgba(200,241,53,.18);}
  .photo-modal-skip{display:block;width:100%;background:transparent;border:none;color:var(--muted);font-family:'DM Sans',sans-serif;font-size:13px;font-weight:600;padding:14px 0 0;cursor:pointer;}
  .hype-line{padding:0 14px 12px;text-align:center;font-size:12.5px;color:#b9c7b3;font-style:italic;line-height:var(--lh-snug);animation:fadeIn .4s var(--ease);}
  #digest-toast,#update-toast{position:fixed;left:50%;transform:translateX(-50%);top:calc(14px + env(safe-area-inset-top));display:flex;align-items:center;gap:12px;background:rgba(24,36,25,.92);border:1px solid var(--glass-edge);border-radius:var(--r-btn);padding:11px 15px;font-size:13px;z-index:210;backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);box-shadow:0 12px 40px rgba(0,0,0,.5);max-width:92vw;transition:opacity .5s var(--ease);}
  #digest-toast.gone{opacity:0;}
  #update-toast span{white-space:nowrap;}
  #digest-toast a,#update-toast a{color:var(--dark);background:var(--lime);border-radius:9px;font-family:'Syne',sans-serif;font-size:11px;font-weight:800;padding:7px 12px;text-decoration:none;text-transform:uppercase;flex-shrink:0;}

  /* KICKOFF SPLASH (shown once at tournament start, injected by cloud.js) */
  #kickoff-splash{position:fixed;inset:0;overflow:hidden;z-index:300;display:flex;align-items:center;justify-content:center;background:rgba(5,9,5,.6);backdrop-filter:blur(14px) saturate(1.3);-webkit-backdrop-filter:blur(14px) saturate(1.3);animation:fadeIn .4s var(--ease);transition:opacity .45s var(--ease);}
  #kickoff-splash.gone{opacity:0;pointer-events:none;}
  .ks-inner{text-align:center;background:rgba(24,36,25,.8);border:1px solid var(--glass-edge);border-radius:var(--r-sheet);padding:36px 30px 28px;max-width:400px;width:calc(100% - 32px);box-shadow:inset 0 1px 0 rgba(255,255,255,.14),0 24px 70px rgba(0,0,0,.5);}
  @media(max-width:360px){.ks-inner{padding:30px 18px 24px;}}
  .ks-icon{font-size:52px;line-height:1;margin-bottom:10px;}
  /* fluid: "BADMINTON" at a fixed 34px overflowed the card on narrow phones.
     No overflow-wrap here — breaking mid-word reads worse than shrinking. */
  .ks-title{font-family:'Syne',sans-serif;font-size:clamp(1.25rem,7vw,2.125rem);font-weight:800;letter-spacing:-.02em;color:var(--lime);line-height:var(--lh-display);}
  .ks-sub{font-size:14px;color:var(--white);font-weight:600;margin-top:6px;}
  .ks-meta{font-size:13px;color:var(--muted);margin-top:14px;line-height:var(--lh-body);}
  .ks-players{font-size:12.5px;color:#b9c7b3;margin-top:12px;line-height:var(--lh-body);}
  .ks-go{margin-top:22px;font-size:14px;letter-spacing:.06em;padding:13px 30px;transition:transform .15s var(--ease);box-shadow:0 8px 24px rgba(200,241,53,.2);}
  .ks-go:active{transform:scale(.97);}
  @media (prefers-reduced-motion: reduce){#kickoff-splash{animation:none;transition:none;}}

  /* ROSTER — who is actually in the hall right now.
     The button sits in the live label row beside the sound toggle; both are
     small controls on a line that is otherwise a heading, so they share its
     chip shape rather than inventing a second one. */
  .roster-btn{display:flex;align-items:center;gap:6px;font-family:'DM Sans',sans-serif;font-size:11px;font-weight:600;letter-spacing:.04em;text-transform:none;color:var(--white);}
  .roster-btn+.fx-toggle{margin-left:0;}
  .roster-btn:active{transform:scale(.96);}
  .roster-box .modal-sub{margin-bottom:var(--s-4);}
  .roster-warn{color:var(--lime);font-weight:600;}
  /* the fade is the scroll cue: without it the clipped row at the bottom reads
     as a rendering fault rather than as more list */
  .roster-list{display:flex;flex-direction:column;gap:6px;margin-bottom:var(--s-4);max-height:46vh;overflow-y:auto;overflow-x:hidden;
    mask-image:linear-gradient(to bottom,#000 calc(100% - 28px),transparent);
    -webkit-mask-image:linear-gradient(to bottom,#000 calc(100% - 28px),transparent);}
  .roster-row{display:flex;align-items:center;gap:var(--s-3);width:100%;text-align:left;background:var(--glass);border:1px solid var(--glass-brd);border-radius:var(--r-ctl);padding:11px 13px;cursor:pointer;font-family:'DM Sans',sans-serif;transition:border-color .2s var(--ease),opacity .2s var(--ease);}
  .roster-row:active{transform:scale(.99);}
  .roster-name{font-size:15px;font-weight:600;color:var(--white);}
  .roster-meta{font-size:var(--fs-sm);color:#6a9a75;margin-left:auto;}
  .roster-tag{font-family:'Syne',sans-serif;font-size:10px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;border-radius:var(--r-chip);padding:4px 8px;white-space:nowrap;}
  /* tinted, not filled: solid lime is the sheet's action (Add), and a status
     that needs no response should not outshout it three times over */
  .roster-row.playing{border-color:rgba(200,241,53,.3);}
  .roster-row.playing .roster-tag{color:var(--lime);background:var(--lime-tint);border:1px solid rgba(200,241,53,.3);}
  .roster-row.waiting .roster-tag{color:var(--muted);background:rgba(8,14,8,.45);border:1px solid var(--glass-brd);}
  /* out reads as struck from the rotation, not deleted: the name stays legible
     because they are still on the leaderboard */
  .roster-row.out{opacity:.5;border-style:dashed;}
  .roster-row.out .roster-name{text-decoration:line-through;}
  .roster-row.out .roster-tag{color:#e2a0a0;background:rgba(120,40,40,.3);border:1px solid rgba(200,120,120,.3);}
  .roster-note{font-size:var(--fs-sm);line-height:var(--lh-snug);color:var(--lime);background:var(--lime-tint);border-radius:var(--r-ctl);padding:9px 12px;margin-bottom:var(--s-4);}
  .roster-add{border-top:1px solid var(--glass-brd);padding-top:var(--s-4);margin-bottom:var(--s-6);}
  .roster-add-label{font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--muted);margin-bottom:var(--s-3);}
  .roster-add-row{display:flex;gap:var(--s-2);}
  .roster-inp{flex:1;min-width:0;background:rgba(8,14,8,.5);border:1px solid var(--glass-edge);border-radius:var(--r-ctl);color:var(--white);font-family:'DM Sans',sans-serif;font-size:15px;padding:11px 13px;outline:none;}
  .roster-inp:focus{border-color:var(--lime);}
  .roster-add-btn{font-size:13px;letter-spacing:.04em;padding:11px 18px;}
  .roster-add-btn:active{transform:scale(.97);}
  .roster-known{display:flex;flex-wrap:wrap;gap:var(--s-2);margin-top:var(--s-3);}
  .roster-known:empty{display:none;}

  /* NO GAME ON — every court paused because too few players are left in */
  .courts-empty{text-align:center;padding:26px 20px;}
  .ce-title{font-family:'Syne',sans-serif;font-size:17px;font-weight:800;margin-bottom:6px;}
  .ce-sub{font-size:var(--fs-body);line-height:var(--lh-body);color:#c7d3c2;margin-bottom:var(--s-4);}
  .ce-btn{font-size:13px;letter-spacing:.04em;padding:13px 22px;}

  /* NIGHT PLANNER — how much of the booking is left.
     Sits between the courts and Up Next: it is about the whole night rather
     than any one court, and it is what makes "Last Round" beneath it mean
     something. Solid where Up Next is dashed, so the two do not read as one
     block. */
  .planner-wrap{margin-top:var(--s-4);}
  .planner-strip{display:flex;align-items:center;gap:var(--s-3);width:100%;text-align:left;background:var(--glass);border:1px solid var(--glass-brd);border-radius:var(--r-card);padding:11px 14px;cursor:pointer;font-family:'DM Sans',sans-serif;transition:border-color .2s var(--ease);}
  .planner-strip:active{transform:scale(.995);}
  .planner-ic{font-size:15px;line-height:1;flex-shrink:0;}
  /* stacked, not inline: "Until 9:00 pm" and "5 more rounds - ~5 games each"
     together overrun a 390px phone, and the note is the half that gets clipped */
  .planner-body{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1;}
  .planner-main{font-size:var(--fs-body);font-weight:600;color:var(--white);line-height:var(--lh-heading);}
  .planner-note{font-size:var(--fs-sm);color:var(--muted);line-height:var(--lh-snug);}
  .planner-note:empty{display:none;}
  .planner-edit{margin-left:auto;font-family:'Syne',sans-serif;font-size:10px;font-weight:800;letter-spacing:.1em;text-transform:uppercase;color:var(--lime);flex-shrink:0;}
  .planner-strip.unset{border-style:dashed;}
  .planner-strip.unset .planner-main{color:var(--muted);font-weight:500;}
  /* the last round is the one announcement here that changes what people do */
  .planner-strip.last{border-color:rgba(200,241,53,.45);background:var(--lime-tint);}
  .planner-strip.last .planner-main{color:var(--lime);}
  .planner-strip.over{border-color:rgba(200,120,120,.35);}
  .planner-strip.over .planner-main{color:#e2a0a0;}

  /* COURT HOURS — the wizard's per-court from/until rows, the ⏱ sheet's court
     list with its Open now / Close now, and the "until 8:00 pm" beside a live
     court's tag. A court booked for part of the night. */
  .hours-toggle{display:block;margin:0 auto var(--s-6);background:none;border:none;color:var(--lime);font-family:'DM Sans',sans-serif;font-size:13px;font-weight:600;text-decoration:underline;text-underline-offset:3px;cursor:pointer;padding:6px;}
  .court-hours-list{display:flex;flex-direction:column;gap:var(--s-3);margin-bottom:var(--s-3);}
  /* the label on its own line, the two clocks side by side beneath it: a phone is not wide enough for all three in a row */
  .court-hours{display:grid;grid-template-columns:1fr 1fr;gap:var(--s-2) var(--s-3);align-items:center;background:var(--glass);border:1px solid var(--glass-brd);border-radius:var(--r-ctl);padding:var(--s-3) var(--s-4);box-shadow:inset 0 1px 0 rgba(255,255,255,.07);}
  .court-hours-lbl{grid-column:1/-1;font-family:'Syne',sans-serif;font-weight:800;font-size:13px;letter-spacing:.08em;text-transform:uppercase;color:var(--white);}
  .court-hours-f{display:flex;align-items:center;gap:6px;min-width:0;font-size:10px;letter-spacing:.08em;text-transform:uppercase;color:var(--muted);}
  .court-hours-f .finish-inp.sm{flex:1;min-width:0;width:auto;font-size:14px;padding:7px 8px;}
  .court-hours-hint{margin-bottom:var(--s-4);}
  .court-hours-hint b{color:var(--white);font-weight:600;}
  .court-tags{display:inline-flex;align-items:center;gap:8px;}
  .court-until{font-size:11px;color:var(--muted);white-space:nowrap;}
  .court-until.last{color:var(--lime);font-weight:600;}
  .round-indicator+.court-until{margin-left:8px;}
  #fb-courts:not(:empty){margin-bottom:var(--s-5);}
  .fb-courts-head{font-family:'Syne',sans-serif;font-size:11px;font-weight:700;letter-spacing:.15em;text-transform:uppercase;color:var(--lime);margin:0 0 var(--s-2);}
  .fb-court{display:flex;align-items:center;gap:var(--s-3);padding:9px 0;border-top:1px solid var(--glass-brd);font-size:13px;}
  .fb-court:last-of-type{border-bottom:1px solid var(--glass-brd);}
  .fb-court-lbl{font-family:'Syne',sans-serif;font-weight:800;font-size:12px;letter-spacing:.08em;text-transform:uppercase;white-space:nowrap;}
  .fb-court.off .fb-court-lbl{color:var(--muted);}
  .fb-court-when{flex:1;min-width:0;color:var(--muted);}
  .fb-court-btn{background:var(--glass);border:1px solid var(--glass-edge);color:var(--white);font-family:'DM Sans',sans-serif;font-size:12px;font-weight:600;border-radius:var(--r-pill);padding:6px 12px;cursor:pointer;white-space:nowrap;}
  .fb-court-btn.on{border-color:var(--lime);color:var(--lime);}
  .fb-court-btn:active{transform:scale(.96);}
  .fb-court-add{display:block;margin:var(--s-3) auto 0;background:none;border:none;color:var(--lime);font-family:'DM Sans',sans-serif;font-size:13px;font-weight:600;cursor:pointer;padding:6px;}

  /* FINISH TIME — the field on the setup wizard and in its own sheet */
  .finish-field{margin:var(--s-5) 0 var(--s-7);text-align:center;}
  .finish-label{display:block;font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--muted);margin-bottom:var(--s-3);}
  .finish-label span{color:#5a6a5c;text-transform:none;letter-spacing:0;}
  .finish-inp{background:rgba(8,14,8,.5);border:1px solid var(--glass-edge);border-radius:var(--r-ctl);color:var(--white);font-family:'DM Sans',sans-serif;font-size:17px;font-weight:600;padding:11px 14px;outline:none;text-align:center;min-width:150px;}
  .finish-inp:focus{border-color:var(--lime);}
  .finish-inp.big{display:block;width:100%;font-size:22px;padding:14px;margin-bottom:var(--s-4);}
  /* iOS renders an empty time input as blank rather than as a placeholder */
  .finish-inp::-webkit-date-and-time-value{text-align:center;}
  .finish-hint{font-size:var(--fs-sm);line-height:var(--lh-snug);color:var(--muted);margin-top:var(--s-3);}
  .fb-quick{display:flex;flex-wrap:wrap;gap:var(--s-2);justify-content:center;margin-bottom:var(--s-6);}

  /* NAME SUGGESTION CHIPS (setup wizard, injected by cloud.js) */
  #name-suggest{display:flex;flex-wrap:wrap;gap:8px;justify-content:center;margin-bottom:14px;}
  .name-suggest-label{width:100%;text-align:center;font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--muted);margin-bottom:2px;}
  .name-chip{transition:border-color .2s var(--ease),background .2s var(--ease),transform .15s var(--ease);box-shadow:inset 0 1px 0 rgba(255,255,255,.08);}
  .name-chip.used{opacity:.35;border-color:var(--glass-brd);cursor:default;text-decoration:line-through;}

  /* LIVE NIGHTS (injected by cloud.js for a device holding the creator key):
     the nights running on another of the organizer's devices and the last few
     finished, in the leaderboard's glass card. It sits after #setup-screen,
     below the fold, so the front door keeps its height lock and the two sports
     and Next fill the screen exactly as always; the top margin is the dock
     allowance the lock leaves, which puts the card's edge at the viewport's
     bottom, and the body's scroll lock lifts so a swipe brings it up. */
  #live-nights{width:min(600px,calc(100% - 2 * var(--page-pad-x)));margin:calc(80px + env(safe-area-inset-bottom)) auto calc(90px + env(safe-area-inset-bottom));}
  #live-nights .pts-bar-head:not(:first-child){border-top:1px solid var(--glass-brd);}
  .ln-row{display:flex;align-items:center;gap:var(--s-3);padding:var(--s-3) var(--s-4);}
  .ln-row+.ln-row{border-top:1px solid var(--glass-brd);}
  .ln-txt{flex:1;min-width:0;font-size:var(--fs-body);line-height:var(--lh-snug);}
  .ln-txt b{color:var(--lime);font-family:'Syne',sans-serif;letter-spacing:.04em;}
  .ln-sub{display:block;color:var(--muted);font-size:var(--fs-sm);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
  #live-nights .lime-btn,#live-nights .setup-back{flex:none;font-size:11px;letter-spacing:.06em;padding:var(--s-2) var(--s-4);border-radius:var(--r-ctl);}
  body.setup-locked:has(#live-nights){overflow-y:auto;}

  /* FLOATING DOCK — and the TV's reaction bar, the same floating pill */
  .dock,.v-react-bar{position:fixed;left:50%;transform:translateX(-50%);display:flex;border:1px solid var(--glass-edge);border-radius:var(--r-pill);backdrop-filter:blur(24px) saturate(1.6);-webkit-backdrop-filter:blur(24px) saturate(1.6);box-shadow:inset 0 1px 0 rgba(255,255,255,.12),0 12px 40px rgba(0,0,0,.45);}
  .dock{bottom:calc(12px + env(safe-area-inset-bottom));gap:4px;background:rgba(24,36,25,.72);padding:6px;z-index:90;max-width:calc(100% - 16px);overflow:hidden;}
  .dock-item{display:flex;flex-direction:column;align-items:center;gap:2px;min-width:64px;padding:7px 12px 6px;border-radius:var(--r-pill);color:var(--muted);text-decoration:none;font-size:10px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;transition:background .2s var(--ease),color .2s var(--ease),transform .15s var(--ease);}
  .dock-item .dock-ic{font-size:19px;line-height:1;}
  .dock-item:hover{color:var(--white);background:rgba(255,255,255,.06);}
  .dock-item:active{transform:scale(.94);}
  .dock-item.active{color:var(--lime);background:var(--lime-tint);}
  /* Five items — Live joins the four during a tournament — come to 363px in
     the house fonts, wider than a 360px phone, and a fixed element wider than
     the screen is a page you can drag sideways. The row tightens on phones
     that narrow rather than overhanging; the max-width above is the backstop
     for text scaled past that. */
  @media (max-width:370px){.dock-item{min-width:58px;padding:7px 10px 6px;}}
  @media (max-width:340px){.dock{gap:2px;padding:4px;}.dock-item{min-width:52px;padding:7px 6px 6px;}}
  @supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){.dock{background:#182419;}}
  @media (prefers-reduced-transparency: reduce){.dock{background:#182419;backdrop-filter:none;-webkit-backdrop-filter:none;}}

  /* FALLBACKS */
  /* no backdrop-filter support: solid surfaces keep full contrast */
  @supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
    .game-card,.pts-bar,.final-table-wrap,.v-court{background:var(--card);}
    .modal-box,.round-box,.photo-modal-box{background:var(--card);}
    .board-box{background:#0e130d;}
    .modal-overlay,#photo-modal{background:rgba(0,0,0,.8);}
  }
  @media (prefers-reduced-transparency: reduce){
    .game-card,.pts-bar,.final-table-wrap,.v-court{background:var(--card);backdrop-filter:none;-webkit-backdrop-filter:none;}
    .modal-box,.round-box,.photo-modal-box{background:var(--card);backdrop-filter:none;-webkit-backdrop-filter:none;}
    .board-box{background:#0e130d;backdrop-filter:none;-webkit-backdrop-filter:none;}
    .modal-overlay,#photo-modal{background:rgba(0,0,0,.8);backdrop-filter:none;-webkit-backdrop-filter:none;}
  }
  @media (prefers-reduced-motion: reduce){
    *,*::before,*::after{animation-duration:.01ms !important;animation-iteration-count:1 !important;transition-duration:.01ms !important;}
    .live-dot,.done-wait-dot{animation:none;}
  }

  /* TABLET & UP — phones stack one 600px column; from 720px (iPad portrait)
     the same pieces get room: wider columns, two courts side by side, and the
     bottom sheets float as centered dialogs instead of pinning to the bottom
     edge. From 1000px (iPad landscape) the game screen stops splitting into a
     column plus a rail: the draws take the whole width two at a time with the
     leaderboard underneath them, and the final screen puts the points table
     and the game log next to each other. */
  @media (min-width: 720px){
    /* the shell steps up once, from the tokens, so every page moves together */
    :root{--page-pad-x:24px;--page-pad-top:48px;}
    #setup-screen{padding:var(--page-pad-top) var(--page-pad-x) 90px;}
    #setup-screen.fit{padding-bottom:var(--s-6);}
    .setup-inner{max-width:640px;}
    /* the two sports stand side by side once there is width for it, so step one
       fills the row as well as the column */
    #setup-screen.fit .game-list{flex-direction:row;}
    /* a tall window stops stretching the cards and banks the rest as air around
       them, so the pair never turns into two empty columns */
    #setup-screen.fit .game-row{max-height:520px;}
    #setup-screen.fit .game-row-ic{height:clamp(120px,26vh,260px);}
    #game-screen{padding:36px 24px 100px;}
    .live-wrap,.pts-bar,.history-wrap,.end-wrap,#board-gen-wrap{max-width:680px;}
    #final-screen{max-width:680px;padding:var(--page-pad-top) var(--page-pad-x) 40px;}
    /* two courts play side by side instead of stacking */
    #courts-container{display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));align-items:start;}
    /* sheets become floating dialogs: full radius, popIn instead of slideUp */
    .modal-overlay{align-items:center;padding:32px;}
    .modal-box,.round-box,.board-box{border-radius:var(--r-sheet);border-bottom:1px solid var(--glass-edge);animation:popIn .3s var(--ease);}
    .modal-box{padding:30px 28px;max-height:calc(100vh - 64px);overflow-y:auto;}
    .aw-box{padding:0;overflow:hidden;max-height:min(700px,86vh);}
    .aw-body{padding-bottom:20px;}
    .round-box{max-height:min(780px,90vh);overflow:hidden;}
    .board-box{max-height:min(860px,92vh);overflow:hidden;}
    .round-footer{padding-bottom:16px;}
    .board-footer{padding-bottom:16px;}
  }
  @media (min-width: 1000px){
    /* iPad landscape and up. The draws are the thing being read across a room,
       so they take the full width two at a time and the leaderboard sits under
       them at that same width. The 380px rail it used to occupy squeezed both:
       the courts back into a single column, and the table into seven columns
       of a third of a screen. */
    #game-screen{max-width:1180px;margin:0 auto;padding:var(--s-9) var(--s-8) 110px;}
    .live-wrap,.pts-bar,.history-wrap,.end-wrap,#board-gen-wrap{max-width:none;}
    /* minmax rather than a flat repeat(2): one court still fills the row, and a
       third court drops to the next line instead of shrinking the other two */
    #courts-container{grid-template-columns:repeat(auto-fit,minmax(420px,1fr));gap:var(--s-5);}
    /* the card has the room now, so the parts you actually touch take it */
    .game-header{padding:var(--s-4) var(--s-6);}
    .winner-row{gap:var(--s-4);padding:var(--s-5);}
    .win-btn{padding:var(--s-5) var(--s-4);}
    .player-names-btn{font-size:17px;}
    .score-section,.confirm-wrap,.skip-wrap{padding-left:var(--s-5);padding-right:var(--s-5);}
    .pts-bar{margin-top:var(--s-6);}
    table.lb-table th{padding:var(--s-3) var(--s-4);}
    table.lb-table td{padding:var(--s-4);font-size:14.5px;}
    /* the played log follows the courts: two matches abreast, rounds full width */
    .history-list .m-list{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--s-3);align-items:start;}
    .history-list .m-list .log-div{grid-column:1/-1;}
    /* final screen: podium + points table beside the full game log */
    #final-screen:has(.rtabs){max-width:1080px;}
    #final-screen .rtabs{max-width:460px;margin-left:auto;margin-right:auto;}
    #panel-scores{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:10px;align-items:start;}
    #panel-scores>#final-podium,#panel-scores>.podium,#panel-scores>.final-table-wrap{grid-column:1;}
    #panel-scores>.game-log-wrap{grid-column:2;grid-row:1/span 2;}
    #panel-scores .final-table-wrap,#panel-scores .game-log-wrap{margin-bottom:0;}
    .copy-btn,.play-again-btn{display:block;max-width:460px;margin-left:auto;margin-right:auto;}
    .copy-btn{margin-top:14px;}
  }
