:root {
  --bg: #050505;
  --surface: #0d0d0e;
  --line: #222225;
  --text: #ededed;
  --muted: #8d8d93;
  --accent: #ededed;
  --unwanted: #ff4d5e;
  --wayback: #e0a85a;
  --skided: #f2f2f2;
  --display: 'Unbounded', 'Segoe UI', sans-serif;
  --body: 'Manrope', 'Segoe UI', sans-serif;
  --ease: cubic-bezier(.16, 1, .3, 1);
  --cw: clamp(104px, 16vw, 196px);
  color-scheme: dark;
}

* { box-sizing: border-box; margin: 0; }
html { background: radial-gradient(ellipse 80% 60% at 50% 35%, #111114 0%, var(--bg) 70%) fixed var(--bg); }
#bg { position: fixed; inset: 0; z-index: -1; width: 100%; height: 100%; pointer-events: none; image-rendering: pixelated; mix-blend-mode: screen; }
body {
  min-height: 100dvh;
  color: var(--text);
  font: 500 15px/1.5 var(--body);
  -webkit-font-smoothing: antialiased;
}
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
::selection { background: #ededed; color: #050505; }
:focus-visible { outline: 1.5px solid var(--text); outline-offset: 3px; border-radius: 6px; }
* { scrollbar-width: thin; scrollbar-color: #2a2a2e transparent; }
[hidden] { display: none !important; }
.num { font-variant-numeric: tabular-nums; }

/* ---------- Bar ---------- */
.bar {
  position: sticky; top: 0; z-index: 5;
  display: flex; align-items: center; justify-content: space-between;
  padding: 18px clamp(16px, 4vw, 40px);
  background: linear-gradient(var(--bg) 60%, transparent);
}
.logo { font: 500 17px var(--display); letter-spacing: -.02em; }
.brand { display: grid; gap: 2px; }
.coins { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--muted); white-space: nowrap; }
.coins[hidden] { display: none; }
.coins::before { content: ""; width: 9px; height: 9px; border-radius: 50%; background: radial-gradient(circle at 35% 35%, #ffe6a3, #e0a85a 60%, #8a5a1c); }
.logo b, .pack-mark b, .back-mark b { font-weight: 900; }
nav { position: relative; display: flex; gap: 4px; padding: 4px; border: 1px solid var(--line); border-radius: 999px; }
/* The active pill (nav and .seg): positioned by slide() in app.js, glides between buttons. */
nav::before, .seg::before {
  content: ""; position: absolute; top: 4px; bottom: 4px; left: 0; width: var(--tw, 0); transform: translateX(var(--px, 0));
  border-radius: 999px; background: var(--text);
  transition: transform .45s var(--ease), width .45s var(--ease), background .3s, box-shadow .3s;
}
.tab { position: relative; padding: 7px 16px; border-radius: 999px; white-space: nowrap; color: var(--muted); transition: color .3s, transform .2s var(--ease); }
.tab:hover { color: var(--text); }
.tab:active, .seg-btn:active, .chip:active, .close:active { transform: scale(.94); }
.tab[aria-current] { color: var(--bg); }
.tab .num:empty { display: none; }
.tab .num { opacity: .6; margin-left: 2px; }

main { padding: 0 clamp(16px, 4vw, 40px) 64px; }
.view { min-height: calc(100dvh - 140px); }

.hint { color: var(--muted); text-align: center; }
.meta { color: var(--muted); font-size: 13px; }
.error { color: var(--unwanted); text-align: center; margin-top: 16px; }

.btn {
  padding: 12px 22px; border: 1px solid var(--line); border-radius: 999px;
  transition: border-color .2s, background .2s, color .2s, transform .25s var(--ease);
}
.btn:hover { border-color: #46464c; }
.btn:hover:not(:disabled) { transform: translateY(-1px); }
.btn:active:not(:disabled) { transform: scale(.96); transition-duration: .08s; }
.btn.primary { background: var(--text); color: var(--bg); border-color: var(--text); font-weight: 700; }
.btn.primary:hover { background: #fff; }
.btn:disabled { opacity: .4; cursor: default; }

/* ---------- Join ---------- */
.join { display: grid; place-items: center; }
/* minmax(0, …): long <option> labels (admin card list) mustn't widen the form past a phone screen. */
.join form { display: grid; grid-template-columns: minmax(0, 1fr); gap: 16px; width: min(380px, 100%); }
.join select { width: 100%; text-overflow: ellipsis; }
#who { width: min(380px, 100%); margin-bottom: 12px; text-align: center; }
.join h1 { margin-bottom: -4px; }
.join input:not([type="checkbox"]), .join select {
  font: 500 17px var(--body); color: var(--text); caret-color: var(--text);
  padding: 13px 18px; border-radius: 999px; border: 1px solid var(--line); background: var(--surface);
  transition: border-color .2s;
}
.join input::placeholder { color: var(--muted); }
.join input:hover, .join select:hover { border-color: #46464c; }
.join input:focus-visible, .join select:focus-visible { outline: none; border-color: var(--text); }
.join .error { text-align: left; margin: 0; }
.join select option { background: var(--surface); }
.check { display: flex; align-items: center; gap: 10px; min-height: 44px; color: var(--muted); cursor: pointer; }
.check input { width: 18px; height: 18px; accent-color: var(--text); }
form[hidden] { display: none; }

/* ---------- Pack ---------- */
.pack-stage {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 20px; min-height: calc(100dvh - 160px); perspective: 1200px;
}
.pack {
  --pw: clamp(190px, 46vw, 250px); --ph: calc(var(--pw) * 1.42); --pd: 22px;
  position: relative; width: var(--pw); height: var(--ph);
  transform-style: preserve-3d; margin-bottom: 24px;
}
.pack-body {
  position: absolute; inset: 0; transform-style: preserve-3d;
  transform: rotateX(var(--rx, 0deg)) rotateY(var(--ry, -16deg));
  transition: transform .5s var(--ease);
  animation: float 6s ease-in-out infinite;
}
@keyframes float { 50% { translate: 0 -10px; } }
.pf { position: absolute; display: block; }
.pf.front, .pf.back { inset: 0; border-radius: 10px; }
.pf.front {
  transform: translateZ(calc(var(--pd) / 2));
  background:
    linear-gradient(115deg, transparent calc(var(--mx, 40%) - 18%), rgba(255,255,255,.09) var(--mx, 40%), transparent calc(var(--mx, 40%) + 18%)),
    repeating-linear-gradient(135deg, rgba(255,255,255,.025) 0 1px, transparent 1px 7px),
    linear-gradient(160deg, #1b1b1f, #070708 70%);
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.1);
  display: flex; flex-direction: column; justify-content: flex-end; padding: 22px;
  overflow: hidden;
}
.pf.front::before {
  content: ""; position: absolute; inset: 10px; border-radius: 6px;
  border: 1px solid transparent;
  background: conic-gradient(from var(--spin, 0deg), #ff6b8b, #ffd36b, #6bffc8, #6bb8ff, #c46bff, #ff6b8b) border-box;
  mask: linear-gradient(#000 0 0) padding-box exclude, linear-gradient(#000 0 0);
  opacity: .55;
}
.pack-mark { font: 500 clamp(26px, 6vw, 34px)/1 var(--display); letter-spacing: -.04em; position: relative; }
.pack-sub { color: var(--muted); font-size: 13px; margin-top: 8px; position: relative; }
.pf.back { transform: rotateY(180deg) translateZ(calc(var(--pd) / 2)); background: #0a0a0b; box-shadow: inset 0 0 0 1px rgba(255,255,255,.08); }
.pf.side { top: 6px; bottom: 6px; width: var(--pd); left: calc(50% - var(--pd) / 2); background: #151518; }
.pf.side.l { transform: rotateY(-90deg) translateZ(calc(var(--pw) / 2)); }
.pf.side.r { transform: rotateY(90deg) translateZ(calc(var(--pw) / 2)); }
.pf.top, .pf.bottom { left: 6px; right: 6px; height: var(--pd); top: calc(50% - var(--pd) / 2); background: #111113; }
.pf.top { transform: rotateX(90deg) translateZ(calc(var(--ph) / 2)); }
.pf.bottom { transform: rotateX(-90deg) translateZ(calc(var(--ph) / 2)); }
.pack-strip {
  position: absolute; left: 0; right: 0; top: 0; height: 13%;
  border-radius: 10px 10px 0 0; pointer-events: none; opacity: 0;
  background: linear-gradient(#26262b, #141417);
  border-bottom: 1px dashed rgba(255,255,255,.25);
}
.pack::after {
  content: ""; position: absolute; left: 10%; right: 10%; bottom: -40px; height: 24px;
  background: radial-gradient(closest-side, rgba(0,0,0,.9), transparent); transform: translateZ(-60px);
}
.pack:hover .pack-body { --rx: 4deg; }
.pack.opening .pack-body { animation: shake .12s ease-in-out; }
@keyframes shake {
  20% { translate: -6px 0; rotate: -2deg; } 40% { translate: 6px 0; rotate: 2deg; }
  60% { translate: -4px 0; rotate: -1deg; } 80% { translate: 3px 0; rotate: 1deg; }
}
.pack.torn .pack-strip { animation: tear .2s var(--ease) forwards; }
@keyframes tear {
  0% { opacity: 1; transform: translateZ(13px); }
  100% { opacity: 0; transform: translate3d(60px, -120px, 40px) rotate(18deg); }
}
.pack.torn .pack-body { animation: sink .2s .03s var(--ease) forwards; }
@keyframes sink { to { opacity: 0; translate: 0 80px; scale: .9; filter: blur(6px) brightness(2); } }

/* ---------- Custom pack (neon purple) ---------- */
:root { --neon: #c04dff; --neon-hi: #e2a6ff; --neon-rgb: 192,77,255; --neon-dk: #2a0e40; --neon-dk2: #12061c; --neon-mid: #4a1a70; --neon-back: #24093a; --neon-back2: #0b0312; --neon-glow: #5a1a8c; --neon-face: #1e0b2e; --neon-face2: #0a0410; }
/* Halloween mode ("halloween": true in cards.json): the custom pack goes orange. */
.halloween { --neon: #ff7a1a; --neon-hi: #ffc38a; --neon-rgb: 255,122,26; --neon-dk: #401a06; --neon-dk2: #1c0b02; --neon-mid: #70300c; --neon-back: #3a1606; --neon-back2: #120602; --neon-glow: #8c3a0a; --neon-face: #2e1406; --neon-face2: #100602; }
.pack.neon .pf.front {
  background:
    linear-gradient(115deg, transparent calc(var(--mx, 40%) - 18%), rgba(255,255,255,.14) var(--mx, 40%), transparent calc(var(--mx, 40%) + 18%)),
    repeating-linear-gradient(135deg, rgba(var(--neon-rgb),.07) 0 1px, transparent 1px 7px),
    radial-gradient(120% 80% at 50% 110%, var(--neon-glow), transparent 60%),
    linear-gradient(160deg, var(--neon-face), var(--neon-face2) 70%);
  box-shadow: inset 0 0 0 1px var(--neon), inset 0 0 28px rgba(var(--neon-rgb),.35), 0 0 34px rgba(var(--neon-rgb),.45);
}
.pack.neon .pf.front::before { background: var(--neon-hi) border-box; opacity: .8; filter: drop-shadow(0 0 4px var(--neon)); }
.pack.neon .pack-mark b { color: var(--neon-hi); text-shadow: 0 0 14px var(--neon); }
.pack.neon .pack-sub { color: var(--neon-hi); }
.pack.neon .pf.side, .pack.neon .pf.top, .pack.neon .pf.bottom { background: var(--neon-dk); }
.pack.neon .pf.back { background: var(--neon-dk2); }
.pack.neon .pack-strip { background: linear-gradient(var(--neon-mid), var(--neon-dk)); border-bottom-color: var(--neon-hi); }
.pack.neon::after { background: radial-gradient(closest-side, rgba(var(--neon-rgb),.45), transparent); }
.reveal-row.neon .back {
  background:
    repeating-linear-gradient(45deg, rgba(var(--neon-rgb),.12) 0 1px, transparent 1px 9px),
    repeating-linear-gradient(-45deg, rgba(var(--neon-rgb),.12) 0 1px, transparent 1px 9px),
    linear-gradient(160deg, var(--neon-back), var(--neon-back2));
  box-shadow: inset 0 0 0 1px var(--neon), inset 0 0 22px rgba(var(--neon-rgb),.4), 0 0 18px rgba(var(--neon-rgb),.35);
}
.reveal-row.neon .back-mark { color: var(--neon-hi); text-shadow: 0 0 12px var(--neon); }

.custom { display: flex; flex-direction: column; align-items: center; gap: 14px; }
.custom[hidden], .stepper[hidden] { display: none; }
.seg { position: relative; display: flex; gap: 4px; padding: 4px; border: 1px solid var(--line); border-radius: 999px; }
.seg-btn { position: relative; padding: 7px 16px; border-radius: 999px; color: var(--muted); transition: color .3s, transform .2s var(--ease); }
.seg-btn:hover { color: var(--text); }
.seg-btn[aria-pressed="true"] { color: var(--bg); }
.seg-btn[data-mode="custom"][aria-pressed="true"] { color: #fff; }
.seg:has([data-mode="custom"][aria-pressed="true"])::before { background: var(--neon); box-shadow: 0 0 18px rgba(var(--neon-rgb),.55); }
.stepper { display: flex; flex-direction: column; align-items: center; gap: 14px; width: min(100%, 380px); padding: 18px 16px 16px; border: 1px solid rgb(192 77 255 / .28); border-radius: 26px; background: linear-gradient(180deg, rgb(192 77 255 / .1), rgb(192 77 255 / .02) 60%), var(--surface); box-shadow: 0 22px 44px -26px rgb(192 77 255 / .6); }
.c-steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; width: 100%; }
.c-steps:has([data-step="1000"]:not([hidden])) { grid-template-columns: repeat(4, 1fr); }
.c-steps .btn { padding: 9px 4px; background: #111113; color: var(--muted); font: 700 12px/1 var(--display); font-variant-numeric: tabular-nums; }
.c-steps .btn:not([data-step^="-"]) { color: var(--neon-hi); border-color: rgb(192 77 255 / .35); }
.c-steps .btn:hover:not(:disabled) { color: var(--text); border-color: var(--neon); background: rgb(192 77 255 / .14); }
.c-steps .btn:disabled { opacity: .3; cursor: not-allowed; }
.c-steps .btn:focus-visible { outline: 2px solid var(--neon-hi); outline-offset: 2px; }
.c-steps .btn[hidden] { display: none; }
/* Slider: neon fill up to the thumb (--fill is set from JS), glowing thumb. */
#c-range { -webkit-appearance: none; appearance: none; width: 100%; height: 28px; background: transparent; cursor: pointer; touch-action: pan-y; }
#c-range::-webkit-slider-runnable-track { height: 8px; border-radius: 999px; box-shadow: inset 0 1px 2px rgb(0 0 0 / .6); background: linear-gradient(90deg, var(--neon) var(--fill, 0%), var(--line) var(--fill, 0%)); }
#c-range::-moz-range-track { height: 8px; border-radius: 999px; box-shadow: inset 0 1px 2px rgb(0 0 0 / .6); background: linear-gradient(90deg, var(--neon) var(--fill, 0%), var(--line) var(--fill, 0%)); }
#c-range::-webkit-slider-thumb { -webkit-appearance: none; width: 24px; height: 24px; margin-top: -8px; border-radius: 50%; background: #fff; border: 4px solid var(--neon); box-shadow: 0 0 14px rgba(var(--neon-rgb),.7); transition: transform .2s var(--ease); }
#c-range::-moz-range-thumb { width: 14px; height: 14px; border-radius: 50%; background: #fff; border: 4px solid var(--neon); box-shadow: 0 0 14px rgba(var(--neon-rgb),.7); transition: transform .2s var(--ease); }
#c-range:active::-webkit-slider-thumb { transform: scale(1.2); }
#c-range:active::-moz-range-thumb { transform: scale(1.2); }
#c-range:focus-visible { outline: none; }
#c-range:focus-visible::-webkit-slider-thumb { outline: 2px solid var(--neon-hi); outline-offset: 2px; }
.c-pay { display: flex; width: 100%; justify-content: space-between; align-items: center; gap: 8px; padding: 4px 14px 4px 4px; border: 1px solid var(--line); border-radius: 999px; background: var(--surface); color: var(--muted); font-size: 13px; transition: border-color .2s, box-shadow .2s; }
.c-pay:focus-within { border-color: var(--neon); box-shadow: 0 0 16px rgba(var(--neon-rgb),.35); }
.c-pay input { flex: 1; min-width: 0; padding: 8px 12px; border: 0; border-radius: 999px; background: rgba(var(--neon-rgb),.12); color: var(--neon-hi); font: 700 16px/1 var(--display); text-align: center; -moz-appearance: textfield; }
.c-pay input:focus { outline: none; }
.c-pay input::-webkit-inner-spin-button, .c-pay input::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
.stepper-val { display: flex; flex-direction: column; align-items: center; min-width: 8em; color: var(--muted); font-size: 13px; }
.stepper-val b { font: 700 34px/1.05 var(--display); letter-spacing: -.03em; color: var(--text); text-shadow: 0 0 22px rgb(192 77 255 / .55); }
.c-price.short { color: var(--muted); text-decoration: line-through; }

/* ---------- Card ---------- */
.card {
  --c: var(--muted); --glow: 0 0 transparent;
  width: var(--cw); aspect-ratio: 5 / 7; perspective: 900px;
  font-size: calc(var(--cw) / 14);
}
.card-inner {
  position: relative; width: 100%; height: 100%; transform-style: preserve-3d;
  transition: transform .5s var(--ease);
}
.face {
  position: absolute; inset: 0; border-radius: calc(var(--cw) / 18); overflow: hidden;
  backface-visibility: hidden; -webkit-backface-visibility: hidden;
}
.front {
  display: flex; flex-direction: column; padding: 6%; gap: 6%;
  background: linear-gradient(170deg, #17171a, #0a0a0b);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--c) 45%, transparent), var(--glow);
}
.art {
  flex: 1; border-radius: calc(var(--cw) / 28);
  background:
    radial-gradient(circle at var(--x1) var(--y1), hsl(var(--h1) 85% 62% / .95), transparent 48%),
    radial-gradient(circle at var(--x2) var(--y2), hsl(var(--h2) 75% 45% / .9), transparent 58%),
    repeating-linear-gradient(var(--a), rgba(255,255,255,.05) 0 2px, transparent 2px 10px),
    #101012;
  background-size: cover; background-position: center;
}
.card-text { display: flex; flex-direction: column; gap: .15em; padding: 0 2% 2%; }
.card-name { font: 700 1.25em/1.1 var(--display); letter-spacing: -.02em; overflow-wrap: break-word; hyphens: auto; }
.card-rarity { color: var(--c); font-size: .85em; font-weight: 700; }
.back {
  transform: rotateY(180deg);
  display: grid; place-items: center;
  background:
    repeating-linear-gradient(45deg, rgba(255,255,255,.035) 0 1px, transparent 1px 9px),
    repeating-linear-gradient(-45deg, rgba(255,255,255,.035) 0 1px, transparent 1px 9px),
    linear-gradient(160deg, #19191c, #08080a);
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.12);
}
.back-mark { font: 500 1.3em var(--display); letter-spacing: -.03em; color: #cfcfd4; }

.card[data-r="rare"] .front, .card[data-r="epic"] .front, .card[data-r="legendary"] .front, .card[data-r="secret"] .front, .card[data-r="mogger"] .front, .card[data-r="glitch"] .front {
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--c) 75%, transparent), var(--glow);
}
/* Glows are box-shadows on the face (--glow, added to every .front box-shadow), not filters around the 3D card: Chrome sometimes clips such a filter to a black box. */
.card[data-r="epic"], .card[data-r="legendary"], .card[data-r="mogger"], .card[data-r="glitch"] {
  --glow: 0 10px 24px color-mix(in srgb, var(--c) 35%, transparent);
}

/* ??? rarity: striped glitch slices + chromatic aberration. The void scene's poppy shares it. */
.card[data-r="glitch"] .art, .void-art {
  position: relative; background-size: contain; background-repeat: no-repeat; background-position: center;
  filter: drop-shadow(3px 0 rgba(255,30,80,.9)) drop-shadow(-3px 0 rgba(0,230,255,.9));
}
/* The whole card face jerks, skews and splits its colours now and then (transform on .front leaves the flip alone). */
.card[data-r="glitch"] .front { animation: card-glitch 2.3s steps(1) infinite; }
/* A copy of the art, cut into offset strips that flicker. */
.card[data-r="glitch"] .art::before, .void-art::before {
  content: ""; position: absolute; inset: 0; background: inherit;
  filter: hue-rotate(170deg) saturate(1.6);
  clip-path: inset(100% 0 0 0); animation: glitch 1.9s steps(1) infinite;
}
/* Scanline stripes, slowly rolling. */
.card[data-r="glitch"] .art::after, .void-art::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: repeating-linear-gradient(to bottom, rgba(0,0,0,.6) 0 2px, transparent 2px 5px);
  mask: var(--img) center / contain no-repeat;
  animation: scan 6s linear infinite;
}
.card[data-r="glitch"] :is(.card-name, .card-rarity) { text-shadow: 2px 0 rgba(255,30,80,.95), -2px 0 rgba(0,230,255,.95); }
@keyframes glitch {
  0%   { clip-path: inset(100% 0 0 0); translate: 0; }
  5%   { clip-path: inset(10% 0 62% 0); translate: -14% 0; }
  7%   { clip-path: inset(55% 0 22% 0); translate: 11% 0; }
  9%   { clip-path: inset(30% 0 58% 0); translate: -6% 0; }
  11%  { clip-path: inset(100% 0 0 0); translate: 0; }
  32%  { clip-path: inset(70% 0 12% 0); translate: 9% 0; }
  34%  { clip-path: inset(100% 0 0 0); translate: 0; }
  52%  { clip-path: inset(22% 0 48% 0); translate: 12% 0; }
  54%  { clip-path: inset(62% 0 8% 0); translate: -10% 0; }
  56%  { clip-path: inset(100% 0 0 0); translate: 0; }
  81%  { clip-path: inset(38% 0 40% 0); translate: -12% 0; }
  83%  { clip-path: inset(5% 0 80% 0); translate: 8% 0; }
  85%  { clip-path: inset(100% 0 0 0); translate: 0; }
}
/* Every step sets both properties: with steps(1) a property missing from a step would hold its last value. */
@keyframes card-glitch {
  0%   { transform: none; filter: drop-shadow(2px 0 rgba(255,30,80,.55)) drop-shadow(-2px 0 rgba(0,230,255,.55)); }
  12%  { transform: translateX(-5%) skewX(-9deg); filter: drop-shadow(7px 0 rgba(255,30,80,.95)) drop-shadow(-7px 0 rgba(0,230,255,.95)); }
  14%  { transform: translateX(4%) skewX(6deg) scaleY(1.03); filter: drop-shadow(-5px 0 rgba(255,30,80,.95)) drop-shadow(5px 0 rgba(0,230,255,.95)) hue-rotate(40deg); }
  16%  { transform: none; filter: drop-shadow(2px 0 rgba(255,30,80,.55)) drop-shadow(-2px 0 rgba(0,230,255,.55)); }
  47%  { transform: translateX(2%) skewX(-4deg); filter: drop-shadow(4px 0 rgba(255,30,80,.85)) drop-shadow(-4px 0 rgba(0,230,255,.85)); }
  48%  { transform: none; filter: drop-shadow(2px 0 rgba(255,30,80,.55)) drop-shadow(-2px 0 rgba(0,230,255,.55)); }
  73%  { transform: translateX(-3%) skewX(12deg) scaleX(1.04); filter: drop-shadow(8px 0 rgba(255,30,80,1)) drop-shadow(-8px 0 rgba(0,230,255,1)) brightness(1.4); }
  74%  { transform: translateX(6%) skewX(-5deg); filter: drop-shadow(-6px 0 rgba(255,30,80,.9)) drop-shadow(6px 0 rgba(0,230,255,.9)) invert(.15); }
  76%  { transform: none; filter: drop-shadow(2px 0 rgba(255,30,80,.55)) drop-shadow(-2px 0 rgba(0,230,255,.55)); }
}
@keyframes scan { to { background-position: 0 40px; } }
.reveal .card:not(.flipped) { filter: none; }

/* НЕЖЕЛАННЫЙ: holo foil + a reject stamp */
.foil, .stamp { display: none; }
.card.unwanted .foil {
  /* No mix-blend-mode: it flattens the card's 3D and shows the front through the back. */
  display: block; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(115deg, transparent 15%, hsl(340 100% 65% / .28) 32%, hsl(50 100% 60% / .24) 42%,
    hsl(160 100% 55% / .24) 52%, hsl(220 100% 65% / .28) 62%, hsl(290 100% 65% / .24) 72%, transparent 88%);
  background-size: 250% 250%; background-position: var(--mx, 30%) var(--my, 30%);
  animation: foil 5s ease-in-out infinite alternate;
}
@keyframes foil { to { background-position: calc(var(--mx, 30%) + 50%) calc(var(--my, 30%) + 40%); } }
.card.unwanted .front { box-shadow: inset 0 0 0 1px var(--unwanted), var(--glow); }
.card.unwanted .stamp-unwanted, .card.wayback .stamp-wayback {
  display: block; position: absolute; top: 34%; left: 50%; translate: -50% 0; rotate: -12deg;
  padding: .25em .6em; border: .15em solid var(--unwanted); border-radius: .3em;
  color: var(--unwanted); font: 900 .78em var(--display); letter-spacing: .06em;
  background: rgba(5,5,5,.55); white-space: nowrap;
}

/* ВЕЙБЕКЯРДЕД: faded old-photo art + an amber stamp */
.card.wayback .art { filter: sepia(.85) contrast(1.1) brightness(.9); }
.card.wayback .front { box-shadow: inset 0 0 0 1px var(--wayback), var(--glow); }
.card.wayback .stamp-wayback { top: 50%; rotate: 8deg; border-color: var(--wayback); color: var(--wayback); }
.card.unwanted.wayback .stamp-unwanted { top: 24%; }

/* СКИДНЫЙ: art crushed to hard black and white (a levels/threshold look)  + a white border */
.card.skided .art { filter: grayscale(1) contrast(4) brightness(1.05); }
.card.skided .front { box-shadow: inset 0 0 0 1px var(--skided), var(--glow); }

/* Секретный: a black card */
.card[data-r="secret"] .front { background: #000; box-shadow: inset 0 0 0 1px rgba(255,255,255,.28), var(--glow); }
.card[data-r="secret"] { --glow: 0 0 1px rgba(255,255,255,.55), 0 12px 26px #000; }
.card[data-r="secret"] .card-rarity { align-self: flex-start; padding: .05em .45em; border-radius: .25em; background: #ececef; color: #000; }

/* ---------- Reveal ---------- */
.reveal { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 28px; min-height: calc(100dvh - 160px); padding: 24px 0; }
.reveal-row { display: flex; flex-wrap: wrap; justify-content: center; gap: clamp(10px, 2vw, 22px); max-width: 1180px; }
.reveal-row.big { --cw: clamp(96px, 11vw, 150px); max-width: calc(5 * var(--cw) + 88px); }
.reveal .card { cursor: pointer; animation: rise .45s var(--ease) backwards; animation-delay: calc(var(--i) * var(--deal, 60ms)); }
@keyframes rise { from { opacity: 0; transform: translateY(60px) scale(.9); } }
.reveal .card .card-inner { transform: rotateY(180deg) rotateX(var(--tx, 0deg)) rotateZ(0); }
.reveal .card.flipped .card-inner { transform: rotateY(var(--ty, 0deg)) rotateX(var(--tx, 0deg)); transition: transform .5s var(--ease); }
.reveal .card.flipped.tilting .card-inner { transition: transform .12s linear; }
.reveal .card:not(.flipped):hover .card-inner { transform: rotateY(180deg) translateY(-8px); }
.reveal .card.flipped.big .face.front { animation: flash 1s var(--ease); }
@keyframes flash { from { filter: brightness(2.2) saturate(1.4); } }

/* Payoff scales with rarity: commons just flip; rare+ burst, sweep and pop; epic+ add a ring and tease from the back. */
.reveal .card { position: relative; isolation: isolate; }
.reveal .card::before, .reveal .card::after { content: ""; position: absolute; pointer-events: none; opacity: 0; }
.reveal .card::before {
  inset: -35%; z-index: -1; border-radius: 50%;
  background: radial-gradient(closest-side, color-mix(in srgb, var(--fx, var(--c)) 60%, transparent), transparent);
}
.reveal .card::after { inset: 0; border-radius: calc(var(--cw) / 18); box-shadow: 0 0 0 2px var(--fx, var(--c)); }
.reveal .card.flipped.big { animation: pop-card .6s cubic-bezier(.2, .9, .3, 1); }
.reveal .card.flipped.big::before { animation: burst 1.2s var(--ease); }
.reveal .card.flipped.big:is([data-r="epic"], [data-r="legendary"], [data-r="secret"], [data-r="mogger"], [data-r="glitch"])::after { animation: ring .9s .05s var(--ease); }
.reveal .card[data-r="secret"] { --fx: #fff; }
@keyframes pop-card { 35% { scale: 1.07; } }
@keyframes burst { 0% { opacity: 0; scale: .5; } 20% { opacity: 1; } 100% { opacity: 0; scale: 1.3; } }
@keyframes ring { 0% { opacity: .9; scale: 1; } 100% { opacity: 0; scale: 1.25; } }
.reveal .card.flipped.big .face.front::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(105deg, transparent 35%, rgba(255,255,255,.45) 50%, transparent 65%);
  translate: -100% 0; animation: sweep .9s .2s var(--ease) forwards;
}
@keyframes sweep { to { translate: 100% 0; } }
/* Tease: an epic+ card's back breathes faintly in its color before it is flipped. */
.reveal .card:is([data-r="epic"], [data-r="legendary"], [data-r="secret"], [data-r="mogger"], [data-r="glitch"]):not(.flipped) .back::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  box-shadow: inset 0 0 0 1px var(--fx, var(--c)), inset 0 0 calc(var(--cw) / 6) color-mix(in srgb, var(--fx, var(--c)) 30%, transparent);
  animation: tease 1.6s ease-in-out infinite alternate;
}
@keyframes tease { from { opacity: .15; } to { opacity: .8; } }
.new-badge {
  position: absolute; top: 4%; right: 4%; z-index: 1;
  padding: .2em .55em; border-radius: 999px;
  background: var(--text); color: var(--bg); font: 900 .62em var(--display); letter-spacing: .04em;
  box-shadow: 0 .2em .6em rgba(0,0,0,.5);
}
.reveal .card.flipped .new-badge { animation: badge-in .5s .35s cubic-bezier(.2, .9, .3, 1.3) backwards; }
@keyframes badge-in { from { opacity: 0; scale: .3; rotate: -20deg; } }
/* A plain copy of a card already owned: quieter than the new ones. Hover brings it back. */
.reveal .card.dupe.flipped .front { filter: brightness(.5) saturate(.55); transition: filter .4s; }
.reveal .card.dupe.flipped:hover .front { filter: none; }
.reveal-sum { display: flex; flex-direction: column; align-items: center; gap: 6px; text-align: center; color: var(--muted); }
.reveal-sum[hidden] { display: none; }
.reveal-sum b { color: var(--text); }
.reveal-moved { font-size: 13px; }
/* Pack screen: per-rarity collection progress. */
.set-progress { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; max-width: 560px; }
.set-progress .num { color: var(--text); }
.set-progress .chip.done { border-color: color-mix(in srgb, var(--text) 30%, var(--line)); }
.tab .num.bump { display: inline-block; animation: bump .35s var(--ease); }
@keyframes bump { 30% { scale: 1.45; opacity: 1; } }
.actions { display: flex; gap: 10px; flex-wrap: wrap; justify-content: center; }

/* ---------- Collection ---------- */
.col-head { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; flex-wrap: wrap; padding: 28px 0 18px; }
h1 { font: 700 clamp(26px, 4vw, 40px)/1.1 var(--display); letter-spacing: -.03em; }
.col-tools { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 14px; }
.col-tools input, .col-tools select {
  font: 500 14px var(--body); color: var(--text); caret-color: var(--text);
  padding: 10px 16px; border-radius: 999px; border: 1px solid var(--line); background: var(--surface);
  transition: border-color .2s;
}
.col-tools input { flex: 1 1 220px; min-width: 0; }
.col-tools input::placeholder { color: var(--muted); }
.col-tools input:hover, .col-tools select:hover { border-color: #46464c; }
.col-tools input:focus-visible, .col-tools select:focus-visible { outline: none; border-color: var(--text); }
.col-tools select { cursor: pointer; }
.col-tools select option { background: var(--surface); }
#no-match { padding: 40px 0; }
.filters { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 28px; }
.sell-rarity { margin-left: auto; color: var(--wayback); border-color: rgba(224,168,90,.35); }
.sell-rarity:hover { color: #ffe6a3; border-color: var(--wayback); }
.chip {
  padding: 6px 13px; border: 1px solid var(--line); border-radius: 999px;
  color: var(--muted); font-size: 13px; display: inline-flex; align-items: center; gap: 7px;
  transition: color .2s, border-color .2s, background .2s, transform .2s var(--ease);
}
.chip:hover { color: var(--text); }
.chip[aria-pressed="true"] { color: var(--text); border-color: #55555b; background: #141416; }
.dot { width: 7px; height: 7px; border-radius: 50%; background: var(--c); box-shadow: 0 0 0 1px rgba(255,255,255,.25); }
.grid {
  --cw: clamp(130px, 15vw, 172px);
  display: grid; grid-template-columns: repeat(auto-fill, minmax(var(--cw), 1fr));
  --gap: clamp(14px, 2vw, 24px); gap: var(--gap); justify-items: center;
}
.grid .card { cursor: pointer; border-radius: calc(var(--cw) / 18); }
.grid .card .card-inner { transition: transform .4s var(--ease); }
.grid .card:hover .card-inner { transform: translateY(-6px) rotateX(6deg); }
/* "Все карты": not owned yet. The filter sits on .front, never on .card (see the glow note). */
.grid .card.missing { cursor: default; --glow: 0 0 transparent; }
.grid .card.missing .front { filter: grayscale(1) brightness(.5); }
.grid .card.missing:hover .card-inner { transform: none; }
/* Pile: copies peek out behind the top card. */
/* Merged: yellow (green from level 5) neon edge and glow, stronger each merge level (--m). On the outer .card, like the rarity glow. */
.card.merged {
  --mc: 255 210 50; --mc2: 255 240 140;
  --g: min(1, calc(.35 + .2 * var(--m)));
  --glow: 0 0 calc(.25em + .45em * var(--m)) rgb(var(--mc) / var(--g)), 0 0 .15em rgb(var(--mc2) / var(--g));
}
.card.merged.merged-green { --mc: 60 230 100; --mc2: 160 255 180; }
.card.merged .front { box-shadow: inset 0 0 0 calc(1px + .05em * var(--m)) rgb(var(--mc)), inset 0 0 calc(.6em * var(--m)) rgb(var(--mc) / .3), var(--glow); }
.btn.merge { color: #ffd84a; border-color: rgb(255 216 74 / .4); }
.btn.merge:hover { border-color: #ffd84a; box-shadow: 0 0 14px rgb(255 216 74 / .35); }
/* Coins a merge adds to the pile's sell value. */
.btn.merge .gain { margin-left: .5em; padding: .1em .5em; border-radius: 999px; background: #ffd84a; color: #000; font-weight: 800; }
.grid .card.stack { box-shadow: 5px 5px 0 -1px #161618, 5px 5px 0 0 #3c3c42, 10px 10px 0 -1px #111113, 10px 10px 0 0 #2c2c30; }
.pile-count {
  position: absolute; top: 4%; right: 4%; z-index: 1;
  padding: .2em .55em; border-radius: 999px;
  background: var(--text); color: var(--bg); font: 900 .78em var(--display);
  box-shadow: 0 .2em .6em rgba(0,0,0,.5);
}
.grid .card.pinned::before {
  content: ""; position: absolute; top: 4%; left: 4%; z-index: 1;
  width: 1.9em; height: 1.9em; border-radius: 50%;
  background: var(--text) url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M15 3l6 6-3 1-4 4 1 5-2 2-4-4-5 5-1-1 5-5-4-4 2-2 5 1 4-4z" fill="%23000"/></svg>') center / 58% no-repeat;
  box-shadow: 0 .2em .6em rgba(0,0,0,.5);
}
.d-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 18px; }
.d-actions .btn[hidden] { display: none; }
#d-pin[aria-pressed="true"] { background: var(--text); color: var(--bg); border-color: var(--text); }
.more { display: block; margin: 28px auto 0; }
.more[hidden] { display: none; }
/* The foil animation repaints every frame; in a grid of hundreds of cards that alone drains a phone. */
.grid .card .foil { animation: none; }
/* Touch devices (mostly phones): skip the per-card glow filters and the blurred dialog backdrop. */
@media (hover: none) {
  .grid .card { filter: none !important; }
  /* Big packs on phones: off-screen cards aren't rendered (or their images decoded), no per-card glow or foil repaint. Keeps 100+ card packs from running out of memory. */
  .reveal-row.big .card { filter: none !important; content-visibility: auto; contain-intrinsic-size: auto var(--cw) calc(var(--cw) * 1.4); }
  .reveal-row.big .card .foil { animation: none; }
  .detail::backdrop { backdrop-filter: none; background: rgba(0,0,0,.88); }
}
.empty { display: grid; justify-items: center; gap: 18px; padding: 12vh 0; color: var(--muted); }

/* ---------- Detail ---------- */
.detail {
  margin: auto; width: min(860px, calc(100vw - 32px)); max-height: calc(100dvh - 32px);
  padding: clamp(20px, 4vw, 40px); border: 1px solid var(--line); border-radius: 20px;
  background: var(--surface); color: var(--text);
}
.detail[open] { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(20px, 4vw, 48px); align-items: center; animation: pop .45s var(--ease); }
@keyframes pop { from { opacity: 0; scale: .96; } }
.detail.account { width: min(420px, calc(100vw - 32px)); }
.detail.account[open] { display: block; }
.account form { width: 100%; }
.gear { display: grid; place-items: center; padding: 7px 10px; }
.vol { display: grid; grid-template-columns: 1fr auto; gap: 8px; margin-top: 20px; color: var(--muted); }
.vol output { color: var(--text); }
.vol input { grid-column: 1 / -1; width: 100%; accent-color: var(--text); }
.settings-account { margin-top: 28px; padding-top: 24px; border-top: 1px solid var(--line); }
.settings-account[hidden] { display: none; }
.settings-account h3 { font: 700 18px/1.2 var(--display); letter-spacing: -.02em; }
.account h2 { font: 700 26px/1.1 var(--display); letter-spacing: -.03em; padding-right: 32px; }
.human-box { min-height: 65px; margin-top: 16px; }   /* Turnstile's widget is 300×65 */
.join-actions { display: flex; gap: 10px; }
.ask-text { margin-bottom: 20px; font-size: 17px; text-wrap: pretty; }
.join-actions .btn { flex: 1; }
.detail::backdrop { background: rgba(0,0,0,.78); backdrop-filter: blur(6px); }
.close { position: absolute; top: 14px; right: 14px; padding: 8px; border-radius: 50%; color: var(--muted); transition: color .2s, background .2s, transform .2s var(--ease); }
.close:hover { color: var(--text); background: #1a1a1d; }
.viewer {
  --cw: min(280px, 62vw);
  display: grid; place-items: center; padding: 20px 0; cursor: grab; touch-action: none; border-radius: 12px;
}
.viewer:active { cursor: grabbing; }
.viewer .card { perspective: 1400px; }
.viewer .card-inner { transition: none; }
.viewer .card-inner.settle { transition: transform .6s var(--ease); }
.info h2 { font: 700 clamp(24px, 3.4vw, 34px)/1.1 var(--display); letter-spacing: -.03em; margin-bottom: 24px; padding-right: 32px; }
dl { display: grid; grid-template-columns: auto 1fr; gap: 12px 24px; margin-bottom: 24px; }
dt { color: var(--muted); }
dd { font-weight: 700; display: flex; align-items: center; gap: 8px; }
dd.unwanted { color: var(--unwanted); }
dd.wayback:not(.unwanted) { color: var(--wayback); }
dd.skided:not(.unwanted):not(.wayback) { color: var(--skided); }

/* ---------- Могг баттл ---------- */
.btn.ghost { border-color: transparent; color: var(--muted); }
.btn.ghost:hover { color: var(--text); border-color: var(--line); }
.tg {
  position: fixed; left: 16px; bottom: 16px; z-index: 5;
  display: grid; place-items: center; width: 48px; height: 48px;
  color: var(--muted); transition: color .2s, transform .25s var(--ease);
}
.tg:hover, .tg:focus-visible { color: #22d3ee; transform: translateY(-1px); }
/* Main menu only: hidden on other tabs and while a pack is being revealed. */
body:has(#packs[hidden], #pack-stage[hidden]) .tg { display: none; }

.b-lobby { display: grid; align-content: center; justify-items: start; gap: 24px; width: min(520px, 100%); min-height: calc(100dvh - 160px); margin: 0 auto; }
.rules { list-style: none; padding: 0; display: grid; gap: 14px; counter-reset: r; color: var(--muted); }
.rules li { counter-increment: r; display: grid; grid-template-columns: 2.2em 1fr; align-items: baseline; }
.rules li::before { content: counter(r); font: 700 15px var(--display); color: var(--text); }
.b-invite { display: grid; gap: 14px; width: 100%; }
.b-link { display: flex; gap: 8px; }
.b-link input {
  flex: 1; min-width: 0; font: 500 14px var(--body); color: var(--text);
  padding: 12px 18px; border-radius: 999px; border: 1px solid var(--line); background: var(--surface);
}
.b-link input:focus-visible { outline: none; border-color: var(--text); }
.b-wait { display: flex; align-items: center; gap: 10px; color: var(--muted); }
.pulse { width: 8px; height: 8px; border-radius: 50%; background: var(--text); animation: pulse 1.4s ease-in-out infinite; }
@keyframes pulse { 50% { opacity: .2; scale: .6; } }
.b-invite .btn { justify-self: start; }
.b-lobby .error { text-align: left; margin: 0; }

/* Lobby: your rank and the bar to the next one, then open battles anyone can join. */
.b-me { display: grid; gap: 10px; width: 100%; }
.b-me-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.b-me-rank { font: 700 22px/1 var(--display); letter-spacing: -.02em; }
.b-me-rank .rank { margin-left: 0; font-size: 26px; }
.b-me-rating { font: 700 clamp(28px, 5vw, 40px)/1 var(--display); letter-spacing: -.03em; }
.b-bar { --c: var(--muted); --c2: var(--c); height: 8px; border-radius: 999px; background: var(--surface); box-shadow: inset 0 0 0 1px var(--line); overflow: hidden; }
.b-bar i { display: block; width: var(--p, 0%); height: 100%; border-radius: inherit; background: linear-gradient(90deg, var(--c), var(--c2)); transition: width .6s var(--ease); }
.b-me-next { font-weight: 700; }
.b-me p { margin: 0; }
.b-lobby:has(#b-start[hidden]) .b-open { display: none; }
.b-open { display: grid; gap: 4px; width: 100%; }
.b-open-title { font: 700 15px var(--display); letter-spacing: -.01em; color: var(--muted); margin: 0 0 6px; }
.b-open-list { list-style: none; padding: 0; margin: 0; }
.b-open-list li { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; align-items: center; gap: 12px; padding: 10px 0; border-top: 1px solid var(--line); }
.b-open-list li:last-child { border-bottom: 1px solid var(--line); }
.b-open-since { color: var(--muted); font-size: 14px; }
.b-open-list .btn { padding: 8px 16px; }
.b-open-list li.b-open-empty { display: block; padding: 18px 0; color: var(--muted); }
.b-rules { width: 100%; color: var(--muted); }
.b-rules summary { cursor: pointer; font-weight: 700; width: max-content; }
.b-rules summary:hover { color: var(--text); }
.b-rules .rules { margin-top: 14px; }

.b-game {
  position: relative; display: grid; grid-template-rows: auto 1fr auto; gap: 8px;
  min-height: calc(100dvh - 140px); max-width: 1100px; margin: 0 auto;
}
.b-seat { display: flex; flex-direction: column; align-items: center; gap: 2px; padding: 4px 0; }
.b-name { font: 700 clamp(17px, 2.4vw, 22px)/1.1 var(--display); letter-spacing: -.02em; }
.b-left { display: flex; align-items: center; gap: 10px; }
/* The opponent's hand, face down; the card they've picked rises. */
.b-opp-hand { display: flex; padding-top: 6px; }
.b-opp-hand i {
  width: 18px; aspect-ratio: 5 / 7; border-radius: 3px;
  background: repeating-linear-gradient(45deg, rgba(255,255,255,.05) 0 1px, transparent 1px 4px), linear-gradient(160deg, #222226, #0b0b0d);
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.16), 0 2px 4px rgba(0,0,0,.6);
  transition: translate .25s var(--ease), box-shadow .25s;
}
.b-opp-hand i + i { margin-left: -6px; }
.b-opp-hand i.picked { translate: 0 -6px; box-shadow: inset 0 0 0 1px var(--text), 0 4px 8px rgba(0,0,0,.6); }

/* Tiebreakers on battle cards: merge level, bonus count, owners. Top-left stays visible in the overlapping hand. */
.b-power {
  position: absolute; top: 5%; left: 5%; z-index: 1; display: flex; flex-direction: column; align-items: flex-start; gap: 3px;
  font: 700 max(10px, calc(var(--cw) / 10))/1 var(--body); font-variant-numeric: tabular-nums; pointer-events: none;
}
.b-power b {
  display: inline-flex; align-items: center; gap: .25em; padding: .25em .45em; border-radius: 999px;
  color: var(--text); background: rgba(5,5,5,.8); box-shadow: inset 0 0 0 1px rgba(255,255,255,.14);
}
.b-power svg, .ico-person { width: .9em; height: .9em; fill: currentColor; }
.ico-person { vertical-align: -.1em; }
.b-power b:last-child { color: var(--muted); }
.card.merged .b-power b:first-child { color: rgb(var(--mc)); box-shadow: inset 0 0 0 1px rgb(var(--mc) / .45); }
.b-forfeit { position: absolute; top: 0; right: 0; padding: 8px 14px; font-size: 13px; }

.b-table {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: clamp(20px, 4vh, 36px);
  padding: 8px 0;
  background: radial-gradient(closest-side, #151518, transparent) center / min(560px, 100%) 80% no-repeat;
}
.pile { --cw: clamp(112px, min(36vw, 26vh), 200px); position: relative; width: var(--cw); aspect-ratio: 5 / 7; }
.pile:empty { border: 1px dashed #2c2c31; border-radius: calc(var(--cw) / 18); }
.pile:empty::after { content: "Стопка пуста"; position: absolute; inset: 0; display: grid; place-items: center; color: var(--muted); font-size: 13px; }
.pile .card {
  position: absolute; top: 0; left: 0;
  translate: var(--dx) var(--dy); rotate: var(--rot);
  filter: drop-shadow(0 6px 10px rgba(0,0,0,.6));
}
/* Buried cards sink into shadow; the top card is the one to beat. */
.pile .card:not(:last-child) .front::before { content: ""; position: absolute; inset: 0; z-index: 2; background: rgba(5,5,5,.5); }
.pile .card:last-child { filter: drop-shadow(0 18px 28px rgba(0,0,0,.75)) drop-shadow(0 0 22px color-mix(in srgb, var(--c) 30%, transparent)); }
.pile .card.drop { animation: drop .55s cubic-bezier(.2, .8, .25, 1) backwards; }
.pile .card.drop.mine { --from: 70vh; --spin: -28deg; }
.pile .card.drop.theirs { --from: -70vh; --spin: 28deg; }
@keyframes drop {
  0% { transform: translateY(var(--from)) rotate(var(--spin)) scale(1.25); opacity: 0; }
  20% { opacity: 1; }
  78% { transform: scale(.97); }
}
.b-status { min-height: 1.5em; text-align: center; color: var(--muted); max-width: 34ch; }
.b-status .go { color: var(--text); font-weight: 700; }
.b-timer { margin-left: .4em; color: var(--muted); }
.b-timer.low { color: oklch(70% 0.2 25); font-weight: 700; }

/* Last round: the opponent's card above, yours below; the one that went back to the hand is dimmed. */
.b-reveal { --cw: clamp(56px, 8vh, 76px); display: flex; gap: 10px; }
.b-reveal:empty { display: none; }
.b-reveal .card.lost { opacity: .4; filter: saturate(.3); }
.b-why { max-width: 40ch; text-align: center; color: var(--muted); font-size: 13px; line-height: 1.4; }
.b-why:empty { display: none; }
/* The weaker card of the round flies back from the table into its owner's hand. */
.hand .card.returning { animation: back-mine .6s cubic-bezier(.2, .8, .25, 1) .25s backwards; }
@keyframes back-mine { from { transform: translateY(-38vh) scale(.8) rotate(8deg); opacity: 0; } 25% { opacity: 1; } }
.b-opp-hand i.returning { animation: back-theirs .5s cubic-bezier(.2, .8, .25, 1) .25s backwards; }
@keyframes back-theirs { from { transform: translateY(30vh) scale(2.5); opacity: 0; } 30% { opacity: 1; } }

/* Rank: the icon from /ranks/, or the rank's name in its rarity colour while there's no icon. */
.rank { display: inline-flex; flex: none; align-self: center; margin-left: .35em; font-style: normal; vertical-align: middle; }
.rank img { display: block; height: 1.25em; width: auto; }
.rank.text {
  padding: .15em .55em; border-radius: 999px; font: 700 max(11px, .55em)/1.2 var(--body); letter-spacing: .02em;
  color: var(--c); background: color-mix(in srgb, var(--c) 14%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--c) 40%, transparent);
}
.b-end-result { font: 700 18px var(--body); color: var(--text); min-height: 1.2em; }

.hand {
  --cw: clamp(80px, min(12vw, 17vh), 128px);
  display: flex; justify-content: safe center; overflow-x: auto; overscroll-behavior-x: contain;
  padding: 22px 12px 12px; margin: 0 calc(-1 * clamp(16px, 4vw, 40px));
}
.hand .card { flex: none; transition: translate .25s var(--ease), opacity .25s; }
.hand .card + .card { margin-left: calc(var(--cw) * -.28); }
.hand .card[aria-disabled="false"] { cursor: pointer; }
.hand .card[aria-disabled="false"]:hover, .hand .card[aria-disabled="false"]:focus-visible { translate: 0 -16px; z-index: 1; }
.hand.waiting .card { opacity: .45; }
.hand .card.picked { opacity: 1; translate: 0 -22px; z-index: 1; }
.hand .card.picked .front { outline: 2px solid var(--text); outline-offset: 3px; }

.b-end {
  position: absolute; inset: 0; z-index: 3; display: grid; place-content: center; justify-items: center; gap: 14px;
  text-align: center; background: rgba(5,5,5,.82); backdrop-filter: blur(4px);
  animation: pop .5s var(--ease);
}
.b-end-title { font: 900 clamp(52px, 11vw, 120px)/.95 var(--display); letter-spacing: -.05em; color: var(--muted); }
.b-end.won .b-end-title {
  color: transparent; background: conic-gradient(from 200deg, #ff6b8b, #ffd36b, #6bffc8, #6bb8ff, #c46bff, #ff6b8b) text;
}
.b-end .actions { margin-top: 12px; }

/* Chat under the game: the game and pile shrink to leave it room, so it shows without scrolling. */
.battle:has(.b-chat:not([hidden])) .b-game { min-height: calc(100dvh - 140px - 150px); }
.battle:has(.b-chat:not([hidden])) .pile { --cw: clamp(96px, min(36vw, 18vh), 200px); }
.b-chat { display: grid; gap: 8px; max-width: 520px; margin: 8px auto 0; }
.b-chat[hidden] { display: none; }
.b-chat-log {
  list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; align-content: start;
  max-height: 84px; overflow-y: auto; overscroll-behavior: contain; font-size: 14px; overflow-wrap: anywhere;
}
.b-chat-log:empty { display: none; }
.b-chat-log b { font-weight: 700; color: var(--muted); }
.b-chat-log .mine b { color: var(--text); }
.b-chat .btn { padding: 10px 16px; font-size: 14px; }

@media (max-width: 640px) {
  .detail[open] { grid-template-columns: 1fr; overflow-y: auto; }
  .viewer { --cw: min(230px, 60vw); }
  .bar { padding-top: 14px; }
  .tab { padding: 7px 12px; }
}
/* Five tabs + gear don't fit beside the logo: the nav takes its own row. */
@media (max-width: 600px) {
  .bar { flex-wrap: wrap; row-gap: 10px; }
  nav { flex: 1 0 100%; justify-content: space-between; }
}
@media (max-width: 420px) {
  .logo { font-size: 15px; }
  .tab { padding: 6px 7px; font-size: 14px; }
  nav { gap: 2px; }
  .gear { padding: 6px; }
  /* Big balances overflow the bar: keep the number, hide the word visually (still read aloud). */
  .coins-word { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: pre; }
}

/* ---------- Void: the ??? card's scene ---------- */
.void {
  position: fixed; inset: 0; z-index: 10; overflow: hidden;
  display: grid; place-content: center; justify-items: center; gap: 28px; padding: 16px;
  background: radial-gradient(circle at 50% 45%, #140608, #000 60%);
  animation: void-in 1.4s var(--ease);
}
.void-art { width: min(72vmin, 520px); aspect-ratio: 1; --img: url("/cards/poppy.webp"); background-image: var(--img); animation: card-glitch 2.3s steps(1) infinite, breathe 7s ease-in-out infinite; }
.void-text { color: #5c5c63; font: 500 .9rem var(--display); letter-spacing: .4em; text-shadow: 1px 0 rgba(255,30,80,.6), -1px 0 rgba(0,230,255,.6); }
@keyframes void-in { from { opacity: 0; filter: brightness(3) blur(8px); } }
/* Scanlines over the whole scene. */
.void::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 5;
  background: repeating-linear-gradient(to bottom, rgba(0,0,0,.35) 0 1px, transparent 1px 3px);
}
.void-ask { display: grid; justify-items: center; text-align: center; font-family: 'Handjet', monospace; color: var(--text); }
.void-q {
  font-size: clamp(60px, 15vw, 128px); line-height: 1;
  text-shadow: 3px 0 rgba(255,30,80,.8), -3px 0 rgba(0,230,255,.8), 0 0 24px rgba(237,237,237,.3);
  animation: vcr-flicker 5s steps(1) infinite;
}
.void-keys { margin-top: 18px; font-size: clamp(22px, 4.4vw, 32px); letter-spacing: .7em; margin-right: -.7em; color: var(--muted); }
.void-opts { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px 32px; margin-top: 56px; }
.void-opt {
  font: 500 clamp(26px, 4.4vw, 34px) 'Handjet', monospace; color: var(--text);
  background: none; border: 0; padding: 6px 16px; cursor: pointer;
}
/* Selected item of a camcorder menu: inverted block. */
.void-opt:is(:hover, :focus-visible) { background: var(--text); color: #000; outline: none; }
@keyframes vcr-flicker {
  0%, 100% { opacity: 1; translate: 0; }
  31% { opacity: .55; translate: -3px 0; }
  32% { opacity: 1; translate: 0; }
  77% { opacity: .8; translate: 4px 0; clip-path: inset(40% 0 35% 0); }
  78% { opacity: 1; translate: 0; clip-path: none; }
}

/* ---------- The rhythm game inside the void ---------- */
.vs { position: fixed; inset: 0; background: #000; overflow: hidden; }
.vs canvas { position: absolute; z-index: 1; inset: 0; width: 100%; height: 100%; touch-action: none; }
.vs-poppy { position: absolute; inset: 0; margin: auto; animation: card-glitch 2.3s steps(1) infinite; }
.vs-bg { width: min(90vmin, 740px); height: min(90vmin, 740px); opacity: .85; }
/* The quick pop-ins sit behind the notes and shake. */
.vs-over { width: min(74vmin, 620px); height: min(74vmin, 620px); animation: card-glitch 2.3s steps(1) infinite, vs-shake .14s steps(1) infinite; }
@keyframes vs-shake {
  0% { translate: 0; } 20% { translate: -14px 6px; } 40% { translate: 10px -10px; } 60% { translate: -8px -4px; } 80% { translate: 12px 8px; }
}
.vs canvas { transition: filter 1.2s; }
#vs.dead canvas { filter: grayscale(1) brightness(.35) blur(2px); }
.vs-flash { position: absolute; inset: 0; opacity: 0; pointer-events: none; z-index: 3; }
/* Ending: the guarded card surfaces out of the dark and flips. */
.vs-reveal { position: absolute; inset: 0; z-index: 2; min-height: 0; padding: 16px; gap: clamp(20px, 4vh, 36px); --cw: clamp(170px, 32vmin, 290px); }
.vs-reveal .card { animation: none; cursor: default; }
.vs-slot { display: grid; place-items: center; min-height: calc(var(--cw) * 1.4); }
.vs-line { font: 500 clamp(24px, 4.4vw, 36px) 'Handjet', monospace; letter-spacing: .3em; color: #ededed; text-align: center; opacity: 0;
  text-shadow: 2px 0 rgba(255,30,80,.8), -2px 0 rgba(0,230,255,.8); }
/* Final stretch: tape playback. Jittering picture, rolling tracking band, vignette. */
.vs.vcr canvas { filter: contrast(1.2) saturate(.6) blur(.4px); animation: vcr-jitter 1.1s steps(1) infinite; }
.vs.vcr::before, .vs.vcr::after { content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 4; }
.vs.vcr::before { background: radial-gradient(ellipse at center, transparent 55%, rgba(0,0,0,.75)); }
.vs.vcr::after {
  background: linear-gradient(to bottom, transparent 0 44%, rgba(237,237,237,.05) 47%, rgba(237,237,237,.16) 50%, rgba(237,237,237,.04) 53%, transparent 56%) 0 0 / 100% 300%;
  animation: vcr-track 3.2s linear infinite;
}
@keyframes vcr-jitter {
  0%, 100% { transform: none; }
  20% { transform: translateX(-4px) skewX(-1.5deg); }
  22% { transform: none; }
  58% { transform: translate(3px, 1px); }
  60% { transform: none; }
  83% { transform: translateX(-2px) scaleY(1.01); }
  84% { transform: none; }
}
@keyframes vcr-track { from { background-position: 0 100%; } to { background-position: 0 0; } }
@keyframes breathe { 50% { scale: 1.04; } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
}

/* Admin: separate the coins form from the cards form */
form#coins, form#reset { margin-top: 32px; padding-top: 32px; border-top: 1px solid var(--line); }

/* ---------- Топ ---------- */
@media (max-width: 520px) { #top .seg { width: 100%; } #top .seg-btn { flex: auto; padding: 7px 8px; font-size: 13px; } }
#top-error:empty { display: none; }
#top-error { color: var(--unwanted); margin-bottom: 12px; }
.top-list { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--line); transition: opacity .2s; }
.top-list[aria-busy] { opacity: .45; }
.top-list button {
  display: grid; grid-template-columns: 3.2em minmax(0, 1fr) auto; align-items: baseline; gap: 12px; width: 100%;
  padding: 14px 8px; border-bottom: 1px solid var(--line); text-align: left; transition: background .2s;
}
.top-list button:hover { background: rgb(255 255 255 / .04); }
.top-rank { font: 700 15px/1 var(--display); color: var(--muted); }
.top-name { display: flex; align-items: baseline; gap: 8px; min-width: 0; font-weight: 700; }
.top-name span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.top-v { color: var(--muted); font-weight: 700; }
.heart { display: inline-block; flex: none; width: .8em; height: .8em; margin-left: .3em; color: oklch(70% 0.2 5); vertical-align: -.02em; }
.top-name .heart { margin-left: 0; align-self: center; }
.heart svg { display: block; width: 100%; height: 100%; fill: currentColor; }
.top-list .podium .top-rank { font-size: 22px; color: var(--text); letter-spacing: -.03em; }
.top-list .podium .top-name { font-size: 17px; }
.top-list .podium .top-v { color: var(--text); }
.top-list .me button { background: var(--surface); }
.top-empty { padding: 12vh 0; text-align: center; color: var(--muted); }

/* ---------- Профиль ---------- */
.pr-find { width: min(320px, 100%); }
#pr-error:empty, #pr-meta:empty { display: none; }
#pr-error { color: var(--unwanted); margin-bottom: 12px; }
.pr-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; margin-bottom: 16px; }
.pr-stats div { display: grid; gap: 4px; padding: 18px 20px; border: 1px solid var(--line); border-radius: 18px; background: var(--surface); }
.pr-stats b { font: 700 clamp(24px, 3vw, 32px)/1 var(--display); letter-spacing: -.02em; }
.pr-stats span { color: var(--muted); font-size: 13px; }
#pr-meta { margin-bottom: 20px; }
#pr-grid .card { cursor: default; }
#pr-copy { margin-right: auto; }

/* Admin names on the profile: hue cycles and letters bob, each a step behind the last (Godot [rainbow][wave]). */
#pr-name.rainbow span {
  display: inline-block;
  white-space: pre;
  animation: rainbow 2.4s linear infinite, wave 1.2s ease-in-out infinite;
}
@keyframes rainbow {
  0%, 100% { color: oklch(78% 0.17 20); }
  17% { color: oklch(84% 0.16 80); }
  33% { color: oklch(86% 0.18 140); }
  50% { color: oklch(80% 0.14 200); }
  67% { color: oklch(72% 0.16 265); }
  83% { color: oklch(74% 0.2 320); }
}
@keyframes wave { 50% { transform: translateY(-0.12em); } }
@media (prefers-reduced-motion: reduce) { #pr-name.rainbow span { animation: rainbow 6s linear infinite; } }
.maint { min-height: 100dvh; padding: 24px 16px; text-align: center; }
.maint div { display: grid; gap: 16px; justify-items: center; width: min(420px, 100%); }
.maint .btn { color: var(--text); text-decoration: none; }

/* Out of packs: the pack dims and the screen points to battles and the collection until the stock refills. */
.pack.empty { filter: grayscale(1) brightness(.5); cursor: default; }
.no-packs { display: flex; flex-direction: column; align-items: center; gap: 10px; color: var(--muted); text-align: center; }
.no-packs[hidden] { display: none; }
/* Pack stock: a segmented gauge, one bar per stored pack. Full bars each show their slice of one rainbow (the big pack's edge) spread across the whole gauge. */
.stock { display: flex; flex-direction: column; align-items: center; gap: 10px; }
.stock-icons { --w: 6px; --gap: 3px; display: flex; gap: var(--gap); padding: 5px; border: 1px solid var(--line); border-radius: 8px; background: #09090a; }
.stock-icons i { width: var(--w); height: 16px; border-radius: 2px; background: #1c1c20; transition: background .4s var(--ease), box-shadow .4s var(--ease); }
.stock-icons i.full {
  background: linear-gradient(90deg, #ff6b8b, #ffd36b, #6bffc8, #6bb8ff, #c46bff) calc(var(--i) * -1 * (var(--w) + var(--gap))) 0 / calc(var(--n) * (var(--w) + var(--gap))) 100%;
  box-shadow: 0 0 6px rgba(255, 255, 255, .12);
}
.stock-text b { color: var(--text); font-weight: 800; }

/* Mystery «???» card: 5 empty rows below the "all cards" list, then a card that is just a question mark. */
.mystery-gap { grid-column: 1 / -1; height: calc(5 * var(--cw) * 7 / 5 + 4 * var(--gap)); }
.card.mystery .art { display: grid; place-items: center; background: #0d0d0f; }
.card.mystery .art::after { content: '?'; font: 900 calc(var(--cw) * .6)/1 var(--display); color: var(--c); text-shadow: 0 0 18px rgb(255 255 255 / .25); }
.nothing { gap: 16px; padding-top: 12px; }
.nothing .ask-text { margin: 0; text-align: center; }
.nothing input, .nothing .btn { width: 100%; }

/* Egg room: a 640×480 pixel room scaled up whole (--s), with a pixel-font textbox. Positions are room pixels. */
.egg { position: fixed; inset: 0; z-index: 60; background: #000; display: grid; place-content: center; overflow: hidden; touch-action: none; user-select: none; }
.egg[hidden] { display: none; }
.egg-room { position: relative; flex: none; width: 640px; height: 480px; transform: scale(var(--s, 2)); image-rendering: pixelated; }
.egg-floor { position: absolute; left: calc(var(--x) * 1px); top: calc(var(--y) * 1px); width: calc(var(--w) * 1px); height: calc(var(--h) * 1px); background: #3a2152; }
.egg-tree, .egg-kid { position: absolute; left: calc(var(--x) * 1px); top: calc(var(--y) * 1px); translate: -50% -100%; }
.egg-tree { z-index: 2; }
.egg-kid { z-index: 3; width: 28px; }   /* the 14×20 PNG at 2× */
.egg-kid.behind { z-index: 1; }
.egg-kid.left { scale: -1 1; }
.egg-kid.walk { animation: egg-bob .3s steps(2) infinite; }
@keyframes egg-bob { 50% { top: calc(var(--y) * 1px - 2px); } }
.egg-box { position: absolute; z-index: 4; left: 32px; right: 32px; bottom: 16px; height: 116px; margin: 0; padding: 20px 24px; background: #000; border: 6px solid #fff; color: #fff; font: 16px/2 'Press Start 2P', monospace; cursor: pointer; }
.egg-z { position: absolute; right: 16px; bottom: 16px; width: 52px; height: 52px; border: 3px solid #fff; background: #000; color: #fff; font: 14px 'Press Start 2P', monospace; cursor: pointer; opacity: .6; }
.egg-z:hover, .egg-z:focus-visible { opacity: 1; }
