@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700;800&display=swap');

:root{
  --bg:#171925; --bg2:#1c1f2e; --panel:#1c1f2e; --panel2:#262a3d;
  --line:#2a2f45; --line2:#3a4166; --txt:#f3f4f6; --dim:#555b82;
  --acc:#6c63ff; --win:#34d399; --lose:#ff5f6d; --gold:#ffc53d;
  --acc2:#9d8cff;                      /* gradient partner for --acc */
  --grad:linear-gradient(180deg,#8079ff 0%,#6c63ff 45%,#5a51e6 100%);
  --r:0.875rem;

  /* One elevation scale, so panels, popovers and overlays read as layers
     of the same system instead of each inventing its own shadow. */
  --sh1:0 0.1rem 0.2rem #0004;
  --sh2:0 0.3rem 0.9rem #00000052;
  --sh3:0 1rem 2.75rem #00000070;
  --glow:0 0 1.1rem #6c63ff45;
  --ring:0 0 0 0.18rem #6c63ff45;       /* focus halo */
  --ease:cubic-bezier(.2,.7,.3,1);      /* shared easing for small moves */
  --spring:cubic-bezier(.34,1.4,.4,1);  /* playful pop for entrances */
  --nav-w:13.5rem;
  --chat-w:18.75rem;

  /* Fluid base size: the whole UI is expressed in rem, so this one value
     scales every dimension. It tracks the viewport between 900px and 1800px
     so zooming out fits more in rather than just shrinking text, and zooming
     in enlarges the layout without pushing it off screen. */
  font-size:clamp(12px,0.52vw + 8.2px,15px);
}
*{box-sizing:border-box}
html,body{height:100%}
body{margin:0;background:var(--bg);color:var(--txt);
  font:1rem/1.5 Poppins,"Segoe UI",system-ui,sans-serif;
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;
  display:flex;flex-direction:column;overflow:hidden}
/* Soft violet ambience, fixed and behind content. */
body::before{content:"";position:fixed;inset:0;z-index:-1;pointer-events:none;
  background:
    radial-gradient(55rem 38rem at 10% -12%,#6c63ff1c,#0000 68%),
    radial-gradient(48rem 34rem at 96% 108%,#9d8cff14,#0000 70%);
  animation:aurora 26s ease-in-out infinite alternate}
@keyframes aurora{
  0%{filter:hue-rotate(0deg) brightness(1)}
  50%{filter:hue-rotate(6deg) brightness(1.08)}
  100%{filter:hue-rotate(-5deg) brightness(.97)}}
code{font-family:ui-monospace,Consolas,monospace}
button{font:inherit}
::selection{background:#6c63ff40;color:#fff}

/* One focus standard for everything keyboard-reachable. :focus-visible keeps
   it off mouse clicks, so it reads as an accessibility aid, not a glitch. */
:focus-visible{outline:2px solid var(--acc);outline-offset:0.12rem;
  border-radius:0.3rem}

/* Honour reduced-motion: kill decorative transitions, keep layout intact. */
@media(prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms!important;
    animation-iteration-count:1!important;transition-duration:.01ms!important;
    scroll-behavior:auto!important}
}

/* ---- loading splash ----
   Two swords rush in from the sides, clash at the centre with a burst,
   then the wordmark rises. The .done class fades the whole splash out. */
.splash{position:fixed;inset:0;z-index:999;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:1.4rem;background:var(--bg);
  animation:splash-in .35s var(--ease) both}
.splash.done{opacity:0;pointer-events:none;transition:opacity .45s var(--ease)}
@keyframes splash-in{from{opacity:0}to{opacity:1}}

/* the stage holds the clash artwork; fixed size so the choreography is stable */
.splash-stage{position:relative;width:240px;height:240px;
  transform:scale(.62)}

/* ---- the swords ----
   Each sword is absolutely centred, rotated ±38°, and slides in along its
   own axis (diagonally) until the tips meet at the centre. */
.sword{position:absolute;left:50%;top:50%;width:64px;height:200px;
  margin:-100px 0 0 -32px}
.sword-l{transform:rotate(-38deg) translate(-190px,-156px);
  animation:sword-in-l .5s cubic-bezier(.2,.85,.3,1) .25s both,
    sword-clang-l .3s cubic-bezier(.3,1.6,.5,1) .75s both}
.sword-r{transform:rotate(38deg) translate(190px,-156px) scaleX(-1);
  animation:sword-in-r .5s cubic-bezier(.2,.85,.3,1) .25s both,
    sword-clang-r .3s cubic-bezier(.3,1.6,.5,1) .75s both}
/* rush in from the corners to the clash point */
@keyframes sword-in-l{
  from{transform:rotate(-38deg) translate(-190px,-156px);opacity:0}
  20%{opacity:1}
  to{transform:rotate(-38deg) translate(0,0);opacity:1}}
@keyframes sword-in-r{
  from{transform:rotate(38deg) translate(190px,-156px) scaleX(-1);opacity:0}
  20%{opacity:1}
  to{transform:rotate(38deg) translate(0,0) scaleX(-1);opacity:1}}
/* impact recoil: a small bounce back along the blade axis */
@keyframes sword-clang-l{
  0%{transform:rotate(-38deg) translate(0,0)}
  45%{transform:rotate(-36deg) translate(-13px,-11px)}
  100%{transform:rotate(-38deg) translate(0,0)}}
@keyframes sword-clang-r{
  0%{transform:rotate(38deg) translate(0,0) scaleX(-1)}
  45%{transform:rotate(36deg) translate(13px,-11px) scaleX(-1)}
  100%{transform:rotate(38deg) translate(0,0) scaleX(-1)}}

/* blade materials: cool steel with a bright edge highlight */
.blade-body{stroke:#0a0e17;stroke-width:1.5}
.blade-edge{fill:#eaf2ff;opacity:.85}
.guard{fill:#2a3450;stroke:#0a0e17;stroke-width:1.5}
.grip{fill:#1a2132;stroke:#0a0e17;stroke-width:1}
.pommel{fill:#2a3450;stroke:#0a0e17;stroke-width:1.5}
/* faint motion streaks trailing the incoming blades */
.sword::after{content:"";position:absolute;top:-30%;bottom:-10%;width:150%;
  left:-25%;background:linear-gradient(to bottom,#6c63ff30 0%,#0000 40%);
  filter:blur(8px);opacity:0}
.sword-l{filter:drop-shadow(0 0 .6rem #6c63ff40)}
.sword-r{filter:drop-shadow(0 0 .6rem #9d8cff40)}

/* ---- the clash burst ----
   Hidden until impact (.75s), then a ring expands + spikes shoot outward
   and fade. All timings line up with the sword-clang keyframes. */
.duel-clash{position:absolute;inset:0;width:100%;height:100%;
  pointer-events:none}
.burst-ring{fill:none;stroke:#fff;stroke-width:5;opacity:0;
  transform-origin:120px 120px;
  animation:burst-ring .55s ease-out .75s both}
@keyframes burst-ring{
  0%{opacity:.95;transform:scale(.18);stroke-width:9}
  100%{opacity:0;transform:scale(1.9);stroke-width:0}}
.burst-spikes{fill:#fff;opacity:0;
  transform-origin:120px 120px;
  animation:burst-spikes .5s cubic-bezier(.15,.8,.3,1) .75s both}
@keyframes burst-spikes{
  0%{opacity:0;transform:scale(.2)}
  30%{opacity:1}
  100%{opacity:0;transform:scale(1.55)}}
.burst-core{fill:#fff;opacity:0;transform-origin:120px 120px;
  animation:burst-core .35s ease-out .75s both;
  filter:drop-shadow(0 0 12px #fff)}
@keyframes burst-core{
  0%{opacity:1;transform:scale(2.4)}
  100%{opacity:0;transform:scale(.4)}}

/* the wordmark rises once the clash lands */
.splash-word{font-size:2.3rem;font-weight:800;font-style:italic;
  letter-spacing:-0.02em;line-height:1;white-space:nowrap;
  font-family:Poppins,"Segoe UI",system-ui,sans-serif;position:relative;
  animation:word-rise .5s var(--spring) 1.05s both}
@keyframes word-rise{
  from{opacity:0;transform:translateY(1.2rem) scale(.92)}
  to{opacity:1;transform:none}}
.splash-word b{font-weight:800;color:#fff}
.splash-word i{font-style:italic;
  background:linear-gradient(90deg,#9d8cff,#6c63ff,#9d8cff);
  background-size:200% 100%;-webkit-background-clip:text;background-clip:text;
  -webkit-text-fill-color:transparent;animation:splash-shift 2.4s linear infinite}
@keyframes splash-shift{to{background-position:200% 0}}
/* soft radial glow behind the clash, breathing */
.splash-stage::before{content:"";position:absolute;inset:-18%;
  background:radial-gradient(50% 50% at 50% 50%,#6c63ff20,#0000 70%);
  z-index:-1;animation:clash-glow 3s ease-in-out .8s infinite}
@keyframes clash-glow{
  0%,100%{opacity:.65;transform:scale(1)}
  50%{opacity:1;transform:scale(1.12)}}

@media(prefers-reduced-motion:reduce){
  .sword-l,.sword-r{animation-duration:.01s;animation-delay:0s}
  .burst-ring,.burst-spikes,.burst-core,
  .splash-word{animation-duration:.01s;animation-delay:0s}
}

.demo-banner{flex:0 0 auto;
  background:linear-gradient(90deg,#2a1d08,#3a2810,#2a1d08);color:var(--gold);
  border-bottom:1px solid #4a3410;padding:0.5rem 1rem;font-size:0.8rem;
  text-align:center;letter-spacing:.2px;font-weight:500;
  box-shadow:0 0.2rem 1rem #ffc53d14}
.demo-banner::before{content:"⚠ ";opacity:.85}

/* flex:1 instead of calc(100vh - banner) — survives the banner wrapping */
.shell{flex:1 1 auto;min-height:0;display:grid;
  grid-template-columns:var(--nav-w) minmax(0,1fr) var(--chat-w);
  overflow:hidden}

/* ---- side nav ---- */
.sidenav{background:var(--bg2);border-right:1px solid var(--line);
  display:flex;flex-direction:column;padding:0.9rem 0.65rem;
  min-width:0;overflow-y:auto}
.brand{display:flex;align-items:center;gap:0.6rem;font-weight:700;font-size:1.05rem;
  padding:0.25rem 0.5rem 1rem}
.logo{display:grid;place-items:center;width:1.85rem;height:1.85rem;
  border-radius:0.55rem;flex:0 0 auto;font-weight:800;letter-spacing:-.02em;
  background:var(--grad);
  font-size:0.8rem;color:#fff;box-shadow:0 0.25rem 0.85rem #6c63ff59}
/* wordmark gets the same gradient, as text */
.brand{background:linear-gradient(90deg,var(--txt),#aebbd6);
  -webkit-background-clip:text;background-clip:text;
  -webkit-text-fill-color:transparent}
.brand .logo{-webkit-text-fill-color:#fff}
#nav{display:flex;flex-direction:column;gap:0.12rem}

/* Section heading above each run of routes. Small, uppercase and accent-tinted
   so it separates the groups without competing with the items. */
.nav-group{font-size:0.62rem;font-weight:700;letter-spacing:.09em;
  text-transform:uppercase;color:var(--acc);opacity:.85;
  padding:0.95rem 0.75rem 0.4rem}
.nav-group:first-child{padding-top:0.15rem}

/* Items read as blue links at rest and brighten to white when active, with a
   full-height accent bar and gradient wash on the active row. */
.navitem{display:flex;align-items:center;gap:0.72rem;padding:0.62rem 0.75rem;
  border-radius:0.58rem;font-size:0.92rem;font-weight:600;
  color:#8ea8e8;cursor:pointer;border:0;background:none;width:100%;
  text-align:left;position:relative;
  transition:background .16s var(--ease),color .16s var(--ease),
    transform .16s var(--ease)}
.navitem:hover{background:var(--panel);color:#cfdcff;
  transform:translateX(0.14rem)}
.navitem.on{background:linear-gradient(90deg,#6c63ff1f,#6c63ff08 70%,#0000);
  color:#fff;box-shadow:var(--sh1)}
.navitem.on::before{content:"";position:absolute;left:-0.65rem;top:0.1rem;
  bottom:0.1rem;width:0.19rem;border-radius:0 0.19rem 0.19rem 0;
  background:var(--grad);box-shadow:0 0 0.55rem #6c63ffaa}
/* the active item's icon picks up the accent so the row reads at a glance */
.navitem.on .ico{filter:drop-shadow(0 0 0.45rem #6c63ff80)}
.navitem .ico{width:1.3rem;text-align:center;font-size:1.05rem;flex:0 0 auto;
  opacity:.92;transition:transform .18s var(--spring)}
.navitem:hover .ico{transform:scale(1.15)}
.nav-foot{margin-top:auto;padding:0.5rem}

/* ---- top bar ---- */
.main{display:flex;flex-direction:column;min-width:0;min-height:0}
.topbar{flex:0 0 auto;position:relative;z-index:95;
  display:flex;align-items:center;gap:0.9rem;
  padding:0.7rem 1.15rem;flex-wrap:wrap;
  border-bottom:1px solid var(--line);
  background:linear-gradient(var(--bg2),#0d111be0);
  backdrop-filter:blur(0.7rem);box-shadow:var(--sh1)}
.spacer{flex:1}

/* ---- wallet cluster ----
   A readout pill with a caret, the purple wallet button beside it, and a
   dropdown listing both figures. Relative so the menu can anchor to it. */
/* Centred against the topbar itself rather than the leftover flex space, so
   the Fair chip and name on the right can't shove it off-centre. */
.wallet-wrap{position:absolute;left:50%;transform:translateX(-50%);
  display:flex;align-items:center;gap:0.45rem;z-index:85}

.wallet{display:flex;align-items:center;gap:0.45rem;line-height:1.2;
  background:linear-gradient(var(--panel),#0f1420cc);
  backdrop-filter:blur(0.4rem);
  border:1px solid var(--line);border-radius:0.65rem;
  padding:0.34rem 0.6rem 0.34rem 0.7rem;cursor:pointer;
  color:inherit;text-align:left;
  transition:border-color .16s var(--ease),background .16s var(--ease),
    box-shadow .16s var(--ease)}
.wallet:hover{border-color:var(--line2);box-shadow:var(--glow)}
.wallet strong{font-size:1rem;color:#fff;font-variant-numeric:tabular-nums}
.wallet-ico{font-size:0.95rem;line-height:1;flex:0 0 auto}

/* caret sits in its own faint well, and flips when the menu is open */
.wallet-caret{display:grid;place-items:center;width:1.35rem;height:1.35rem;
  margin-left:0.15rem;border-radius:0.4rem;background:var(--panel2);
  transition:transform .18s var(--ease),background .16s var(--ease)}
.wallet-caret svg{width:0.85rem;height:0.85rem;fill:none;stroke:var(--dim);
  stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round}
.wallet[aria-expanded="true"] .wallet-caret{transform:rotate(180deg)}

/* the purple wallet button — the accent element of the cluster */
.wallet-btn{display:grid;place-items:center;width:2.35rem;height:2.1rem;
  flex:0 0 auto;cursor:pointer;border:0;border-radius:0.65rem;
  background:var(--grad);
  box-shadow:0 0.25rem 0.85rem #6c63ff55;
  transition:filter .16s var(--ease),transform .16s var(--ease),
    box-shadow .16s var(--ease)}
.wallet-btn:hover{filter:brightness(1.15);transform:translateY(-1px);
  box-shadow:0 0.4rem 1.1rem #6c63ff70}
.wallet-btn:active{transform:translateY(1px);box-shadow:var(--sh1)}
.wallet-btn svg{width:1.15rem;height:1.15rem;fill:none;stroke:#fff;
  stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}

/* ---- wallet dropdown ---- */
.wallet-menu{position:absolute;top:calc(100% + 0.5rem);left:0;z-index:60;
  min-width:11.5rem;padding:0.3rem;
  background:var(--panel);border:1px solid var(--line);
  border-radius:0.7rem;box-shadow:var(--sh3);
  animation:wallet-menu-in .16s var(--ease) both}
.wallet-menu[hidden]{display:none}
@keyframes wallet-menu-in{
  from{opacity:0;transform:translateY(-0.3rem)}
  to{opacity:1;transform:none}}

.wallet-row{display:flex;align-items:center;gap:0.5rem;width:100%;
  padding:0.55rem 0.6rem;border:0;border-radius:0.5rem;cursor:pointer;
  background:none;color:var(--txt);font-size:0.86rem;text-align:left;
  transition:background .14s var(--ease)}
.wallet-row:hover{background:var(--panel2)}
.wallet-row .grow{flex:1;min-width:0}
.wallet-row strong{color:#fff;font-variant-numeric:tabular-nums}
/* the figure currently in the pill is marked, so the menu shows state */
.wallet-row.on{background:var(--panel2)}
.wallet-row.on .grow{color:#fff;font-weight:600}

/* brief pop on switch, so the number visibly changes meaning */
.wallet.swapped strong{animation:wallet-pop .28s var(--ease)}
@keyframes wallet-pop{
  from{opacity:0;transform:translateY(-0.25rem)}
  to{opacity:1;transform:none}}
.fair{display:flex;align-items:center;gap:0.4rem;
  font-size:0.74rem;font-weight:600;color:var(--dim);cursor:pointer;
  padding:0.3rem 0.6rem;background:none;
  border:1px solid var(--line);border-radius:0.45rem;
  transition:border-color .16s var(--ease),color .16s var(--ease)}
.fair:hover{border-color:var(--win);color:var(--txt)}
/* sound toggle chip */
.sfx-chip svg{width:0.95rem;height:0.95rem;fill:none;stroke:currentColor;
  stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.sfx-chip .spk{fill:currentColor;stroke:none}
.sfx-chip .wav{transition:opacity .15s ease}
.sfx-chip.off .wav{opacity:0}
.sfx-chip.off{color:var(--dim);border-color:var(--line)}
/* Checked shield: the filled body carries the colour, the tick is stroked over
   it, so the badge reads as "verified" at this small size. */
.fair-shield{width:0.95rem;height:0.95rem;flex:0 0 auto;
  fill:var(--win);filter:drop-shadow(0 0 0.35rem #2fd37a55)}
.fair-shield .tick{fill:none;stroke:var(--bg);stroke-width:2.2;
  stroke-linecap:round;stroke-linejoin:round}
.me{display:flex;align-items:center;gap:0.5rem;font-size:0.85rem;
  font-weight:600;cursor:pointer;border:0;
  background:var(--grad);border-radius:0.4rem;
  padding:0 1.25rem;height:2.4rem;
  color:#fff;text-align:left;position:relative;letter-spacing:.015em;
  box-shadow:none;
  transition:filter .16s var(--ease),transform .16s var(--ease)}
.me:hover{filter:brightness(1.15)}
.me:active{transform:translateY(1px)}
.me .avatar{width:1.55rem;height:1.55rem;box-shadow:0 0 0 2px #ffffff33;
  color:inherit;flex:0 0 auto;display:none}
.me.signed-in{background:#1c1f2e;border:1px solid #2a2f45;
  padding:0.24rem 0.7rem 0.24rem 0.35rem;height:auto;color:var(--txt)}
.me.signed-in .avatar{display:inline-block;box-shadow:0 0 0 2px var(--line)}
.me.signed-in:hover{border-color:#3a4166;background:#262a3d;filter:none}
.me .avatar.guest{background:transparent;display:none}
.me-caret{display:grid;place-items:center;width:1.05rem;height:1.05rem;
  margin-left:0.1rem}
.me-caret svg{width:0.7rem;height:0.7rem;fill:none;stroke:var(--dim);
  stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round}
.me[aria-expanded="true"] .me-caret{transform:rotate(180deg)}

/* ---- auth modal ---- */
.auth-form{display:flex;flex-direction:column;gap:0.7rem;margin-top:0.6rem}
.auth-form input{background:var(--bg)}
.auth-err{color:var(--lose);font-size:0.8rem;min-height:1.1em;margin:0}
.avatar{width:1.7rem;height:1.7rem;border-radius:50%;
  background:linear-gradient(135deg,var(--acc),var(--acc2));
  display:inline-block;flex:0 0 auto;box-shadow:0 0 0 2px var(--line)}

/* ---- Roblox verification ---- */
.avatar.rbx{background:var(--panel2);overflow:hidden;
  box-shadow:0 0 0 2px #6c63ff66}
.avatar.rbx.has-img{box-shadow:0 0 0 2px var(--line)}

/* BloxyPot-style login modal */
.auth-steps{display:flex;flex-direction:column;gap:0.7rem;align-items:center;
  text-align:center;padding:0.35rem 0 0.5rem}
.rbx-modal-logo{width:5.5rem;height:5.5rem;border-radius:50%;
  display:grid;place-items:center;margin:0 auto 0.5rem;
  background:var(--grad);
  box-shadow:0 0.3rem 1.2rem #6c63ff55;
  animation:rbx-logo-in .4s var(--spring) both}
@keyframes rbx-logo-in{from{transform:scale(.6);opacity:0}}
.rbx-modal-swords{font-size:2.5rem;line-height:1;
  filter:drop-shadow(0 0 0.4rem #ffffff66)}
.rbx-modal-title{margin:0;font-size:1.9rem;font-weight:600;
  letter-spacing:-.01em;color:#f3f4f6;animation:rbx-fade .35s var(--ease) .08s both}
.rbx-modal-title b{color:#9d8cff;font-weight:800}
.rbx-modal-sub{margin:0 0 0.6rem;font-size:0.9rem;color:#9793ba;
  line-height:1.55;max-width:28rem;animation:rbx-fade .35s var(--ease) .12s both}
@keyframes rbx-fade{from{opacity:0;transform:translateY(0.3rem)}}
.auth-form{display:flex;flex-direction:column;gap:0.75rem;width:100%;
  text-align:left;animation:rbx-fade .35s var(--ease) .16s both}
.auth-form .field span{font-size:0.78rem;font-weight:600;color:#8f9ac6;
  margin-bottom:0.3rem;display:block}
.auth-form input[type=text]{width:100%;background:#1c1f2e}
/* checkbox rows */
.check{display:flex;align-items:center;gap:0.6rem;cursor:pointer;
  font-size:0.82rem;color:#9793ba;user-select:none}
.check input[type=checkbox]{appearance:none;-webkit-appearance:none;
  width:1.25rem;height:1.25rem;flex:0 0 auto;border-radius:0.3rem;
  border:2px solid #3a4166;background:#171925;cursor:pointer;position:relative;
  transition:background .15s ease,border-color .15s ease}
.check input[type=checkbox]:checked{background:var(--grad);border-color:#8079ff}
.check input[type=checkbox]:checked::after{content:"✓";position:absolute;
  inset:0;display:grid;place-items:center;color:#fff;font-size:0.75rem;
  font-weight:800}
.check b{color:#c7cce2;font-weight:600}
/* the Continue button spans the card bottom */
.auth-continue{width:100%;padding:0.8rem;font-size:0.95rem;font-weight:600;
  border-radius:0.4rem;margin-top:0.2rem}
.auth-err{color:var(--lose);font-size:0.8rem;min-height:1.1em;margin:0;
  text-align:center}

/* step 2 */
.rbx-code{display:flex;flex-wrap:wrap;gap:0.4rem;cursor:pointer;
  padding:0.7rem 0.8rem;background:#171925;
  border:1px dashed #3a4166;border-radius:0.5rem;user-select:all;
  align-items:center;position:relative;
  transition:border-color .15s var(--ease),background .15s var(--ease)}
.rbx-code:hover{border-color:var(--acc);background:#141624}
.rbx-code.copied{border-color:var(--win);border-style:solid}
.rbx-word{font-family:ui-monospace,Consolas,monospace;font-size:0.9rem;
  font-weight:600;color:var(--gold);background:#1c1f2e;
  border:1px solid #2a2f45;border-radius:0.35rem;padding:0.15rem 0.5rem}
.rbx-code.copied .rbx-word{color:var(--win)}
/* the live status tag riding along the code row */
.rbx-copied-tag{margin-left:auto;font-size:0.68rem;font-weight:700;
  color:var(--dim);letter-spacing:.04em;text-transform:uppercase;
  padding:0.14rem 0.5rem;border-radius:0.85rem;
  background:#1c1f2e;border:1px solid #2a2f45;pointer-events:none;
  transition:color .15s ease,border-color .15s ease}
.rbx-code:hover .rbx-copied-tag{color:#c7cce2}
.rbx-code.copied .rbx-copied-tag{color:var(--win);border-color:var(--win)}

/* ---- views ---- */
.views{flex:1 1 auto;min-height:0;overflow-y:auto;padding:1.25rem}
.view{display:none}
/* height:100% gives children (e.g. the battle lobby) a definite height to
   resolve percentages against; min-height keeps short views from stretching. */
.view.on{display:block;height:100%;animation:view-in .32s var(--ease)}
@keyframes view-in{from{opacity:0;transform:translateY(0.5rem)}}
h1{font-size:1.5rem;margin:0 0 0.25rem;letter-spacing:-.02em;font-weight:800}
h1::after{content:"";display:block;width:2.4rem;height:0.2rem;margin-top:0.4rem;
  border-radius:0.2rem;background:var(--grad);
  box-shadow:0 0 0.6rem #6c63ff66}
.sub{color:var(--dim);font-size:0.88rem;margin:0 0 1.15rem;max-width:62ch}
/* Panels: solid BloxyPot-style surfaces with soft 14px corners. */
.panel{background:#1c1f2e;
  border:1px solid #1b1935;
  border-radius:0.875rem;padding:1rem;min-width:0;
  box-shadow:0 0.35rem 1rem #00000040;
  transition:box-shadow .2s var(--ease)}
.panel:hover{box-shadow:0 0.45rem 1.3rem #0000004d}
/* views scroll past the sticky topbar; give the scrollbar the panel palette */
.views{scrollbar-color:var(--line) transparent;scrollbar-width:thin}
.views::-webkit-scrollbar{width:0.55rem;height:0.55rem}
.views::-webkit-scrollbar-thumb{background:#2b344a;border-radius:1rem}
.views::-webkit-scrollbar-thumb:hover{background:#3a4560}
.views::-webkit-scrollbar-track{background:transparent}
.grid{display:grid;gap:0.9rem}
.row{display:flex;gap:0.65rem;align-items:center;flex-wrap:wrap}
.sect{font-size:0.74rem;text-transform:uppercase;letter-spacing:.7px;
  color:var(--dim);margin:0 0 0.58rem;font-weight:600}

/* ---- controls ---- */
.btn{position:relative;overflow:hidden;
  background:var(--grad);color:#fff;border:0;
  border-radius:0.4rem;padding:0.58rem 1.05rem;font-size:0.9rem;font-weight:600;
  cursor:pointer;box-shadow:none,inset 0 1px 0 #ffffff26;
  transition:filter .14s var(--ease),transform .12s var(--ease),
    box-shadow .14s var(--ease)}
.btn::after{content:"";position:absolute;top:0;bottom:0;left:-70%;width:45%;
  background:linear-gradient(105deg,#0000,#ffffff2e,#0000);
  transform:skewX(-18deg);transition:left .5s var(--ease);pointer-events:none}
.btn:hover::after{left:130%}
.btn:hover:not(:disabled){filter:brightness(1.15)}
/* 1px press — enough to feel mechanical, too small to shift layout */
.btn:active:not(:disabled){transform:translateY(1px);box-shadow:none}
.btn:disabled{opacity:.42;cursor:not-allowed;filter:none;box-shadow:none}
.btn.ghost{background:var(--panel2);color:var(--txt);border:1px solid var(--line);
  box-shadow:none}
.btn.ghost::after{display:none}
.btn.ghost:hover:not(:disabled){border-color:var(--line2);background:#222a3a;
  filter:none;box-shadow:var(--glow)}
.btn.sm{padding:0.38rem 0.7rem;font-size:0.8rem;border-radius:0.35rem}
.btn.danger{background:linear-gradient(180deg,#ff6b78,#e84a58)}
.btn.go{background:linear-gradient(180deg,#3ddc93,#24b968);color:#04240f}
.btn.gold{background:linear-gradient(180deg,#ffcf55,#eaa91f);color:#201700;
  box-shadow:none,inset 0 1px 0 #fff5,0 0.2rem 0.9rem #ffc53d3d}
input,select{background:#1c1f2e;border:2px solid #2a2f45;color:#c7cce2;
  border-radius:0.4rem;padding:0.55rem 0.75rem;font-size:0.9rem;
  outline:none;min-width:0;max-width:100%;
  transition:border-color .16s ease,box-shadow .16s ease}
input::placeholder{color:#555b82}
input:focus,select:focus{border-color:var(--acc);
  box-shadow:0 0 0 0.2rem #6c63ff2b}
.field{display:flex;flex-direction:column;gap:0.3rem;min-width:0}
.field label{font-size:0.74rem;color:var(--dim)}
.chips{display:flex;gap:0.38rem;flex-wrap:wrap}
.chip{background:var(--panel2);border:1px solid var(--line);color:var(--dim);
  border-radius:1.25rem;padding:0.25rem 0.75rem;font-size:0.8rem;cursor:pointer;
  transition:border-color .15s ease,color .15s ease,box-shadow .15s ease}
.chip:hover,.chip.on{border-color:var(--acc);color:var(--txt);
  box-shadow:0 0 0.7rem #6c63ff2e}

/* ---- items ---- */
/* Rarity drives a faint wash behind the art as well as the top bar, so the
   tier is legible from the card's colour alone at a glance. The flat
   background is declared first as the fallback; browsers without color-mix
   drop the gradient line and keep the plain panel colour. */
.item{background:var(--panel2);
  background:
    radial-gradient(90% 60% at 50% 0%,
      color-mix(in srgb,var(--rar,#555) 17%,#0000),#0000),
    var(--panel2);
  border:1px solid var(--line);border-radius:0.6rem;
  padding:0.45rem 0.4rem;display:flex;flex-direction:column;gap:0.25rem;
  position:relative;overflow:hidden;min-width:0;
  box-shadow:inset 0 1px 0 #ffffff0a;
  transition:transform .18s var(--spring),box-shadow .18s var(--ease),
    border-color .18s var(--ease)}
.item::before{content:"";position:absolute;inset:0 0 auto;height:3px;
  background:var(--rar,#555);box-shadow:0 0 0.75rem var(--rar,#555)}
.item .art{height:4.6rem;display:flex;align-items:center;justify-content:center;
  font-size:1.5rem;overflow:hidden;
  filter:drop-shadow(0 0.25rem 0.55rem #0008);
  transition:transform .22s var(--spring)}
.item .art img{max-width:100%;max-height:100%;object-fit:contain;
  border-radius:0.35rem}
.item:hover{transform:translateY(-2px) scale(1.015);
  box-shadow:var(--sh2),0 0 1.2rem color-mix(in srgb,var(--rar,#555) 33%,#0000),
    inset 0 1px 0 #ffffff14;
  border-color:color-mix(in srgb,var(--rar,#555) 45%,var(--line))}
.item:hover .art{transform:scale(1.1) rotate(-3deg)}
.item .nm{font-size:0.66rem;font-weight:600;white-space:nowrap;overflow:hidden;
  text-overflow:ellipsis;text-align:center}
.item .vl{font-size:0.7rem;color:var(--gold);text-align:center;
  font-variant-numeric:tabular-nums}
.item.pick{outline:2px solid var(--acc);outline-offset:-1px;
  box-shadow:var(--ring),0 0 1.2rem #6c63ff3d,inset 0 1px 0 #ffffff14}
/* a corner tick, so selection survives being read without colour */
.item.pick::after{content:"✓";position:absolute;top:0.3rem;right:0.4rem;
  font-size:0.7rem;font-weight:800;color:var(--acc)}
.item-grid{display:grid;gap:0.5rem;
  grid-template-columns:repeat(auto-fill,minmax(6.5rem,1fr))}

/* ---- admin panel ---- */
.navitem.admin{color:#ffb020}
.navitem.admin:hover{color:#ffd57a}
.navitem.admin .ico{filter:drop-shadow(0 0 0.4rem #ffb02066)}
.admin-row{display:flex;align-items:center;gap:0.7rem;margin:0.45rem 0;
  flex-wrap:wrap}
.admin-lbl{font-size:0.78rem;font-weight:600;color:var(--dim);
  min-width:6.2rem;flex:0 0 auto}
.admin-in{flex:1;min-width:8rem}
.admin-amt{max-width:7rem;flex:0 0 auto}
.admin-sect{font-size:0.7rem;font-weight:800;letter-spacing:.09em;
  text-transform:uppercase;color:#ffb020;margin:1rem 0 0.4rem;
  padding-top:0.7rem;border-top:1px solid var(--line)}
.admin-btns{display:flex;gap:0.45rem;flex-wrap:wrap;align-items:center}
.admin-amt-wrap{display:inline-flex}
.admin-item-wrap{display:inline-flex;flex:1;min-width:12rem}
.admin-item-wrap select{flex:1}
.auth-err.good{color:var(--win)}
.admin-edge-live{font-size:0.8rem;font-weight:700;color:#ffb020;
  min-width:2.6rem;text-align:right;flex:0 0 auto}

/* ---- auth gate ----
   Two-column BloxyPot-style login wall: art panel left, form right. */
.gate{display:none}
.gate.on{display:grid;place-items:center;flex:1 1 auto;min-height:0;
  overflow-y:auto;padding:1.5rem;
  animation:gate-in .35s var(--ease) both}
@keyframes gate-in{from{opacity:0;transform:translateY(0.6rem)}}
.gate-card{display:grid;grid-template-columns:min(20rem,38%) minmax(0,1fr);
  width:min(52rem,100%);max-height:calc(100% - 1rem);
  background:#131520;border:1px solid #1b1935;border-radius:0.875rem;
  overflow:hidden;box-shadow:0 0.75rem 2.5rem #00000080;
  animation:rbx-logo-in .4s var(--spring) both}

/* left panel: full-bleed art, dark gradient up from the bottom, brand */
.gate-left{position:relative;display:flex;align-items:flex-end;
  justify-content:center;overflow:hidden;
  background:
    radial-gradient(120% 70% at 50% 20%,#3b2d7a,#1a1630 60%,#131520 100%),
    #131520}
.gate-left::before{content:"";position:absolute;inset:0;
  background:linear-gradient(rgba(16,15,32,0) 0%,rgba(16,15,32,.28) 35%,
    rgba(16,15,32,.85) 75%,#100f20 100%)}
.gate-left-art{position:absolute;inset:0;display:grid;place-items:center;
  font-size:clamp(4rem,55%,9rem);
  filter:drop-shadow(0 0.5rem 1.6rem #6c63ff88);opacity:.9;
  animation:hero-float 4.5s ease-in-out infinite;
  overflow:hidden}
.gate-left-orbs{position:absolute;inset:0}
.gate-left-brand{position:relative;display:flex;flex-direction:column;
  align-items:center;gap:0.55rem;padding:0 1rem 1.6rem}
.gate-brand-mark{font-size:2.6rem;line-height:1;
  filter:drop-shadow(0 0 0.9rem #6c63ff99)}
.gate-brand-word{font-size:2rem;font-weight:800;font-style:italic;
  letter-spacing:-0.02em;line-height:1;white-space:nowrap;
  font-family:Poppins,"Segoe UI",system-ui,sans-serif}
.gate-brand-word b{font-weight:800;color:#fff}
.gate-brand-word i{font-style:italic;
  background:linear-gradient(90deg,#9d8cff,#6c63ff,#9d8cff);
  background-size:200% 100%;-webkit-background-clip:text;background-clip:text;
  -webkit-text-fill-color:transparent;animation:splash-shift 2.4s linear infinite}

/* right panel: the form, matching the sign-in modal */
.gate-right{display:flex;flex-direction:column;gap:0.7rem;
  padding:1.8rem 1.7rem 1.4rem;overflow-y:auto;
  background:#131520}
.gate-title{margin:0;font-size:1.9rem;font-weight:600;
  letter-spacing:-.01em;color:#f3f4f6}
.gate-title b{color:#9d8cff;font-weight:800}
.gate-sub{margin:0 0 0.4rem;font-size:0.9rem;color:#9793ba;line-height:1.55}
.gate-form{display:flex;flex-direction:column;gap:0.75rem}
.gate-field{display:flex;flex-direction:column;gap:0.3rem}
.gate-field>span{font-size:0.78rem;font-weight:600;color:#8f9ac6}
.gate-field input{width:100%;background:#1c1f2e}
.gate-hint{font-size:0.72rem;margin:0.5rem 0 0;line-height:1.5;color:var(--dim)}
.gate-hint.auth-err{color:var(--lose)}
@media(max-width:62em){
  .gate-card{grid-template-columns:minmax(0,1fr);width:100%}
  .gate-left{min-height:9rem}
  .gate-left-art{font-size:4.5rem}
  .gate-brand-word{font-size:1.5rem}
  .gate-right{padding:1.4rem 1.2rem 1.2rem}
  .gate-title{font-size:1.5rem}
}
/* while gated, dim the nav so it reads as locked — but the wallet and
   the LOGIN chip stay interactive so the player always sees their money */
body.gated .sidenav{opacity:.45;pointer-events:none;filter:saturate(.6)}
body.gated .topbar{pointer-events:none}
body.gated .topbar .me{pointer-events:auto}
body.gated .topbar .wallet-wrap{pointer-events:auto;opacity:1;filter:none}
body.gated .topbar .fair,body.gated .topbar .sfx-chip{pointer-events:auto}
body.gated .chatpane{opacity:.35;pointer-events:none;filter:saturate(.5)}

/* ---- BloxyPot-style home ---- */
.home{display:flex;flex-direction:column;gap:1.6rem;max-width:none;
  margin:0 auto}

/* hero: big gradient-edged card like BloxyPot's landing banner */
.hero{position:relative;overflow:hidden;border-radius:0.75rem;
  background:linear-gradient(120deg,#20263f 0%,#1a1d2e 55%,#221f3a 100%);
  border:1px solid #252839;
  box-shadow:0 0.5rem 1.5rem #0000004d;
  animation:hero-in .45s var(--ease) both}
@keyframes hero-in{from{opacity:0;transform:translateY(0.7rem)}}
.hero-glow{position:absolute;inset:-40% -10% auto auto;width:60%;height:180%;
  background:radial-gradient(50% 50% at 70% 40%,#6c63ff2e,#0000 70%);
  pointer-events:none}
.hero-split{position:relative;display:flex;align-items:stretch;
  justify-content:space-between;gap:1.5rem;padding:1.75rem 2rem;flex-wrap:wrap}
.hero-left{display:flex;flex-direction:column;gap:0.85rem;min-width:15rem;
  flex:1 1 18rem;z-index:1}
.hero-hi{font-size:1.25rem;font-weight:700;color:#fff}
.hero-hi b{color:#9d8cff}
.hero-lvl{display:flex;align-items:center;gap:0.6rem}
.hero-lvl-chip{font-size:0.66rem;font-weight:800;letter-spacing:.08em;
  color:#c7cce2;background:#6c63ff26;border:1px solid #6c63ff40;
  border-radius:0.85rem;padding:0.14rem 0.6rem}
.hero-lvl-bar{position:relative;flex:1;max-width:11rem;height:0.45rem;
  background:#171925;border-radius:1rem;overflow:hidden}
.hero-lvl-bar i{position:absolute;inset:0 auto 0 0;border-radius:1rem;
  background:var(--grad);box-shadow:0 0 0.6rem #6c63ff80}
.hero-lvl-xp{font-size:0.7rem;color:var(--dim)}
.hero-stats{display:flex;gap:0.8rem;flex-wrap:wrap}
.hero-stat{display:flex;flex-direction:column;gap:0.15rem;
  background:#17192588;border:1px solid #252839;border-radius:0.6rem;
  padding:0.55rem 0.9rem;min-width:6.2rem}
.hero-stat-k{font-size:0.66rem;font-weight:700;letter-spacing:.05em;
  text-transform:uppercase;color:var(--dim)}
.hero-stat-v{font-size:1.05rem;font-weight:700;color:#fff;
  font-variant-numeric:tabular-nums}
.hero-btn{margin-top:0.35rem;align-self:flex-start;border:0;cursor:pointer;
  font:600 0.9rem Poppins,sans-serif;color:#fff;
  background:var(--grad);border-radius:0.4rem;padding:0.62rem 1.4rem;
  transition:filter .15s var(--ease),transform .12s var(--ease)}
.hero-btn:hover{filter:brightness(1.15)}
.hero-btn:active{transform:translateY(1px)}
/* right side: floating art + orbiting orbs */
.hero-right{position:relative;flex:0 1 21rem;min-height:13rem;
  display:grid;place-items:center;z-index:0}
/* the showcase: the player's most valuable pet, framed like a display case */
.hero-pet{position:relative;display:flex;flex-direction:column;
  align-items:center;gap:0.4rem;padding:1.3rem 1.5rem 1.1rem;
  background:linear-gradient(180deg,#1c1f2e88,#171925cc);
  border:1px solid color-mix(in srgb,var(--rar,#6c63ff) 40%,var(--line));
  border-top:3px solid var(--rar,#6c63ff);
  border-radius:0.9rem;overflow:visible;
  animation:hero-float 4.5s ease-in-out infinite}
.hero-pet-glow{position:absolute;inset:-35% -25%;pointer-events:none;
  background:radial-gradient(50% 50% at 50% 45%,
    color-mix(in srgb,var(--rar,#6c63ff) 24%,#0000),#0000 72%);
  z-index:-1}
.hero-pet-img{height:8.8rem;max-width:100%;object-fit:contain;
  filter:drop-shadow(0 0.35rem 1rem #0008)}
.hero-pet-nm{font-size:0.82rem;font-weight:700;color:#c7cce2;
  max-width:11rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.hero-art{font-size:5.2rem;line-height:1;
  filter:drop-shadow(0 0.4rem 1.2rem #6c63ff66);
  animation:hero-float 4.5s ease-in-out infinite}
@keyframes hero-float{
  0%,100%{transform:translateY(0) rotate(-6deg)}
  50%{transform:translateY(-0.8rem) rotate(4deg)}}
.hero-orb{position:absolute;border-radius:50%;pointer-events:none;
  filter:blur(0.12rem)}
.hero-orb.o1{width:3.4rem;height:3.4rem;left:6%;bottom:18%;
  background:radial-gradient(circle at 35% 30%,#9d8cff,#6c63ff88);
  animation:orb-a 7s ease-in-out infinite}
.hero-orb.o2{width:2.2rem;height:2.2rem;right:10%;top:14%;
  background:radial-gradient(circle at 35% 30%,#c7b8ff,#9d8cff99);
  animation:orb-b 5.5s ease-in-out infinite}
.hero-orb.o3{width:1.4rem;height:1.4rem;right:28%;bottom:10%;
  background:radial-gradient(circle at 35% 30%,#fff9,#9d8cffaa);
  animation:orb-a 4s ease-in-out infinite reverse}
@keyframes orb-a{0%,100%{transform:translate(0,0)}50%{transform:translate(0.8rem,-1rem)}}
@keyframes orb-b{0%,100%{transform:translate(0,0)}50%{transform:translate(-1rem,0.7rem)}}

/* section header: bold title + violet gradient line running right */
.home-section{display:flex;flex-direction:column;gap:0.85rem;
  animation:sect-in .4s var(--ease) .08s both}
@keyframes sect-in{from{opacity:0;transform:translateY(0.5rem)}}
.sect-head{display:flex;align-items:center;gap:0.8rem}
.sect-head-title{font-size:1.15rem;font-weight:800;color:#fff;
  letter-spacing:.02em;white-space:nowrap}
.sect-head-line{flex:1;height:2px;border-radius:1px;
  background:linear-gradient(to left,#6c63ffc6,#6c63ff00)}

/* game tiles: horizontal scroll row like BloxyPot's Top Games */
.gtile-row{display:flex;gap:1rem;overflow-x:auto;padding-bottom:0.4rem;
  scrollbar-width:thin;scrollbar-color:#2a2f45 transparent}
.gtile-row::-webkit-scrollbar{height:0.4rem}
.gtile-row::-webkit-scrollbar-thumb{background:#2a2f45;border-radius:1rem}
.gtile{position:relative;flex:0 0 13.5rem;display:flex;flex-direction:column;
  background:#232748;border-radius:0.5rem;overflow:hidden;
  text-decoration:none;color:inherit;
  transition:transform .18s var(--spring),box-shadow .18s ease,
    border-color .18s ease;outline:1px solid #00000000}
.gtile:hover{transform:translateY(-3px);
  box-shadow:0 0.4rem 1.2rem #0006,0 0 1.1rem #6c63ff3d;
  outline-color:#6c63ff66}
.gtile-art{position:relative;display:grid;place-items:center;
  height:7.2rem;background:linear-gradient(160deg,#2a2f55,#1d2040);
  overflow:hidden}
.gtile-ico{font-size:2.6rem;line-height:1;
  filter:drop-shadow(0 0.3rem 0.8rem #0008);
  transition:transform .22s var(--spring)}
.gtile:hover .gtile-ico{transform:scale(1.18) rotate(-5deg)}
.gtile-glow{position:absolute;inset:auto -30% -60% -30%;height:80%;
  background:radial-gradient(50% 60% at 50% 100%,#6c63ff33,#0000 70%);
  pointer-events:none}
.gtile-info{display:flex;flex-direction:column;gap:0.22rem;
  padding:0.85rem 0.95rem 0.95rem}
.gtile-name{font-size:0.98rem;font-weight:700;color:#fff}
.gtile-desc{font-size:0.74rem;color:#9793ba}
.gtile-play{margin-top:0.5rem;align-self:stretch;text-align:center;
  font-size:0.74rem;font-weight:700;letter-spacing:.06em;color:#cfc9ff;
  background:#6c63ff22;border:1px solid #6c63ff44;border-radius:0.35rem;
  padding:0.4rem 0;transition:background .15s ease,color .15s ease}
.gtile:hover .gtile-play{background:var(--grad);color:#fff;
  border-color:#0000}

/* live feed: grid rows like BloxyPot's table */
.feed{display:flex;flex-direction:column;gap:0.35rem}
.feed-row{display:grid;grid-template-columns:1.25fr 1fr 0.9fr 0.8fr 0.9fr;
  align-items:center;gap:0.5rem;padding:0.6rem 0.9rem;
  background:#1a1d2b;border-radius:0.5rem;
  animation:feed-in .3s var(--ease) both}
@keyframes feed-in{from{opacity:0;transform:translateY(0.3rem)}}
.feed-row:nth-child(2){animation-delay:.03s}.feed-row:nth-child(3){animation-delay:.06s}
.feed-row:nth-child(4){animation-delay:.09s}.feed-row:nth-child(5){animation-delay:.12s}
.feed-row:nth-child(6){animation-delay:.15s}.feed-row:nth-child(7){animation-delay:.18s}
.feed-row:nth-child(8){animation-delay:.21s}.feed-row:nth-child(9){animation-delay:.24s}
.feed-head{background:none;padding:0.2rem 0.9rem}
.feed-head>div{font-size:0.72rem;font-weight:700;color:#9ca3af;
  text-transform:uppercase;letter-spacing:.04em}
.feed-user{display:flex;align-items:center;gap:0.5rem;min-width:0}
.feed-av{width:1.5rem;height:1.5rem;border-radius:50%;flex:0 0 auto;
  display:grid;place-items:center;font-size:0.7rem;font-weight:800;color:#fff;
  text-shadow:0 1px 2px #0008}
.feed-name{font-size:0.82rem;font-weight:600;color:#e1e4f2;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.feed-game{display:flex;align-items:center;gap:0.4rem;
  font-size:0.8rem;color:#9793ba}
.feed-game-ico{font-size:0.95rem}
.feed-amt{font-size:0.82rem;color:#e1e4f2;font-weight:600;
  font-variant-numeric:tabular-nums;text-align:right}
.feed-mult{font-size:0.82rem;font-weight:700;color:var(--dim);
  font-variant-numeric:tabular-nums;text-align:right}
.feed-mult.hit{color:#7a73ff}
.feed-pay{font-size:0.82rem;font-weight:700;color:#34d399;
  font-variant-numeric:tabular-nums;text-align:right}
.feed-pay.zero{color:#555b82}
@media(max-width:44em){
  .feed-row{grid-template-columns:1.2fr 1fr 0.8fr;gap:0.4rem}
  .feed-amt,.feed-pay{display:none}
  .feed-head .feed-amt,.feed-head .feed-pay{display:none}
}

.r-common{--rar:#6b7a94}.r-uncommon{--rar:#3fa9f5}.r-rare{--rar:#9b6bff}
.r-epic{--rar:#e65ce0}.r-legend{--rar:#ffb020}.r-mythic{--rar:#ff4d5e}

/* ---- case reel ---- */
/* staked items previewed in an open-flip row */
.cf-lob-items{display:flex;align-items:center;gap:0.2rem;flex:0 0 auto}
.cf-chip{display:grid;place-items:center;width:2.9rem;height:2.9rem;
  font-size:1.5rem;background:var(--bg);border-radius:0.5rem;
  border-left:4px solid var(--rar,var(--line));overflow:hidden}
.cf-chip img{max-width:100%;max-height:100%;object-fit:contain}

/* ---- coinflip pick modal + stacked pets ---- */
.cf-pick-modal{width:min(36rem,95vw)}
.cf-pick-grid{max-height:22rem;overflow-y:auto;padding-right:0.3rem}
/* the stack count badge: shows how many copies you own / have picked */
.cf-stack{position:relative;cursor:pointer}
.cf-stack-count{position:absolute;top:0.25rem;left:0.3rem;
  font-size:0.68rem;font-weight:800;color:var(--dim);
  background:var(--panel);border:1px solid var(--line);
  border-radius:0.55rem;padding:0.08rem 0.4rem;
  pointer-events:none;transition:all .15s ease}
.cf-stack-count.on{color:#fff;background:var(--grad);border-color:#0000}

/* ---- coinflip face-off overlay ---- */
.cf-sheet{position:fixed;inset:0;z-index:100;display:grid;place-items:center;
  background:#000b;padding:1rem;animation:cffade .18s ease}
@keyframes cffade{from{opacity:0}}
.cf-pop{width:min(46rem,100%);max-height:calc(100vh - 2rem);
  overflow-y:auto;background:linear-gradient(165deg,#161c2b,#0f1420);
  border:1px solid var(--line2);
  border-radius:1.1rem;padding:1.1rem 1.4rem 1.4rem;
  box-shadow:var(--sh3),0 0 4rem #00000088,inset 0 1px 0 #ffffff12;
  animation:cfin .26s var(--spring)}
@keyframes cfin{from{opacity:0;transform:translateY(0.9rem) scale(.96)}}

.cf-pop-bar{display:flex;align-items:center;justify-content:center;
  position:relative;margin-bottom:0.4rem}
.cf-brand{font-weight:900;letter-spacing:0.06em;font-size:0.95rem}
.cf-x{position:absolute;right:0;top:0;background:none;border:0;
  color:var(--dim);font-size:1rem;cursor:pointer;padding:0.2rem 0.4rem;
  border-radius:0.4rem;transition:color .14s ease,background .14s ease}
.cf-x:hover{color:var(--txt);background:#ffffff0d}
.cf-x{position:absolute;right:0;top:0;background:none;border:0;
  color:var(--dim);font-size:1rem;cursor:pointer;padding:0.2rem 0.4rem}
.cf-x:hover{color:var(--txt)}

/* duel row: avatar — coin — avatar */
.cf-duel{display:grid;grid-template-columns:1fr auto 1fr;
  align-items:center;gap:1rem;padding:1.4rem 0 0.6rem}
.cf-duel-p{display:flex;flex-direction:column;align-items:center;gap:0.5rem;
  min-width:0;transition:opacity .25s ease}
.cf-duel-p.won .cf-pic{box-shadow:0 0 0 3px var(--gold),0 0 1.6rem #ffc53d66}
.cf-pic{position:relative;width:5.5rem;height:5.5rem;border-radius:50%;
  display:grid;place-items:center;font-size:2rem;font-weight:800;
  color:#06080d;box-shadow:0 0 0 3px var(--line)}
.cf-pip{position:absolute;right:-0.15rem;bottom:-0.15rem;
  width:1.8rem;height:1.8rem;border-radius:50%;background:var(--panel);
  box-shadow:0 0 0 2px var(--line);display:grid;place-items:center;
  font-size:0.8rem;font-weight:800;color:#4a3608}
.cf-pip[data-face=heads]{background:#f0b429}
.cf-pip[data-face=tails]{background:#8c99b0}
.cf-duel-nm{font-weight:700;font-size:1rem;max-width:100%;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.cf-coin-wrap{width:8rem;height:8rem;border-radius:50%;flex:0 0 auto;
  display:grid;place-items:center;background:var(--bg);
  box-shadow:0 0 0 4px var(--line2),0 0 1.8rem #ffc53d22,
    inset 0 0 2rem #0008;transition:box-shadow .3s ease}
.cf-duel-p.won ~ .cf-coin-wrap{box-shadow:0 0 0 4px var(--gold),
  0 0 2.2rem #ffc53d40,inset 0 0 2rem #0008}
/* the coin itself: a drawn disc that fills the ring edge to edge, with
   the H/T mark centred by grid. transition covers the squash animation. */
.cf-coin{width:100%;height:100%;border-radius:50%;display:grid;
  place-items:center;font-weight:800;font-size:2.6rem;color:#4a3608;
  transition:transform .1s linear}
.cf-coin::after{content:'H'}
.cf-coin[data-face=heads]{background:radial-gradient(circle at 34% 30%,
  #ffe694,#f0b429 58%,#b97e10)}
.cf-coin[data-face=tails]{background:radial-gradient(circle at 34% 30%,
  #cfd8e6,#8c99b0 58%,#5a6478)}
.cf-coin[data-face=tails]::after{content:'T'}

.cf-hash{display:block;width:fit-content;margin:0.2rem auto 1.1rem;
  background:var(--panel2);border:1px solid var(--line);border-radius:1rem;
  padding:0.3rem 0.8rem;font-family:ui-monospace,monospace;
  font-size:0.72rem;color:var(--dim);max-width:100%;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}

/* stakes side by side */
.cf-stakes{display:grid;grid-template-columns:1fr 1fr;gap:0.8rem}
.cf-stake{border:1px solid var(--line);border-radius:0.6rem;
  padding:0.6rem;min-width:0;transition:border-color .2s ease}
.cf-stake.won{border-color:var(--gold);box-shadow:0 0 0 1px var(--gold) inset}
.cf-stake-hd{display:flex;justify-content:space-between;align-items:baseline;
  font-size:0.85rem;font-weight:700;padding-bottom:0.5rem;
  border-bottom:1px solid var(--line);margin-bottom:0.5rem}
.cf-pct{color:var(--dim);font-size:0.78rem}
.cf-list{display:flex;flex-direction:column;gap:0.3rem}
.cf-row{display:flex;align-items:center;gap:0.7rem;min-width:0;
  background:var(--bg);border-left:4px solid var(--rar,var(--line));
  border-radius:0.55rem;padding:0.62rem 0.8rem}
.cf-row .ic{width:2.75rem;height:2.75rem;display:grid;place-items:center;
  flex:0 0 auto}
.cf-row .ic img{max-width:100%;max-height:100%;object-fit:contain}
.cf-row .inm{flex:1;min-width:0;font-size:1rem;font-weight:600;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.cf-row .iv{font-size:1rem;flex:0 0 auto}
.cf-out{text-align:center;margin-top:1rem;min-height:1.4rem}

@media(max-width:34em){
  .cf-duel{gap:0.5rem}
  .cf-pic{width:4rem;height:4rem;font-size:1.4rem}
  .cf-coin-wrap{width:5.5rem;height:5.5rem}
  .cf-coin{font-size:1.8rem}
  .cf-stakes{grid-template-columns:1fr}
}

/* ---- cases: picker card + per-case opening page ---- */
.case-card{cursor:pointer;transition:border-color .18s ease,transform .18s var(--spring),
  box-shadow .18s ease;text-align:center;padding:1.15rem 1rem 0.95rem}
.case-card:hover{border-color:var(--acc);transform:translateY(-3px);
  box-shadow:var(--sh3),0 0 1.4rem #6c63ff33}
.case-card:hover .case-open{color:var(--txt)}
.case-open{font-size:0.7rem;margin-top:0.5rem;color:var(--acc);
  transition:color .18s ease}
.case-hero{display:flex;align-items:center;gap:1rem;margin-top:0.75rem}
.case-hero-art{font-size:2.6rem;line-height:1;flex:0 0 auto;
  filter:drop-shadow(0 0 0.8rem #ffc53d55)}
.case-hero-nums{display:flex;gap:1.5rem;text-align:right;flex:0 0 auto}

.reel-wrap{position:relative;overflow:hidden;border:1px solid var(--line);
  border-radius:var(--r);background:
    linear-gradient(90deg,#0a0e17,#0e1320 20%,#0e1320 80%,#0a0e17),
    var(--bg);height:6.4rem;
  box-shadow:inset 0 0 2rem #00000080}
.reel{display:flex;gap:0.4rem;padding:0.55rem 0;will-change:transform}
.reel .item{min-width:5.25rem;width:5.25rem}

/* ---- mystery reel tiles ----
   During the spin every tile is just the pet image on a dark rarity-tinted
   tile: no name, no value. The landed winner gets its name revealed. */
.mystery{position:relative;flex:0 0 auto;display:grid;place-items:center;
  overflow:hidden;border:1px solid var(--line);border-radius:0.55rem;
  padding:0.35rem;box-sizing:border-box;
  background:
    radial-gradient(85% 60% at 50% 35%,
      color-mix(in srgb,var(--rar,#555) 15%,#0000),#0000),
    var(--panel2)}
.reel.vert .mystery{width:100%;flex-basis:auto}
/* the crossed-swords marker tile */
.mystery.swords-tile{
  background:
    radial-gradient(85% 60% at 50% 35%,#6c63ff3d,#0000 75%),
    #1a1630;
  border-color:#6c63ff88;
  box-shadow:inset 0 0 1rem #6c63ff26}
.mystery-swords{font-size:2rem;line-height:1;
  filter:drop-shadow(0 0 0.5rem #9d8cffcc);
  animation:swords-pulse 1.1s ease-in-out infinite}
@keyframes swords-pulse{
  0%,100%{transform:scale(1);filter:drop-shadow(0 0 0.35rem #9d8cffaa)}
  50%{transform:scale(1.12);filter:drop-shadow(0 0 0.8rem #9d8cffee)}}
.mystery.swords-tile.landed .mystery-swords{
  animation:swords-land .5s var(--spring)}
@keyframes swords-land{
  0%{transform:scale(.7)} 55%{transform:scale(1.35)} 100%{transform:scale(1.15)}}
.mystery .art-img{max-width:100%;max-height:100%;width:100%;height:100%;
  object-fit:contain;object-position:center;
  border-radius:0.35rem;
  filter:drop-shadow(0 0.2rem 0.4rem #0007)}
/* grid tiles must not grow to the image: clamp the grid track */
.mystery{grid-template-rows:100%;grid-template-columns:100%}
/* the landed winner: pop + name slides in under the art */
.mystery.landed{border-color:color-mix(in srgb,var(--rar,#ffc53d) 60%,var(--line));
  box-shadow:0 0 0.9rem color-mix(in srgb,var(--rar,#ffc53d) 40%,#0000);
  animation:mystery-land .4s var(--spring)}
@keyframes mystery-land{
  0%{transform:scale(.92)} 55%{transform:scale(1.06)} 100%{transform:scale(1)}}
.mystery-nm{position:absolute;left:0;right:0;bottom:0;
  font-size:0.6rem;font-weight:700;color:#fff;text-align:center;
  padding:0.22rem 0.3rem;white-space:nowrap;overflow:hidden;
  text-overflow:ellipsis;
  background:linear-gradient(#0000,#000000b3 45%);
  animation:nm-in .3s var(--ease) .1s both}
@keyframes nm-in{from{opacity:0;transform:translateY(0.3rem)}}
/* vertical reel (battles): mystery tiles stack, same look */
.reel.vert .mystery{width:100%;min-height:0}
/* result reveal: value hidden (dimmed) until .shown pops it in */
.reveal-card .vl{opacity:0;transform:translateY(0.3rem);
  transition:opacity .25s var(--ease),transform .25s var(--spring)}
.reveal-card.shown .vl{opacity:1;transform:none}
.reveal-fig{min-width:4.5rem;display:inline-block}

/* ---- WIN BANNER ----
   The big centered reveal: a tall dark card with a rarity-colored glow,
   large pet art, name, rarity tag, and a big gold value that counts up. */
.win-row{display:flex;gap:1.2rem;justify-content:center;flex-wrap:wrap;
  margin:1.1rem 0 0.4rem}
.win-banner{position:relative;display:flex;flex-direction:column;
  align-items:center;gap:0.4rem;width:11rem;padding:1.2rem 0.9rem 1rem;
  background:linear-gradient(180deg,#1c1f2e,#171925);
  border:1px solid color-mix(in srgb,var(--rar,#ffc53d) 45%,var(--line));
  border-radius:0.9rem;overflow:hidden;
  opacity:0;transform:scale(.75) translateY(1rem);
  transition:opacity .3s var(--ease),transform .38s var(--spring)}
.win-banner.shown{opacity:1;transform:none}
.win-banner::before{content:"";position:absolute;inset:0 0 auto;height:4px;
  background:var(--rar,#ffc53d);box-shadow:0 0 1rem var(--rar,#ffc53d)}
/* rarity glow halo behind the art */
.win-banner::after{content:"";position:absolute;inset:-30% -10% auto;
  height:110%;pointer-events:none;
  background:radial-gradient(50% 55% at 50% 45%,
    color-mix(in srgb,var(--rar,#ffc53d) 26%,#0000),#0000 72%);
  opacity:0;transition:opacity .4s ease .12s}
.win-banner.shown::after{opacity:1}
.win-art{height:6.2rem;display:grid;place-items:center;position:relative;z-index:1}
.win-art-img{max-width:100%;max-height:100%;object-fit:contain;
  filter:drop-shadow(0 0.35rem 0.9rem #0009)}
.win-banner.shown .win-art{animation:win-float 2.6s ease-in-out .4s infinite}
@keyframes win-float{
  0%,100%{transform:translateY(0)}
  50%{transform:translateY(-0.4rem)}}
.win-art-emoji{font-size:4rem}
.win-nm{font-size:0.92rem;font-weight:700;color:#fff;text-align:center;
  max-width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  position:relative;z-index:1}
.win-rar{font-size:0.62rem;font-weight:800;letter-spacing:.14em;
  color:var(--rar,#ffc53d);text-transform:uppercase;position:relative;z-index:1}
.win-vl{font-size:1.75rem;font-weight:800;color:var(--gold);
  font-variant-numeric:tabular-nums;line-height:1.1;position:relative;z-index:1;
  text-shadow:0 0 1.2rem #ffc53d40}
.win-banner.sold{opacity:.45;filter:grayscale(.7)}
.win-banner.sold .win-vl{text-decoration:line-through}

/* ---- BIG WIN celebration overlay ----
   Full-screen takeover for major wins: dark backdrop, spinning rays, a
   giant counting value, confetti rain. Click anywhere to dismiss. */
.bigwin{position:fixed;inset:0;z-index:90;display:grid;place-items:center;
  background:rgba(6,7,12,.88);backdrop-filter:blur(0.4rem);
  animation:cffade .25s ease both;cursor:pointer}
.bigwin.out{animation:bigwin-out .35s ease both}
@keyframes bigwin-out{to{opacity:0;transform:scale(1.04)}}
/* rotating light rays behind the card */
.bigwin-rays{position:absolute;inset:-50%;
  background:repeating-conic-gradient(from 0deg,
    #ffffff08 0deg 9deg,#0000 9deg 18deg);
  animation:bigwin-spin 22s linear infinite;pointer-events:none}
@keyframes bigwin-spin{to{transform:rotate(360deg)}}
.bigwin-card{position:relative;display:flex;flex-direction:column;
  align-items:center;gap:0.55rem;text-align:center;
  padding:2.6rem 3.2rem;max-width:92vw;
  background:linear-gradient(180deg,#1c1f2e,#14161f);
  border:1px solid #6c63ff55;border-radius:1.1rem;
  box-shadow:0 1rem 3rem #000c,0 0 2.5rem #6c63ff2e;
  animation:bigwin-pop .45s var(--spring) both}
@keyframes bigwin-pop{from{opacity:0;transform:scale(.7) translateY(1.4rem)}}
.bigwin-label{font-size:0.8rem;font-weight:800;letter-spacing:.35em;
  color:#9d8cff;text-transform:uppercase;
  animation:bigwin-glow 1.6s ease-in-out infinite alternate}
@keyframes bigwin-glow{from{text-shadow:0 0 0.5rem #6c63ff66}
  to{text-shadow:0 0 1.3rem #9d8cffcc}}
.bigwin-who{font-size:1.7rem;font-weight:800;color:#fff;
  max-width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.bigwin-value{font-size:3.6rem;font-weight:900;color:var(--gold);line-height:1.05;
  font-variant-numeric:tabular-nums;letter-spacing:-.02em;
  text-shadow:0 0 1.6rem #ffc53d59,0 0.1rem 0.3rem #0009}
.bigwin-sub{font-size:0.85rem;color:#9793ba}
.bigwin-items{display:flex;gap:0.55rem;margin-top:0.55rem;flex-wrap:wrap;
  justify-content:center}
.bigwin-item{display:flex;flex-direction:column;align-items:center;gap:0.2rem;
  width:5.6rem;padding:0.55rem 0.4rem;
  background:var(--panel2);border:1px solid var(--line);
  border-top:2px solid var(--rar,#555);border-radius:0.55rem;
  animation:bigwin-item-in .4s var(--spring) both}
.bigwin-item:nth-child(2){animation-delay:.08s}
.bigwin-item:nth-child(3){animation-delay:.16s}
.bigwin-item:nth-child(4){animation-delay:.24s}
.bigwin-item:nth-child(5){animation-delay:.32s}
@keyframes bigwin-item-in{from{opacity:0;transform:translateY(0.9rem) scale(.8)}}
.bigwin-item img{max-width:100%;height:2.7rem;object-fit:contain;
  filter:drop-shadow(0 0.2rem 0.4rem #0008)}
.bigwin-item-nm{font-size:0.6rem;font-weight:600;color:#c7cce2;
  max-width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.bigwin-hint{font-size:0.68rem;color:#555b82;margin-top:0.7rem;
  letter-spacing:.06em;text-transform:uppercase}
/* confetti: little falling shards */
.bigwin-confetti{position:fixed;inset:0;z-index:91;pointer-events:none;
  overflow:hidden}
.bigwin-confetti i{position:absolute;top:-1.2rem;left:var(--x);
  width:0.55rem;height:0.85rem;background:var(--c);opacity:0;
  transform:rotate(0deg);
  animation:confetti-fall 2.8s linear var(--d) infinite}
@keyframes confetti-fall{
  0%{transform:translateY(-1.4rem) rotate(0deg);opacity:0}
  8%{opacity:.95}
  85%{opacity:.9}
  100%{transform:translateY(105vh) rotate(680deg);opacity:0}}

/* ---- mini sword-clash overlay (reel version of the splash) ----
   Same SVG swords and burst as the splash screen, self-scaled to the host
   element. Two steel blades rush in from opposite corners, clash with a
   flash + shockwave + spikes, then everything fades. */
.clash-layer{position:absolute;inset:0;z-index:30;
  display:flex;align-items:center;justify-content:center;
  pointer-events:none;overflow:hidden;border-radius:inherit;
  background:radial-gradient(80% 70% at 50% 45%,#131520f2,#080b12f8);
  animation:clash-fade .12s ease both,clash-fade-out .3s ease 1.25s both}
@keyframes clash-fade{from{opacity:0}}
@keyframes clash-fade-out{to{opacity:0}}
.clash-stage{position:relative;width:min(70%,16rem);aspect-ratio:1;
  max-height:88%;flex:0 0 auto}
/* ---- the swords ----
   Each SVG sword pivots at the stage centre and starts flung out to a
   corner, then rushes in to vertical. The blades cross at the middle. */
.clash-sword{position:absolute;left:50%;top:50%;
  width:38%;height:88%;
  transform-origin:50% 82%;
  filter:drop-shadow(0 0 .4rem #6c63ff99)}
.clash-l{transform:translate(-50%,-82%) rotate(-115deg);
  animation:clash-in-l .42s cubic-bezier(.18,.9,.28,1) .08s both,
    clash-clang-l .28s cubic-bezier(.3,1.6,.5,1) .5s both,
    clash-out-sword .25s ease 1.1s both}
.clash-r{transform:translate(-50%,-82%) rotate(115deg);
  animation:clash-in-r .42s cubic-bezier(.18,.9,.28,1) .08s both,
    clash-clang-r .28s cubic-bezier(.3,1.6,.5,1) .5s both,
    clash-out-sword .25s ease 1.1s both}
@keyframes clash-in-l{
  from{transform:translate(-50%,-82%) rotate(-160deg) scale(.7);opacity:0}
  25%{opacity:1}
  to{transform:translate(-50%,-82%) rotate(-115deg) scale(1);opacity:1}}
@keyframes clash-in-r{
  from{transform:translate(-50%,-82%) rotate(160deg) scale(.7);opacity:0}
  25%{opacity:1}
  to{transform:translate(-50%,-82%) rotate(115deg) scale(1);opacity:1}}
/* impact recoil — blades bounce back a few degrees */
@keyframes clash-clang-l{
  0%{transform:translate(-50%,-82%) rotate(-115deg)}
  45%{transform:translate(-50%,-82%) rotate(-108deg)}
  100%{transform:translate(-50%,-82%) rotate(-115deg)}}
@keyframes clash-clang-r{
  0%{transform:translate(-50%,-82%) rotate(115deg)}
  45%{transform:translate(-50%,-82%) rotate(108deg)}
  100%{transform:translate(-50%,-82%) rotate(115deg)}}
@keyframes clash-out-sword{to{opacity:0}}
/* blade materials: gradient fills live in the SVG defs, strokes here */
.clash-sword .blade-body{stroke:#0a0e17;stroke-width:1.5}
.clash-sword .blade-edge{fill:#eaf2ff;opacity:.85}
.clash-sword .guard{fill:#2a3450;stroke:#0a0e17;stroke-width:1.5}
.clash-sword .grip{fill:#1a2132;stroke:#0a0e17;stroke-width:1}
.clash-sword .pommel{fill:#2a3450;stroke:#0a0e17;stroke-width:1.5}
/* ---- the burst (flash + ring + spikes) ----
   Hidden until impact (.5s), then fires in one quick pulse. */
.clash-burst{position:absolute;inset:0;width:100%;height:100%;
  pointer-events:none}
.clash-burst .burst-ring{fill:none;stroke:#fff;stroke-width:5;opacity:0;
  transform-origin:120px 120px;
  animation:clash-ring .5s ease-out .5s both}
@keyframes clash-ring{
  0%{opacity:.95;transform:scale(.18);stroke-width:9}
  100%{opacity:0;transform:scale(1.9);stroke-width:0}}
.clash-burst .burst-spikes{fill:#fff;opacity:0;
  transform-origin:120px 120px;
  animation:clash-spikes .45s cubic-bezier(.15,.8,.3,1) .5s both}
@keyframes clash-spikes{
  0%{opacity:0;transform:scale(.2)}
  30%{opacity:1}
  100%{opacity:0;transform:scale(1.55)}}
.clash-burst .burst-core{fill:#fff;opacity:0;transform-origin:120px 120px;
  animation:clash-core .3s ease-out .5s both;
  filter:drop-shadow(0 0 10px #fff)}
@keyframes clash-core{
  0%{opacity:1;transform:scale(2.4)}
  100%{opacity:0;transform:scale(.4)}}
/* an ambient violet glow behind the whole stage while it plays */
.clash-stage::before{content:"";position:absolute;inset:-25%;
  background:radial-gradient(50% 50% at 50% 50%,#6c63ff30,#0000 70%);
  z-index:-1;animation:clash-glow 1.2s ease-in-out .45s both}
@keyframes clash-glow{
  0%,100%{opacity:0;transform:scale(.9)}
  35%{opacity:1;transform:scale(1.1)}}

/* ---- SWORDS materialize reveal ----
   After the clash: the reel dims behind a violet wash, a bright scan line
   sweeps down the column, then the big pet punches through with expanding
   shockwave rings, its name and value blazing in. */
.reel-wrap.materialize{position:relative;overflow:hidden}
.reel-wrap.materialize::after{content:"";position:absolute;inset:0;
  z-index:5;pointer-events:none;
  background:radial-gradient(80% 70% at 50% 50%,#6c63ff3d,#080b12e8 85%);
  animation:mat-dim .4s ease both}
@keyframes mat-dim{from{opacity:0}to{opacity:1}}
/* the energy scan line */
.mat-scan{position:absolute;left:0;right:0;top:-15%;height:18%;z-index:6;
  pointer-events:none;
  background:linear-gradient(180deg,#0000,#9d8cffcc 40%,#fff 50%,#9d8cffcc 60%,#0000);
  box-shadow:0 0 1.2rem #9d8cffaa;
  animation:mat-scan .5s cubic-bezier(.4,.1,.3,1) both}
@keyframes mat-scan{from{top:-18%}to{top:105%}}
/* the reveal card */
.mat-reveal{position:absolute;inset:0;z-index:8;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:0.3rem;pointer-events:none;
  animation:mat-in .3s var(--spring) both}
@keyframes mat-in{from{opacity:0;transform:scale(.7)}}
/* shockwave rings — two staggered expanding circles */
.mat-ring{position:absolute;left:50%;top:50%;width:3rem;height:3rem;
  margin:-1.5rem 0 0 -1.5rem;border-radius:50%;
  border:0.22rem solid #9d8cff;opacity:0;
  animation:mat-ring .7s cubic-bezier(.15,.8,.3,1) both}
.mat-ring.r2{border-color:#fff;border-width:0.14rem;
  animation-delay:.12s}
@keyframes mat-ring{
  0%{opacity:.95;transform:scale(.3)}
  100%{opacity:0;transform:scale(4.5)}}
/* the pet punching through */
.mat-pet{position:relative;z-index:2;
  animation:mat-pet-in .45s var(--spring) .05s both}
.mat-pet img{height:6.5rem;max-width:100%;object-fit:contain;
  filter:drop-shadow(0 0 1.2rem #9d8cffbb) drop-shadow(0 0.3rem 0.6rem #0009)}
@keyframes mat-pet-in{
  0%{opacity:0;transform:scale(.3) translateY(1.5rem)}
  60%{opacity:1;transform:scale(1.15) translateY(-0.3rem)}
  100%{opacity:1;transform:scale(1)}}
.mat-name{position:relative;z-index:2;font-size:0.88rem;font-weight:700;
  color:#fff;text-align:center;max-width:95%;white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis;
  text-shadow:0 0 0.6rem #6c63ffcc;
  animation:mat-text .3s var(--ease) .25s both}
.mat-val{position:relative;z-index:2;font-size:1.35rem;font-weight:800;
  color:var(--gold);font-variant-numeric:tabular-nums;
  text-shadow:0 0 1rem #ffc53d66;
  animation:mat-text .3s var(--ease) .35s both}
@keyframes mat-text{from{opacity:0;transform:translateY(0.5rem)}}
/* fade everything out at the end — removed by JS after the hold */
.mat-reveal.mat-out,.reel-wrap.materialize.mat-out::after{
  animation:mat-out .3s ease both}
@keyframes mat-out{to{opacity:0}}

.needle{position:absolute;left:50%;top:0;bottom:0;width:2px;background:var(--gold);
  box-shadow:0 0 0.9rem var(--gold);z-index:2}

/* vertical reel (case battles) */
.reel.vert{flex-direction:column;padding:0 0.75rem}
.reel.vert .item{min-width:0;width:auto}
.needle.horiz{left:0;right:0;top:50%;bottom:auto;width:auto;height:2px}

/* ---- battle creation screen ---- */
.bc-head{display:flex;align-items:center;gap:0.75rem;margin-bottom:1.1rem;
  flex-wrap:wrap}
.bc-back{background:none;border:0;color:var(--dim);cursor:pointer;
  font-size:1.25rem;padding:0 0.2rem;line-height:1}
.bc-back:hover{color:var(--txt)}
.bc-title{font-size:1.4rem;font-weight:700;margin:0}
.bc-meter{display:flex;align-items:center;gap:0.75rem;background:var(--panel);
  border:1px solid var(--line);border-radius:0.58rem;padding:0.45rem 0.8rem;
  font-size:0.85rem}
.bc-meter .k{color:var(--dim);font-size:0.74rem;text-transform:uppercase;
  letter-spacing:.5px}
.bc-meter .sep{width:1px;height:1.1rem;background:var(--line)}

/* format / players picker */
.fmt-grid{display:grid;gap:0.75rem;
  grid-template-columns:repeat(auto-fit,minmax(15rem,1fr))}
.fmt-card{background:var(--panel);border:1px solid var(--line);
  border-radius:var(--r);padding:0.7rem 0.8rem 0.8rem;min-width:0;
  border-top:2px solid var(--fc,var(--acc))}
.fmt-card .lbl{font-size:0.68rem;font-weight:700;letter-spacing:.8px;
  text-transform:uppercase;color:var(--fc,var(--acc))}
.fmt-opts{display:flex;gap:0.4rem;margin-top:0.55rem}
.fmt-opt{flex:1;min-width:0;background:none;border:1px solid transparent;
  border-radius:0.5rem;color:var(--dim);cursor:pointer;padding:0.4rem 0.2rem;
  display:flex;flex-direction:column;align-items:center;gap:0.15rem}
.fmt-opt:hover{background:var(--panel2);color:var(--txt)}
.fmt-opt.on{background:var(--panel2);border-color:var(--fc,var(--acc));
  color:#fff}
.fmt-opt .pips{font-size:0.7rem;letter-spacing:-1px;opacity:.85}
.fmt-opt .nm{font-size:0.78rem;font-weight:600}

/* case basket */
.slot-grid{display:grid;gap:0.62rem;
  grid-template-columns:repeat(auto-fill,minmax(8.2rem,1fr))}
.slot{aspect-ratio:1;border-radius:var(--r);border:1px dashed var(--line);
  background:var(--bg);display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:0.35rem;cursor:pointer;
  color:var(--dim);min-width:0}
.slot:hover{border-color:var(--acc);color:var(--txt);
  box-shadow:inset 0 0 1rem #6c63ff14}
.slot .plus{display:grid;place-items:center;width:2rem;height:2rem;
  border-radius:0.5rem;background:var(--panel2);font-size:1.1rem}
.slot .cap{font-size:0.78rem}
.bskt{position:relative;background:var(--panel);border:1px solid var(--line);
  border-radius:var(--r);padding:0.7rem;display:flex;flex-direction:column;
  align-items:center;gap:0.25rem;min-width:0;overflow:hidden}
.bskt::before{content:"";position:absolute;inset:0 0 auto;height:3px;
  background:var(--rar,var(--acc))}
.bskt .art{font-size:1.9rem;line-height:1.2}
.bskt .nm{font-size:0.76rem;font-weight:600;text-align:center;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}
.bskt .pr{font-size:0.74rem;color:var(--gold)}
.bskt-qty{display:flex;align-items:center;gap:0.3rem;margin-top:0.2rem}
.qbtn{width:1.35rem;height:1.35rem;border-radius:0.35rem;border:1px solid var(--line);
  background:var(--panel2);color:var(--txt);cursor:pointer;line-height:1;
  display:grid;place-items:center;font-size:0.8rem;padding:0}
.qbtn:hover{border-color:var(--acc)}
.bskt-qty .n{font-size:0.8rem;font-weight:700;min-width:1.2rem;text-align:center}

/* win modes */
.mode-grid{display:grid;gap:0.62rem;
  grid-template-columns:repeat(auto-fit,minmax(16rem,1fr))}
.mode-card{display:flex;gap:0.62rem;text-align:left;align-items:flex-start;
  background:var(--panel);border:1px solid var(--line);
  border-left:2px solid var(--mc,var(--acc));border-radius:0.62rem;
  padding:0.7rem 0.8rem;cursor:pointer;min-width:0;color:var(--txt)}
.mode-card:hover{background:var(--panel2);transform:translateY(-1px)}
.mode-card.on{background:var(--panel2);border-color:var(--mc);
  box-shadow:inset 0 0 0 1px var(--mc),0 0 1rem color-mix(in srgb,var(--mc) 22%,#0000)}
.mode-card .mi{font-size:1.1rem;line-height:1.3;flex:0 0 auto}
.mode-card .mt{font-weight:600;font-size:0.88rem;color:var(--mc)}
.mode-card.on .mt{color:#fff}
.mode-card .md{font-size:0.76rem;color:var(--dim);line-height:1.45;
  margin-top:0.1rem}

/* ---- case battle stage ----
   Fits the whole battle in the viewport: fixed header/footer, the player
   columns take the remaining height. min-width/min-height:0 everywhere stops
   the reel's content from forcing the grid wider than the screen. */
.battle{display:flex;flex-direction:column;gap:10px;
  height:var(--bh,70vh)}
.battle-head{display:flex;justify-content:space-between;align-items:center;
  flex:0 0 auto}

/* ---- case track: every case in the battle, with the live one highlighted ---- */
.ctrack{flex:0 0 auto;display:flex;gap:0.3rem;align-items:center;
  overflow-x:auto;padding:0.1rem 0 0.2rem;scrollbar-width:none}
.ctrack::-webkit-scrollbar{display:none}
.ctk{flex:0 0 auto;display:flex;align-items:center;gap:0.3rem;
  background:var(--panel);border:1px solid var(--line);
  border-radius:0.5rem;padding:0.22rem 0.45rem;opacity:.42;
  transition:opacity .25s ease,border-color .25s ease,transform .25s ease}
.ctk .art{font-size:0.95rem;line-height:1}
.ctk .nm{font-size:0.68rem;white-space:nowrap;max-width:6rem;
  overflow:hidden;text-overflow:ellipsis}
/* already opened: visible but receded */
.ctk.done{opacity:.72}
.ctk.done .nm{color:var(--dim)}
/* the case being opened right now */
.ctk.live{opacity:1;border-color:var(--gold);transform:scale(1.04);
  box-shadow:0 0 0 1px var(--gold) inset}
.ctk.live .nm{color:var(--fg);font-weight:600}
/* clip the win pulse: scale(1.025) on an edge column would otherwise
   overflow the page and flash a horizontal scrollbar */
.battle-cols{flex:1 1 auto;min-height:0;display:grid;gap:10px;overflow:hidden}
.battle-foot{flex:0 0 auto}
.bcol{display:flex;flex-direction:column;gap:8px;min-width:0;min-height:0;
  background:var(--panel);border:1px solid var(--line);
  border-radius:var(--r);padding:11px}
.bcol-head{display:flex;align-items:center;gap:8px;flex:0 0 auto;min-width:0}
.bcol-head .nm{font-weight:600;flex:1;min-width:0;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap;font-size:13px}
.bcol-head .tot{font-size:17px;font-weight:700;color:var(--gold)}
/* column splits 55% reel / 45% pulled items */
.bcol .reel-wrap{flex:0 0 42%;min-height:0;height:auto}
.bcol-got{flex:1 1 58%;min-height:0;display:flex;flex-direction:column;
  gap:4px;overflow-y:auto;padding-top:8px;margin-top:2px;
  border-top:1px solid var(--line)}
.bcol-got::-webkit-scrollbar{width:5px}
.bcol-got::-webkit-scrollbar-thumb{background:var(--line);border-radius:3px}
.bcol.won{border-color:var(--win);box-shadow:0 0 0 1px var(--win) inset;
  animation:bwin .45s ease}
.bcol.lost{opacity:.62}
@keyframes bwin{
  0%{transform:scale(1)} 45%{transform:scale(1.025)} 100%{transform:scale(1)}}

/* terminal: only the last pull counts — fade the rest, ring the decider */
.bcol-got.term .item.mini{opacity:.3;transition:opacity .3s ease}
.bcol-got.term .item.mini:last-child{opacity:1;
  outline:1px solid var(--lose);outline-offset:-1px}

/* wild: lowest wins, so flag it in the "reversed" colour */
.bcol.won.wild{border-color:#2fd37a}

/* ---- waiting lobby (open battle before it starts) ---- */
/* Fill the scroll area so the bot prompt can sit in the middle of the dead
   space below the roster rather than hugging the header. */
.wait{display:flex;flex-direction:column;gap:0.9rem;min-height:100%}
.wait-top{display:flex;align-items:center;gap:0.75rem;flex-wrap:wrap}
.wait-top .ttl{font-weight:700;font-size:1.05rem}
.pulse{display:inline-block;width:0.5rem;height:0.5rem;border-radius:50%;
  background:var(--gold);animation:pls 1.1s ease-in-out infinite}
@keyframes pls{0%,100%{opacity:1}50%{opacity:.25}}
.seat-grid{display:grid;gap:0.62rem;
  grid-template-columns:repeat(auto-fit,minmax(10rem,1fr))}
.seat{background:var(--panel);border:1px solid var(--line);
  border-radius:var(--r);padding:0.9rem 0.8rem;min-height:7.5rem;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:0.4rem;text-align:center;min-width:0;
  box-shadow:inset 0 1px 0 #ffffff0a;
  transition:transform .16s var(--spring),border-color .16s ease,
    box-shadow .16s ease}
.seat:hover{transform:translateY(-2px)}
.seat.open{border-style:dashed;color:var(--dim)}
.seat.open:hover{border-color:var(--acc);color:var(--txt)}
.seat.filled{border-color:var(--acc);box-shadow:0 0 1rem #6c63ff24,
  inset 0 1px 0 #ffffff10}
.seat .av{width:2.6rem;height:2.6rem;border-radius:50%;flex:0 0 auto;
  display:grid;place-items:center;font-weight:700;color:#06080d;
  font-size:1rem}
.seat .who{font-size:0.85rem;font-weight:600;white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis;max-width:100%}
.seat .role{font-size:0.7rem;color:var(--dim)}
.seat .spin{width:1.5rem;height:1.5rem;border-radius:50%;
  border:2px solid var(--line);border-top-color:var(--acc);
  animation:sp .8s linear infinite}
@keyframes sp{to{transform:rotate(360deg)}}

/* full-width band under the seat grid: the host's "fill the rest" action */
/* ---- lobby case lineup: the cases this battle will open, in order ---- */
.lineup{flex:1 1 auto;display:flex;flex-direction:column;
  justify-content:center;gap:0.6rem;min-height:0;padding:0.4rem 0}
.lineup-hd{display:flex;align-items:baseline;gap:0.5rem;
  font-size:0.78rem;color:var(--dim);text-transform:uppercase;
  letter-spacing:0.04em}
.lineup-hd b{color:var(--fg);font-size:0.85rem;letter-spacing:0}
/* up to 25 cases can be queued — wrap, and scroll rather than shove the
   roster off-screen */
.lineup-row{display:flex;gap:0.5rem;flex-wrap:wrap;align-items:flex-start;
  overflow-y:auto;min-height:0}
.lcase{position:relative;flex:0 0 auto;width:5.4rem;
  background:var(--panel);border:1px solid var(--line);
  border-radius:0.62rem;padding:0.6rem 0.35rem 0.5rem;text-align:center}
.lcase .art{font-size:1.65rem;line-height:1.1}
.lcase .nm{font-size:0.68rem;margin-top:0.2rem;white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis}
.lcase .pr{font-size:0.68rem;color:var(--gold);font-weight:600}
.lcase .ix{position:absolute;top:0.22rem;left:0.3rem;font-size:0.6rem;
  color:var(--dim)}

/* roster + prompt sit below the lineup, sized to their content; the lineup
   above takes the slack, which keeps this pair low on the screen */
.wait-mid{flex:0 0 auto;display:flex;flex-direction:column;gap:0.9rem}
.callbots{display:flex;align-items:center;justify-content:center;
  gap:0.9rem;flex-wrap:wrap;text-align:center;
  background:var(--panel2);border:1px dashed var(--line);
  border-radius:var(--r);padding:1.2rem 1rem}
.callbots .cb-txt{font-size:0.88rem;color:var(--dim)}
.callbots .cb-txt b{color:var(--fg);font-weight:600}

/* ---- jackpot slider ----
   A strip of segments sized by each side's share, spun under a fixed centre
   needle. Several identical laps are rendered so the travel looks continuous. */
.jp{position:relative;overflow:hidden;border:1px solid var(--line);
  border-radius:0.62rem;background:var(--bg);height:3.1rem;
  margin-bottom:0.5rem}
.jp-strip{display:flex;height:100%;will-change:transform}
.jp-seg{display:flex;align-items:center;justify-content:center;
  flex:0 0 auto;height:100%;font-size:0.76rem;font-weight:600;
  color:#06080d;white-space:nowrap;overflow:hidden;
  border-right:1px solid #0006;padding:0 0.3rem}
.jp-needle{position:absolute;left:50%;top:0;bottom:0;width:3px;
  margin-left:-1.5px;background:var(--gold);z-index:3;
  box-shadow:0 0 0.8rem var(--gold)}
.jp-needle::before,.jp-needle::after{content:"";position:absolute;
  left:50%;transform:translateX(-50%);border:0.34rem solid transparent}
.jp-needle::before{top:0;border-top-color:var(--gold)}
.jp-needle::after{bottom:0;border-bottom-color:var(--gold)}
.jp-fade{position:absolute;inset:0;z-index:2;pointer-events:none;
  background:linear-gradient(90deg,var(--bg),#0000 18%,#0000 82%,var(--bg))}

/* reveal banner above the result row */
.reveal{display:flex;align-items:center;gap:0.62rem;flex-wrap:wrap;
  background:var(--panel2);border:1px solid var(--line);
  border-left:2px solid var(--rc,var(--acc));border-radius:0.62rem;
  padding:0.55rem 0.8rem;margin-bottom:0.5rem;font-size:0.85rem}
.reveal .rt{font-weight:700;color:var(--rc,var(--acc))}
.reveal .odds{display:flex;gap:0.45rem;flex-wrap:wrap;margin-left:auto}
.odds b{font-weight:600}
.odds .o{background:var(--panel);border:1px solid var(--line);
  border-radius:1rem;padding:0.1rem 0.55rem;font-size:0.76rem;
  color:var(--dim);white-space:nowrap}
.odds .o.hit{border-color:var(--gold);color:var(--gold)}

/* group: per-member split chips */
.splits{display:flex;gap:0.4rem;flex-wrap:wrap}
.splits .s{background:var(--panel);border:1px solid var(--win);
  color:var(--win);border-radius:1rem;padding:0.1rem 0.55rem;font-size:0.76rem}

/* compact card used inside a battle column */
.item.mini{width:var(--cell,48px);padding:4px;gap:2px;border-radius:7px}
.item.mini .art{height:auto;font-size:var(--cellart,16px)}
.item.mini .art-img{max-height:calc(var(--cellart,16px) * 1.4)}
.item.mini .nm{display:none}
.item.mini .vl{font-size:9px;text-align:center}

/* inside a vertical reel the card is full-column width: art left, text right */
.reel.vert .item.mini{width:auto;flex-direction:row;align-items:center;
  gap:6px;padding:0 8px;justify-content:flex-start}
.reel.vert .item.mini::before{inset:0 auto 0 0;height:auto;width:3px}
.reel.vert .item.mini .art{font-size:19px;flex:0 0 auto}
.reel.vert .item.mini .art-img{max-height:26px}
.reel.vert .item.mini .nm{display:block;flex:1;min-width:0;font-size:10px}
.reel.vert .item.mini .vl{font-size:9px;text-align:right;flex:0 0 auto}

/* pulled items: one row each — art, name, value. Full column width with a
   properly sized pet image (fills the row height without overshooting). */
.bcol-got .item.mini{width:100%;flex:0 0 auto;flex-direction:row;
  align-items:center;gap:0.45rem;padding:0.3rem 0.5rem;border-radius:0.45rem;
  min-height:var(--gotrow,2rem)}
.bcol-got .item.mini::before{inset:0 auto 0 0;height:auto;width:2px}
.bcol-got .item.mini .art{height:var(--prow-img,2.3rem);width:var(--prow-img,2.3rem);
  font-size:var(--cellart,13px);flex:0 0 auto;display:grid;place-items:center}
.bcol-got .item.mini .art-img{max-width:100%;max-height:100%;width:100%;
  height:100%;object-fit:contain}
.bcol-got .item.mini .nm{display:block;flex:1;min-width:0;
  font-size:var(--gotfs,9px);font-weight:500}
.bcol-got .item.mini .vl{display:block;font-size:var(--gotfs,9px);
  flex:0 0 auto;text-align:right}

/* ---- mines ---- */
.mines{display:grid;grid-template-columns:repeat(5,1fr);gap:0.5rem;
  max-width:min(24rem,100%)}
.tile{aspect-ratio:1;border-radius:0.68rem;
  background:linear-gradient(160deg,var(--panel2),#141a29);
  border:1px solid var(--line);min-width:0;
  display:grid;place-items:center;font-size:1.35rem;cursor:pointer;
  box-shadow:inset 0 1px 0 #ffffff0d,var(--sh1);
  transition:transform .14s var(--spring),background .14s var(--ease),
    border-color .14s var(--ease),box-shadow .14s var(--ease)}
.tile:hover:not(.done){background:#28314a;transform:translateY(-2px) scale(1.03);
  border-color:var(--line2);box-shadow:var(--glow),inset 0 1px 0 #ffffff14}
.tile:active:not(.done){transform:scale(.96)}
.tile.safe{background:linear-gradient(160deg,#0f4a2a,#0a3820);
  border-color:var(--win);box-shadow:0 0 0.85rem #31e07f3d,inset 0 1px 0 #ffffff12;
  animation:tile-pop .3s var(--spring)}
.tile.boom{background:linear-gradient(160deg,#4a1420,#340d16);
  border-color:var(--lose);box-shadow:0 0 0.85rem #ff5f6d45;
  animation:tile-shake .32s ease}
.tile.done{cursor:default}
@keyframes tile-pop{0%{transform:scale(.85)}55%{transform:scale(1.08)}100%{transform:scale(1)}}
@keyframes tile-shake{
  0%,100%{transform:translateX(0)}
  25%{transform:translateX(-0.2rem)}
  50%{transform:translateX(0.2rem)}
  75%{transform:translateX(-0.12rem)}}

/* ---- misc ---- */
.bar{height:0.5rem;border-radius:0.3rem;background:var(--panel2);overflow:hidden}
.bar>i{display:block;height:100%;background:var(--acc)}
.list{display:flex;flex-direction:column;gap:0.5rem}
.lrow{display:flex;align-items:center;gap:0.62rem;background:var(--panel2);
  border:1px solid var(--line);border-radius:0.62rem;padding:0.62rem 0.75rem;
  min-width:0;flex-wrap:wrap}
.lrow .grow{flex:1;min-width:0}

/* ---- leaderboard ---- */
.lrow{transition:border-color .16s ease,background .16s ease,
  transform .16s var(--ease)}
.lrow:hover{border-color:var(--line2);transform:translateX(0.15rem)}
.lb-rank{width:2.2rem;flex:0 0 auto;font-size:0.78rem;font-weight:700;
  color:var(--dim);font-variant-numeric:tabular-nums}
/* the top three get the medal treatment, so the podium reads at a glance */
.lb-rank.top{color:var(--gold);text-shadow:0 0 0.6rem #ffc53d59}
/* your own row is tinted and ringed so it is findable in a long list */
.lrow.lb-me{border-color:var(--acc);background:
  linear-gradient(90deg,#6c63ff1c,var(--panel2) 60%);
  box-shadow:inset 0 0 0 1px #6c63ff30}
.mono{font-family:ui-monospace,Consolas,monospace;font-size:0.8rem}
.dim{color:var(--dim)}
/* tabular-nums stops big counters jittering as digits change width */
.big{font-size:1.8rem;font-weight:800;line-height:1.2;letter-spacing:-.02em;
  font-variant-numeric:tabular-nums}
.big.win{color:var(--win);text-shadow:0 0 1.5rem #31e07f59}
.big.lose{color:var(--lose);text-shadow:0 0 1.5rem #ff5f6d59}
.big.gold{color:var(--gold);text-shadow:0 0 1.5rem #ffc53d4d}
.win{color:var(--win)}.lose{color:var(--lose)}.gold{color:var(--gold)}
.empty{color:var(--dim);text-align:center;padding:1.6rem;font-size:0.88rem}
.drop-art{display:inline-grid;place-items:center;min-width:2rem;
  min-height:2rem;flex:0 0 auto}
.drop-art img{border-radius:0.3rem}
.tag{font-size:0.68rem;padding:0.1rem 0.45rem;border-radius:0.3rem;
  background:var(--panel);border:1px solid var(--line);color:var(--dim);
  text-transform:uppercase;letter-spacing:.5px;white-space:nowrap}

/* ---- chat ---- */
.chatpane{background:var(--bg2);border-left:1px solid var(--line);
  display:flex;flex-direction:column;min-height:0;min-width:0}
.chat-head{flex:0 0 auto;display:flex;justify-content:space-between;
  align-items:center;gap:0.5rem;padding:0.75rem 0.9rem;
  border-bottom:1px solid var(--line);font-weight:600;font-size:0.85rem}
.online{font-size:0.74rem;color:var(--dim);display:flex;align-items:center;
  gap:0.3rem;white-space:nowrap}
.dot{width:0.45rem;height:0.45rem;border-radius:50%;background:var(--win);
  display:inline-block;flex:0 0 auto;box-shadow:0 0 0 0 #2fd37a66;
  animation:pulse 2.4s var(--ease) infinite}
@keyframes pulse{
  0%{box-shadow:0 0 0 0 #2fd37a59}
  70%{box-shadow:0 0 0 0.4rem #2fd37a00}
  100%{box-shadow:0 0 0 0 #2fd37a00}}
.chat-log{flex:1 1 auto;min-height:0;overflow-y:auto;padding:0.62rem 0.75rem;
  display:flex;flex-direction:column;gap:0.58rem}
.msg{font-size:0.85rem;word-break:break-word;animation:msgin .2s var(--ease);
  padding:0.18rem 0.4rem;border-radius:0.4rem;transition:background .14s ease}
.msg:hover{background:#ffffff06}
@keyframes msgin{from{opacity:0;transform:translateY(0.3rem)}}
/* own messages get a faint gold rail so you can find yourself in the scroll */
.msg.me{border-left:2px solid #ffc53d59;padding-left:0.5rem;
  margin-left:-0.62rem}
.chat-log{scrollbar-color:var(--line) transparent;scrollbar-width:thin}
.chat-log::-webkit-scrollbar{width:0.4rem}
.chat-log::-webkit-scrollbar-thumb{background:#2b344a;border-radius:1rem}
.msg .who{font-weight:600;color:var(--acc)}
.msg.sys{color:var(--dim);font-size:0.8rem;font-style:italic}
.msg.me .who{color:var(--gold)}
.chat-form{flex:0 0 auto;display:flex;gap:0.45rem;padding:0.62rem;
  border-top:1px solid var(--line)}
.chat-form input{flex:1;min-width:0}
.rain{flex:0 0 auto;padding:0 0.75rem}
.rain-card{background:linear-gradient(135deg,#1b2a4d,#2a1b4d);
  border:1px solid #3f5290;border-radius:0.68rem;padding:0.75rem;
  margin:0.62rem 0;text-align:center;
  box-shadow:0 0 1.4rem #6c63ff24,inset 0 1px 0 #ffffff10;
  animation:rain-in .35s var(--spring)}
@keyframes rain-in{from{opacity:0;transform:scale(.94)}}
.rain-card .amt{font-size:1.15rem;font-weight:700;color:var(--gold)}
.rain-card .cd{font-size:0.74rem;color:var(--dim);margin:0.2rem 0 0.5rem}
.rain-joined-tag{font-size:0.72rem;font-weight:700;color:var(--win);
  background:#2fd37a1a;border:1px solid #2fd37a44;border-radius:0.5rem;
  padding:0.35rem 0.6rem;margin-top:0.2rem}

/* ---- toasts / modal ---- */
.toasts{position:fixed;right:calc(var(--chat-w) + 1rem);bottom:1.15rem;
  display:flex;flex-direction:column;gap:0.5rem;z-index:60;max-width:90vw}
.toast{background:linear-gradient(165deg,#1c2436,#141a29);
  backdrop-filter:blur(0.5rem);
  border:1px solid var(--line2);
  border-left:3px solid var(--acc);border-radius:0.62rem;
  padding:0.65rem 0.95rem;font-size:0.85rem;min-width:13rem;
  animation:slide .26s var(--spring);box-shadow:0 0.5rem 1.5rem #000a}
.toast.good{border-left-color:var(--win);box-shadow:0 0.5rem 1.5rem #000a,0 0 1rem #31e07f26}
.toast.bad{border-left-color:var(--lose);box-shadow:0 0.5rem 1.5rem #000a,0 0 1rem #ff5f6d26}
@keyframes slide{from{opacity:0;transform:translateX(1.15rem)}}
.modal-root:empty{display:none}
.modal-root{position:fixed;inset:0;background:#000b;display:grid;
  place-items:center;z-index:70;padding:1rem;overflow-y:auto}
.modal-root{backdrop-filter:blur(0.5rem) saturate(1.2);
  animation:cffade .18s ease}
.modal{background:#131520;
  border:1px solid #1b1935;
  border-radius:0.875rem;padding:1.4rem;width:min(28rem,100%);
  max-height:90vh;overflow-y:auto;
  box-shadow:0 1rem 3rem #000000b3;
  animation:modal-in .28s var(--spring)}
@keyframes modal-in{
  from{opacity:0;transform:translateY(0.9rem) scale(.96)}}
.modal:has(> .auth-steps){width:min(26.5rem,100%)}
.modal h3{margin:0 0 0.88rem;font-size:1.15rem;letter-spacing:-.01em;font-weight:700}

/* floating chat toggle — only shown when the sidebar collapses to a drawer */
/* ---- upgrader wheel ----
   The win sector is a conic-gradient sized by --win, so the green arc covers
   exactly the success chance. The needle spins to roll*360deg, which means
   "needle inside the arc" and "roll < chance" are the same test. */
.up-wheel{position:relative;width:min(13.5rem,100%);aspect-ratio:1;margin:0 auto}
.up-arc{position:absolute;inset:0;border-radius:50%;
  border:0.2rem solid var(--line);
  background:conic-gradient(var(--win) 0 var(--warc,0deg),
    var(--panel2) var(--warc,0deg) 360deg);
  transition:background .2s linear}
.up-hub{position:absolute;inset:22%;border-radius:50%;background:var(--panel);
  border:1px solid var(--line);display:grid;place-items:center;gap:0.1rem;
  box-shadow:0 0 0 0.35rem #080b1299,0 0.3rem 0.9rem #0008,
    0 0 1.4rem #6c63ff22}
.up-art{font-size:2.1rem;line-height:1}
.up-pct{font-size:0.8rem;font-weight:700;color:var(--gold);
  font-family:ui-monospace,Consolas,monospace}
/* pivots at the hub centre and points at the top of the wheel */
.up-needle{position:absolute;left:50%;top:4%;width:0.3rem;height:46%;
  margin-left:-0.15rem;transform-origin:50% 100%;transform:rotate(0deg);
  background:linear-gradient(var(--txt),#fff);border-radius:0.15rem;
  box-shadow:0 0 0.5rem #000c;pointer-events:none}
.up-needle::after{content:"";position:absolute;left:50%;top:-0.45rem;
  width:0.7rem;height:0.7rem;margin-left:-0.35rem;border-radius:50%;
  background:#fff;box-shadow:0 0 0.5rem #fff6}
/* Draggable handle sitting at the end of the green arc. Rotated from the
   wheel centre so it rides the rim; only the knob itself takes the pointer. */
.up-grip{position:absolute;left:50%;top:0;width:1.5rem;height:50%;
  margin-left:-0.75rem;transform-origin:50% 100%;pointer-events:none;
  z-index:4}
.up-grip::after{content:"";position:absolute;left:50%;top:-0.1rem;
  width:1.15rem;height:1.15rem;margin-left:-0.575rem;border-radius:50%;
  background:var(--win);border:0.14rem solid #0b0e14;pointer-events:auto;
  box-shadow:0 0 0.55rem #2fd37a99;cursor:grab}
.up-wheel.drag .up-arc{cursor:pointer}
.up-wheel.grabbing .up-grip::after{cursor:grabbing;transform:scale(1.15)}
.up-wheel.grabbing{user-select:none}
.up-grip:focus{outline:none}
.up-grip:focus-visible::after{outline:0.15rem solid var(--acc);
  outline-offset:0.15rem}
/* the hub stays above the drag surface so the art and readout stay legible */
.up-hub{z-index:5}
/* no transition while dragging — the arc must track the pointer exactly */
.up-wheel.grabbing .up-arc{transition:none}
/* the grip is meaningless once the needle is spinning */
.up-wheel.spin .up-grip,.up-wheel.landed .up-grip{display:none}

.up-wheel.spin .up-needle{transition:transform 4s cubic-bezier(.12,.72,.08,1)}
.up-wheel.landed .up-hub{animation:up-pop .45s ease}
@keyframes up-pop{
  0%{transform:scale(1)} 40%{transform:scale(1.14)} 100%{transform:scale(1)}}

/* ---- upgrader stake slider ---- */
.up-slider{margin-top:0.7rem}
.up-slider input[type=range]{-webkit-appearance:none;appearance:none;
  width:100%;height:1.1rem;background:transparent;cursor:pointer;margin:0}
.up-slider input[type=range]:disabled{cursor:not-allowed;opacity:.45}
/* WebKit has no ::-webkit-slider-progress, so the filled portion is a
   gradient stop driven by --fill, which the JS updates as the thumb moves. */
.up-slider input[type=range]::-webkit-slider-runnable-track{
  height:0.4rem;border-radius:0.2rem;border:1px solid var(--line);
  background:linear-gradient(90deg,var(--gold) 0 var(--fill,0%),
    var(--bg) var(--fill,0%) 100%)}
.up-slider input[type=range]::-moz-range-track{
  height:0.4rem;border-radius:0.2rem;border:1px solid var(--line);
  background:var(--bg)}
.up-slider input[type=range]::-moz-range-progress{
  height:0.4rem;border-radius:0.2rem;background:var(--gold)}
.up-slider input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;
  appearance:none;width:1.05rem;height:1.05rem;border-radius:50%;
  background:var(--gold);border:2px solid #0b0e14;margin-top:-0.37rem;
  box-shadow:0 0 0.5rem #ffc53d66}
.up-slider input[type=range]::-moz-range-thumb{width:1.05rem;height:1.05rem;
  border-radius:50%;background:var(--gold);border:2px solid #0b0e14;
  box-shadow:0 0 0.5rem #ffc53d66}
.up-slider input[type=range]:focus-visible{outline:2px solid var(--acc);
  outline-offset:0.2rem;border-radius:0.2rem}
.up-ticks{display:flex;gap:0.3rem;margin-top:0.45rem}
.up-ticks .btn{flex:1;padding:0.26rem 0.2rem;font-size:0.7rem}

.chat-fab{display:none;position:fixed;right:1.15rem;bottom:1.15rem;z-index:55;
  width:3.15rem;height:3.15rem;border-radius:50%;border:0;cursor:pointer;
  background:var(--grad);color:#fff;font-size:1.3rem;
  box-shadow:0 0.4rem 1.35rem #6c63ff50;
  transition:transform .18s var(--spring),box-shadow .18s ease}
.chat-fab:hover{transform:scale(1.08);box-shadow:0 0.5rem 1.7rem #6c63ff70}
.chat-fab .badge{position:absolute;top:-0.1rem;right:-0.1rem;min-width:1.15rem;
  height:1.15rem;border-radius:0.6rem;background:var(--lose);color:#fff;
  font-size:0.68rem;line-height:1.15rem;padding:0 0.3rem;display:none}
.chat-fab .badge.on{display:block}
.chat-close{display:none}

/* Breakpoints in em so they track browser zoom: zooming in crosses them and
   the layout steps down gracefully instead of overflowing. */

/* chat becomes a slide-in drawer; games keep the full width */
@media(max-width:78em){
  .shell{grid-template-columns:var(--nav-w) minmax(0,1fr)}
  /* sits below the demo banner, whatever height it wraps to */
  .chatpane{position:fixed;top:var(--banner-h,2rem);right:0;bottom:0;
    width:min(21rem,88vw);
    z-index:56;transform:translateX(101%);
    transition:transform .22s ease;box-shadow:-0.5rem 0 1.75rem #000a}
  .chatpane.open{transform:translateX(0)}
  .chat-fab{display:grid;place-items:center}
  .chat-close{display:block}
  .toasts{right:1.15rem;bottom:5.2rem}
}

/* collapse the nav to icons */
@media(max-width:62em){
  .shell{grid-template-columns:3.9rem minmax(0,1fr)}
  .brand span:last-child,.navitem span:last-child{display:none}
  .navitem,.brand{justify-content:center}
  .sidenav{padding:0.9rem 0.3rem}
  /* icon-only rail: headings have nothing to label, and the accent bar would
     sit outside the narrower padding */
  .nav-group{display:none}
  .navitem.on::before{left:-0.3rem}
  .nav-foot .btn{padding:0.38rem 0.3rem;font-size:0.68rem}
}

/* phones / heavy zoom: nav moves to a bottom bar, battle columns stack */
@media(max-width:44em){
  body{overflow:auto}
  .shell{grid-template-columns:minmax(0,1fr);height:auto}
  .sidenav{position:fixed;left:0;right:0;bottom:0;top:auto;z-index:54;
    flex-direction:row;border-right:0;border-top:1px solid var(--line);
    padding:0.3rem;overflow-x:auto}
  .brand,.nav-foot,.nav-group{display:none}
  #nav{flex-direction:row;gap:0.2rem}
  .navitem{padding:0.5rem 0.62rem}
  /* horizontal bottom bar: the marker moves to the top edge of the item */
  .navitem.on::before{left:0.1rem;right:0.1rem;top:-0.3rem;bottom:auto;
    width:auto;height:0.19rem;border-radius:0 0 0.19rem 0.19rem}
  .views{padding:0.9rem 0.9rem 4.5rem}
  .topbar{gap:0.62rem;padding:0.62rem 0.75rem}
  /* too little width to centre into: the cluster rejoins the flex row and the
     bar wraps normally */
  .wallet-wrap{position:static;left:auto;transform:none;order:-1}
  .chat-fab{bottom:4.3rem}
  .toasts{bottom:8.5rem;right:0.75rem}
  .battle{height:auto!important}
  .battle-cols{grid-template-columns:minmax(0,1fr)!important}
  .bcol{min-height:15rem}
  .grid{grid-template-columns:minmax(0,1fr)!important}
}
