/* ==========================================================================
   Playbox - shared design system
   Sections: tokens / reset / layout / topbar / menu / setup / controls
             / modal+toast / boards (connect4, snakes, ludo, uno, memory, xo) / net
   ========================================================================== */

/* ---------- tokens ---------- */
:root{
  --bg:#0d1020;
  --bg-glow-1:#1b2450;
  --bg-glow-2:#2a1340;
  --panel:#171b2e;
  --panel-2:#1f2440;
  --panel-3:#283056;
  --line:#2e3659;
  --line-soft:#242b47;
  --text:#eef1ff;
  --muted:#98a1c6;
  --accent:#7c5cff;
  --accent-2:#43d9ad;
  --danger:#ff5c6c;
  --gold:#f7c948;

  --r-sm:8px; --r-md:14px; --r-lg:22px; --r-pill:999px;
  --shadow-1:0 2px 6px rgba(0,0,0,.28);
  --shadow-2:0 12px 34px rgba(0,0,0,.42);
  --shadow-3:0 22px 60px rgba(0,0,0,.55);
  --ease:cubic-bezier(.22,.68,.28,1);

  --seat-red:#f0483c;
  --seat-green:#22b36b;
  --seat-yellow:#f5c518;
  --seat-blue:#2f7df6;
}

/* ---------- reset ---------- */
*,*::before,*::after{box-sizing:border-box}
html,body{height:100%}
body{
  margin:0;
  background:
    radial-gradient(1100px 620px at 12% -8%, var(--bg-glow-1) 0%, transparent 62%),
    radial-gradient(900px 560px at 92% 6%, var(--bg-glow-2) 0%, transparent 58%),
    var(--bg);
  background-attachment:fixed;
  color:var(--text);
  font:15px/1.5 "Segoe UI Variable Text","Segoe UI",system-ui,-apple-system,"Helvetica Neue",Arial,sans-serif;
  -webkit-font-smoothing:antialiased;
  overscroll-behavior:none;
}
h1,h2,h3,h4{margin:0;font-weight:650;letter-spacing:-.015em}
p{margin:0}
button{font:inherit;color:inherit}
.muted{color:var(--muted)}
[hidden]{display:none !important}
::selection{background:var(--accent);color:#fff}

/* ---------- layout ---------- */
#app{
  min-height:100%;
  max-width:1180px;
  margin:0 auto;
  padding:0 clamp(12px,3vw,28px) 40px;
  display:flex;
  flex-direction:column;
}
.screen{display:none;animation:screen-in .34s var(--ease)}
.screen.is-active{display:block}
@keyframes screen-in{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}

/* ---------- topbar ---------- */
#topbar{
  position:sticky; top:0; z-index:40;
  display:flex; align-items:center; gap:14px;
  padding:14px 0 12px;
  background:linear-gradient(180deg, rgba(13,16,32,.94) 62%, rgba(13,16,32,0));
  backdrop-filter:blur(10px);
}
.brand{display:flex;align-items:center;gap:11px;min-width:0;flex:1}
.brand-mark{
  width:34px;height:34px;border-radius:11px;flex:none;
  background:conic-gradient(from 220deg,var(--seat-red),var(--seat-yellow),var(--seat-green),var(--seat-blue),var(--seat-red));
  box-shadow:0 0 0 1px rgba(255,255,255,.14), var(--shadow-1);
}
.brand-text{display:flex;flex-direction:column;line-height:1.2;min-width:0}
.brand-text strong{font-size:16px;letter-spacing:-.01em}
.brand-text small{color:var(--muted);font-size:12px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.icon-btn{
  width:38px;height:38px;flex:none;
  display:grid;place-items:center;
  border:1px solid var(--line); border-radius:12px;
  background:var(--panel); cursor:pointer;
  transition:background .16s, border-color .16s, transform .16s;
}
.icon-btn:hover{background:var(--panel-2);border-color:var(--panel-3)}
.icon-btn:active{transform:scale(.94)}

/* ---------- menu ---------- */
.menu-hero{padding:clamp(14px,4vw,38px) 2px clamp(18px,3vw,26px)}
.menu-hero h1{font-size:clamp(28px,5.2vw,44px);letter-spacing:-.03em}
.menu-hero p{color:var(--muted);margin-top:8px;font-size:clamp(14px,1.6vw,17px)}

.game-grid{
  display:grid;
  grid-template-columns:repeat(auto-fit,minmax(230px,1fr));
  gap:clamp(12px,2vw,18px);
}
.game-card{
  position:relative; overflow:hidden;
  text-align:left; cursor:pointer;
  padding:20px 20px 18px;
  min-height:186px;
  display:flex; flex-direction:column; gap:10px;
  border:1px solid var(--line);
  border-radius:var(--r-lg);
  background:linear-gradient(155deg,var(--panel-2),var(--panel) 72%);
  box-shadow:var(--shadow-1);
  transition:transform .2s var(--ease), box-shadow .2s, border-color .2s;
}
.game-card::after{
  content:""; position:absolute; inset:-40% -30% auto auto;
  width:200px;height:200px;border-radius:50%;
  background:radial-gradient(circle,var(--card-accent) 0%,transparent 68%);
  opacity:.2; transition:opacity .25s, transform .35s var(--ease);
}
.game-card:hover{transform:translateY(-4px);border-color:var(--card-accent);box-shadow:var(--shadow-2)}
.game-card:hover::after{opacity:.4;transform:scale(1.15)}
.game-card:active{transform:translateY(-1px)}
.gc-icon{
  width:50px;height:50px;border-radius:15px;display:grid;place-items:center;
  background:color-mix(in srgb, var(--card-accent) 20%, transparent);
  border:1px solid color-mix(in srgb, var(--card-accent) 42%, transparent);
  position:relative; z-index:1;
}
.gc-title{font-size:20px;letter-spacing:-.02em;position:relative;z-index:1}
.gc-tag{color:var(--muted);font-size:13.5px;position:relative;z-index:1;flex:1}
.gc-meta{
  display:flex;align-items:center;gap:8px;font-size:12px;color:var(--muted);
  position:relative;z-index:1;
}
.pill{
  padding:3px 9px;border-radius:var(--r-pill);
  background:var(--panel-3);border:1px solid var(--line);
  font-size:11.5px;font-weight:600;letter-spacing:.02em;
}

.stats-strip{
  margin-top:26px;display:flex;flex-wrap:wrap;gap:10px;
  color:var(--muted);font-size:13px;
}
.stat-chip{
  display:flex;align-items:center;gap:7px;
  padding:7px 13px;border-radius:var(--r-pill);
  background:var(--panel);border:1px solid var(--line-soft);
}
.stat-chip b{color:var(--text);font-variant-numeric:tabular-nums}

.credit{
  margin-top:clamp(26px,6vw,50px);
  padding:16px 2px 0;
  border-top:1px solid var(--line-soft);
  text-align:center;
  font-size:12.5px;
  color:var(--muted);
  letter-spacing:.01em;
}

/* ---------- setup ---------- */
.setup-wrap{max-width:620px;margin:0 auto;padding-top:clamp(8px,2vw,20px)}
.setup-head{display:flex;align-items:center;gap:15px;margin-bottom:26px}
.setup-icon{
  width:56px;height:56px;border-radius:17px;display:grid;place-items:center;flex:none;
  background:color-mix(in srgb,var(--card-accent) 20%,transparent);
  border:1px solid color-mix(in srgb,var(--card-accent) 42%,transparent);
}
.setup-head h2{font-size:26px;letter-spacing:-.025em}
.setup-block{margin-bottom:24px}
.setup-block h3{
  font-size:12px;text-transform:uppercase;letter-spacing:.09em;
  color:var(--muted);font-weight:700;margin-bottom:11px;
}
.chip-row{display:flex;flex-wrap:wrap;gap:9px}
.chip{
  padding:9px 17px;border-radius:var(--r-pill);cursor:pointer;
  border:1px solid var(--line);background:var(--panel);
  font-size:14px;font-weight:550;
  transition:background .15s,border-color .15s,color .15s,transform .15s;
}
.chip:hover{background:var(--panel-2)}
.chip:active{transform:scale(.96)}
.chip.is-on{
  background:color-mix(in srgb,var(--card-accent) 24%,var(--panel));
  border-color:var(--card-accent);
  color:#fff;
}

.seat-list{display:flex;flex-direction:column;gap:9px}
.seat-row{
  display:flex;align-items:center;gap:12px;
  padding:11px 13px;border-radius:var(--r-md);
  background:var(--panel);border:1px solid var(--line-soft);
}
.seat-dot{width:17px;height:17px;border-radius:50%;flex:none;box-shadow:0 0 0 3px rgba(255,255,255,.07)}
.seat-name{
  flex:1;min-width:0;background:transparent;border:0;outline:0;
  color:var(--text);font-size:15px;font-weight:550;padding:4px 2px;
  border-bottom:1px dashed transparent;
}
.seat-name:focus{border-bottom-color:var(--line)}
.toggle{
  display:flex;padding:3px;gap:3px;border-radius:var(--r-pill);
  background:var(--bg);border:1px solid var(--line-soft);flex:none;
}
.toggle button{
  border:0;background:transparent;cursor:pointer;color:var(--muted);
  padding:6px 13px;border-radius:var(--r-pill);font-size:12.5px;font-weight:650;
  transition:background .15s,color .15s;
}
.toggle button.is-on{background:var(--panel-3);color:var(--text)}

.option-list{display:flex;flex-direction:column;gap:9px}
.option-row{
  display:flex;align-items:center;gap:12px;cursor:pointer;
  padding:12px 13px;border-radius:var(--r-md);
  background:var(--panel);border:1px solid var(--line-soft);
}
.option-row:hover{border-color:var(--line)}
.option-row .opt-text{flex:1}
.option-row .opt-text b{display:block;font-weight:600}
.option-row .opt-text span{color:var(--muted);font-size:12.5px}
.switch{
  width:44px;height:26px;border-radius:var(--r-pill);flex:none;
  background:var(--panel-3);border:1px solid var(--line);position:relative;
  transition:background .18s;cursor:pointer;
}
.switch::after{
  content:"";position:absolute;top:2px;left:2px;width:19px;height:19px;border-radius:50%;
  background:var(--muted);transition:transform .18s var(--ease),background .18s;
}
.switch.is-on{background:color-mix(in srgb,var(--accent-2) 42%,var(--panel-3));border-color:var(--accent-2)}
.switch.is-on::after{transform:translateX(18px);background:#fff}

/* ---------- buttons ---------- */
.btn{
  border:1px solid var(--line);background:var(--panel-2);
  padding:11px 20px;border-radius:var(--r-pill);cursor:pointer;
  font-size:14.5px;font-weight:600;
  transition:transform .15s var(--ease),background .16s,border-color .16s,opacity .16s;
}
.btn:hover:not(:disabled){background:var(--panel-3)}
.btn:active:not(:disabled){transform:scale(.96)}
.btn:disabled{opacity:.4;cursor:not-allowed}
.btn-primary{
  background:linear-gradient(150deg,var(--accent),#5b3fe0);
  border-color:transparent;color:#fff;
  box-shadow:0 8px 22px rgba(124,92,255,.34);
}
.btn-primary:hover:not(:disabled){background:linear-gradient(150deg,#8d70ff,#6a4ee8)}
.btn-lg{width:100%;padding:15px 22px;font-size:16px;border-radius:var(--r-md)}
.btn-ghost{background:transparent}
.btn-sm{padding:8px 15px;font-size:13px}

/* ---------- game shell ---------- */
.game-shell{display:flex;flex-direction:column;gap:14px;padding-top:4px}
.hud{
  display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  padding:11px 13px;border-radius:var(--r-md);
  background:var(--panel);border:1px solid var(--line-soft);
}
.hud-seat{
  display:flex;align-items:center;gap:9px;
  padding:7px 13px 7px 9px;border-radius:var(--r-pill);
  border:1px solid transparent;background:var(--bg);
  transition:border-color .2s,background .2s,transform .2s var(--ease);
  font-size:13.5px;
}
.hud-seat .seat-dot{width:13px;height:13px;box-shadow:none}
.hud-seat.is-turn{
  border-color:var(--seat-color);
  background:color-mix(in srgb,var(--seat-color) 16%,var(--bg));
  transform:translateY(-2px);
}
.hud-seat .who{font-weight:600}
.hud-seat .sub{color:var(--muted);font-variant-numeric:tabular-nums}
.hud-spacer{flex:1}
.banner{
  min-height:26px;text-align:center;font-size:15px;font-weight:550;
  color:var(--muted);transition:color .2s;
}
.banner b{color:var(--text)}
.board-stage{display:grid;place-items:center;padding:2px}
/* Games that want the full width (not a centred board) opt in.
   justify-items:center above would otherwise shrink-wrap a block child. */
.board-stage.full{display:block;justify-items:stretch}
.action-bar{display:flex;justify-content:center;gap:10px;flex-wrap:wrap;min-height:44px;align-items:center}

.thinking{display:inline-flex;gap:4px;vertical-align:middle;margin-left:6px}
.thinking i{
  width:5px;height:5px;border-radius:50%;background:var(--muted);
  animation:blink 1.1s infinite;
}
.thinking i:nth-child(2){animation-delay:.18s}
.thinking i:nth-child(3){animation-delay:.36s}
@keyframes blink{0%,60%,100%{opacity:.25}30%{opacity:1}}

/* ---------- modal + toast ---------- */
.modal-layer{
  position:fixed;inset:0;z-index:100;
  display:grid;place-items:center;padding:22px;
  background:rgba(6,8,18,.72);backdrop-filter:blur(5px);
  animation:fade .2s var(--ease);
}
@keyframes fade{from{opacity:0}to{opacity:1}}
.modal{
  width:min(420px,100%);
  padding:26px;border-radius:var(--r-lg);
  background:linear-gradient(160deg,var(--panel-2),var(--panel));
  border:1px solid var(--line);box-shadow:var(--shadow-3);
  animation:pop .3s var(--ease);
  text-align:center;
}
@keyframes pop{from{opacity:0;transform:scale(.9) translateY(14px)}to{opacity:1;transform:none}}
.modal h2{font-size:23px;margin-bottom:8px}
.modal .modal-body{color:var(--muted);font-size:14.5px;margin-bottom:20px}
.modal .modal-actions{display:flex;gap:10px;justify-content:center;flex-wrap:wrap}
.modal-crown{font-size:46px;line-height:1;margin-bottom:10px;animation:pop .45s .1s var(--ease) backwards}

.toast-layer{
  position:fixed;left:50%;bottom:26px;transform:translateX(-50%);
  z-index:120;display:flex;flex-direction:column;gap:8px;align-items:center;
  pointer-events:none;
}
.toast{
  padding:10px 18px;border-radius:var(--r-pill);
  background:var(--panel-3);border:1px solid var(--line);
  box-shadow:var(--shadow-2);font-size:14px;font-weight:550;
  animation:toast-in .26s var(--ease);
}
.toast.out{animation:toast-out .26s var(--ease) forwards}
@keyframes toast-in{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
@keyframes toast-out{to{opacity:0;transform:translateY(-8px)}}

/* ---------- dice (shared: ludo + snakes) ---------- */
.dice{
  width:58px;height:58px;border-radius:14px;flex:none;
  background:linear-gradient(150deg,#fdfdff,#d8ddf0);
  box-shadow:inset 0 -3px 0 rgba(0,0,0,.12), var(--shadow-2);
  display:grid;grid-template:repeat(3,1fr)/repeat(3,1fr);
  padding:9px;gap:2px;cursor:pointer;border:0;
  transition:transform .18s var(--ease),box-shadow .18s;
}
.dice:disabled{cursor:default;opacity:.75}
.dice:not(:disabled):hover{transform:translateY(-3px) scale(1.04)}
.dice:not(:disabled):active{transform:scale(.95)}
.dice.rolling{animation:roll .5s var(--ease)}
@keyframes roll{
  0%{transform:rotate(0) scale(1)}
  30%{transform:rotate(140deg) scale(1.13)}
  60%{transform:rotate(280deg) scale(.94)}
  100%{transform:rotate(360deg) scale(1)}
}
.dice span{border-radius:50%;background:#1b2036;place-self:center;width:9px;height:9px}
.dice span.off{background:transparent}

/* ==========================================================================
   CONNECT FOUR
   ========================================================================== */
.c4-board{
  --cell:clamp(38px,10.5vw,64px);
  position:relative;
  padding:calc(var(--cell)*.16);
  border-radius:calc(var(--cell)*.28);
  background:linear-gradient(160deg,#2c47c9,#1b2c86);
  box-shadow:var(--shadow-3), inset 0 2px 0 rgba(255,255,255,.16);
}
.c4-grid{
  display:grid;
  grid-template-columns:repeat(7,var(--cell));
  grid-auto-rows:var(--cell);
  gap:calc(var(--cell)*.09);
  position:relative;z-index:2;
}
.c4-cell{
  border-radius:50%;
  background:radial-gradient(circle at 34% 30%, #0b0f1e, #0d1226 62%, #131a33);
  box-shadow:inset 0 3px 7px rgba(0,0,0,.75);
  position:relative;
}
.c4-disc{
  position:absolute;inset:0;border-radius:50%;
  background:radial-gradient(circle at 33% 28%, color-mix(in srgb,var(--disc) 62%,#fff), var(--disc) 58%, color-mix(in srgb,var(--disc) 68%,#000));
  box-shadow:inset 0 -3px 6px rgba(0,0,0,.4), 0 1px 3px rgba(0,0,0,.5);
  animation:c4-drop .44s cubic-bezier(.42,.02,.62,1.1);
}
@keyframes c4-drop{
  from{transform:translateY(var(--from,-420px))}
  70%{transform:translateY(0)}
  82%{transform:translateY(-7%)}
  100%{transform:translateY(0)}
}
.c4-disc.win{animation:c4-pulse 1s ease-in-out infinite}
@keyframes c4-pulse{
  0%,100%{box-shadow:inset 0 -3px 6px rgba(0,0,0,.4),0 0 0 0 rgba(255,255,255,.55)}
  50%{box-shadow:inset 0 -3px 6px rgba(0,0,0,.4),0 0 0 8px rgba(255,255,255,0)}
}
.c4-cols{
  position:absolute;inset:calc(var(--cell)*.16);z-index:3;
  display:grid;grid-template-columns:repeat(7,1fr);gap:calc(var(--cell)*.09);
}
.c4-col{border:0;background:transparent;cursor:pointer;border-radius:calc(var(--cell)*.2);position:relative}
.c4-col:disabled{cursor:default}
.c4-col:not(:disabled):hover{background:rgba(255,255,255,.09)}
.c4-ghost{
  position:absolute;top:calc(var(--cell)*-1.06);left:50%;transform:translateX(-50%);
  width:calc(var(--cell)*.86);height:calc(var(--cell)*.86);border-radius:50%;
  background:var(--disc);opacity:0;transition:opacity .15s;pointer-events:none;
}
.c4-col:not(:disabled):hover .c4-ghost{opacity:.85}

/* ==========================================================================
   SNAKES & LADDERS
   ========================================================================== */
.sl-wrap{display:flex;gap:clamp(10px,2.4vw,22px);align-items:flex-start;flex-wrap:wrap;justify-content:center}
.sl-board{
  --cell:clamp(30px,7.6vw,52px);
  position:relative;
  display:grid;grid-template-columns:repeat(10,var(--cell));grid-auto-rows:var(--cell);
  border-radius:var(--r-md);overflow:hidden;
  box-shadow:var(--shadow-3);
  border:3px solid #3b2a14;
}
.sl-cell{
  position:relative;
  padding:3px 0 0 4px;
  font-size:calc(var(--cell)*.23);font-weight:700;color:rgba(24,18,8,.5);
  font-variant-numeric:tabular-nums;
}
.sl-cell.odd{background:#f3e2c0}
.sl-cell.even{background:#e3cf9f}
.sl-cell.is-ladder{background:#cfe6bd}
.sl-cell.is-snake{background:#f1c3c3}
.sl-cell.is-goal{background:#f6dd8c}
.sl-cell .mark{
  position:absolute;right:3px;bottom:1px;font-size:calc(var(--cell)*.34);line-height:1;opacity:.9;
}
.sl-svg{position:absolute;inset:0;pointer-events:none;z-index:3}
.sl-token{
  position:absolute;z-index:4;
  width:calc(var(--cell)*.46);height:calc(var(--cell)*.46);border-radius:50%;
  background:radial-gradient(circle at 34% 30%, color-mix(in srgb,var(--seat-color) 55%,#fff), var(--seat-color) 60%, color-mix(in srgb,var(--seat-color) 62%,#000));
  border:2px solid rgba(255,255,255,.82);
  box-shadow:0 3px 7px rgba(0,0,0,.45);
  transition:left .18s linear, top .18s linear, transform .18s var(--ease);
}
.sl-token.hop{transform:scale(1.3)}
.sl-side{display:flex;flex-direction:column;gap:14px;align-items:center;min-width:150px}
.sl-legend{font-size:12.5px;color:var(--muted);text-align:center;line-height:1.7}
.sl-legend b{color:var(--text)}

/* ==========================================================================
   LUDO
   ========================================================================== */
.ludo-wrap{display:flex;gap:clamp(10px,2.4vw,22px);align-items:flex-start;flex-wrap:wrap;justify-content:center}
.ludo-board{
  --cell:clamp(21px,5.1vw,36px);
  position:relative;
  display:grid;grid-template-columns:repeat(15,var(--cell));grid-auto-rows:var(--cell);
  background:#fbfcff;border-radius:var(--r-md);overflow:hidden;
  box-shadow:var(--shadow-3);border:2px solid #10142a;
}
.lu-cell{border:1px solid rgba(16,20,42,.16);position:relative;background:#fbfcff}
.lu-cell.safe::after{
  content:"\2605";position:absolute;inset:0;display:grid;place-items:center;
  font-size:calc(var(--cell)*.62);color:rgba(16,20,42,.34);line-height:1;
}
.lu-cell.tinted.safe::after{color:rgba(255,255,255,.8)}
.lu-cell.blank{border:0;background:transparent}
.lu-yard{
  border-radius:calc(var(--cell)*.35);
  display:grid;grid-template:repeat(2,1fr)/repeat(2,1fr);
  place-items:center;padding:calc(var(--cell)*.55);
  box-shadow:inset 0 0 0 calc(var(--cell)*.34) #fbfcff;
}
.lu-slot{
  width:calc(var(--cell)*.78);height:calc(var(--cell)*.78);border-radius:50%;
  background:rgba(255,255,255,.6);box-shadow:inset 0 0 0 2px rgba(0,0,0,.2);
}
.ludo-token{
  position:absolute;z-index:6;
  width:calc(var(--cell)*.78);height:calc(var(--cell)*.78);
  border-radius:50%;
  background:radial-gradient(circle at 34% 28%, color-mix(in srgb,var(--seat-color) 48%,#fff), var(--seat-color) 58%, color-mix(in srgb,var(--seat-color) 60%,#000));
  border:2px solid #fff;
  box-shadow:0 3px 6px rgba(0,0,0,.45);
  transition:left .22s var(--ease), top .22s var(--ease), transform .18s var(--ease), width .2s, height .2s;
}
.ludo-token.stack{width:calc(var(--cell)*.62);height:calc(var(--cell)*.62)}
.ludo-token.movable{
  cursor:pointer;
  animation:lu-bob .9s ease-in-out infinite;
  box-shadow:0 0 0 3px rgba(255,255,255,.85), 0 4px 10px rgba(0,0,0,.5);
  z-index:8;
}
@keyframes lu-bob{0%,100%{transform:translateY(0)}50%{transform:translateY(-18%)}}
.ludo-token .cnt{
  position:absolute;right:-5px;top:-6px;
  min-width:15px;height:15px;padding:0 3px;border-radius:var(--r-pill);
  background:#10142a;color:#fff;font-size:10px;font-weight:800;
  display:grid;place-items:center;border:1px solid rgba(255,255,255,.55);
}
.ludo-side{display:flex;flex-direction:column;gap:14px;align-items:center;min-width:170px}
.ludo-yards{display:flex;flex-direction:column;gap:7px;width:100%}
.ludo-yardrow{
  display:flex;align-items:center;gap:9px;font-size:12.5px;
  padding:7px 11px;border-radius:var(--r-pill);
  background:var(--panel);border:1px solid var(--line-soft);
}
.ludo-yardrow.is-turn{border-color:var(--seat-color);background:color-mix(in srgb,var(--seat-color) 14%,var(--panel))}
.ludo-yardrow .seat-dot{width:12px;height:12px;box-shadow:none}
.ludo-yardrow .fill{flex:1;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ludo-yardrow b{font-variant-numeric:tabular-nums}

/* ==========================================================================
   UNO
   ========================================================================== */
.uno-table{
  display:flex;flex-direction:column;gap:clamp(10px,2vw,18px);
  padding:clamp(12px,2.4vw,22px);
  border-radius:var(--r-lg);
  background:radial-gradient(720px 420px at 50% 44%, #1d4a36 0%, #10261d 72%, #0b1a14 100%);
  border:1px solid #1d3a2c;
  box-shadow:var(--shadow-3), inset 0 1px 0 rgba(255,255,255,.07);
  min-height:min(70vh,560px);
  max-width:900px;margin:0 auto;
}
.uno-opponents{display:flex;justify-content:center;gap:clamp(10px,3vw,34px);flex-wrap:wrap}
.uno-opp{
  display:flex;flex-direction:column;align-items:center;gap:6px;
  padding:9px 15px;border-radius:var(--r-md);
  border:1px solid transparent;background:rgba(0,0,0,.22);
  transition:border-color .2s,background .2s,transform .2s var(--ease);
  min-width:112px;
}
.uno-opp.is-turn{border-color:var(--seat-color);background:rgba(0,0,0,.4);transform:translateY(-3px)}
.uno-opp .who{font-size:13.5px;font-weight:650;display:flex;align-items:center;gap:6px}
.uno-opp .who .seat-dot{width:9px;height:9px;box-shadow:none}
.uno-backs{display:flex;height:38px;align-items:center}
.uno-backs .mini{
  width:22px;height:33px;border-radius:4px;margin-left:-12px;
  background:linear-gradient(150deg,#22283f,#0e1225);
  border:1.5px solid #fbfcff;box-shadow:0 1px 3px rgba(0,0,0,.5);
}
.uno-backs .mini:first-child{margin-left:0}
.uno-opp .cardcount{font-size:11.5px;color:#9fd8bd;font-variant-numeric:tabular-nums}
.uno-opp.uno-called .cardcount{color:var(--gold);font-weight:800}

.uno-middle{display:flex;align-items:center;justify-content:center;gap:clamp(14px,4vw,42px);flex:1;padding:14px 0 26px}
.uno-pile{position:relative;display:grid;place-items:center}
.uno-pile .label{
  position:absolute;bottom:-22px;left:0;right:0;text-align:center;
  font-size:11px;letter-spacing:.09em;text-transform:uppercase;color:#8fc9ae;font-weight:700;
}
.uno-card{
  --w:clamp(56px,12vw,78px);
  width:var(--w);height:calc(var(--w)*1.5);
  border-radius:calc(var(--w)*.13);
  background:var(--uno-color,#2a2f4a);
  border:calc(var(--w)*.055) solid #fbfcff;
  box-shadow:0 5px 14px rgba(0,0,0,.5);
  position:relative;display:grid;place-items:center;flex:none;
  user-select:none;
}
.uno-card .oval{
  position:absolute;inset:11%;border-radius:50%/34%;
  background:rgba(255,255,255,.93);transform:rotate(-28deg);
}
.uno-card .glyph{
  position:relative;z-index:2;
  font-size:calc(var(--w)*.52);font-weight:900;line-height:1;
  color:var(--uno-color,#2a2f4a);
}
.uno-card .glyph.sym{font-size:calc(var(--w)*.38)}
.uno-card .corner{
  position:absolute;z-index:2;font-size:calc(var(--w)*.19);font-weight:900;color:#fff;line-height:1;
  text-shadow:0 1px 2px rgba(0,0,0,.55);
}
.uno-card .corner.tl{top:5%;left:8%}
.uno-card .corner.br{bottom:5%;right:8%;transform:rotate(180deg)}
.uno-card.wild{background:#20243c}
.uno-card.wild .oval{
  background:conic-gradient(from 45deg,#f0483c 0 25%,#2f7df6 0 50%,#f5c518 0 75%,#22b36b 0);
}
.uno-card.wild .glyph{color:#fff;text-shadow:0 2px 4px rgba(0,0,0,.75)}
.uno-card.back{background:#20243c}
.uno-card.back .oval{background:#c0342c}
.uno-card.back .glyph{
  color:#f5c518;font-size:calc(var(--w)*.3);font-style:italic;transform:rotate(-24deg);
}
.uno-deck{cursor:pointer;transition:transform .18s var(--ease)}
.uno-deck:not(.dim):hover{transform:translateY(-5px)}
.uno-deck.dim{opacity:.55;cursor:default}
.uno-discard .uno-card{animation:uno-land .3s var(--ease)}
@keyframes uno-land{from{transform:translateY(-34px) rotate(-12deg) scale(1.12);opacity:.4}to{transform:none;opacity:1}}
.uno-arrow{
  display:flex;flex-direction:column;align-items:center;gap:7px;
  color:#9fd8bd;font-size:11px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;
}
.uno-arrow svg{transition:transform .4s var(--ease)}
.uno-arrow.rev svg{transform:scaleX(-1)}
.uno-colorchip{
  width:18px;height:18px;border-radius:50%;border:2px solid rgba(255,255,255,.85);
  box-shadow:0 1px 4px rgba(0,0,0,.5);
}

.uno-hand-wrap{display:flex;flex-direction:column;gap:9px}
.uno-hand-head{
  display:flex;align-items:center;gap:10px;justify-content:center;
  font-size:13.5px;color:#cdead9;
}
.uno-hand{
  display:flex;justify-content:center;align-items:flex-end;
  min-height:calc(clamp(56px,12vw,78px)*1.68);
  padding:22px 4px 2px;overflow-x:auto;overflow-y:hidden;
  scrollbar-width:thin;
}
/* --slot-shift is set per render: a gap when the hand fits, an overlap when it does not. */
.uno-hand .slot{margin-left:var(--slot-shift,6px);flex:none}
.uno-hand .slot:first-child{margin-left:0}
.uno-hand .uno-card{
  transition:transform .18s var(--ease), box-shadow .18s, filter .18s;
  cursor:pointer;
}
.uno-hand .uno-card.playable:hover{transform:translateY(-19px) scale(1.05);box-shadow:0 14px 26px rgba(0,0,0,.55);z-index:5}
.uno-hand .uno-card.blocked{filter:grayscale(.72) brightness(.62);cursor:default}
.uno-hand .uno-card.just-drawn{animation:uno-draw .34s var(--ease)}
@keyframes uno-draw{from{transform:translateY(26px) scale(.86);opacity:0}to{transform:none;opacity:1}}

.uno-btn-uno{
  background:linear-gradient(150deg,var(--gold),#e0a41a);
  color:#2a1e00;border-color:transparent;font-weight:800;letter-spacing:.06em;
  box-shadow:0 8px 20px rgba(247,201,72,.34);
  animation:uno-throb .8s ease-in-out infinite;
}
@keyframes uno-throb{0%,100%{transform:scale(1)}50%{transform:scale(1.06)}}
.uno-picker{display:flex;gap:12px;justify-content:center}
.uno-swatch{
  width:62px;height:62px;border-radius:17px;border:2px solid rgba(255,255,255,.32);
  cursor:pointer;transition:transform .16s var(--ease),border-color .16s;
}
.uno-swatch:hover{transform:scale(1.1);border-color:#fff}

/* ==========================================================================
   MEMORY
   ========================================================================== */
.mem-wrap{display:flex;gap:clamp(10px,2.4vw,22px);align-items:flex-start;flex-wrap:wrap;justify-content:center}
.mem-side{display:flex;flex-direction:column;gap:14px;align-items:center;min-width:150px}
.mem-grid{
  --cell:clamp(46px,9.4vw,78px);
  display:grid;
  grid-template-columns:repeat(var(--cols),var(--cell));
  grid-auto-rows:var(--cell);
  gap:clamp(5px,1.1vw,10px);
}
.mem-grid.is-big{--cell:clamp(38px,7.6vw,66px)}
.mem-card{
  position:relative;padding:0;border:0;background:transparent;
  border-radius:calc(var(--cell)*.17);
  cursor:pointer;
  perspective:700px;
}
.mem-card:disabled{cursor:default}
.mem-inner{
  position:absolute;inset:0;
  transform-style:preserve-3d;
  transition:transform .42s var(--ease);
}
.mem-card.is-up .mem-inner{transform:rotateY(180deg)}
.mem-card:not(:disabled):hover .mem-inner{transform:translateY(-3px)}
.mem-card:not(:disabled):active .mem-inner{transform:translateY(-1px) scale(.97)}
.mem-face{
  position:absolute;inset:0;
  display:grid;place-items:center;
  border-radius:calc(var(--cell)*.17);
  backface-visibility:hidden;-webkit-backface-visibility:hidden;
  box-shadow:var(--shadow-1);
}
.mem-front{
  background:linear-gradient(150deg,#5b48d6,#332688 72%);
  border:1px solid rgba(255,255,255,.16);
}
/* The dot on the back of every card. */
.mem-front::after{
  content:'';width:40%;height:40%;border-radius:50%;
  background:radial-gradient(circle at 34% 30%, rgba(255,255,255,.52), rgba(255,255,255,.09) 60%, transparent 72%);
}
.mem-back{
  transform:rotateY(180deg);
  background:linear-gradient(150deg,var(--panel-2),var(--panel) 74%);
  border:1px solid var(--line);
  font-size:calc(var(--cell)*.46);line-height:1;
}
.mem-card.is-matched{animation:mem-pop .4s var(--ease)}
.mem-card.is-matched .mem-back{
  border-color:var(--owner);
  background:color-mix(in srgb,var(--owner) 20%,var(--panel));
  box-shadow:0 0 0 2px color-mix(in srgb,var(--owner) 52%,transparent),var(--shadow-1);
}
@keyframes mem-pop{0%{transform:scale(1)}45%{transform:scale(1.09)}100%{transform:scale(1)}}

/* ==========================================================================
   X'S & O'S
   ========================================================================== */
.xo-wrap{display:flex;flex-direction:column;align-items:center;gap:14px}
.xo-svg{width:100%;height:100%;display:block;animation:xo-pop .22s var(--ease)}
@keyframes xo-pop{from{transform:scale(.5);opacity:0}to{transform:scale(1);opacity:1}}

/* ---- classic 3x3 ---- */
.xo-board{
  --cell:clamp(66px,17vw,104px);
  display:grid;
  grid-template-columns:repeat(3,var(--cell));
  grid-auto-rows:var(--cell);
  gap:8px;
  padding:8px;
  border-radius:var(--r-lg);
  background:var(--panel);
  border:1px solid var(--line);
  box-shadow:var(--shadow-2);
}
.xo-cell{
  padding:18%;
  border:1px solid var(--line-soft);
  border-radius:var(--r-md);
  background:var(--bg);
  cursor:default;
  transition:background .16s,border-color .16s,transform .16s var(--ease);
}
.xo-cell.is-open{cursor:pointer}
.xo-cell.is-open:hover{background:var(--panel-2);border-color:var(--panel-3)}
.xo-cell.is-open:active{transform:scale(.95)}
.xo-cell.is-win{
  background:color-mix(in srgb,var(--gold) 20%,var(--bg));
  border-color:var(--gold);
  animation:xo-glow 1.1s ease-in-out infinite;
}
@keyframes xo-glow{
  0%,100%{box-shadow:0 0 0 0 rgba(247,201,72,.45)}
  50%{box-shadow:0 0 0 7px rgba(247,201,72,0)}
}

/* ---- ultimate: nine boards ---- */
.xo-ultimate{
  --cell:clamp(19px,4.4vw,32px);
  display:grid;
  grid-template-columns:repeat(3,auto);
  gap:9px;
  padding:9px;
  border-radius:var(--r-lg);
  background:var(--panel);
  border:1px solid var(--line);
  box-shadow:var(--shadow-2);
}
.xo-mini{
  position:relative;
  display:grid;
  grid-template-columns:repeat(3,var(--cell));
  grid-auto-rows:var(--cell);
  gap:3px;
  padding:5px;
  border-radius:var(--r-md);
  border:2px solid transparent;
  background:var(--bg);
  transition:border-color .2s,background .2s;
}
.xo-mini .xo-cell{padding:14%;border-radius:6px;background:var(--panel-2);border-color:transparent}
.xo-mini .xo-cell.is-open:hover{background:var(--panel-3)}
/* The board you are being sent to. */
.xo-mini.is-active{
  border-color:var(--accent-2);
  background:color-mix(in srgb,var(--accent-2) 11%,var(--bg));
}
.xo-mini.is-drawn{opacity:.55}
/* A claimed board dims its cells and shows one large mark on top. */
.xo-mini.is-won .xo-cell{opacity:.16}
.xo-mini-claim{
  position:absolute;inset:14%;
  pointer-events:none;
  display:block;
}
.xo-mini.is-win{animation:xo-glow 1.1s ease-in-out infinite;border-color:var(--gold)}
.xo-ultimate .xo-cell.is-win{background:color-mix(in srgb,var(--gold) 16%,var(--panel-2));animation:none}

/* ==========================================================================
   ACROSS DEVICES
   ========================================================================== */
.net-badge{
  display:inline-flex;align-items:center;gap:8px;
  margin:0 0 10px;padding:8px 15px;
  border:1px solid var(--line);border-radius:var(--r-pill);
  background:var(--panel);color:var(--muted);
  font-size:13px;cursor:pointer;
  transition:border-color .16s,color .16s,background .16s;
}
.net-badge::before{
  content:'';width:8px;height:8px;border-radius:50%;
  background:var(--muted);transition:background .16s;
}
.net-badge:hover{border-color:var(--panel-3);color:var(--text)}
.net-badge.is-on{border-color:var(--accent-2);color:var(--text)}
.net-badge.is-on::before{background:var(--accent-2);box-shadow:0 0 0 3px color-mix(in srgb,var(--accent-2) 26%,transparent)}

.net-lobby{display:flex;flex-direction:column;gap:12px;text-align:left;min-width:min(320px,76vw)}
.net-lobby .muted{font-size:13px}
.net-row{display:flex;gap:9px;align-items:center}
.net-label{font-size:13px;color:var(--muted);flex:none;min-width:74px}
.net-row .seat-name{flex:1}
.net-actions{display:flex;gap:9px;justify-content:center;flex-wrap:wrap}
.net-actions .btn{flex:1}
.net-sep{
  display:flex;align-items:center;gap:10px;
  color:var(--muted);font-size:12px;text-transform:uppercase;letter-spacing:.09em;
}
.net-sep::before,.net-sep::after{content:'';flex:1;height:1px;background:var(--line-soft)}
.net-code{
  text-align:center;font-size:34px;font-weight:700;letter-spacing:.22em;
  padding:12px 0 10px;color:var(--accent-2);
  font-variant-numeric:tabular-nums;
}
.net-code-input{text-align:center;letter-spacing:.2em;text-transform:uppercase;font-weight:600}
.net-status{font-size:12.5px;color:var(--gold);text-align:center;margin:0}

/* While another device is thinking, the board is visibly not yours to touch. */
.net-waiting{position:relative}
.net-waiting::after{
  content:'';position:absolute;inset:0;z-index:5;
  cursor:not-allowed;background:transparent;
}
.net-waiting .board-stage{opacity:.72;transition:opacity .2s}

/* ---------- rules sheet ---------- */
.rules-body{text-align:left;color:var(--muted);font-size:14px;line-height:1.65;max-height:58vh;overflow-y:auto}
.rules-body h4{color:var(--text);font-size:13px;text-transform:uppercase;letter-spacing:.08em;margin:14px 0 6px}
.rules-body h4:first-child{margin-top:0}
.rules-body ul{margin:0;padding-left:19px}
.rules-body li{margin-bottom:4px}
.rules-body b{color:var(--text)}

/* ---------- responsive ---------- */
@media (max-width:720px){
  .menu-hero{padding-top:8px}
  .hud{gap:7px;padding:9px}
  .hud-seat{padding:6px 10px 6px 8px;font-size:12.5px}
  .sl-side,.ludo-side,.mem-side{flex-direction:row;flex-wrap:wrap;justify-content:center;min-width:0;width:100%}
  .ludo-yards{flex-direction:row;flex-wrap:wrap;justify-content:center}
  .ludo-yardrow{flex:1 1 150px}
}
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms !important;animation-iteration-count:1 !important;transition-duration:.01ms !important}
}
