:root.short-view { --sab: 0px; }
/* Typing: the keyboard covers the home indicator, so nothing needs to stay clear of it. */
:root.typing { --sab: 0px; }
:root {
  /* env() cannot be read from JS; mirrored here so the dev layout beacon can report them. */
  --probe-top: env(safe-area-inset-top, 0px);
  --probe-bot: env(safe-area-inset-bottom, 0px);
  /* The bottom inset the layout actually honours. It is the real one, except in `.short-view`: on
     the user's iPhone the installed app's view stops 62 px short of the screen, so the home
     indicator sits over iOS's strip below it and not over the game - and 34 px of padding for an
     indicator that is not there is what made the tab bar look oversized. See appHeight(). */
  --sab: env(safe-area-inset-bottom, 0px);
  --bg1: #2b3bd6; --bg2: #1b1f6b; --bg3: #120f3d;
  --gold: #ffd23f; --gold-d: #d99a00;
  --green: #3ddc6b; --green-d: #1f9c44;
  --red: #ff4d5e; --red-d: #b8202f;
  --blue: #4fb4ff; --ink: #1a2352; --white: #fff;
  --panel: #fff7e6;

  /* Surfaces. Every raised thing in the game is one of these three, so the depth reads as one material. */
  /* Opaque enough that nothing shows through, which is why the panels no longer ask the phone to
     blur what is behind them: a backdrop-filter under a 94% white panel is invisible and is still
     a full snapshot-blur-composite of the screen, every frame, for every panel wearing it. */
  --glass: linear-gradient(180deg, rgba(255,255,255,.96), rgba(226,236,255,.93));
  --glass-line: rgba(255,255,255,.95);      /* hairline rim on a glass edge */
  --glass-top: rgba(255,255,255,.95);       /* light catching the top edge */
  --sink: linear-gradient(180deg, rgba(26,20,64,.12), rgba(26,20,64,.05)); /* recessed wells */
  --drop: 0 14px 26px -12px rgba(20,26,70,.45);
  --ink-2: #4a5590;                         /* secondary text on a light panel */
  --r-lg: 24px; --r-md: 18px; --r-sm: 13px;

  --display: "Lilita One", "Arial Black", Impact, system-ui, sans-serif;
  --body: "Nunito", system-ui, -apple-system, "Segoe UI", sans-serif;
}
* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
/* No visible scrollbars anywhere. A grey track down the side of a match reads as a browser artefact,
   not part of the game; every list still scrolls exactly as before. */
* { scrollbar-width: none; -ms-overflow-style: none; }
*::-webkit-scrollbar { width: 0; height: 0; display: none; }
html, body { margin: 0; height: 100%; background: var(--bg3); color: var(--white); font-family: var(--body); overflow: hidden; }
button { font: inherit; color: inherit; border: 0; background: none; cursor: pointer; touch-action: manipulation; }
[hidden] { display: none !important; }

#app {
  --arena-blur: 8px;                         /* depth of field behind the menus; 0 turns it off */
  /* --app-h is window.innerHeight, set by appHeight() in js/main.js; 100dvh is only the fallback
     for the first paint. In the installed app on iOS, 100dvh came up 62 px SHORT of the window -
     measured off the user's own screenshot, a band of --bg3 under the tab bar that the game could
     not draw into. innerHeight is the one number that is always the real window.
     (position: fixed would also have fixed it and was tried, but a fixed box stops scaling with
     the page under zoom, and that is a worse failure than the band.) */
  position: relative; height: var(--app-h, 100dvh); max-width: 480px; margin: 0 auto; background: var(--bg3);
  /* clip, not hidden: the oversized backdrop below (inset: -7%) makes this box scrollable, and a
     button taking focus - a tab, a card - has the browser scroll the whole frame to reveal it,
     which drags the game sideways under the notch. clip is the same clipping with no scroll
     container at all. hidden stays first for anything that has not got clip. */
  overflow: hidden; overflow: clip;
}
/* The arena sits on its own layer so it can be blurred without dragging the UI out of focus with it.
   The layer is oversized, because a blur softens its own edges and would show a seam at the frame. */
#app::before {
  content: ""; position: absolute; inset: -7%; z-index: 0; pointer-events: none;
  /* The arena render on top, the old stadium photo underneath as the fallback for arenas not yet built. */
  background: var(--arena, none) center / cover no-repeat, url("../assets/stadium.webp") center / cover no-repeat;
  filter: blur(var(--arena-blur));
  transition: filter .35s ease;
}
/* The arena's moving layer. Same box and same fit as the backdrop above, so a layer rendered from
   the backdrop's own camera lands exactly on it. Screen blending, because everything in it is
   light being added to a picture that is already there - the phones and the ring boards are in the
   still too, at their resting brightness.

   It is drawn only during a match: on the menus the backdrop is blurred and thrown out of focus,
   where a crisp layer of lights on top would sit in front of the blur looking pasted on - and a
   phone should not be decoding an animation to put it behind a page nobody is looking at. */
.arena-fx { display: none; position: absolute; inset: -7%; z-index: 0; pointer-events: none;
  background: var(--arena-fx, none) center / cover no-repeat; mix-blend-mode: screen; }
#app.in-match.has-fx .arena-fx { display: block; animation: fade .5s; }
@media (prefers-reduced-motion: reduce) { .arena-fx { display: none !important; } }

/* In a match the backdrop is sharp and, from arena 2 up, lit for a night game. */
#app.in-match::before {
  filter: none;
  background: var(--arena-night, var(--arena, none)) center / cover no-repeat,
    url("../assets/stadium.webp") center / cover no-repeat;
}
/* No scrim and no vignette over the arena: the user wants the render shown as it is.
   Text stays readable because every panel carries its own background. */
.screen { position: absolute; inset: 0; z-index: 1; display: flex; flex-direction: column; padding: max(12px, env(safe-area-inset-top)) 16px max(12px, var(--sab)); }
.outline { text-shadow: 0 3px 0 rgba(0,0,0,.35), 0 0 2px #000; }

/* ---------- buttons ---------- */
.btn {
  position: relative; overflow: hidden; isolation: isolate;
  font-family: var(--display); font-size: 26px; letter-spacing: 1px; padding: 15px 20px; border-radius: 20px;
  text-shadow: 0 2px 0 rgba(0,0,0,.35); transition: transform .08s, box-shadow .08s; width: 100%;
}
.btn::before { /* the gloss that sells the plastic */
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 46%; z-index: -1; border-radius: inherit;
  background: linear-gradient(180deg, rgba(255,255,255,.42), rgba(255,255,255,0)); pointer-events: none;
}
.btn:active { transform: translateY(4px); }
.btn-play {
  background: linear-gradient(180deg, #ffe98d, var(--gold) 52%, #f0a800); color: #5a3500;
  box-shadow: 0 6px 0 var(--gold-d), 0 12px 22px -6px rgba(217,154,0,.55), var(--drop),
    inset 0 2px 0 rgba(255,255,255,.75), inset 0 0 0 2px rgba(255,255,255,.28);
  text-shadow: 0 2px 0 rgba(255,255,255,.45);
}
.btn-play::after { /* a highlight that sweeps across every few seconds — the button never looks dead */
  content: ""; position: absolute; top: -60%; bottom: -60%; left: 0; width: 38%; z-index: -1; pointer-events: none;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.62), transparent); transform: skewX(-18deg);
  --sw0: -118%; --sw1: 329%;          /* -45% and 125% of the button, in the band's own widths */
  animation: sweep 4.5s cubic-bezier(.5,0,.5,1) infinite;
}
.btn-play:active { box-shadow: 0 2px 0 var(--gold-d), inset 0 2px 0 rgba(255,255,255,.7); }
/* Every other window's button: the game's own blue - the tabs', the menus' (the user, 2026-09-29: the
   yellow ones "don't quite match the game"). Gold is kept for PLAY, START and the premium pass. */
.btn-blue {
  background: linear-gradient(180deg, #86c6ff, #4a92f2 50%, #2b62d4); color: #fff;
  box-shadow: 0 6px 0 #1b3f99, 0 12px 22px -8px rgba(27,63,153,.6), var(--drop),
    inset 0 2px 0 rgba(255,255,255,.55), inset 0 0 0 2px rgba(255,255,255,.18);
  text-shadow: 0 2px 0 rgba(12,30,90,.45);
}
.btn-blue:active { box-shadow: 0 2px 0 #1b3f99, inset 0 2px 0 rgba(255,255,255,.5); }
.btn-blue:disabled { filter: grayscale(.6) brightness(.95); }
.btn-ghost { font-size: 18px; margin-top: 10px; opacity: .8; }
.btn-ghost::before { display: none; }
/* By transform, not by `left`: left is a layout change, and the PLAY button ran one every frame
   forever - including all through a swipe onto the menu, which was part of that swipe's lag. */
@keyframes sweep { 0% { transform: translateX(var(--sw0)) skewX(-18deg); }
  55%, 100% { transform: translateX(var(--sw1)) skewX(-18deg); } }

/* ---------- first run ---------- */
.setup { gap: 10px; }
/* The profile page scrolls. For an existing player it carries the record as well as the name, icon,
   colour and club, and at phone height a fixed column squeezed the club list to nothing and pushed
   SAVE down onto the home bar - a colour could be picked and never saved. Nothing in it shrinks
   now; the page scrolls instead, and SAVE stays pinned to the bottom. */
.screen.setup { overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; }
.setup > * { flex-shrink: 0; }
.setup .field.grow { flex: 1 0 auto; height: 340px; min-height: 340px; }
#setupDone { position: sticky; bottom: 0; z-index: 2; }
.setup-head { text-align: center; }
.setup-head h1 { font-family: var(--display); font-weight: 400; font-size: 38px; margin: 0; letter-spacing: 3px; color: #fff;
  text-shadow: 0 3px 0 rgba(26,35,82,.45); }
.setup-head p { margin: 2px 0 0; font-weight: 800; font-size: 13px; color: #dbe5ff; text-shadow: 0 2px 0 rgba(12,18,50,.5); }
.field { display: flex; flex-direction: column; gap: 6px; background: var(--glass);
  border: 1px solid var(--glass-line); border-radius: var(--r-md); padding: 10px 12px; color: var(--ink);
  box-shadow: inset 0 1px 0 var(--glass-top), var(--drop); }
.field.grow { flex: 1; min-height: 0; }
.field-label { font-weight: 900; font-size: 10px; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-2); }
/* What a change costs, said on the label itself, and the line under the field that says whether you
   can afford it. See renameCost() in js/main.js: the first change is free, the rest are 60 gems. */
.field-label em { font-style: normal; font-weight: 900; font-size: 9.5px; letter-spacing: .1em;
  color: var(--gold-d); text-transform: uppercase; }
.field-note { display: block; margin-top: 5px; font-weight: 800; font-size: 10.5px;
  letter-spacing: .04em; color: var(--ink-2); min-height: 13px; }
.field-note.warn { color: #d22b3d; }
.field-label em { font-style: normal; opacity: .7; }
.field input { font: 900 17px var(--body); color: var(--ink); background: #fff; border: 0; border-radius: 12px;
  padding: 10px 12px; outline: none; box-shadow: inset 0 0 0 2px rgba(26,35,82,.10); }
.field input:focus { box-shadow: inset 0 0 0 2px var(--gold), 0 0 14px -4px var(--gold); }

.icon-row { display: flex; gap: 8px; }
.icon-opt { width: 46px; height: 46px; border-radius: 50%; position: relative;
  background: radial-gradient(circle at 34% 28%, color-mix(in srgb, var(--t) 55%, #fff), var(--t) 72%);
  box-shadow: inset 0 -3px 6px rgba(20,26,70,.25), 0 3px 0 rgba(20,26,70,.2); }
.icon-opt::after { content: ""; position: absolute; inset: 0;
  background: url("../assets/ui/ball.svg") center / 100% no-repeat; }
.icon-opt.on { outline: 3px solid var(--gold); outline-offset: 3px; }

.club-grid { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(84px, 1fr)); align-content: start; gap: 7px; padding: 2px; }
.club-opt { display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 7px 4px; border-radius: 12px;
  background: #fff; box-shadow: inset 0 0 0 2px rgba(26,35,82,.08); }
.club-opt.on { box-shadow: inset 0 0 0 3px var(--gold), 0 0 14px -4px var(--gold); }
.club-opt-name { font-weight: 900; font-size: 10px; line-height: 1.1; text-align: center; color: var(--ink);
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; }
/* A stand-in crest: the club's two colours and its code, never a real badge. */
.fake-badge { width: 34px; height: 34px; flex: none; border-radius: 50% 50% 44% 44%; display: grid; place-items: center;
  font-family: var(--display); font-size: 11px; color: #fff; text-shadow: 0 1px 2px rgba(0,0,0,.6);
  background: linear-gradient(135deg, var(--c1) 0 55%, var(--c2) 55%); box-shadow: 0 0 0 2px #fff, 0 2px 0 2px rgba(26,35,82,.25); }

/* The player strip above the chips on Home. */
/* The header is only a container: the arena behind it stays visible, and the blue is spent on the
   one bar that earns it. */
.head { display: grid; gap: 8px; margin-bottom: 10px; }
.head-top { display: flex; align-items: stretch; justify-content: space-between; gap: 8px; }

/* The name bar, in the tab bar's blue lifted a couple of steps: the same surface at both ends of
   the screen, but the one at the top sits over a bright arena rather than under the screen's edge,
   and matching the tab bar exactly made it read as heavy up there. Everything about you rides in
   here - name, streak, trophy count. */
.me { display: flex; align-items: center; gap: 9px; width: 100%; padding: 5px 11px 5px 5px;
  border-radius: 999px; color: #fff;
  background: linear-gradient(180deg, var(--me-a, #7dbaff), var(--me-b, #4a86e8) 78%, var(--me-c, #3f79dd));
  border: 1px solid rgba(255,255,255,.45);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.35), 0 6px 16px -8px rgba(16,34,96,.9), var(--drop); }
.me { cursor: pointer; -webkit-tap-highlight-color: transparent; }
.me:active { transform: translateY(2px); }
.me-icon { width: 30px; height: 30px; flex: none; border-radius: 50%; position: relative;
  background: radial-gradient(circle at 34% 28%, color-mix(in srgb, var(--t, #fff) 55%, #fff), var(--t, #fff) 72%);
  box-shadow: inset 0 -2px 4px rgba(20,26,70,.25); }
.me-icon::after { content: ""; position: absolute; inset: 0;
  background: url("../assets/ui/ball.svg") center / 100% no-repeat; }
.me-main { flex: 1; min-width: 0; display: flex; align-items: center; gap: 9px; }
/* The way to the table of managers: a small coin of a button between your name and your crest. */
.me-lb { flex: none; width: 30px; height: 30px; border-radius: 50%; display: grid; place-items: center;
  background: linear-gradient(180deg, #ffe98d, var(--gold) 55%, #e09a00);
  box-shadow: 0 2px 0 #b07c00, inset 0 1px 0 rgba(255,255,255,.7); }
/* A flat silhouette, not the trophy render: at 17px the render is all thin stem and reads as a stroke. */
.me-lb::before { content: ""; width: 17px; height: 17px; background: #4a3400;
  --cup: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M6 2h12v2h4v3a5 5 0 0 1-5 5h-.5A6 6 0 0 1 13 15.7V18h4v4H7v-4h4v-2.3A6 6 0 0 1 7.5 12H7a5 5 0 0 1-5-5V4h4V2Zm0 4H4v1a3 3 0 0 0 2 2.8V6Zm12 0v3.8A3 3 0 0 0 20 7V6h-2Z"/></svg>');
  -webkit-mask: var(--cup) center / contain no-repeat; mask: var(--cup) center / contain no-repeat; }
.me-lb:active { transform: translateY(2px); }
.me-name { flex: 1; min-width: 0; font-family: var(--display); font-size: 19px; text-align: left; color: #fff;
  text-shadow: 0 2px 0 rgba(6,14,44,.45);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* The trophy count, in the name bar rather than in a chip of its own. No tile, no rim: the rendered
   cup stands up out of the bar and the number sits beside it in the display face - the one figure on
   this screen that says how far you have come, given the room to say it. The rule to its right
   separates it from the crest without drawing another box. */
.me-streak, .me-cups { flex: none; display: flex; align-items: center; gap: 4px;
  font-family: var(--display); font-size: 20px; line-height: 1; color: #fff;
  text-shadow: 0 2px 0 rgba(6,14,44,.45); }
.me-streak { margin-right: 4px; }
.me-streak::before { content: ""; width: 17px; height: 21px; flex: none;
  background: linear-gradient(180deg, #ffd06a, #ff7a2f 60%, #ff4d2a);
  -webkit-mask: var(--flame) center / contain no-repeat; mask: var(--flame) center / contain no-repeat;
  filter: drop-shadow(0 2px 3px rgba(6,14,44,.5)); }
.me-streak { --flame: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13 2c.6 4.4-3.4 5.6-3.4 9.4a2.9 2.9 0 0 0 5.8.3c0-1.4-.6-2.4-1-3 2.4 1.2 4.6 3.6 4.6 6.8A8 8 0 1 1 5 13C5 7.6 11 6.8 13 2Z"/></svg>'); }
.me-cups { margin: -8px 0; padding-right: 2px; font-size: 21px; }
.me-cups::before { content: ""; width: 31px; height: 48px; flex: none;
  background: url("../assets/ui/trophy.png") center / contain no-repeat;
  filter: drop-shadow(0 3px 4px rgba(20,26,70,.45)); }
/* The rule belongs to the crest, not to the count: with no club chosen there is nothing to separate
   from, and a hairline hanging off the end of the bar is worse than no rule at all. */
.me-club:not(:empty)::before { content: ""; width: 1px; height: 22px; margin-right: 10px;
  background: linear-gradient(180deg, transparent, rgba(255,255,255,.45), transparent); }
.me-cups.bump, .me-streak.bump { animation: chipBump .32s cubic-bezier(.2,1.7,.4,1); }

.me-club { flex: none; display: flex; align-items: center; }
.me-club .fake-badge { width: 28px; height: 28px; font-size: 9px; }

/* ---------- home ---------- */
.topbar { display: flex; justify-content: space-between; align-items: flex-start; gap: 8px; }
.chips { display: flex; gap: 6px; }
/* Sits in the gap the two chip groups leave in the middle of the top bar. */
.stats-btn { flex: none; align-self: stretch; padding: 0 12px; border-radius: 999px;
  font-family: var(--display); font-size: 12px; letter-spacing: .1em; color: var(--ink);
  background: var(--glass); border: 1px solid var(--glass-line);
  box-shadow: inset 0 1px 0 var(--glass-top), var(--drop); }
.stats-btn:active { transform: translateY(2px); }
.gear-btn { padding: 0 8px; margin-right: auto; display: grid; place-items: center; }
.gear-btn svg { width: 18px; height: 18px; }
/* The settings window's music list: a row per track, a play button to listen, a tick on the one chosen. */
.settings-panel { max-width: 380px; }
.set-label { font-weight: 900; font-size: 12px; letter-spacing: .12em; color: var(--ink-2); margin: 6px 0 8px; text-align: left; }
.music-list { display: grid; gap: 8px; margin-bottom: 14px; }
.music-row { display: flex; align-items: center; gap: 10px; width: 100%; padding: 10px 12px; border: 0; border-radius: 16px;
  text-align: left; font: inherit; color: var(--ink); cursor: pointer; background: rgba(26,35,82,.06);
  box-shadow: inset 0 0 0 2px rgba(26,35,82,.08); }
.music-row .mu-text { flex: 1; display: grid; gap: 2px; min-width: 0; }
.music-row b { font-size: 15px; } .music-row small { font-size: 11.5px; color: var(--ink-2); font-weight: 700; }
.music-row.on { background: linear-gradient(180deg, #fff3c8, #ffe08a); box-shadow: inset 0 0 0 2px var(--gold), 0 3px 0 var(--gold-d); }
.music-row.locked { opacity: .55; cursor: default; }
.music-row .mu-check { width: 20px; height: 20px; flex: none; border-radius: 50%; box-shadow: inset 0 0 0 2px rgba(26,35,82,.25); }
.music-row.on .mu-check { background: var(--gold-d); box-shadow: none;
  -webkit-mask: radial-gradient(circle, #000 60%, transparent 62%); }
.mu-play { width: 34px; height: 34px; flex: none; display: grid; place-items: center; border-radius: 50%; color: #fff;
  background: linear-gradient(180deg, #4f9bff, #2a5fd8); box-shadow: 0 3px 0 #1c3f99; }
.mu-play.on { background: linear-gradient(180deg, #ff7a7a, #d83a3a); box-shadow: 0 3px 0 #9a2020; }
.mu-play svg { width: 18px; height: 18px; }
.music-row svg.lock-ic, .music-row .slot-lock { width: 26px; height: 26px; }

.stat-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin: 12px 0 14px; }
.stat-grid div { display: flex; flex-direction: column; gap: 1px; padding: 8px 10px; border-radius: 14px;
  background: #fff; box-shadow: inset 0 0 0 2px rgba(26,35,82,.07), 0 3px 0 rgba(201,185,143,.45); }
.stat-grid span { font-weight: 900; font-size: 10px; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-2); }
.stat-grid b { font-family: var(--display); font-weight: 400; font-size: 21px; color: var(--ink); line-height: 1.1; }

.pill {
  display: flex; align-items: center; gap: 7px; background: var(--glass);
  border: 1px solid var(--glass-line); border-radius: 999px; padding: 5px 15px 5px 11px; font-weight: 900; font-size: 16px;
  color: var(--ink); box-shadow: inset 0 1px 0 var(--glass-top), var(--drop);
}
.pill::before { /* trophy / flame, drawn as a mask so the game stays emoji-free */
  content: ""; width: 17px; height: 17px; flex: none; background: linear-gradient(180deg, #ffc93c, #e08a00);
  -webkit-mask: var(--icon) center / contain no-repeat; mask: var(--icon) center / contain no-repeat;
}
/* The cup is the rendered model, not a glyph: no mask, and a taller box for its proportions. */
.pill.coin::before { width: 18px; height: 18px; background: url("../assets/ui/coin.png") center / contain no-repeat;
  -webkit-mask: none; mask: none; filter: drop-shadow(0 2px 3px rgba(20,26,70,.35)); }
.pill.gem::before { width: 19px; height: 19px; background: url("../assets/ui/gem.png") center / contain no-repeat;
  -webkit-mask: none; mask: none; filter: drop-shadow(0 2px 3px rgba(20,26,70,.35)); }
/* The two balances sit tighter than the trophy and the streak: they are a running total you glance
   at, not the headline the trophy count is. Smaller icon, less padding, smaller type. */
.pill.coin, .pill.gem { gap: 5px; padding: 4px 11px 4px 8px; }
.pill.trophy::before { width: 34px; height: 54px; margin: -18px 0; background: url("../assets/ui/trophy.png") center / contain no-repeat;
  -webkit-mask: none; mask: none; filter: drop-shadow(0 2px 3px rgba(20,26,70,.35)); }
.pill.trophy { --icon: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M6 2h12v2h4v3a5 5 0 0 1-5 5h-.5A6 6 0 0 1 13 15.7V18h4v4H7v-4h4v-2.3A6 6 0 0 1 7.5 12H7a5 5 0 0 1-5-5V4h4V2Zm0 4H4v1a3 3 0 0 0 2 2.8V6Zm12 0v3.8A3 3 0 0 0 20 7V6h-2Z"/></svg>'); }
.pill.streak { --icon: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13 2c.6 4.4-3.4 5.6-3.4 9.4a2.9 2.9 0 0 0 5.8.3c0-1.4-.6-2.4-1-3 2.4 1.2 4.6 3.6 4.6 6.8A8 8 0 1 1 5 13C5 7.6 11 6.8 13 2Z"/></svg>'); }
.pill span { display: none; } /* the icon says it */
.pill b { font-family: var(--display); font-weight: 400; color: var(--ink); font-size: 19px; line-height: 1;
  display: inline-block; text-align: center; }   /* the box is sized by chipTo(), see js/main.js */
/* The two balances in the thickest face in the game. Loaded subset to the ten digits, which is all
   they ever show. Slightly smaller than the others because Titan One sets much heavier than Lilita
   One at the same size and would otherwise tower over the trophy count beside it. */
.pill.coin b, .pill.gem b { font-family: "Titan One", var(--display); font-weight: 400;
  font-size: 14px; letter-spacing: .01em; font-variant-numeric: tabular-nums; }
.screen.with-tabs { padding-bottom: calc(66px + max(4px, var(--sab)));
  /* room for the wallet at the top of the page */
  padding-top: calc(42px + max(12px, env(safe-area-inset-top))); }
/* The menu has a row of its own for it, so it needs no room made above. */
/* The space the arena box was wasting goes here, as room between the blocks - they were sitting
   2 to 8 px apart while a quarter of the screen was empty. `space-between` spreads whatever is left
   after the arena has taken its own height, so it stays right on any screen instead of being tuned
   to one. */
#home.screen.with-tabs { padding-top: max(12px, env(safe-area-inset-top)); justify-content: space-between; gap: 10px; }
/* Lifted off the tab bar: space-between leaves the last item hard against the bottom padding, and
   the play button is the one thing on this screen that should not look wedged in. */
#home #playBtn { margin-bottom: 18px; }

/* The balances, pinned to the top of every menu page. Not a bar across the screen - two chips in
   the corner, so the page underneath keeps its full width and the arena still reads behind them. */
/* The same spot on every page: the menu's top row (its screen padding is max(12px, safe area)). */
.wallet { position: absolute; z-index: 6; top: max(12px, env(safe-area-inset-top)); right: 16px;
  display: flex; gap: 6px; pointer-events: none; }
/* Brought back for a payout on a page that hides it: it drops in, and the chip it lands in is lit
   for as long as it is there. See showWallet() in js/main.js. */
.wallet.landing { animation: walletIn .28s cubic-bezier(.2,1.5,.4,1) both; }
.wallet.landing .pill { box-shadow: inset 0 1px 0 var(--glass-top), 0 0 0 2px rgba(255,210,63,.8), var(--drop); }
@keyframes walletIn { from { transform: translateY(-14px); opacity: 0; } }

/* The menu's top row keeps the wallet's room (the wallet itself stays pinned over it, see show()). */
.wallet-slot { display: flex; min-height: 29px; }
/* A section label, not a heading. The rules either side carry it across the width without putting
   another block of type up against the pack art, and they fade out rather than stopping dead —
   a full-width line would cut the screen in two. Drawn from the one element, no extra markup. */
.section-title { display: flex; align-items: center; gap: 12px; margin: 16px 0 10px;
  font-family: var(--display); font-weight: 400; font-size: 21px; letter-spacing: 2px; color: #fff;
  text-shadow: 0 2px 0 rgba(20,28,66,.55), 0 0 16px rgba(150,190,255,.4); }
.section-title::before, .section-title::after {
  content: ""; flex: 1; height: 2px; border-radius: 2px;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.14) 35%, rgba(255,255,255,.6));
  box-shadow: 0 1px 0 rgba(20,28,66,.35); }
.section-title::after { rotate: 180deg; }

/* Card art is a full 2:3 card; small squares zoom in on the face (top ~30%). */
/* Small square thumbnails show the top of the card art (head and shoulders), never the middle. */
.portrait { display: block; width: 100%; height: 100%; object-fit: cover; object-position: 50% var(--fo, 0%); transform: scale(var(--fs, 1.3)); transform-origin: 50% var(--ft, 0%); }
.ability-btn:has(.portrait) { overflow: hidden; padding: 0; }

/* The ladder, as a list of arenas: passed, current, still locked. */
.arenas-panel { display: flex; flex-direction: column; max-height: 88dvh; overflow: hidden; }
.arena-list { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; display: grid; gap: 8px;
  margin: 12px 0 14px; padding: 2px; }
.arena-row { display: flex; align-items: center; gap: 11px; padding: 8px 12px 8px 8px; border-radius: var(--r-md);
  background: #fff; box-shadow: inset 0 0 0 2px rgba(26,35,82,.08), 0 3px 0 rgba(201,185,143,.45); text-align: left; }
.ar-art { flex: none; width: 76px; height: 54px; border-radius: 11px; overflow: hidden; background: linear-gradient(180deg, #dce6ff, #b9c8ee);
  display: grid; place-items: center; }
.ar-art img { width: 100%; height: 100%; object-fit: cover; }
.ar-text { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.ar-tier { font-weight: 900; font-size: 10px; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-2); }
.ar-name { font-family: var(--display); font-size: 19px; line-height: 1.05; color: var(--ink); }
.ar-min { font-weight: 800; font-size: 11px; color: var(--ink-2); }
.ar-state { flex: none; font-weight: 900; font-size: 10px; letter-spacing: .06em; text-transform: uppercase;
  padding: 5px 9px; border-radius: 999px; background: rgba(26,35,82,.08); color: var(--ink-2); white-space: nowrap; }
.arena-row.here { box-shadow: inset 0 0 0 3px var(--gold), 0 4px 0 var(--gold-d), 0 0 22px -6px var(--gold); }
.arena-row.here .ar-state { background: linear-gradient(180deg, #ffe98d, var(--gold)); color: #5a3500; }
.arena-row.done .ar-state { background: linear-gradient(180deg, #a6ffc2, var(--green)); color: #073d1c; }
.arena-row.locked { opacity: .62; }
.arena-row.locked .ar-art img { filter: grayscale(.85) brightness(.9); }

/* The arena, seen from outside, sitting in the middle of Home the way a Clash Royale arena does. */
/* Sized to the arena, and full width.
   It used to be `flex: 4.4` - it took whatever share of the column was going, and the render inside
   it is a WIDE picture (1142x511) that object-fit could only ever fit by width. Measured at 375px:
   a 364 px tall box holding a 154 px tall drawing, 210 px of nothing, a quarter of the screen. The
   box is the drawing's own height now, and the arena breaks out of the screen's side padding so it
   is drawn as wide as the phone allows rather than 32 px narrower. */
.arena-hero { position: relative; flex: 0 0 auto; min-height: 0; margin: 0 -16px; padding: 0; border: 0; background: none;
  cursor: pointer; display: flex; align-items: center; justify-content: center; }
.arena-hero:active img { transform: scale(.97); }
/* Its shadow and glow are painted gradients under it, not `filter: drop-shadow` on the picture: two
   big blurred shadows of a large image are redrawn in software every time the menu page is shown,
   and a swipe onto the menu shows it - that was the hitch at the start of every swipe there.
   The shadow stays on the ground while the tile floats above it. */
.arena-hero::before { content: ""; position: absolute; left: 6%; right: 6%; top: 18%; bottom: 4%; z-index: 0;
  pointer-events: none; border-radius: 50%;
  background: radial-gradient(50% 50% at 50% 62%, rgba(0,0,0,.62), rgba(0,0,0,.3) 55%, transparent 100%),
              radial-gradient(50% 50% at 50% 50%, rgba(120,170,255,.22), transparent 100%); }
/* No taller than the arena pictures have always been (about 0.45 of the width): arena 2's street
   tile came out taller and pushed the rest of the menu page together. */
.arena-hero img { position: relative; z-index: 1; width: 100%; height: auto; max-height: min(42vh, 46vw); object-fit: contain;
  animation: heroFloat 6s ease-in-out infinite; }
/* Arena 2's street diorama (and arena 3's beach court) is much squarer than the others, so the same height cap drew it at about
   two thirds of the phone's width - the user found it too small. It gets a taller cap. */
/* But only out of the space that is left: a fixed cap pushed PLAY under the tab bar on the user's
   iPhone (a shorter screen than the test one). The tile takes whatever the column has spare and the
   picture fits inside it, so on a short phone it simply draws smaller. */
.arena-hero[data-arena="2"], .arena-hero[data-arena="3"], .arena-hero[data-arena="4"], .arena-hero[data-arena="5"] { flex: 1 1 0; min-height: 70px; }
.arena-hero[data-arena="2"] img, .arena-hero[data-arena="3"] img, .arena-hero[data-arena="4"] img, .arena-hero[data-arena="5"] img { height: 100%; max-height: min(50vh, 64vw); }
@keyframes heroFloat { 50% { transform: translateY(-7px); } }
@media (prefers-reduced-motion: reduce) { .arena-hero img { animation: none; } }

/* The game-mode switch. Two Clubs is first and stays the default. */
.modes { display: grid; grid-template-columns: 1fr 1fr; gap: 7px; margin-bottom: 8px; }
.mode { display: flex; flex-direction: column; gap: 1px; padding: 6px 9px; border-radius: var(--r-md); text-align: left;
  background: var(--glass); border: 1px solid var(--glass-line); color: var(--ink-2);
  box-shadow: inset 0 1px 0 var(--glass-top), var(--drop); transition: color .15s, background .15s; }
.mode-name { font-family: var(--display); font-size: 15px; line-height: 1.05; color: var(--ink); }
.mode-blurb { font-weight: 800; font-size: 10px; line-height: 1.15; }
.mode.on { background: linear-gradient(180deg, #62b9ff, #2f7fe8); border-color: #fff; color: rgba(255,255,255,.85);
  box-shadow: 0 4px 0 #1f60bd, inset 0 1px 0 rgba(255,255,255,.5); }
.mode.on .mode-name { color: #fff; }
.mode:not(.on):active { transform: translateY(2px); }

/* A nation instead of a crest. */
/* A flag is 3:2 and must not be cropped into the crest's square, so the plate goes transparent and
   the flag sits inside it as its own tile. Needs .badge in the selector: the plain .badge rule comes
   later in the file and would otherwise win. */
.badge.country-badge { background: none; box-shadow: none; overflow: visible; }
.badge.country-badge::after { display: none; }        /* no gloss over a flag */
.badge.country-badge img { width: 58px; height: auto; max-height: 40px; border-radius: 6px;
  box-shadow: 0 0 0 1px rgba(0,0,0,.15), 0 6px 12px -4px rgba(0,0,0,.6); }
.badge.country-badge .cb-ini { font-size: 20px; color: var(--ink); }
/* A flag as itself - its own shape, no white card behind it (the user) - with a soft gloss and shadow. */
.cine-flag, .cinema-club img.cine-flag { display: block; width: 150px; height: auto; max-height: 104px; object-fit: fill;
  border-radius: 10px; filter: none; box-shadow: 0 12px 26px rgba(0,0,0,.6), 0 0 0 1px rgba(255,255,255,.18); }
.cb-ini { font-family: var(--display); font-size: 17px; color: #fff; text-shadow: 0 2px 0 rgba(10,20,60,.45); }
.cine-country { width: 128px; height: 128px; display: grid; place-items: center; border-radius: 50%;
  font-family: var(--display); font-size: 42px; color: #fff; background: linear-gradient(180deg, #7bc4ff, #2f7fe8);
  box-shadow: 0 0 0 4px rgba(255,255,255,.7), 0 10px 22px rgba(0,0,0,.55); }

/* ---------- match hud ---------- */
.hud { display: flex; align-items: center; justify-content: space-between; gap: 6px; }
.side { display: flex; align-items: center; gap: 8px; min-width: 0; }
.side.ai { text-align: right; }
/* A side of the HUD: the manager's own crest, and the star or stars they came with sitting under
   it in little circles. No box around the pair - the crest is the shape, and the stars hang off it. */
.avatar { position: relative; flex: none; width: 52px; display: flex; flex-direction: column;
  align-items: center; gap: 0; background: none; box-shadow: none; }
.av-icon { width: 40px; height: 40px; border-radius: 50%; position: relative;
  background: radial-gradient(circle at 34% 28%, color-mix(in srgb, var(--t, #fff) 55%, #fff), var(--t, #fff) 72%);
  box-shadow: inset 0 -2px 4px rgba(20,26,70,.25), 0 0 0 2px rgba(255,255,255,.6), 0 5px 0 -1px rgba(0,0,0,.45),
              0 8px 14px -6px rgba(0,0,0,.8); }
.av-icon::after { content: ""; position: absolute; inset: 0;
  background: url("../assets/ui/ball.svg") center / 100% no-repeat; }
/* The stars overlap the crest a little, so the two read as one badge rather than as a stack. */
.av-stars { display: flex; gap: -4px; margin-top: -9px; z-index: 1; }
.av-star { position: relative; width: 24px; height: 24px; border-radius: 50%; overflow: hidden; display: grid; place-items: center;
  background: var(--c, #888); box-shadow: 0 0 0 2px var(--r, #fff), 0 0 0 3.5px rgba(8,14,44,.7); }
.av-star + .av-star { margin-left: -7px; }
/* A 24px circle only has room for a face, so the crop is pinned to the very top of the art and the
   zoom grows downward from there: whatever else is in the picture, what lands in the circle is the
   top of it.
   The picture has to be taken out of the grid flow to do that. `height: 100%` against a grid area
   of indefinite height is not a height at all - it fell back to the image's own aspect, so a 24px
   circle held a 24x32 picture, the row grew to fit it and `place-items: center` put the MIDDLE of
   that picture in the circle. Pinned to the box with inset, the height is real and `cover` crops
   from the top, which is where the face is. */
.av-star .portrait { position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: 50% 0%; transform: scale(1.3); transform-origin: 50% 0%; }
.av-star .mono { font-family: var(--display); font-size: 11px; color: #fff; }
.avatar.active { animation: pulse 1s ease-in-out infinite; }
/* Whose turn it is: the ring goes round the crest, not round the whole badge. */
.avatar.active::after { content: ""; position: absolute; left: 50%; top: -4px; width: 48px; height: 48px;
  margin-left: -24px; border-radius: 50%; border: 2px solid var(--gold); box-shadow: 0 0 14px var(--gold);
  animation: ring 1s ease-in-out infinite; }
.who { font-family: var(--display); font-size: 15px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 110px;
  text-shadow: 0 2px 0 rgba(12,18,50,.55), 0 0 10px rgba(12,18,50,.45); }
.pips { display: flex; gap: 4px; margin-top: 3px; }
.side.ai .pips { justify-content: flex-end; }
.pip { width: 15px; height: 15px; border-radius: 50%; background: rgba(0,0,0,.45); border: 2px solid rgba(255,255,255,.22); box-shadow: inset 0 2px 3px rgba(0,0,0,.5); }
.pip.on { background: linear-gradient(180deg, #fff3b0, var(--gold)); border-color: #fff; box-shadow: 0 0 10px var(--gold), inset 0 1px 0 #fff; }
.round-label { font-family: var(--display); font-size: 15px; letter-spacing: .06em; background: var(--glass); border: 1px solid var(--glass-line);
  padding: 5px 12px; border-radius: 11px; white-space: nowrap; color: var(--ink); box-shadow: inset 0 1px 0 var(--glass-top), var(--drop); }

.pair-card { margin-top: 12px; display: flex; align-items: center; justify-content: space-between; gap: 6px; position: relative; overflow: hidden;
  background: linear-gradient(180deg, rgba(255,255,255,.95), rgba(224,235,255,.90));
  border: 1px solid var(--glass-line); border-radius: var(--r-lg); padding: 13px 10px; color: var(--ink);
  box-shadow: inset 0 1px 0 var(--glass-top), var(--drop); }
.pair-card::before { content: ""; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(70% 120% at 50% -20%, rgba(255,255,255,.55), transparent 70%); }
.pair-card.pop { animation: pop .5s cubic-bezier(.2,1.6,.4,1); }
.club { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 7px; min-width: 0; }
/* The crest sits on a lit plate, the way a team badge sits on a scoreboard. */
.badge { width: 62px; height: 62px; border-radius: 20px; display: grid; place-items: center; font-family: var(--display); font-size: 17px; position: relative;
  background: linear-gradient(180deg, #fff, #dfe6ff); box-shadow: 0 0 0 2px rgba(255,255,255,.5), 0 5px 0 -1px rgba(0,0,0,.45), 0 10px 18px -8px rgba(0,0,0,.85); }
.badge::after { content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  background: linear-gradient(180deg, rgba(255,255,255,.85), transparent 46%); mix-blend-mode: overlay; }
.badge img { width: 66%; height: 66%; object-fit: contain; filter: drop-shadow(0 2px 3px rgba(0,0,0,.3)); }
.badge span { display: none; background: rgba(0,0,0,.55); color: #fff; padding: 1px 6px; border-radius: 8px; }
.badge.no-logo { background: linear-gradient(135deg, var(--c1) 0 55%, var(--c2) 55%); }
.badge.no-logo span { display: block; } /* crest missing: fall back to the club code */
.club-name { font-family: var(--display); font-size: 18px; text-align: center; line-height: 1; color: var(--ink); }
.link-icon { font-family: var(--display); font-size: 22px; color: #d98a00; flex: none; width: 34px; height: 34px; display: grid; place-items: center;
  border-radius: 50%; background: linear-gradient(180deg, #fff6d8, #ffe79a); border: 1px solid #ffd97a; box-shadow: inset 0 2px 4px rgba(180,120,0,.25); }

.turn-zone { margin-top: 10px; }
/* The line over the clock, as a ribbon with slanted ends (see banner() in js/main.js). */
.turn-banner { display: flex; justify-content: center; font-family: var(--display); text-align: center; letter-spacing: .05em; }
.turn-banner .tb { position: relative; display: inline-flex; align-items: center; gap: 8px; height: 38px; padding: 0 26px;
  overflow: hidden; font-size: 24px; line-height: 1; color: #fff; white-space: nowrap; max-width: 100%;
  clip-path: polygon(12px 0, 100% 0, calc(100% - 12px) 100%, 0 100%);
  background: linear-gradient(180deg, rgba(60,72,130,.92), rgba(26,34,82,.92));
  text-shadow: 0 2px 0 rgba(8,12,40,.55); }
.turn-banner .tb::before { content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg, rgba(255,255,255,.28), transparent 48%); }
.turn-banner .tb-name { position: relative; overflow: hidden; text-overflow: ellipsis; }
/* Your turn: gold letters on royal blue, a shine sweeping across now and then, a slow glow. */
.turn-banner.you .tb { background: linear-gradient(180deg, #4f8dff, #2349c9 60%, #1a3596); font-size: 27px;
  animation: tbGlow 1.6s ease-in-out infinite; }
.turn-banner.you .tb-name { color: #ffe066; text-shadow: 0 2px 0 #8a4b00, 0 0 12px rgba(255,214,90,.55); }
.turn-banner.you .tb::after, .turn-banner.won .tb::after { content: ""; position: absolute; top: 0; bottom: 0; left: -40%; width: 30%;
  transform: skewX(-20deg); pointer-events: none;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.55), transparent);
  animation: tbShine 2.4s ease-in-out .3s infinite; }
@keyframes tbShine { 0% { left: -40%; } 45%, 100% { left: 130%; } }
@keyframes tbGlow { 50% { filter: brightness(1.12) drop-shadow(0 0 8px rgba(90,150,255,.7)); } }
/* The opponent thinking: their name, "is thinking" smaller, and three dots that bounce on. */
.turn-banner.ai .tb { background: linear-gradient(180deg, #ff5d6f, #c8203a 60%, #8e1027); font-size: 22px; }
.turn-banner .tb-sub { position: relative; font-size: 13px; letter-spacing: .14em; opacity: .9; }
.tb-dots { position: relative; display: inline-flex; gap: 4px; margin-left: -2px; }
.tb-dots i { width: 6px; height: 6px; border-radius: 50%; background: #fff; animation: tbDot 1s ease-in-out infinite; }
.tb-dots i:nth-child(2) { animation-delay: .15s; } .tb-dots i:nth-child(3) { animation-delay: .3s; }
@keyframes tbDot { 0%, 60%, 100% { transform: translateY(0); opacity: .55; } 30% { transform: translateY(-6px); opacity: 1; } }
/* A round's end. */
.turn-banner.won .tb { background: linear-gradient(180deg, #5ee08a, #18a54c 60%, #0d7a36); font-size: 27px; }
.turn-banner.won .tb-name { color: #fff6c2; text-shadow: 0 2px 0 #0a5a27, 0 0 12px rgba(255,240,150,.6); }
.turn-banner.lost .tb { background: linear-gradient(180deg, #7a7f99, #4a4f6a 60%, #33374d); font-size: 27px; }
.turn-banner.flash .tb { animation-name: tbIn, tbGlow; animation-duration: .5s, 1.6s; animation-delay: 0s, .5s;
  animation-timing-function: cubic-bezier(.2,1.5,.4,1), ease-in-out; animation-iteration-count: 1, infinite; }
.turn-banner.flash:not(.you) .tb { animation: tbIn .5s cubic-bezier(.2,1.5,.4,1); }
@keyframes tbIn { from { transform: scale(.55) translateY(4px); opacity: 0; } 60% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .turn-banner .tb, .turn-banner .tb::after, .tb-dots i { animation: none !important; } }
.timer { display: flex; align-items: center; gap: 10px; margin-top: 6px; }
.timer-bar { flex: 1; height: 20px; border-radius: 999px; background: rgba(255,255,255,.85); border: 1px solid #fff; overflow: hidden; position: relative;
  box-shadow: inset 0 2px 5px rgba(26,20,64,.28), var(--drop); }
#timerFill { height: 100%; width: 100%; border-radius: 999px; background: linear-gradient(180deg, #a6ffc2, var(--green) 55%, #23a851); transform-origin: left;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.6), 0 0 14px rgba(61,220,107,.5); }
#timerFill.warn { background: linear-gradient(180deg, #ffefa8, #ffb400 55%, #e08a00); box-shadow: inset 0 1px 0 rgba(255,255,255,.6), 0 0 14px rgba(255,180,0,.5); }
#timerFill.danger { background: linear-gradient(180deg, #ffb3bb, var(--red) 55%, #c32333); box-shadow: inset 0 1px 0 rgba(255,255,255,.5), 0 0 16px rgba(255,77,94,.6); }
#timerFill.calling { background: linear-gradient(180deg, #ecd0ff, #b65cff 55%, #8a2fd8); box-shadow: inset 0 1px 0 rgba(255,255,255,.5), 0 0 16px rgba(182,92,255,.6); }
#timerFill.reveal { background: linear-gradient(180deg, #e2e8ff, #8f9dff 55%, #6472e0); box-shadow: inset 0 1px 0 rgba(255,255,255,.5); }
#timerFill.frozen { background: linear-gradient(180deg, #e8faff, #6ccfff 55%, #2ba6e0); box-shadow: inset 0 1px 0 rgba(255,255,255,.7), 0 0 18px rgba(108,207,255,.7); }
.timer-num { font-family: var(--display); font-size: 26px; min-width: 50px; text-align: center; color: var(--ink);
  background: var(--glass); border: 1px solid var(--glass-line); border-radius: 12px; padding: 3px 8px;
  box-shadow: inset 0 1px 0 var(--glass-top), var(--drop); }
.timer-num.danger { color: var(--red-d); animation: pulse .5s ease-in-out infinite; }

.chain { list-style: none; margin: 10px 0 0; padding: 4px 2px; flex: 1; overflow-y: auto; display: flex; flex-direction: column; gap: 7px;
  mask-image: linear-gradient(180deg, transparent, #000 18px); }
.chain li { max-width: 78%; padding: 8px 13px; border-radius: 15px; font-weight: 900; font-size: 15px; animation: slideIn .3s cubic-bezier(.2,1.4,.4,1); display: flex; gap: 8px; align-items: baseline; }
.chain li small { font-weight: 800; opacity: .75; font-size: 11px; }
.chain li.you { align-self: flex-end; background: linear-gradient(180deg, #6bf59a, var(--green)); color: #073d1c; box-shadow: 0 3px 0 var(--green-d), 0 8px 14px -8px rgba(0,0,0,.8), inset 0 1px 0 rgba(255,255,255,.55); border-bottom-right-radius: 5px; }
.chain li.ai { align-self: flex-start; background: linear-gradient(180deg, #ff97a2, #f2596b); color: #4a0812; box-shadow: 0 3px 0 var(--red-d), 0 8px 14px -8px rgba(0,0,0,.8), inset 0 1px 0 rgba(255,255,255,.5); border-bottom-left-radius: 5px; }
.chain li.skip { opacity: .75; font-style: italic; }
.chain li.miss { opacity: .6; text-decoration: line-through; font-size: 13px; padding: 4px 10px; box-shadow: none; }
.chain li.sys { align-self: center; background: rgba(255,255,255,.90); border: 1px solid #fff; color: var(--ink-2); font-size: 12px; box-shadow: var(--drop); }

.hint { text-align: center; font-family: var(--display); font-size: 22px; letter-spacing: 2px; color: #e9c8ff; background: linear-gradient(180deg, rgba(120,40,180,.55), rgba(60,16,100,.6));
  border: 1px solid rgba(220,160,255,.35); border-radius: 14px; padding: 7px; margin-top: 6px; animation: pop .4s; box-shadow: inset 0 1px 0 rgba(255,255,255,.2); }
/* The Wizard's surname: a blank a letter, drawn as the line under it (the first letter written in with
   his Kickie); and his keyboard, down to the letters that spell it - the rest gone, their places kept. */
.hint:not([hidden]) { display: flex; justify-content: center; gap: 6px; padding: 9px 12px 8px; }
.hint .wz { flex: 0 1 24px; min-width: 9px; height: 26px; line-height: 26px; text-align: center; color: #fff;
  border-bottom: 3px solid #e9c8ff; border-radius: 1px; }
.kb-key.kb-gone { visibility: hidden; }

/* The dock is the one piece of chrome that never moves, so it gets a lifted edge. */
/* --kb is the height of the on-screen keyboard, set from js/main.js. The dock rides up over it and
   NOTHING ELSE MOVES: before this, focusing the field let iOS scroll the whole game up to reveal it,
   which threw the clubs, the clock and the chain off the top of the screen at the exact moment you
   needed to read them. See keyboardDock() - the browser only scrolls when the field it wants is
   hidden, so putting the field above the keyboard first is what stops the scroll. */
.dock { display: flex; gap: 8px; margin-top: 10px; padding-top: 10px; align-items: stretch; position: relative;
  transform: translateY(calc(-1 * var(--kb, 0px))); transition: transform .2s ease; }
.dock::before { content: ""; position: absolute; top: 0; left: -16px; right: -16px; height: 1px;
  background: linear-gradient(90deg, transparent, var(--glass-line), transparent); }
.dock input { flex: 1; min-width: 0; font: 900 18px var(--body); color: var(--ink); background: linear-gradient(180deg, #f4f6ff, #fff); border: 0; border-radius: var(--r-md); padding: 0 16px; height: 58px;
  box-shadow: inset 0 -4px 0 #cfd5f5, inset 0 2px 6px rgba(80,90,160,.28), 0 6px 14px -8px rgba(0,0,0,.8); outline: none; }
.dock input::placeholder { color: #8d97c9; }
.dock input:focus { box-shadow: inset 0 -4px 0 #cfd5f5, 0 0 0 3px var(--gold), 0 0 20px -4px var(--gold); }
.dock input:disabled { background: #c9cde8; }
.dock.shake { animation: shake .35s; }
.dock.calling input { box-shadow: inset 0 -4px 0 #7a3ca8, 0 0 0 3px #b65cff, 0 0 22px -4px #b65cff; } /* Maestro: naming the trap */
.kick-btn { width: 66px; height: 58px; border-radius: var(--r-md); font-family: var(--display); font-size: 22px; color: #0d4a22; text-shadow: 0 1px 0 rgba(255,255,255,.45);
  background: linear-gradient(180deg, #9dffba, var(--green) 55%, #23a851);
  box-shadow: 0 5px 0 var(--green-d), 0 10px 18px -8px rgba(31,156,68,.8), inset 0 2px 0 rgba(255,255,255,.6); }
.kick-btn:active { transform: translateY(3px); box-shadow: 0 2px 0 var(--green-d), inset 0 2px 0 rgba(255,255,255,.6); }
.kick-btn:disabled { filter: grayscale(.85) brightness(.75); }
.ability-btn { width: 58px; height: 58px; border-radius: var(--r-md); font-size: 28px; position: relative;
  background: linear-gradient(180deg, color-mix(in srgb, var(--c) 60%, #fff), var(--c));
  box-shadow: 0 5px 0 color-mix(in srgb, var(--c) 55%, #000), 0 10px 18px -8px rgba(0,0,0,.85), inset 0 2px 0 rgba(255,255,255,.4); }
.ability-btn.ready { animation: glow 1.2s ease-in-out infinite; }
.ability-btn:disabled { filter: grayscale(1) brightness(.65); animation: none; }
.ability-btn:not(:disabled):active { transform: translateY(3px); }

/* ---------- overlays ---------- */
.overlay { position: absolute; inset: 0; background: rgba(6,6,26,.74); backdrop-filter: blur(6px); display: grid; place-items: center; padding: 16px; z-index: 20; animation: fade .2s; }
.panel { width: 100%; background: linear-gradient(180deg, #fffdf6, var(--panel) 60%, #f0e3c6); color: var(--ink); border-radius: 28px; padding: 22px 18px 18px; text-align: center;
  box-shadow: 0 8px 0 #c9b98f, 0 26px 50px -12px rgba(0,0,0,.75), inset 0 2px 0 rgba(255,255,255,.9), inset 0 0 0 2px rgba(255,255,255,.5);
  animation: pop .45s cubic-bezier(.2,1.6,.4,1); max-height: 92%; overflow-y: auto; }
.panel-title { font-family: var(--display); font-size: 42px; line-height: 1; }
.panel-title.big { font-size: 56px; }
.panel-title.win { color: #19a54a; text-shadow: 0 3px 0 rgba(13,106,46,.18); }
.panel-title.lose { color: var(--red-d); }
.panel-reason { font-weight: 900; margin: 8px 0 4px; opacity: .85; }
.score { font-family: var(--display); font-size: 36px; margin: 6px 0 16px; }
.trophy-delta { font-family: var(--display); font-size: 30px; margin: 8px 0; display: flex; align-items: center; justify-content: center; gap: 8px; }
/* The cup made bigger on the match-end panel (the user's ask) - it is the reward being handed over. */
.trophy-delta::before { content: ""; width: 78px; height: 124px; background: url("../assets/ui/trophy.png") center / contain no-repeat;
  filter: drop-shadow(0 3px 5px rgba(20,26,70,.35)); }
/* A win's captions in gold: the trophy swing, and the streak's extra trophies under it. */
#matchOverlay .trophy-delta.gold, .streak-bonus b, .streak-bonus span {
  background: linear-gradient(180deg, #fff3b0 0%, #ffd23f 38%, #e8a10c 62%, #b86e00 100%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
  filter: drop-shadow(0 2px 0 rgba(122,72,0,.55)) drop-shadow(0 4px 6px rgba(120,70,0,.25)); }
.streak-bonus { display: flex; align-items: center; justify-content: center; gap: 6px; margin: -4px 0 8px;
  font-family: var(--display); animation: streakIn .5s .9s cubic-bezier(.2,1.6,.4,1) both; }
.streak-bonus[hidden] { display: none; }
.streak-bonus b { font-weight: 400; font-size: 32px; }
.streak-bonus img { height: 58px; width: auto; margin: -12px -14px; filter: drop-shadow(0 2px 3px rgba(20,26,70,.35)); }
.streak-bonus span { font-size: 22px; letter-spacing: .08em; }
@keyframes streakIn { from { opacity: 0; transform: scale(.4); } }
/* What the match paid out, next to the trophy swing. */
.reward { display: flex; justify-content: center; gap: 12px; margin: 2px 0 6px; }
.rw { display: flex; align-items: center; gap: 5px; font-family: var(--display); font-size: 20px; color: var(--ink); }
.rw::before { content: ""; width: 22px; height: 22px; background-size: contain; background-position: center; background-repeat: no-repeat; }
.rw.coin::before { background-image: url("../assets/ui/coin.png"); }
.rw.gem::before { background-image: url("../assets/ui/gem.png"); }

/* A chip carrying the rendered turn drops the flat icon: the canvas is the icon now, and it is the
   same 3D coin the pack gives, at the size the old picture was. See rewardChip() in js/main.js. */
.rw.spun::before { content: none; }
.rw-prop { display: block; width: 26px; height: auto; }

.stats { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin: 12px 0 16px; }
.stats div { background: #fff; border-radius: 14px; padding: 9px; font-weight: 800; font-size: 13px; box-shadow: inset 0 0 0 2px rgba(26,20,64,.07), 0 3px 0 rgba(201,185,143,.5); }
.stats b { display: block; font-family: var(--display); font-weight: 400; font-size: 24px; }

/* ---------- cinematic club reveal ---------- */
.cinema { position: absolute; inset: 0; z-index: 25; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px;
  background: radial-gradient(70% 50% at 50% 45%, rgba(30,40,120,.88), rgba(6,8,32,.97)); animation: fade .25s;
  padding: 8px 16px 132px; }
.cinema::before { /* stadium beams, so the reveal feels staged rather than flat */
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: conic-gradient(from 180deg at 50% 38%, transparent 0 18%, rgba(140,170,255,.10) 22%, transparent 26% 74%, rgba(140,170,255,.10) 78%, transparent 82%); }
.cinema.has-power { padding-bottom: 224px; }
.cinema-club { display: flex; flex-direction: column; align-items: center; gap: 10px; }
.cinema-club.left { animation: flyLeft .5s cubic-bezier(.2,1.4,.4,1); }
.cinema-club.right { animation: flyRight .5s cubic-bezier(.2,1.4,.4,1); }
.cinema-club img { width: 128px; height: 128px; object-fit: contain; filter: drop-shadow(0 10px 22px rgba(0,0,0,.65)) drop-shadow(0 0 26px rgba(130,170,255,.35)); }
/* The crest on a spotlight: a soft disc of light behind it. */
.cine-art { position: relative; display: grid; place-items: center; min-width: 128px; min-height: 128px; }
.cine-art::before { content: ""; position: absolute; inset: -22px; border-radius: 50%; z-index: -1; pointer-events: none;
  background: radial-gradient(closest-side, rgba(160,190,255,.35), rgba(90,120,255,.12) 60%, transparent); }
.cine-art.flag img { filter: none; }
/* The roulette: a strip of crests running up through a window (spinReel), blurred while it is fast,
   the name waiting for the landing. Flags run in one fixed frame - they are all different shapes. */
.cinema-club .cn { transition: opacity .18s ease-out; }
.cinema-club.spinning .cn { opacity: 0; }
.cinema-club.spinning { animation: none; }
/* No fade at the window's edges: when the reel stops, the still picture that takes its place must look
   exactly the same, or the swap shows as a flicker. */
.cine-art.reel-win { --reel-h: 128px; height: var(--reel-h); min-height: 0; overflow: hidden; align-items: start; }
.cine-art.reel-win::before { display: none; }
.reel-strip { display: flex; flex-direction: column; align-items: center; will-change: transform; }
.reel-strip img { display: block; flex: none; }
.cinema-club .reel-strip img:not(.cine-flag) { width: var(--reel-h); height: var(--reel-h); }
.cine-art.reel-win.flag { --reel-h: 100px; }
.cinema-club .reel-strip img.cine-flag { width: 150px; height: var(--reel-h); max-height: none; object-fit: cover; border-radius: 10px; box-shadow: none; }
/* Landing: plain (the user: the pop, the ring of light and the columns sliding in again after the
   reel stopped read as the game lagging). It stops, and its name is there - nothing moves again. */
.cinema-club.spinning, .cinema-club.landed { animation: none; }
.cinema-club.landed .cine-art::before { animation: fade .35s ease-out; }   /* the spotlight comes up softly */
/* A flag stays in the frame it spun in, so landing does not change its shape. */
.cinema-club .cine-art.flag img.cine-flag { width: 150px; height: 100px; max-height: none; object-fit: cover; }
/* The powers you can use in the look appear once the crests have landed. */
.cinema.rolling .cinema-actions { opacity: 0; pointer-events: none; }
.cinema-actions { transition: opacity .25s ease; }
.cinema-club .cn { font-family: var(--display); font-size: 30px; text-shadow: 0 4px 0 rgba(0,0,0,.5); text-align: center; }
.cinema-vs { font-family: var(--display); font-size: 30px; color: var(--gold); width: 46px; height: 46px; display: grid; place-items: center; border-radius: 50%;
  background: rgba(8,10,40,.6); border: 2px solid rgba(255,210,63,.4); box-shadow: 0 0 22px -4px rgba(255,210,63,.6), inset 0 2px 6px rgba(0,0,0,.6);
  animation: pop .5s .25s backwards; }
@media (max-height: 660px) {
  .cinema-club img { width: 104px; height: 104px; }
  .cine-art.reel-win:not(.flag) { --reel-h: 104px; }
  .cinema-club .cn { font-size: 24px; }
  .cinema-vs { font-size: 24px; width: 38px; height: 38px; }
}
/* --- the same screen, used for the round's result --- */
/* --res is the result's colour, and everything that marks the winner takes it from here. */
.cinema.result { --res: #3ddc6b; }
.cinema.result.lost { --res: #ff5f6d; }
/* The ampersand becomes the score. It is already a circle in the middle of the two sides, which is
   exactly where a scoreline wants to be. */
.cinema.result .cinema-vs { color: #fff; width: auto; min-width: 84px; height: 46px; padding: 0 14px;
  border-radius: 14px; background: rgba(4,8,26,.55); font-variant-numeric: tabular-nums;
  box-shadow: inset 0 0 0 2px rgba(255,255,255,.10), 0 0 26px -6px var(--res); }
/* The loser steps back rather than disappearing: you should still see who you beat. */
.cinema.result .cinema-club { transition: none; }
.cinema.result .cinema-club:has(.res-tag.lost) { opacity: .55; scale: .88; }
.cinema.result .cinema-club:has(.res-tag.won) img { filter: drop-shadow(0 10px 22px rgba(0,0,0,.65)) drop-shadow(0 0 30px var(--res)); }
.res-tag { font-family: var(--display); font-size: 15px; letter-spacing: .12em; padding: 3px 14px;
  border-radius: 999px; color: #0b1230; background: #cfd6e8; }
.res-tag.won { background: var(--res); color: #06240f; box-shadow: 0 0 22px -4px var(--res); }
.res-tag.lost { background: rgba(255,255,255,.16); color: rgba(255,255,255,.75); }
/* The reason line sits where the countdown does, and reads as a ticker rather than a sentence. */
.cinema.result .cinema-count { font-family: var(--body); font-weight: 900; font-size: 11.5px;
  letter-spacing: .14em; text-transform: uppercase; opacity: .7; }

.cinema-foot { position: absolute; left: 0; right: 0; bottom: max(24px, var(--sab)); display: flex; flex-direction: column; align-items: center; gap: 10px; padding: 0 16px; }
.cinema-count { font-family: var(--display); font-size: 22px; color: #b9c6ff; opacity: .85; }
.cinema-actions { display: flex; flex-direction: column; gap: 10px; width: 100%; max-width: 340px; }
.cinema-actions .btn { font-size: 20px; padding: 13px 14px; }

/* A power offered before the round: the star's own card, not a generic button. */
.powerbtn { display: flex; align-items: center; gap: 12px; width: 100%; padding: 8px 12px 8px 8px; border: 0; cursor: pointer; position: relative; overflow: hidden;
  border-radius: var(--r-md); color: #fff; text-align: left; font: inherit; -webkit-tap-highlight-color: transparent;
  background: linear-gradient(140deg, color-mix(in srgb, var(--rc) 82%, #0b1730), color-mix(in srgb, var(--rc) 34%, #0b1730));
  box-shadow: 0 5px 0 color-mix(in srgb, var(--rc) 55%, #000), 0 12px 26px -8px color-mix(in srgb, var(--rc) 60%, transparent),
    inset 0 1px 0 rgba(255,255,255,.35), inset 0 0 0 2px color-mix(in srgb, var(--rc) 70%, #fff);
  animation: powerGlow 1.8s ease-in-out infinite; }
.powerbtn::after { content: ""; position: absolute; top: -60%; bottom: -60%; left: 0; width: 34%; pointer-events: none;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.38), transparent); transform: skewX(-18deg);
  --sw0: -132%; --sw1: 368%; animation: sweep 3.8s cubic-bezier(.5,0,.5,1) infinite; }
.powerbtn:active { transform: translateY(4px); box-shadow: 0 1px 0 color-mix(in srgb, var(--rc) 55%, #000), inset 0 0 0 2px color-mix(in srgb, var(--rc) 70%, #fff); animation: none; }
.pb-art { flex: none; width: 54px; height: 54px; border-radius: var(--r-sm); overflow: hidden; background: rgba(6, 14, 30, .55);
  display: flex; align-items: center; justify-content: center; box-shadow: inset 0 0 0 2px rgba(255, 255, 255, .4); }
.pb-art img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 12%; }
.pb-ini { font-family: var(--display); font-size: 20px; }
.pb-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.pb-rar { font-size: 10px; letter-spacing: .12em; text-transform: uppercase; opacity: .85; }
.pb-name { font-family: var(--display); font-size: 20px; line-height: 1.05; text-shadow: 0 2px 0 rgba(0, 0, 0, .35); }
.pb-sub { font-size: 11px; opacity: .8; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pb-use { flex: none; font-family: var(--display); font-size: 14px; padding: 7px 13px; border-radius: 999px;
  background: linear-gradient(180deg, #fff, #e6ecff); color: color-mix(in srgb, var(--rc) 70%, #10203a); box-shadow: 0 2px 0 rgba(0,0,0,.25); }
@keyframes powerGlow {
  50% { box-shadow: 0 5px 0 color-mix(in srgb, var(--rc) 55%, #000), 0 14px 34px -6px color-mix(in srgb, var(--rc) 85%, transparent),
    inset 0 1px 0 rgba(255,255,255,.35), inset 0 0 0 2px color-mix(in srgb, var(--rc) 70%, #fff); }
}
@media (prefers-reduced-motion: reduce) { .powerbtn, .powerbtn::after, .btn-play::after { animation: none; } }

@keyframes flyLeft { from { transform: translateX(-60vw) scale(.7); opacity: 0; } }
@keyframes flyRight { from { transform: translateX(60vw) scale(.7); opacity: 0; } }

/* ---------- fx ---------- */
#fx { position: absolute; inset: 0; pointer-events: none; z-index: 30; overflow: hidden; }
/* Starboy's coins flying into your avatar (starboyCoins in js/main.js), and the avatar's bump as each lands. */
.sb-coin { position: absolute; left: 0; top: 0; height: auto; filter: drop-shadow(0 4px 6px rgba(80,50,0,.45)); will-change: transform; }
.avatar.coin-hit { animation: coinHit .22s ease-out; }
@keyframes coinHit { 40% { transform: scale(1.12); filter: brightness(1.25) drop-shadow(0 0 10px rgba(255,210,63,.9)); } }
.float { position: absolute; left: 50%; top: 42%; transform: translateX(-50%); font-family: var(--display); font-size: 36px; white-space: nowrap;
  text-shadow: 0 4px 0 rgba(0,0,0,.5), 0 0 26px currentColor; animation: floatUp 1.1s ease-out forwards; }
.float small { display: block; font-family: var(--body); font-weight: 900; font-size: 15px; text-align: center; text-shadow: 0 2px 0 rgba(0,0,0,.5); }
.float.good { color: var(--gold); }
.float.bad { color: var(--red); }
.float.ice { color: #bdeeff; }
/* Starboy's pay, thrown up over the pitch the moment a name lands. */
.float.coin { color: var(--gold); text-shadow: 0 3px 0 rgba(90,53,0,.55), 0 0 18px rgba(255,210,63,.6); }
/* Coins and trophies thrown into their chip after a match. */
.flyer { position: absolute; width: 26px; height: 26px; margin: -13px 0 0 -13px; pointer-events: none;
  background-position: center; background-repeat: no-repeat; background-size: contain;
  filter: drop-shadow(0 3px 5px rgba(16,22,60,.5)); }
.flyer.trophy { background-image: url("../assets/ui/trophy.png"); width: 22px; height: 35px; margin: -17px 0 0 -11px; }
.flyer.coin { background-image: url("../assets/ui/coin.png"); }
.flyer.gem { background-image: url("../assets/ui/gem.png"); }
.pill.bump, .me-cups.bump, .me-streak.bump { animation: chipBump .32s cubic-bezier(.2,1.7,.4,1); }
@keyframes chipBump { 40% { transform: scale(1.14); } }

.flash-screen { position: absolute; inset: 0; animation: flash .5s forwards; }

@keyframes bob { 50% { transform: translateY(-6px) rotate(8deg); } }
@keyframes pulse { 50% { transform: scale(1.08); } }
@keyframes ring { 50% { transform: scale(1.1); opacity: .6; } }
@keyframes pop { 0% { transform: scale(.6); opacity: 0; } 100% { transform: scale(1); opacity: 1; } }
@keyframes slideIn { from { transform: translateY(14px) scale(.9); opacity: 0; } }
@keyframes shake { 20%, 60% { transform: translateX(-9px); } 40%, 80% { transform: translateX(9px); } }
@keyframes glow { 50% { box-shadow: 0 5px 0 color-mix(in srgb, var(--c) 55%, #000), 0 0 20px 5px var(--c); } }
@keyframes fade { from { opacity: 0; } }
@keyframes floatUp { 0% { transform: translate(-50%, 10px) scale(.6); opacity: 0; } 20% { transform: translate(-50%, 0) scale(1.15); opacity: 1; } 100% { transform: translate(-50%, -90px) scale(1); opacity: 0; } }
@keyframes flash { from { opacity: .55; } to { opacity: 0; } }

@media (max-height: 600px) {
  .arena-name { font-size: 17px; }
  .badge { width: 52px; height: 52px; font-size: 14px; border-radius: 17px; }
}

/* ---------- home: selected star ---------- */
.arena-card { margin: 2px 0 8px; padding: 8px 12px 9px; border-radius: var(--r-md); text-align: center;
  background: var(--glass); border: 1px solid var(--glass-line); color: var(--ink);
  box-shadow: inset 0 1px 0 var(--glass-top), var(--drop); }
.arena-top { display: flex; align-items: center; justify-content: center; gap: 9px; }
.arena-tier { font-weight: 900; font-size: 10px; letter-spacing: .14em; text-transform: uppercase; color: #0d1130;
  background: linear-gradient(180deg, #ffe98d, var(--gold-d)); padding: 2px 7px; border-radius: 999px; box-shadow: inset 0 1px 0 rgba(255,255,255,.6); }
.arena-name { font-family: var(--display); font-size: 23px; line-height: 1; color: var(--ink); }
.arena-bar { height: 7px; margin: 7px 0 4px; border-radius: 999px; background: var(--sink); border: 1px solid rgba(26,20,64,.10); overflow: hidden;
  box-shadow: inset 0 2px 4px rgba(26,20,64,.25); }
#arenaFill { height: 100%; border-radius: 999px; transform-origin: left; transition: transform .5s cubic-bezier(.2,1.2,.4,1);
  background: linear-gradient(180deg, #ffe98d, var(--gold) 55%, #e09a00); box-shadow: 0 0 12px rgba(255,210,63,.55); }
.arena-next { font-weight: 800; font-size: 11px; letter-spacing: .03em; color: var(--ink-2); }
.arena-move { font-family: var(--display); font-size: 19px; margin: 2px 0 6px; }
.arena-move.up { color: #19a54a; }
.arena-move.down { color: var(--red-d); }

/* The star strip is a reminder of who you picked, not the hero of the screen. */
/* Never squeezed: a taller arena picture above it once shrank this card (flex-shrink). */
.star-card { flex-shrink: 0; display: flex; align-items: center; gap: 11px; width: 100%; margin: 10px 0 8px; padding: 7px 11px 7px 7px; border-radius: var(--r-md); text-align: left; color: #fff;
  position: relative; overflow: hidden;
  background: linear-gradient(180deg, color-mix(in srgb, var(--c) 72%, #fff), var(--c) 62%, color-mix(in srgb, var(--c) 80%, #0b1030));
  box-shadow: 0 6px 0 color-mix(in srgb, var(--c) 55%, #000), 0 16px 28px -10px rgba(0,0,0,.8), inset 0 2px 0 rgba(255,255,255,.55); }
.star-card::before { content: ""; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(60% 90% at 14% 10%, rgba(255,255,255,.45), transparent 60%); }
.star-card:active { transform: translateY(3px); }
.star-face { width: 46px; height: 46px; border-radius: var(--r-sm); overflow: hidden; flex: none; display: grid; place-items: center; font-size: 40px; position: relative;
  background: rgba(255,255,255,.35); box-shadow: 0 0 0 3px #fff, 0 6px 14px -6px rgba(0,0,0,.7); }
.star-info { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.star-label { display: none; }
.star-rarity { align-self: flex-start; font-weight: 900; font-size: 9px; letter-spacing: .14em; text-transform: uppercase;
  padding: 2px 8px; border-radius: 999px; background: rgba(255,255,255,.82); color: color-mix(in srgb, var(--c) 72%, #101a3c);
  margin-bottom: 2px; }
/* The pass star's colour is a cream: mixed into the chip's ink it came out near-white on white (the
   user: "black, not white"). The pass's own dark ink instead. */
.star-rarity.pass { color: #3a2f14; }
.star-name { font-family: var(--display); font-size: 19px; line-height: 1.05; text-shadow: 0 2px 0 rgba(10,16,48,.35); }
.star-power { font-weight: 900; font-size: 12px; margin-top: 1px; opacity: .78; }
.star-change { font-family: var(--display); font-size: 13px; background: rgba(0,0,0,.28); color: #fff; padding: 5px 10px; border-radius: 10px; white-space: nowrap;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.18); }

/* ---------- powers page ---------- */
.stage { position: relative; height: clamp(190px, 34dvh, 360px); margin: 0 -16px; flex: none;
  background: radial-gradient(60% 55% at 50% 62%, rgba(120,150,255,.35), transparent 70%); }
.stage canvas { position: absolute; inset: 0; width: 100% !important; height: 100% !important; cursor: grab; }
.stage-label { display: flex; align-items: center; justify-content: center; gap: 8px; margin-top: -6px; flex: none; }
.stage-rarity { font-weight: 900; font-size: 11px; letter-spacing: 1px; text-transform: uppercase; padding: 3px 9px; border-radius: 7px;
  background: var(--r); color: var(--ri, #16233a); box-shadow: 0 2px 0 rgba(0,0,0,.35), inset 0 1px 0 rgba(255,255,255,.5); }
.stage-name { font-family: var(--display); font-size: 30px; line-height: 1; text-shadow: 0 3px 0 rgba(12,18,50,.55), 0 0 14px rgba(12,18,50,.4); }

.power-info { margin: 6px 0 2px; padding: 11px 13px; border-radius: var(--r-md); flex: none; animation: pop .35s cubic-bezier(.2,1.5,.4,1);
  background: linear-gradient(180deg, rgba(255,255,255,.95), rgba(226,236,255,.90)); color: var(--ink);
  border: 2px solid color-mix(in srgb, var(--c) 55%, #fff); box-shadow: 0 0 26px -10px var(--c), var(--drop); }
.pi-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; flex-wrap: wrap; }
.pi-power { font-family: var(--display); font-size: 21px; color: color-mix(in srgb, var(--c) 72%, #101a3c); }
.tags { display: flex; flex-wrap: wrap; gap: 5px; }
.tag { font-weight: 900; font-size: 11px; padding: 3px 9px; border-radius: 999px; background: var(--c); color: var(--ri, var(--ink)); box-shadow: inset 0 1px 0 rgba(255,255,255,.35); }
.tag.ghost { background: rgba(26,35,82,.10); color: var(--ink-2); }
.pi-desc { font-weight: 900; font-size: 15px; margin: 6px 0 4px; }
.pi-once { opacity: .65; font-weight: 800; }
.pi-tip { font-weight: 800; font-size: 13px; color: var(--ink-2); margin: 0; }

/* The whole Powers page scrolls as one (stage, details and cards together). */
#powers, #shop { overflow-y: auto; overscroll-behavior: contain; }
/* The Stars page's two tabs (Clash Royale's cards / emotes): the same blue, glyphs and marker as the
   game's own tab bar at the bottom, so the switch reads as part of the game, not a web form. */
.coll-tabs { position: relative; display: flex; gap: 6px; margin: 0 0 10px; padding: 5px; border-radius: 18px; flex: none;
  background: linear-gradient(180deg, #4f9bff, #2b62d4 78%, #2454bd);
  box-shadow: 0 4px 0 #1b3f99, 0 10px 20px -10px rgba(16,34,96,.8), inset 0 1px 0 rgba(255,255,255,.4); }
.coll-tab { position: relative; flex: 1; display: flex; align-items: center; justify-content: center; gap: 7px;
  padding: 9px 0 10px; border: 0; border-radius: 13px; background: none; cursor: pointer;
  font-family: var(--display); font-size: 17px; letter-spacing: .06em; color: rgba(255,255,255,.72);
  transition: color .16s, background .16s; }
.coll-tab::before { content: ""; width: 18px; height: 18px; background: currentColor;
  -webkit-mask: var(--icon) center / contain no-repeat; mask: var(--icon) center / contain no-repeat; }
.coll-tab[data-coll="stars"] { --icon: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13.8 2 5 13.1a.7.7 0 0 0 .55 1.15H10L9.5 22l8.8-11.1a.7.7 0 0 0-.55-1.15H13.3L13.8 2Z"/></svg>'); }
.coll-tab[data-coll="stickers"] { --icon: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 3C6.5 3 2.5 6.6 2.5 11c0 2.4 1.2 4.5 3.1 6l-1 3.6a.6.6 0 0 0 .86.68L9.6 19.4c.8.2 1.6.3 2.4.3 5.5 0 9.5-3.6 9.5-8.2S17.5 3 12 3Z"/></svg>'); }
.coll-tab.on { color: #fff; background: rgba(255,255,255,.2); box-shadow: inset 0 0 0 1px rgba(255,255,255,.4), 0 2px 8px -2px rgba(10,20,70,.5);
  text-shadow: 0 2px 0 rgba(10,20,70,.35); }
.coll-tab.on::after { content: ""; position: absolute; left: 30%; right: 30%; bottom: 3px; height: 3px; border-radius: 3px;
  background: linear-gradient(90deg, #ffe680, #ffc21a); box-shadow: 0 0 8px rgba(255,200,40,.8); }
.coll-tab:active { transform: translateY(1px); }
.coll-pane { display: flex; flex-direction: column; }
.coll-pane[hidden] { display: none; }
/* The sticker deck: four slots on a dark panel, the collection under it. */
.deck-head { display: flex; align-items: baseline; justify-content: space-between; margin: 10px 2px 7px; }
.deck-head span { font-family: var(--display); font-size: 18px; letter-spacing: .05em; color: #fff; text-shadow: 0 2px 0 rgba(12,18,50,.5); }
.deck-head em { font-style: normal; font-weight: 800; font-size: 12px; color: rgba(255,255,255,.75); }
.sticker-deck { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; padding: 10px; border-radius: 18px;
  background: linear-gradient(180deg, #243a8f, #16266a); box-shadow: inset 0 0 0 2px rgba(255,210,63,.55), inset 0 3px 8px rgba(0,0,0,.35), 0 6px 14px -6px rgba(0,0,0,.6); }
.deck-slot { position: relative; aspect-ratio: 1 / 1.12; border: 0; border-radius: 14px; padding: 5px 5px 18px; cursor: pointer;
  display: grid; place-items: center; background: #fff; box-shadow: 0 4px 0 rgba(0,0,0,.25); }
.deck-slot img { width: 100%; height: 100%; min-width: 0; min-height: 0; object-fit: contain; }
.deck-slot .ds-name { position: absolute; left: 3px; right: 3px; bottom: 3px; overflow: hidden; font-family: var(--display); font-size: 11px; color: var(--ink); }
.deck-slot.empty { background: rgba(255,255,255,.08); box-shadow: inset 0 0 0 2px rgba(255,255,255,.35); }
.deck-slot .ds-plus { font-family: var(--display); font-size: 30px; color: rgba(255,255,255,.55); }
.deck-slot:active { transform: translateY(2px); }
.deck-slot.swap { animation: deckWiggle .5s ease-in-out infinite; }
.deck-slot.swap:nth-child(2n) { animation-delay: -.25s; }
@keyframes deckWiggle { 25% { transform: rotate(-2.5deg); } 75% { transform: rotate(2.5deg); } }
.sticker-coll { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; }
.coll-sticker { position: relative; display: flex; flex-direction: column; align-items: center; gap: 3px; padding: 6px 4px 7px;
  border: 0; border-radius: 14px; cursor: pointer; background: linear-gradient(180deg, #ffffff, #e9eefb);
  box-shadow: 0 4px 0 rgba(26,35,82,.35); transition: transform .15s ease; }
.coll-sticker .cs-art { display: block; width: 100%; aspect-ratio: 1; }
.coll-sticker .cs-art img { width: 100%; height: 100%; object-fit: contain; }
.coll-sticker .cs-name { font-family: var(--display); font-size: 12px; color: var(--ink); max-width: 100%; overflow: hidden; }
.coll-sticker .cs-tag, .coll-sticker .cs-price { font-weight: 900; font-size: 10px; letter-spacing: .04em; padding: 2px 6px; border-radius: 8px; }
.coll-sticker .cs-tag { color: #fff; background: #19a54a; }
.coll-sticker .cs-tag.own { background: linear-gradient(180deg, #6fb4ff, #2b6fe0); }
.coll-sticker .cs-price { color: #4a2a00; background: #ffd34d; display: inline-flex; align-items: center; }
.coll-sticker .cs-price .sk-coin { width: 12px; height: 12px; margin-right: 3px; vertical-align: 0; }
.coll-sticker.in-deck { opacity: .6; }
.coll-sticker.locked .cs-art { filter: grayscale(1) brightness(.8); opacity: .6; }
.coll-sticker.picked { transform: translateY(-6px) scale(1.06); box-shadow: 0 0 0 3px #ffd34d, 0 10px 18px -4px rgba(255,190,40,.7); }
@media (prefers-reduced-motion: reduce) { .deck-slot.swap { animation: none; } }
#powers > * { flex-shrink: 0; }
.scroll { margin: 6px -16px 0; padding: 8px 16px 12px; }
.power-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 9px; }

/* The pass shelf. A rule and a label rather than another panel: it is the same collection, kept in
   a place of its own so that nobody goes looking for these in a pack. */
.pass-shelf { margin-top: 16px; padding-top: 12px; border-top: 2px solid rgba(255,255,255,.14); }
.shelf-head { display: flex; align-items: baseline; gap: 8px; margin: 0 2px 9px; }
.shelf-head span { font-family: var(--display); font-weight: 400; font-size: 15px; letter-spacing: 1.2px;
  color: #ffdf8a; text-shadow: 0 2px 0 rgba(8,14,44,.6); }
.shelf-head em { font-style: normal; font-weight: 800; font-size: 10px; letter-spacing: .04em;
  color: rgba(255,255,255,.62); }
/* Only ever a couple of cards, so they keep the size of the ones above rather than stretching. */
.pass-shelf .power-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
/* Full-bleed card: art fills the whole card, rarity colour is the frame, name sits on the art. */
.power-card { min-width: 0; position: relative; display: block; aspect-ratio: 3 / 4; padding: 0; border-radius: var(--r-sm); overflow: visible; color: #fff;
  box-shadow: 0 0 0 2px var(--r), 0 0 0 3px rgba(255,255,255,.18), 0 5px 0 3px color-mix(in srgb, var(--r) 55%, #000), 0 12px 18px -8px rgba(0,0,0,.85);
  transition: transform .12s; }
.power-card:active { transform: translateY(3px) scale(.97); }

/* Foil: a glass edge over every card, and a slow holo sweep on the rare-and-up ones. */
.power-card::before { content: ""; position: absolute; inset: 0; z-index: 1; border-radius: inherit; pointer-events: none; overflow: hidden;
  background: linear-gradient(150deg, rgba(255,255,255,.34) 0 14%, transparent 34%);
  mix-blend-mode: screen; }
.power-card[data-rarity="epic"]::before, .power-card[data-rarity="legendary"]::before {
  background:
    linear-gradient(150deg, rgba(255,255,255,.34) 0 14%, transparent 34%),
    linear-gradient(115deg, transparent 42%, color-mix(in srgb, var(--r) 30%, #fff) 48%, transparent 54%);
  background-size: 100% 100%, 320% 100%; background-repeat: no-repeat;
  animation: foil 5.5s ease-in-out infinite; }
@keyframes foil { 0%, 12% { background-position: 0 0, 160% 0; } 60%, 100% { background-position: 0 0, -60% 0; } }
@media (prefers-reduced-motion: reduce) { .power-card::before { animation: none; } }
.power-card.sel { box-shadow: 0 0 0 3px var(--r), 0 0 0 6px #fff, 0 5px 0 6px color-mix(in srgb, var(--r) 55%, #000), 0 0 24px 6px var(--r); }
.power-card.sel::after { content: "✓"; position: absolute; top: -9px; right: -9px; z-index: 2; width: 26px; height: 26px; border-radius: 50%; display: grid; place-items: center;
  background: linear-gradient(180deg, #6bf59a, var(--green)); color: #073d1c; font-weight: 900; box-shadow: 0 3px 0 var(--green-d), inset 0 1px 0 rgba(255,255,255,.6); }
.power-card .card-art { position: absolute; inset: 0; width: 100%; height: 100%; aspect-ratio: auto; border-radius: var(--r-sm); box-shadow: none; }
/* Per-star framing: --art-zoom > 1 zooms in from the top edge, trimming the bottom of the art. */
.power-card .card-art .portrait { transform: scale(var(--art-zoom, 1)); transform-origin: 50% 0%; }
.power-card .card-art::after { content: ""; position: absolute; inset: 0; border-radius: inherit;
  background: linear-gradient(180deg, rgba(255,255,255,.18) 0 18%, transparent 42%, rgba(8,6,30,.88)); }
.pc-name { position: absolute; left: 3px; right: 3px; bottom: 5px; z-index: 1; font-family: var(--display); font-size: 12px; line-height: 1.05; text-align: center;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; /* long names wrap onto a second line */
  text-shadow: 0 2px 0 rgba(0,0,0,.7); }
/* A pass star's card is cream, and white lettering vanished on it (the user, twice: "black, not white"):
   its name in the pass's dark ink, lifted with a light edge instead of the dark shadow. */
.power-card[data-rarity="pass"] .pc-name { color: #3a2f14; text-shadow: none; left: 6px; right: 6px; bottom: 6px; padding: 2px 3px;
  border-radius: 6px; background: rgba(245,239,220,.94); box-shadow: 0 2px 0 rgba(0,0,0,.25); }  /* on a cream strip: the photo is dark */
.pc-rarity { position: absolute; top: 4px; left: 4px; z-index: 1; font-weight: 900; font-size: 7px; letter-spacing: .3px; text-transform: uppercase;
  padding: 2px 5px; border-radius: 5px; background: var(--r); color: var(--ri, #16233a); box-shadow: 0 2px 0 rgba(0,0,0,.35), inset 0 1px 0 rgba(255,255,255,.5); }

/* card art: photos fill the card; stars without art get a gradient with their initials */
.card-art { display: grid; place-items: center; aspect-ratio: 3 / 4; width: 100%; border-radius: 12px; overflow: hidden; position: relative;
  background: radial-gradient(circle at 50% 35%, color-mix(in srgb, var(--c) 45%, #fff), color-mix(in srgb, var(--c) 70%, #0b1060) 75%); }
.card-art .portrait { position: absolute; inset: 0; transform: none; object-fit: cover; object-position: 50% 12%; }

/* initials for stars without art */
.mono { font-family: var(--display); color: #fff; text-shadow: 0 3px 0 rgba(0,0,0,.25); line-height: 1; }
.card-art .mono { font-size: 40px; }
.star-face .mono { font-size: 20px; }
.avatar .mono { font-size: 18px; }
.ability-btn .mono { font-size: 20px; }

/* ---------- shop ---------- */
.shop-clock { text-align: center; font-weight: 900; font-size: 12px; letter-spacing: .06em; text-transform: uppercase;
  color: #fff; text-shadow: 0 2px 0 rgba(12,18,50,.5); margin-top: 4px; }
/* One row per rarity: the star's own card, portrait and chunky, with the offer beside it. */
.shop-col { display: grid; gap: 12px; margin-top: 10px; align-content: start; }
.shop-card { display: flex; align-items: center; gap: 13px; padding: 12px; border-radius: var(--r-lg);
  background: var(--glass); border: 1px solid var(--glass-line); color: var(--ink);
  box-shadow: inset 0 1px 0 var(--glass-top), 0 0 0 3px color-mix(in srgb, var(--r) 45%, transparent), var(--drop); }
.sc-card { flex: none; position: relative; width: 116px; aspect-ratio: 3 / 4; border-radius: 16px;
  box-shadow: 0 0 0 4px var(--r), 0 0 0 6px rgba(255,255,255,.75),
    0 7px 0 5px color-mix(in srgb, var(--r) 55%, #000), 0 16px 22px -10px rgba(16,22,60,.7); }
.sc-art { position: absolute; inset: 0; border-radius: 16px; overflow: hidden; display: grid; place-items: center;
  background: radial-gradient(circle at 50% 35%, color-mix(in srgb, var(--c) 45%, #fff), color-mix(in srgb, var(--c) 70%, #0b1060) 75%); }
.sc-art .portrait { position: absolute; inset: 0; object-fit: cover; object-position: 50% 10%;
  transform: scale(var(--art-zoom, 1)); transform-origin: 50% 0%; }
.sc-art .mono { font-size: 38px; }
.sc-card::after { content: ""; position: absolute; inset: 0; border-radius: 16px; pointer-events: none;
  background: linear-gradient(180deg, rgba(255,255,255,.22) 0 16%, transparent 45%, rgba(8,6,30,.35)); }
.sc-side { flex: 1; min-width: 0; display: flex; flex-direction: column; align-items: flex-start; gap: 2px; }
.sc-rarity { font-weight: 900; font-size: 10px; letter-spacing: .12em; text-transform: uppercase; padding: 3px 9px;
  border-radius: 999px; background: var(--r); color: #fff; }
.sc-name { font-family: var(--display); font-size: 21px; line-height: 1.05; margin-top: 3px; }
.sc-power { font-weight: 900; font-size: 12px; color: var(--ink-2); }
.sc-left { font-weight: 800; font-size: 11px; color: var(--ink-2); margin-bottom: 7px; }
.btn-buy { display: flex; align-items: center; justify-content: center; gap: 8px; font-size: 21px; padding: 10px;
  background: linear-gradient(180deg, #7de3a0, var(--green) 55%, #23a851); color: #073d1c;
  box-shadow: 0 5px 0 var(--green-d), inset 0 2px 0 rgba(255,255,255,.55); text-shadow: 0 1px 0 rgba(255,255,255,.4); }
.btn-buy::after { content: ""; width: 21px; height: 21px; order: -1;
  background: url("../assets/ui/gem.png") center / contain no-repeat; }
.btn-buy:disabled { filter: grayscale(.8) brightness(.92); box-shadow: 0 5px 0 rgba(26,35,82,.25); }
.shop-card.done { opacity: .72; }
.shop-card.done .btn-buy::after { display: none; }

/* The star the shop just handed over. */
.reveal-card { display: flex; flex-direction: column; align-items: center; gap: 4px; margin: 10px 0 14px; }
.rv-art { width: 130px; aspect-ratio: 3 / 4; border-radius: var(--r-md); overflow: hidden; display: grid; place-items: center;
  background: radial-gradient(circle at 50% 35%, color-mix(in srgb, var(--c) 45%, #fff), color-mix(in srgb, var(--c) 70%, #0b1060) 75%);
  box-shadow: 0 0 0 3px var(--r), 0 0 0 6px #fff, 0 0 26px 4px var(--r); animation: pop .5s cubic-bezier(.2,1.6,.4,1); }
.rv-art .portrait { object-fit: cover; object-position: 50% 12%; transform: scale(var(--art-zoom, 1)); transform-origin: 50% 0%; }
.rv-rarity { margin-top: 10px; font-weight: 900; font-size: 11px; letter-spacing: .12em; text-transform: uppercase;
  padding: 3px 10px; border-radius: 999px; background: var(--r); color: var(--ri, #fff); }
.rv-name { font-family: var(--display); font-size: 27px; line-height: 1.1; }
.rv-power { font-weight: 900; font-size: 15px; color: var(--ink-2); }
.rv-desc { font-weight: 800; font-size: 13px; color: var(--ink-2); text-align: center; }

/* A star you do not own yet: visible in the collection, but not selectable. */
.power-card.locked .card-art { filter: grayscale(.85) brightness(.62); }
.power-card.locked::before { z-index: 2; background: rgba(10,14,40,.28); }
/* A card you cannot have yet says which arena it turns up in, the way the ladder does. */
.pc-arena { position: absolute; z-index: 3; left: 50%; top: 50%; transform: translate(-50%, -50%);
  font-weight: 900; font-size: 9px; letter-spacing: .06em; white-space: nowrap; color: #0d1130;
  background: linear-gradient(180deg, #ffe98d, var(--gold-d)); padding: 3px 7px; border-radius: 999px;
  box-shadow: 0 2px 6px rgba(0,0,0,.45), inset 0 1px 0 rgba(255,255,255,.6); }

/* ---------- tab bar ---------- */
/* Icon over a small caps label, the selected tab marked by a tint and a bar on the rail above it —
   a quieter, more finished nav than a full blue slab under the active word. */
/* Trimmed on 2026-09-22 at the user's ask: roughly 16 px shorter than it was, which goes to the
   game above it. The safe-area padding stays - that part is the home indicator, not spare room. */
.tabbar { position: absolute; left: 0; right: 0; bottom: 0; z-index: 10; display: flex; gap: 6px;
  padding: 3px 12px max(3px, var(--sab));
  background: linear-gradient(180deg, #4f9bff, #2b62d4 78%, #2454bd);
  border-top: 1px solid rgba(255,255,255,.45); box-shadow: 0 -14px 30px -16px rgba(16,34,96,.75), inset 0 1px 0 rgba(255,255,255,.35); }
.tabbar::before { /* the rail the active marker sits on */
  content: ""; position: absolute; top: 0; left: 14px; right: 14px; height: 1px;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.55), transparent); }
.tabbar button { position: relative; flex: 1; display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 5px 0 4px; border-radius: 11px; font-family: var(--display); font-size: 10px; letter-spacing: .08em;
  text-transform: uppercase; color: rgba(255,255,255,.72); transition: color .16s, background .16s, transform .1s; }
.tabbar button::before { /* the glyph, drawn as a mask so the game stays emoji-free */
  content: ""; width: 18px; height: 18px; background: currentColor;
  -webkit-mask: var(--icon) center / contain no-repeat; mask: var(--icon) center / contain no-repeat;
  transition: transform .16s; }
.tabbar button[data-tab="home"] { --icon: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M8.6 4.4a1.9 1.9 0 0 0-2.9 1.6v12a1.9 1.9 0 0 0 2.9 1.6l9.6-6a1.9 1.9 0 0 0 0-3.2l-9.6-6Z"/></svg>'); }
.tabbar button[data-tab="shop"] { --icon: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M6 7V6a6 6 0 0 1 12 0v1h2.1a1 1 0 0 1 1 1.1l-1.2 12A2 2 0 0 1 18 22H6a2 2 0 0 1-2-1.9L2.9 8.1A1 1 0 0 1 3.9 7H6Zm2 0h8V6a4 4 0 0 0-8 0v1Z"/></svg>'); }
.tabbar button[data-tab="powers"] { --icon: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13.8 2 5 13.1a.7.7 0 0 0 .55 1.15H10L9.5 22l8.8-11.1a.7.7 0 0 0-.55-1.15H13.3L13.8 2Z"/></svg>'); }
.tabbar button.on { color: #fff; background: rgba(255,255,255,.18); box-shadow: inset 0 0 0 1px rgba(255,255,255,.35); }
.tabbar button.on::before { transform: translateY(-1px) scale(1.08); }
.tabbar button.on::after { /* the marker on the rail */
  content: ""; position: absolute; top: -7px; left: 50%; transform: translateX(-50%); width: 38px; height: 3px;
  border-radius: 0 0 4px 4px; background: linear-gradient(90deg, #ffe98d, var(--gold));
  box-shadow: 0 2px 10px rgba(255,210,63,.75); }
.tabbar button:not(.on):active { transform: translateY(1px); color: #fff; }

@keyframes floaty { 50% { transform: translateY(-6px) rotate(-1deg); } }


/* ---------- star loadout ---------- */
.loadout { display: flex; gap: 10px; margin: 0 0 10px; }
.slot { flex: 1; display: flex; align-items: center; gap: 9px; padding: 8px 10px; border-radius: 16px;
  background: #fff; border: 2px solid color-mix(in srgb, var(--r, #c8d2e8) 45%, #fff);
  box-shadow: 0 3px 0 rgba(201,185,143,.4); text-align: left; min-width: 0; }
.slot.armed { border-color: var(--r); box-shadow: 0 0 0 3px color-mix(in srgb, var(--r) 22%, transparent), 0 3px 0 rgba(201,185,143,.4); }
.slot.locked { opacity: 1; }
.slot.locked .slot-txt { opacity: .6; }
/* The coloured padlock on a locked second slot sits on a dark disc, so the gold reads. */
.slot-art.slot-lock { border-radius: 50%; background: radial-gradient(circle at 50% 35%, #3a4488, #1a2352);
  box-shadow: inset 0 0 0 2px rgba(255,210,63,.55), 0 2px 5px rgba(10,16,48,.35); }
.slot-art { width: 34px; height: 34px; flex: none; display: grid; place-items: center; overflow: hidden;
  border-radius: 10px; background: color-mix(in srgb, var(--c, #dfe6f5) 22%, #fff); font-size: 18px; }
.slot-art img { width: 100%; height: 100%; object-fit: cover; }
.slot-txt { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.slot-name { font-family: var(--display); font-size: 14px; color: var(--ink); line-height: 1;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.slot-sub { font-weight: 900; font-size: 8px; letter-spacing: .09em; color: var(--ink-2); white-space: nowrap; }
.slot.empty .slot-name { color: var(--ink-2); }
.ability-btn.spent { opacity: .35; }
/* The Viking recharges, so his button shows the meter instead of just going dark. */
.ability-btn.charging { opacity: .6; }
.ability-btn[data-meter]:not([data-meter=""])::after {
  content: attr(data-meter); position: absolute; right: -3px; bottom: -3px; z-index: 2;
  font-weight: 900; font-size: 10px; letter-spacing: .02em; padding: 2px 5px; border-radius: 999px;
  background: linear-gradient(180deg, #ffe98d, var(--gold-d)); color: #2a1d00;
  box-shadow: 0 2px 5px rgba(0,0,0,.5); }


/* ---------- leaderboard ---------- */
/* The list takes the slack so the BACK button is never pushed off the bottom of the panel. */
#lbList { flex: 1 1 auto; min-height: 0; }
#lbClose { flex: none; margin-top: 10px; }
.lb-you { flex: none; display: flex; align-items: center; gap: 10px; margin: 2px 0 10px; padding: 9px 12px; border-radius: var(--r-md);
  background: linear-gradient(180deg, #ffe98d, var(--gold) 60%, #e0a300); color: #35260a;
  box-shadow: 0 4px 0 #b07c00, inset 0 2px 0 rgba(255,255,255,.6); }
.lb-rank { font-family: var(--display); font-size: 27px; line-height: 1; }
.lb-rank sup { font-size: 13px; }
.lb-you-txt { flex: 1; font-weight: 900; font-size: 11px; letter-spacing: .05em; text-transform: uppercase; }
.lb-you-tr { display: flex; align-items: center; gap: 5px; font-family: var(--display); font-size: 20px; }
.lb-you-tr img { width: auto; height: 26px; }

.lb-row { display: flex; align-items: center; gap: 9px; padding: 7px 10px; border-radius: 14px; background: #fff;
  box-shadow: inset 0 0 0 2px rgba(26,35,82,.06); }
.lb-row .fake-badge { width: 26px; height: 26px; font-size: 8px; }
.lb-place { flex: none; width: 24px; text-align: center; font-family: var(--display); font-size: 16px; color: var(--ink-2); }
.lb-name { flex: 1; min-width: 0; font-weight: 900; font-size: 13px; color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lb-tr { flex: none; display: flex; align-items: center; gap: 4px; font-family: var(--display); font-size: 16px; color: var(--ink); }
.lb-tr img { width: auto; height: 19px; }
/* The top three wear gold, and your own row is the one that stands out. */
.lb-row.podium .lb-place { color: var(--gold-d); font-size: 18px; }
.lb-row.me { background: linear-gradient(180deg, #e8f0ff, #cfe0ff); box-shadow: 0 0 0 2px var(--blue), inset 0 1px 0 #fff; }
.lb-row.me .lb-name { color: #12224e; }


/* ---------- packs ---------- */
.pack-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 9px; margin-bottom: 6px; }
.pack { display: flex; flex-direction: column; align-items: center; gap: 2px; padding: 9px 6px 8px; border-radius: var(--r-md);
  background: #fff; border: 2px solid color-mix(in srgb, var(--r) 40%, #fff); text-align: center; min-width: 0;
  box-shadow: 0 4px 0 color-mix(in srgb, var(--r) 45%, #b9a878), 0 10px 16px -10px rgba(0,0,0,.5); }
.pack:active { transform: translateY(3px); box-shadow: 0 1px 0 color-mix(in srgb, var(--r) 45%, #b9a878); }
.pack.poor { filter: grayscale(.55); opacity: .75; }
.pack-art { width: 100%; max-width: 88px; aspect-ratio: 339 / 550; object-fit: contain; }
.pack-name { font-family: var(--display); font-size: 12px; color: var(--ink); line-height: 1.05; }
.pack-holds { font-weight: 900; font-size: 9px; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-2); }
.pack-price { display: flex; align-items: center; justify-content: center; gap: 3px; margin-top: 3px;
  font-family: var(--display); font-size: 15px; color: var(--ink);
  background: var(--sink); border-radius: 999px; padding: 2px 9px; width: 100%; }
.pack-price img { width: 14px; height: 14px; }
.rv-gems { display: grid; place-items: center; }
.rv-gems img { width: 86px; height: 86px; object-fit: contain; }



/* ---------- the result screens, in a match ---------- */
/* The cream panel is the game's furniture on the menus, and on the menus it belongs. In a match you
   are standing in a stadium, and a round ending should read like the board lighting up rather than
   like a settings sheet sliding in. Same markup, different clothes — scoped to the two overlays that
   appear during play so nothing on the menus moves. --res is set from JS to the result's colour. */
#roundOverlay, #matchOverlay { --res: #12a05a; background: rgba(120,140,190,.24); backdrop-filter: blur(4px); }
#roundOverlay.lost, #matchOverlay.lost { --res: #e0394b; }

/* The board is bright glass, not a black slab: the game's own furniture is cream and white, and a
   result screen that goes dark reads as a system dialog rather than as part of the match. It stays
   translucent so the arena shows through - the overlay behind has already blurred it, and a second
   backdrop-filter here would be a full snapshot-blur-composite every frame for a blur already paid
   for. --res is set from JS to the result's colour, dark enough to read on white. */
#roundOverlay .panel, #matchOverlay .panel {
  background: linear-gradient(180deg, rgba(255,255,255,.78) 0%, rgba(240,246,255,.72) 55%, rgba(230,238,255,.72) 100%);
  color: var(--ink); border-radius: 22px; padding: 0 18px 18px; overflow: hidden;
  box-shadow: 0 10px 0 rgba(201,185,143,.45), 0 30px 60px -18px rgba(12,18,46,.5),
              inset 0 0 0 2px rgba(255,255,255,.9), inset 0 1px 0 rgba(255,255,255,.95); }
/* The lit strip across the top: the one piece of colour that says which way it went. */
#roundOverlay .panel::before, #matchOverlay .panel::before {
  content: ""; display: block; height: 7px; margin: 0 -18px 16px;
  background: linear-gradient(90deg, transparent, var(--res), transparent);
  box-shadow: 0 0 22px var(--res); }

#roundOverlay .panel-title, #matchOverlay .panel-title,
#roundOverlay .panel-title.win, #roundOverlay .panel-title.lose,
#matchOverlay .panel-title.win, #matchOverlay .panel-title.lose {
  color: var(--res); letter-spacing: .02em;
  text-shadow: 0 3px 0 rgba(255,255,255,.95), 0 6px 18px rgba(12,18,46,.18); }

/* The reason reads as a ticker line under the result, not as a sentence in a dialog. */
#roundOverlay .panel-reason, #matchOverlay .panel-reason {
  font-size: 11.5px; letter-spacing: .16em; text-transform: uppercase; color: var(--ink-2); margin: 8px 0 14px; }

/* The score in its own box, the way a scoreboard holds it. */
#roundOverlay .score, #matchOverlay .score {
  display: inline-flex; align-items: center; gap: 12px; margin: 0 0 18px;
  padding: 4px 22px; border-radius: 14px; background: rgba(255,255,255,.62);
  box-shadow: inset 0 0 0 2px rgba(255,255,255,.9), 0 3px 0 rgba(201,185,143,.35);
  font-variant-numeric: tabular-nums; }

#matchOverlay .trophy-delta { color: var(--ink); }

/* The tiles are the panel again - light, with the number in ink over a quiet label, which is what a
   scoreboard does with a stat. */
#matchOverlay .stats div {
  background: rgba(255,255,255,.60); color: var(--ink-2);
  box-shadow: inset 0 0 0 2px rgba(255,255,255,.9), 0 3px 0 rgba(201,185,143,.35);
  font-size: 11px; letter-spacing: .06em; text-transform: uppercase; }
#matchOverlay .stats b { color: var(--ink); letter-spacing: 0; text-transform: none; text-shadow: none; }

/* What the match paid, as a chip rather than as two words floating on the panel. */
#matchOverlay .reward { gap: 10px; }
#matchOverlay .rw { color: var(--ink); font-size: 22px; padding: 3px 14px 3px 10px; border-radius: 999px;
  background: rgba(255,255,255,.62); box-shadow: inset 0 0 0 2px rgba(255,255,255,.9), 0 3px 0 rgba(201,185,143,.35);
  text-shadow: none; }

/* Promotion and relegation, dark enough to read on the light board. */
#matchOverlay .arena-move.up { color: #0f9a4f; }
#matchOverlay .arena-move.down { color: #d22b3d; }

#roundOverlay .btn-ghost, #matchOverlay .btn-ghost { color: var(--ink-2); }

/* The pass on the menu: a badge at the side of the arena rather than a strip across it.
   Three layers, each doing one job. The ring is a conic gradient masked into a true annulus, so the
   season's progress is drawn on the rim itself rather than behind a disc that has to cover it up.
   The core is glass with the light coming from the top left, like every other raised surface in the
   game. The reward the pass owes you next sits in the middle and the tier rides the bottom of the
   rim. --p, how far into the tier the season is, is set from JS and is all the ring needs.
   Centred with a margin rather than a transform, which leaves transform free for the float. */
/* Floating at the right, above the arena. In FLOW rather than absolutely positioned: pinned to a
   percentage of the screen it sat on the arena render, and the one rule here is that it must not
   touch the arena. A row of its own makes that true by construction, at any render height, on any
   screen - and it still reads as floating, because it is still floating (see bpFloat). */
.pass-dot { --p: 0; position: relative; align-self: flex-end; flex: 0 0 auto; margin: 0 2px -6px 0; z-index: 3;
  width: 58px; height: 58px; padding: 0; border-radius: 50%; color: var(--ink);
  filter: drop-shadow(0 10px 14px rgba(4,10,35,.55));
  box-shadow: inset 0 0 0 1.5px rgba(255,255,255,.55);
  animation: bpFloat 5.5s ease-in-out infinite; transition: transform .12s; }
.pass-dot:active { transform: scale(.93); }
@keyframes bpFloat { 50% { transform: translateY(-5px); } }

/* the rim: an unfilled dark track, the season's share of it in gold */
.pass-dot::before {
  content: ""; position: absolute; inset: 0; border-radius: 50%;
  /* Two stops and a hard cut: every stop before the cut has to be a fraction of --p, or a tier only
     a few percent in would put the mid-gold past the end of its own arc and bleed round the rim. */
  background: conic-gradient(from -90deg, #ffe07a, #f0a800 calc(var(--p) * 1%), rgba(9,16,44,.55) 0);
  -webkit-mask: radial-gradient(farthest-side, #0000 calc(100% - 7px), #000 calc(100% - 6px));
          mask: radial-gradient(farthest-side, #0000 calc(100% - 7px), #000 calc(100% - 6px)); }

.bp-core { position: absolute; inset: 7px; display: grid; place-items: center; border-radius: 50%;
  overflow: hidden; isolation: isolate;
  background: radial-gradient(80% 66% at 30% 20%, #fff, #eef3ff 52%, #cfdcf7);
  box-shadow: inset 0 1px 0 #fff, inset 0 -7px 12px rgba(26,35,82,.16), 0 2px 5px rgba(4,10,35,.45); }
/* the gloss: a soft sweep across the top half, the same light the buttons catch */
.bp-core::before {
  content: ""; position: absolute; left: -10%; right: -10%; top: -32%; height: 72%; border-radius: 50%;
  background: linear-gradient(180deg, rgba(255,255,255,.95), rgba(255,255,255,0));
  opacity: .55; pointer-events: none; }

/* What the pass owes you next, at the size the circle allows. A pack is a tall card rather than a
   round icon, so it is given more of the badge and cropped by the core's own edge. */
.bp-next { position: relative; z-index: 1; display: grid; place-items: center; width: 27px; height: 27px;
  margin-bottom: 4px; filter: drop-shadow(0 2px 3px rgba(20,26,70,.4)); }
.bp-next img { width: 100%; height: 100%; object-fit: contain; }
.bp-next.bp-pack { width: 24px; height: 34px; margin-bottom: 5px; }
.bp-next.bp-pack img { transform: scale(1.3); }

/* The tier, as a chip on the rim: the ring says how far into it you are, this says which one. */
.bp-tier { position: absolute; left: 50%; bottom: -3px; transform: translateX(-50%); z-index: 2;
  min-width: 21px; padding: 0 5px; border-radius: 999px;
  font-family: var(--display); font-weight: 400; font-size: 11.5px; line-height: 16px; text-align: center;
  color: #5a3500; background: linear-gradient(180deg, #ffe98d, var(--gold) 65%, #f0a800);
  box-shadow: 0 0 0 2px rgba(9,16,44,.45), inset 0 1px 0 rgba(255,255,255,.8), 0 2px 4px rgba(0,0,0,.4); }

/* A tier waiting to be collected. The badge breathes and the reward inside it lifts - an invitation
   rather than a notice. */
.pass-dot.nudge { animation: bpFloat 5.5s ease-in-out infinite, bpReady 1.9s ease-in-out infinite; }
.pass-dot.nudge .bp-next { animation: bpBob 1.9s ease-in-out infinite; }
.pass-dot.nudge .bp-core { background: radial-gradient(80% 66% at 30% 20%, #fff, #fff6dd 55%, #ffe3a1); }
.pass-dot.nudge::after {
  content: ""; position: absolute; top: 0; right: 0; width: 13px; height: 13px; border-radius: 50%;
  background: radial-gradient(70% 70% at 35% 30%, #ff8b98, #ff4d63 60%, #e01b33);
  box-shadow: 0 0 0 2px rgba(255,255,255,.9), 0 2px 6px rgba(0,0,0,.5); }
@keyframes bpReady { 50% { filter: drop-shadow(0 10px 14px rgba(4,10,35,.55)) drop-shadow(0 0 14px rgba(255,205,60,.85)); } }
@keyframes bpBob { 50% { transform: translateY(-3px) scale(1.06); } }
.pass-dot.full::before { background: linear-gradient(180deg, #ffe98d, var(--gold)); }
@media (prefers-reduced-motion: reduce) {
  .pass-dot, .pass-dot.nudge, .pass-dot.nudge .bp-next,
  .pt-card.ready::after, .pass-buy::after, .pt-cell.hero::before,
  .pt-row.here .pt-no { animation: none; }
}

/* ---------- the battle pass ---------- */
/* Built like a pass screen in a game rather than a list in an app: the season's art IS the header,
   and the track under it is two continuous lanes with the tier number straddling the join - free on
   the left, premium on the right. The lanes are unbroken on purpose; a stack of separate cards with
   gaps between them reads as an inventory, a lane reads as a road. */
/* No room made at the top: the picture starts at the very edge of the screen, and the wallet that
   normally floats there is hidden on this page (see show() in js/main.js). */
/* The track runs right down to the tab bar. Every other page keeps twelve pixels of air under its
   content so nothing sits flush against the bar; on this page that air was a strip of bare
   background between the end of the lanes and the bar - a gap across the bottom of the screen with
   the lane clip showing through it, which on a phone is most of what you see when you scroll to the
   end. 72px is the bar itself; the lanes end where it begins. */
#pass.screen.with-tabs { padding: 0 0 calc(60px + max(4px, var(--sab))); }
#pass { background:
  radial-gradient(130% 60% at 50% 0%, rgba(96,130,255,.28), transparent 62%),
  linear-gradient(180deg, #16205a 0%, #101745 46%, #0a0e2c 100%); }

/* ---- the hero ---- */
/* The header's shape IS the picture's shape (1672x941 in the file), so the whole banner is on
   screen at any width - no crop, no letterbox. Everything written over it sits on the gradient at
   its foot rather than on the picture itself. */
.pass-hero { position: relative; flex: none; display: flex; flex-direction: column;
  justify-content: flex-end; aspect-ratio: 1672 / 941; margin: 0;
  padding: max(12px, env(safe-area-inset-top)) 14px 12px; overflow: hidden;
  box-shadow: 0 10px 22px -12px #000; }
.ph-art { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  object-position: 50% 50%; }
/* The picture is a background, so everything on it needs a floor to stand on. */
/* Lighter than it was: the picture is the point of this header, and the scrim only has to carry the
   type at its foot. It starts at almost nothing and only gathers where the words are - a touch of
   shade across the picture, a few points of alpha, not a curtain over it. */
.pass-hero::after { content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(8,12,40,.11) 0%, rgba(8,12,40,.20) 45%,
              rgba(8,12,40,.47) 76%, rgba(10,14,44,.80) 100%); }
/* Everything written on the picture stacks above it - except the way out, which is pinned to the
   corner below and must keep the `absolute` its own rule gives it. */
.pass-hero > *:not(.ph-art):not(.pass-back) { position: relative; z-index: 1; }
.ph-text { display: grid; gap: 1px; margin: 18px 0 7px; }
.ph-kicker { font-weight: 900; font-size: 10px; letter-spacing: .2em; color: #ffd23f;
  text-shadow: 0 2px 3px rgba(0,0,0,.8); }
.ph-name { font-family: var(--display); font-weight: 400; font-size: 26px; line-height: 1; color: #fff;
  text-shadow: 0 3px 0 rgba(6,10,34,.75), 0 6px 18px rgba(0,0,0,.6); }
/* The way out, in the corner of the artwork where a back button belongs. It spent a while sitting
   a third of the way down the picture instead, because the rule above it - which lifts everything
   written on the hero above the picture - was also resetting this to `relative` and dropping it
   back into the flex column. A round badge rather than a rounded square: the same shape as the
   other badges the game floats over art. */
.pass-back { position: absolute; z-index: 2; top: max(10px, env(safe-area-inset-top)); left: 10px;
  width: 34px; height: 34px; border-radius: 50%; font-family: var(--display); font-size: 26px;
  line-height: 30px; color: #fff; background: rgba(8,12,40,.55);
  backdrop-filter: blur(3px);
  box-shadow: inset 0 0 0 2px rgba(255,255,255,.35), 0 3px 10px -3px rgba(0,0,0,.7); }
.pass-back:active { transform: translateY(1px); }

/* The meter, on the art: the tier in a badge and the bar running out of it. */
.ph-meter { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.ph-tier { flex: none; display: grid; place-items: center; width: 44px; height: 44px; border-radius: 14px;
  background: linear-gradient(180deg, #6fb0ff, #3a72dd 62%, #2f62c9); color: #fff;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.5), 0 3px 0 #24509f, 0 6px 12px -5px rgba(0,0,0,.8); }
.ph-tier b { font-weight: 900; font-size: 22px; line-height: 1; }
/* The meter sits on a photograph, so it is lit rather than sunk: a pale track instead of a black
   one, and a fill that runs from near-white into the game's blue. */
.pass-bar { flex: 1; min-width: 120px; display: block; height: 14px; border-radius: 999px; overflow: hidden;
  background: rgba(255,255,255,.26);
  box-shadow: inset 0 2px 4px rgba(6,12,40,.45), inset 0 0 0 1.5px rgba(255,255,255,.45); }
.pass-bar > * { display: block; height: 100%; border-radius: 999px; width: 0;
  background: linear-gradient(180deg, #ffffff, #b6dcff 40%, #6fb0ff 80%, #4f9bff);
  box-shadow: 0 0 14px rgba(150,200,255,.85), inset 0 1px 0 rgba(255,255,255,.9);
  transition: width .7s cubic-bezier(.25,.9,.3,1); }
.pass-note { width: 100%; font-weight: 800; font-size: 10.5px; letter-spacing: 0; color: rgba(255,255,255,.8);
  text-shadow: 0 1px 3px rgba(0,0,0,.8); }

/* ---- what the premium track costs ---- */
/* The strip that sells the premium track. Tapping it opens the dialog rather than buying anything -
   the price is agreed to there, not here.
   It runs the full width and fills the whole band between the picture and the lanes: floated in the
   middle of that band with a margin all round, it read as a notice someone had dropped on the page,
   and the two strips of background either side of it were doing nothing. Edge to edge it is part of
   the page's masonry - the picture, then the offer, then the track - which is how a shop front in a
   game of this kind is built. */
/* The premium-pass player in the corner of the page. Moves by transform only - he floats, and when he
   "talks" he nods from the feet in quick little beats. */
/* His lower edge goes behind the blue tab bar (the user): the bar sits above the page, so it simply
   covers him from the waist of the picture down. */
.pass-guy { position: absolute; right: 4px; bottom: calc(max(3px, var(--sab)) + 6px); z-index: 6; width: 118px;
  padding: 0; border: 0; background: none; cursor: pointer; -webkit-tap-highlight-color: transparent;
  animation: guyFloat 3.2s ease-in-out infinite; }
.pass-guy img { display: block; width: 100%; height: auto; transform-origin: 50% 100%;
  filter: drop-shadow(0 8px 10px rgba(0,0,0,.45)); }
.pass-guy:active img { transform: scale(.95); }
.pass-guy.talking img { animation: guyTalk .24s ease-in-out 8 alternate; }
@keyframes guyFloat { 50% { transform: translateY(-5px); } }
@keyframes guyTalk { from { transform: rotate(-2.2deg) scale(1, 1.015); } to { transform: rotate(1.6deg) scale(1.01, .985); } }
@media (prefers-reduced-motion: reduce) { .pass-guy, .pass-guy.talking img { animation: none; } }
.pass-buy { position: relative; overflow: hidden; flex: none; display: flex; align-items: center;
  justify-content: space-between; gap: 11px; width: 100%; margin: 0; min-height: 68px;
  padding: 10px 13px; border-radius: 0; text-align: left; color: #3b2400;
  background: linear-gradient(180deg, #fff0bd 0 2px, #ffd873 2px, #f5a41d 62%, #e08c12);
  box-shadow: inset 0 -3px 0 rgba(122,70,4,.45), 0 8px 16px -10px rgba(0,0,0,.9);
  transition: transform .12s, filter .12s; }
.pass-buy::after { content: ""; position: absolute; inset: 0;
  background: linear-gradient(104deg, transparent 38%, rgba(255,255,255,.75) 50%, transparent 62%);
  transform: translateX(-130%); animation: passShine 3.6s ease-in-out infinite; pointer-events: none; }
.pass-buy:active { filter: brightness(.95); transform: translateY(2px); }
/* The crown, still, with nothing behind it.
   It sat on a dark disc to begin with - the badge the lock on the lane is built as - and a black
   coin on a gold strip is a hole in the strip. Gold on gold needs separation, not a container, so
   it gets a shadow of its own and the strip shows through.
   It also turned, for a while, on a 6x8 sheet of rendered frames. It does not need to: this is a
   label on a button, not a reward coming out of a pack, and something spinning beside the words
   asks to be watched instead of read. The still is frame 0 of that same render (crown.png), and
   the sheet is left in assets for whatever wants it. It sits a few pixels above the middle, where
   a crown looks placed rather than dropped. */
.pb-crown { position: relative; flex: none; width: 40px; height: 40px; }
.pb-crown::after { content: ""; position: absolute; left: 50%; top: 50%; width: 38px; height: 22px;
  margin: -14px 0 0 -19px;
  background: url("../assets/ui/crown.png") center / contain no-repeat;
  filter: drop-shadow(0 2px 2px rgba(60,34,0,.55)) drop-shadow(0 0 6px rgba(255,240,190,.35)); }
.pb-text { display: grid; gap: 2px; flex: 1; min-width: 0; }
.pb-text b { font-family: var(--display); font-weight: 400; font-size: 19px; letter-spacing: .6px;
  line-height: 1; text-shadow: 0 1px 0 rgba(255,255,255,.45); }
.pb-text small { font-weight: 800; font-size: 10.5px; line-height: 1.25; color: rgba(58,34,0,.78); }
/* The way in, as a chip: a word and a chevron, and no number - the price is the dialog's to state. */
.pb-price { flex: none; display: flex; align-items: center; gap: 4px; padding: 7px 10px 7px 13px;
  border-radius: 999px; font-family: var(--display); font-weight: 400; font-size: 16px; line-height: 1;
  letter-spacing: .06em; color: #ffe9b8;
  background: linear-gradient(180deg, rgba(62,36,0,.78), rgba(34,19,0,.86));
  box-shadow: inset 0 0 0 1.5px rgba(255,226,150,.45), 0 2px 6px -2px rgba(0,0,0,.6); }
.pb-price::after { content: "›"; font-size: 20px; line-height: .9; color: rgba(255,226,150,.8);
  margin-left: 1px; }

/* ---- and the dialog that prices it ----
   A celebration, not a form (the user: "more festive, with this picture"): deep blue and gold, the
   user's art framed in gold at the top with light turning behind it and a shine running across it,
   and confetti coming down over the panel. Transform and opacity only: the phone does all of it on
   the compositor. */
.bp-panel { position: relative; overflow: hidden; padding: 16px 16px 16px; color: #fff;
  background: radial-gradient(120% 80% at 50% 0%, #2f5bd8 0%, #1a2f8a 45%, #0d1552 100%);
  box-shadow: 0 8px 0 #b8860b, 0 26px 50px -12px rgba(0,0,0,.8), inset 0 0 0 3px #ffd34d, inset 0 2px 0 rgba(255,255,255,.35); }
.bp-panel .bp-list li { color: #dfe6ff; }
.bp-panel .bp-list b { color: #ffd34d; }
.bp-panel .btn-ghost { color: #dfe6ff; }
.bp-art { position: relative; width: min(100%, 300px); aspect-ratio: 1; margin: 0 auto 14px; z-index: 1; }
.bp-art img { position: relative; z-index: 1; width: 100%; height: 100%; border-radius: 20px; display: block;
  box-shadow: 0 0 0 4px #ffd34d, 0 0 0 7px #b8860b, 0 14px 30px -8px rgba(0,0,0,.8);
  animation: bpArtIn .6s cubic-bezier(.2,1.5,.4,1) both; }
@keyframes bpArtIn { from { transform: scale(.6) rotate(-4deg); opacity: 0; } }
.bp-rays { position: absolute; inset: -40%; z-index: 0; pointer-events: none; border-radius: 50%;
  background: repeating-conic-gradient(rgba(255,215,90,.28) 0 9deg, transparent 9deg 22deg);
  -webkit-mask-image: radial-gradient(closest-side, #000 35%, transparent 100%);
  mask-image: radial-gradient(closest-side, #000 35%, transparent 100%);
  animation: bpRays 14s linear infinite; }
@keyframes bpRays { to { transform: rotate(360deg); } }
.bp-shine { position: absolute; inset: 0; z-index: 2; border-radius: 20px; overflow: hidden; pointer-events: none; }
.bp-shine::after { content: ""; position: absolute; top: -20%; bottom: -20%; left: 0; width: 35%;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.55), transparent);
  transform: translateX(-150%) skewX(-18deg); animation: bpShine 3.4s cubic-bezier(.5,0,.5,1) 0.7s infinite; }
@keyframes bpShine { 0% { transform: translateX(-150%) skewX(-18deg); } 45%, 100% { transform: translateX(400%) skewX(-18deg); } }
.bp-confetti { position: absolute; inset: 0; z-index: 3; pointer-events: none; }
.bp-confetti i { position: absolute; top: -8%; width: 8px; height: 12px; border-radius: 2px; opacity: 0;
  animation: bpFall var(--d, 3.2s) linear var(--delay, 0s) infinite; }
@keyframes bpFall {
  0% { transform: translate(0, 0) rotate(0); opacity: 0; }
  8% { opacity: 1; }
  100% { transform: translate(var(--dx, 20px), 120vh) rotate(var(--r, 540deg)); opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .bp-rays, .bp-shine::after, .bp-confetti i { animation: none; } }
.bp-list { margin: 0 0 14px; padding: 0; list-style: none; display: grid; gap: 7px; text-align: left; }
.bp-list li { position: relative; padding-left: 22px; font-weight: 800; font-size: 12.5px;
  line-height: 1.35; color: var(--ink-2); }
/* A gem rather than a bullet: the list is what gems buy. */
.bp-list li::before { content: ""; position: absolute; left: 3px; top: .3em; width: 11px; height: 11px;
  background: linear-gradient(180deg, #ffd873, #e89a13); clip-path: polygon(50% 0, 100% 38%, 50% 100%, 0 38%); }
.bp-list b { color: var(--ink); }
.bp-cost { display: flex; flex-direction: column; align-items: center; gap: 5px; margin: 0 0 12px; }
.bp-price { display: inline-flex; align-items: center; gap: 6px; padding: 4px 16px 4px 11px;
  border-radius: 999px; font-family: var(--display); font-size: 22px; color: #3b2400;
  background: linear-gradient(180deg, #ffd873, #f0a01a);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.7), 0 3px 0 #b96f07; }
.bp-price img { width: 20px; height: 20px; object-fit: contain; }
.bp-price.short { filter: grayscale(.55) brightness(.95); }
.bp-short { font-weight: 900; font-size: 11px; letter-spacing: .06em; color: #c0392b; }
#bpGo:disabled { filter: grayscale(.7); }

/* ---- the two lanes ---- */
/* No gap over the headings: picture, offer, lanes, track - four bands stacked with nothing between
   them. The strip below fills the whole band it is in, so a strip of background above the headings
   would be the only seam on the page. */
.pass-cols { flex: none; display: flex; gap: 0; margin: 0; }
.pc-head { flex: 1; text-align: center; padding: 6px 6px 7px;
  font-family: var(--display); font-weight: 400; font-size: 13px; letter-spacing: 1.2px; color: #fff;
  text-shadow: 0 2px 0 rgba(0,0,0,.35); }
/* The free lane is steel grey: it is the ordinary track, and next to gold it should read as the
   plain one rather than compete with it. */
.pc-head.free { background: linear-gradient(180deg, #7b8499, #5c6478); }
.pc-head.prem { background: linear-gradient(180deg, #ffc247, #e08c12); color: #3b2400;
  text-shadow: 0 1px 0 rgba(255,255,255,.35); }

/* The two lanes are painted on the track itself as well as on the tiles, so wherever the rungs do
   not reach - the last screenful before the bar, the bounce at the end of a scroll - the lanes carry
   on instead of opening a hole onto the page behind. Grey on the left, and nothing on the right so
   the premium lane's clip shows through. */
.pass-track { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
  background: linear-gradient(90deg, #565d70 0 50%, rgba(226,144,15,.45) 50%); }
.pt-row { position: relative; display: flex; align-items: stretch; }
.pt-row + .pt-row { border-top: 2px solid rgba(4,8,28,.45); }

.pt-cell { position: relative; flex: 1; min-width: 0; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 2px; padding: 7px 10px 8px; color: #fff;
  transition: filter .12s, transform .1s; }
.pt-cell.free { background: linear-gradient(180deg, #6c7489, #565d70); }
/* The premium lane's clip: ONE video down the right half of the page, with the tiles painting their
   scrim over it rather than painting a copy of it each.
   It was an animated WebP as a CSS background, and that is the most expensive way to put moving
   pictures on a screen: the browser re-rasterises the element on every frame of the animation, and
   with it on all thirty premium tiles this screen measured 32 fps against 58 with it switched off.
   Moving it to one big element made it worse, not better - one 240x633 rescale per frame beat
   thirty small ones, and frames of 2 seconds and more showed up. A <video> is decoded on the
   hardware and handed to the compositor as its own layer: no rasterising, no per-frame CSS work.
   It is also smoother - 24 fps against the WebP's 10 - and smaller: 129 KB against 153. */
.pt-clip { position: absolute; z-index: 0; top: 0; bottom: 0; left: 50%; right: 0; pointer-events: none;
  width: 50%; height: 100%; object-fit: cover; }
/* Everything else on the page sits over it. */
.pass-hero, .pass-buy, .pass-cols, .pass-track { z-index: 1; }
.pass-cols, .pass-track { position: relative; }
/* A gold veil over the clip rather than a dark one. The clip is a filmed shimmer: bright at one end
   and almost black at the other, and with only a dark scrim on top the lane came out in patches -
   some rungs gold, some nearly black, which on a phone reads as holes in the lane rather than as
   light moving over it. The veil holds every rung at the same gold and lets the shimmer play. */
.pt-cell.prem { color: #fff;
  background: linear-gradient(180deg, rgba(150,88,0,.30), rgba(110,60,0,.42)); }
.pt-cell:not(:disabled):active { transform: translateY(2px); filter: brightness(.94); }
/* The one rung on the whole track that is not currency. Light coming off it, a gold frame round the
   portrait and the name in gold: from a scroll past, the season's prize should look like the prize
   and not like another pile of coins. Clipped to the cell, so the rays stay in their own lane. */
.pt-cell.hero { overflow: hidden; }
.pt-cell.hero::before { content: ""; position: absolute; inset: -40% -20%; pointer-events: none;
  background: conic-gradient(from 0deg, rgba(255,240,200,.40) 0 5deg, transparent 5deg 30deg);
  -webkit-mask-image: radial-gradient(closest-side, #000 18%, transparent 76%);
  mask-image: radial-gradient(closest-side, #000 18%, transparent 76%);
  animation: passRays 18s linear infinite; }
.pt-cell.hero > * { position: relative; }
.pt-cell.hero .pt-star { box-shadow: 0 0 0 2px #ffe9a8, 0 0 0 4px rgba(90,50,0,.6),
  0 0 20px -2px rgba(255,210,110,.95); }
.pt-cell.hero .pt-name { color: #ffe6a6;
  text-shadow: 0 2px 0 rgba(50,25,0,.7), 0 0 12px rgba(255,200,90,.55); }
@keyframes passRays { to { transform: rotate(1turn); } }

.pt-art { width: 38px; height: 38px; display: grid; place-items: center; }
.pt-art img { width: 100%; height: 100%; object-fit: contain;
  filter: drop-shadow(0 3px 4px rgba(0,0,0,.55)); }
.pt-art .pt-pack { width: auto; height: 44px; }
/* A sticker rung: the sticker on its white card, the way the speech bubble shows it (the user: the
   cut-out alone on the gold tile did not read). */
/* (Inside the art's own 38 px box: at 50 px it spilled down over the rung's name - the user.) */
.pt-art .pt-sticker { width: 38px; height: 38px; object-fit: contain; padding: 2px; box-sizing: border-box;
  background: #fff; border-radius: 9px; box-shadow: inset 0 0 0 1.5px rgba(20,30,80,.10), 0 2px 0 rgba(0,0,0,.25); }
/* The bag, held to the size of the coin beside it.
   Both icons sit in the same 38px box, but they are not the same KIND of file: coin.png is the
   game's old hand-made icon and carries about 15% of empty margin on every side, so the coin you
   see is only two thirds of its box, while bag.png is cut tight to the render. Worse, the rule
   above cannot size either one by height - a percentage height against a grid area with no
   definite height is not a height - so every icon is sized by its WIDTH, and the bag, the only
   portrait-shaped prop, came out 51px tall in a 38px row.
   So: an explicit box, in pixels, with the inherited `object-fit: contain` fitting the bag inside
   it. Not `auto` (on a centred grid item the width collapsed to nothing) and not a percentage.
   32px is the middle the user settled on: the full box read as too big beside the coin, the
   coin's own visible 26px as too small. */
.pt-art .pt-bag { width: 32px; height: 32px; }
/* A star on the track: the card's own art in a little frame in its rarity colour, so the top of the
   premium lane looks like what it is - a character, not another pile of coins. */
.pt-star { display: block; width: 40px; height: 40px; border-radius: 9px; overflow: hidden;
  background: linear-gradient(180deg, color-mix(in srgb, var(--c) 70%, #fff), var(--c));
  box-shadow: 0 0 0 2px var(--r), 0 3px 6px -2px rgba(0,0,0,.7); }
.pt-star .portrait { transform: scale(1.35); }
.pt-star .mono { display: grid; place-items: center; width: 100%; height: 100%;
  font-family: var(--display); font-size: 15px; color: #fff; }
.pt-name { max-width: 100%; font-family: var(--display); font-weight: 400; font-size: 13px;
  letter-spacing: .2px; text-transform: capitalize; white-space: nowrap; overflow: hidden;
  text-overflow: ellipsis; text-shadow: 0 2px 0 rgba(0,0,0,.35); }
.pt-cell.prem .pt-name { text-shadow: 0 2px 0 rgba(20,10,0,.65), 0 0 10px rgba(0,0,0,.5); }

/* The tier, in a diamond straddling the join - the one thing that belongs to both lanes. */
.pt-no { position: absolute; left: 50%; top: 50%; z-index: 2; width: 34px; height: 34px;
  margin: -17px 0 0 -17px; rotate: 45deg; border-radius: 9px; color: #222a55;
  background: linear-gradient(135deg, #ffffff, #cfdcf6);
  box-shadow: 0 0 0 3px rgba(4,8,28,.6), inset 0 2px 0 #fff; }
.pt-row.passed .pt-no { color: #3b2400; background: linear-gradient(135deg, #ffe38a, #f5a41d); }
.pt-row.here .pt-no { animation: passHere 1.9s ease-in-out infinite; }
@keyframes passHere { 50% { box-shadow: 0 0 0 3px rgba(4,8,28,.6), inset 0 2px 0 #fff, 0 0 0 9px rgba(120,180,255,.3); } }
/* The number is written upright inside a diamond that is not: the diamond is turned 45 degrees and
   the number inside it is turned back. It has to be an element to be turned - as a bare text node
   it simply came out lying on its side, which is what it was doing.
   
   It fills the diamond and centres inside it rather than sitting in a grid cell, so the digit is
   centred on the SHAPE and not on a text box whose height depends on the font's own metrics -
   which is what had it riding low and to one side. */
.pt-no > b { position: absolute; inset: 0; display: grid; place-items: center; rotate: -45deg;
  font-family: var(--display); font-weight: 400; font-size: 15px; line-height: 1; letter-spacing: .3px;
  text-shadow: 0 1px 0 rgba(255,255,255,.7); }

/* Ready: the cell lifts out of its lane and glows; it is the only thing on the page asking to be
   pressed, so nothing else needs decoration. */
.pt-cell.ready { z-index: 1; box-shadow: inset 0 0 0 3px rgba(255,255,255,.9), 0 0 22px -2px rgba(255,255,255,.5); }
.pt-cell.free.ready { background: linear-gradient(180deg, #8d97ad, #6c7489); }
/* Ready: the scrim lifts, so the tile that can be collected is the brightest thing on the lane. */
.pt-cell.prem.ready { background: linear-gradient(180deg, rgba(255,220,140,.14), rgba(255,180,40,.10)); }

/* Taken: sunk into the lane, with a tick over the reward. */
.pt-cell.claimed { filter: saturate(.55) brightness(.72); }
.pt-cell.claimed .pt-tick { position: absolute; inset: 0; display: grid; place-items: center; }
.pt-cell.claimed .pt-tick::before { content: ""; width: 19px; height: 10px; margin-top: -5px;
  border-left: 5px solid #55e08a; border-bottom: 5px solid #55e08a; transform: rotate(-45deg);
  border-radius: 3px; filter: drop-shadow(0 2px 3px rgba(0,0,0,.6)); }

/* Locked: dim, and on the premium lane a padlock, because that lock is a price rather than a wait. */
.pt-cell.locked { filter: brightness(.82) saturate(.85); }
/* The lock on a premium tile you do not own yet.
   It used to be a 15x12 translucent rectangle with a wire shackle, sitting on a lane whose
   background is a bright, busy, moving clip - at that size and that contrast it read as a smudge in
   the corner rather than as a lock. Now it is a proper badge: a dark disc that separates it from
   whatever the clip is doing underneath, and a gold padlock on it, in the same gold as the lane's
   own furniture. Built from the one element the markup gives it - the disc is the element, the
   shackle is ::before and the body (with its keyhole) is ::after. */
.pt-lock { position: absolute; top: 5px; right: 6px; width: 21px; height: 21px; border-radius: 50%;
  background: radial-gradient(circle at 50% 32%, rgba(58,38,4,.92), rgba(24,14,0,.95));
  box-shadow: inset 0 0 0 1.5px rgba(255,226,150,.55), 0 2px 5px -1px rgba(0,0,0,.65); }
/* The shackle: a half-ring standing on the body. */
.pt-lock::before { content: ""; position: absolute; left: 50%; top: 3.5px; width: 9px; height: 7px;
  margin-left: -4.5px; border: 2px solid #ffd873; border-bottom: 0; border-radius: 5px 5px 0 0; }
/* The body, with a keyhole punched through it by the radial stop in its own background. */
.pt-lock::after { content: ""; position: absolute; left: 50%; top: 9.5px; width: 13px; height: 9px;
  margin-left: -6.5px; border-radius: 2.5px;
  background: radial-gradient(circle at 50% 42%, rgba(40,24,0,.95) 0 1.5px, transparent 1.6px),
              linear-gradient(180deg, #ffe7a6, #e9a61d);
  box-shadow: inset 0 -1px 0 rgba(120,70,0,.35); }

/* Collecting one pops it before it settles back as taken. */
.pt-cell.pop { animation: passPop .42s cubic-bezier(.2,1.6,.4,1); }
@keyframes passPop { 40% { transform: translateY(-6px) scale(1.06); } }
@keyframes passShine { 0%, 55% { transform: translateX(-130%); } 100% { transform: translateX(130%); } }

@media (prefers-reduced-motion: reduce) {
  .pass-buy::after, .pt-cell.hero::before, .pt-row.here .pt-no { animation: none; }
}

/* The pass strip on the match-end board. */
.pass-gain { display: grid; gap: 5px; margin: 2px 0 12px; }
/* A number that has just finished counting gives a little bump (js/main.js countUpBoard). */
.counted { display: inline-block; animation: countBump .32s cubic-bezier(.2,1.7,.4,1); }
.pg-xp { display: inline-block; }          /* so its .counted bump can scale */
@keyframes countBump { 40% { transform: scale(1.3); } }
.pg-line { display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
  font-weight: 900; font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-2); }
.pg-xp { font-family: var(--display); font-size: 17px; letter-spacing: .5px; color: var(--gold-d); }
.pass-gain.up .pg-line { color: var(--gold-d); }
/* The moment a tier is reached on the match-end board: the line bumps and glows gold. */
.pass-gain.tier-hit .pg-line { animation: tierHit .7s cubic-bezier(.2,1.6,.4,1); }
.pass-gain.tier-hit .pass-bar { animation: tierGlow 1.2s ease-out; }
@keyframes tierHit { 30% { transform: scale(1.12); filter: drop-shadow(0 0 8px rgba(255,200,60,.9)); } }
@keyframes tierGlow { 0% { box-shadow: 0 0 0 0 rgba(255,210,63,.9); } 100% { box-shadow: 0 0 0 12px rgba(255,210,63,0); } }

/* ---------- pack opening ---------- */
/* Deliberately NOT .overlay: the arena behind stays visible and blurred, only lightly dimmed.
   --rar is set from JS to whatever is at stake, and every glow in here takes its colour from it. */
#app.in-pack .screen, #app.in-pack .tabbar { visibility: hidden; }
/* No scrim: the arena behind stays as bright as it is on every other screen. The pack reads against
   it on its own drop shadow, and the labels carry their own text shadow. */
.opening { --rar: #ffd23f; --mouth: 7vh; position: absolute; inset: 0; z-index: 25; display: grid; place-items: center;
  background: none; animation: fade .25s; overflow: hidden; perspective: 1200px; }


/* --- the pack --- */
/* The pack sits IN FRONT of whatever is coming out of it, and that is the whole trick.
   Clipping the reward to a line did not work: the clip travels with the element, so the coin slid up
   over the pack's face and read as passing through it. Behind it, the pack's own body hides the coin
   while it is still inside and the tear is what lets it out — which is what actually happens. */
.op-shake { display: grid; place-items: center; position: relative; z-index: 2; }
/* No kick here either. The rendered clip already grows the pack as the wrapper gives way; a second
   scale on top of it fought the first and read as a jolt rather than as weight. */
/* The torn pack bows out as the reward comes up, so the two never fight for the same space — but
   not straight away. It has to still be there while the reward is climbing out of it, or there is
   nothing for the reward to be coming out of. */
/* The pack's exit is played by playReveal() in js/main.js, end state included.
   There is deliberately NO `opacity: 0` here any more. As a static rule it applied the moment
   `.revealing` was added - including through the animation's 340 ms delay, before the pack had
   begun to go anywhere - so on a browser that back-fills a delayed animation differently the pack
   simply blinked out and was never seen opening at all. The reward sits above the pack now
   (z-index), so nothing needs the pack hidden in order to be visible. */

/* Sized to what the clip actually holds: 627 px of rendered pack. Blown up much past this it goes
   soft again on a high-DPR phone, which is the whole reason the frames were re-rendered. */
/* Dead centre. The offsets were there to make room for rings and rays that have been removed. */
.op-stage { position: relative; width: min(64vw, 280px); aspect-ratio: 241 / 340; margin-top: 0; }
/* The pack's shadow, painted behind it. It was a filter: drop-shadow() on the pack's canvas, which
   the phone has to redo whenever the canvas or its animation changes - at the landing, and on every
   frame of a turn. A soft gradient behind the pack costs nothing and reads the same. */
.op-stage::before { content: ""; position: absolute; inset: 9% 7% -4% 7%; z-index: 0; pointer-events: none;
  border-radius: 18%; background: radial-gradient(closest-side, rgba(0,0,0,.5), rgba(0,0,0,.28) 60%, transparent);
  transform: translateY(18px); }
/* The pack's sheets are made ready while the screen fades in (see runPackOpening); it drops after. */
.opening.preparing .op-stage { opacity: 0; }
.opening.arriving .op-stage { animation: opDrop .8s cubic-bezier(.2,1.5,.4,1) both; }
.opening.waiting .op-stage { animation: opFloat 2.6s ease-in-out infinite; }
/* The turn itself is rendered, not faked here: the stage holds a canvas, and a CSS rotateY would
   only have spun the flat picture of the pack. All this does is hold it still while that plays. */
.opening.turning .op-stage { animation: none; }

/* What the turn throws off, in the PACK's colour — not the reward's, so nothing about what is
   inside leaks before the tear. --turn is set from JS to the clip's own length, so the effect and
   the revolution start and finish together however that is retimed.
   The radial flash that used to go with this is gone: a coloured disc expanding out of the pack read
   as a circle stuck on the screen rather than as light. What is left is the band crossing the pack,
   which is the part that looks like something catching the light. */
.op-sweep { position: absolute; inset: -14% -30%; z-index: 2; opacity: 0; pointer-events: none;
  background: linear-gradient(100deg, transparent 42%,
              color-mix(in srgb, var(--pack) 80%, transparent) 50%, transparent 58%);
  /* Faded out at both ends, or the band is a bar with two cut edges running off the screen. */
  -webkit-mask-image: linear-gradient(transparent, #000 22%, #000 78%, transparent);
  mask-image: linear-gradient(transparent, #000 22%, #000 78%, transparent);
  filter: blur(5px); }
.opening.turning .op-sweep  { animation: opSweep var(--turn, .72s) linear both; }
/* One frame of the sheet, drawn into a canvas. As a CSS background the browser had to rescale the
   whole 3360x3784 sheet on every frame; drawing just the source rectangle is a fixed, tiny cost. */
.op-film { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 1; }


/* The flash at the tear is not here. It is rendered into the clip in Blender, where the light can
   light the underside of the flap as it lifts, catch the torn edge, and be shaped by the mouth it
   is coming through — none of which an overlay drawn on top of the canvas can do. See flash() in
   tools/packs/build_pack.py. */

/* --- what came out --- */
.op-reward { position: absolute; left: 50%; top: 50%; translate: -50% -50%; display: flex;
  flex-direction: column; align-items: center; gap: 14px; opacity: 0; pointer-events: none;
  transform-style: preserve-3d; z-index: 1; }
/* Visible, full stop. The climb out of the pack is played by playReveal() in js/main.js; this rule
   is what guarantees that the prize can be SEEN even if that animation never runs. The two were one
   thing once - the reward's only opacity came from inside the keyframes - and a pack whose animation
   did not restart showed an open pack with nothing in it. */
.op-reward.in { opacity: 1; }

/* Face up, on the way out. The flip was the moment this was built around, but it meant the thing
   climbing out of the tear was the BACK of the card — a flat panel in the rarity's colour, showing
   only its rounded top, which read as a purple or blue dome rising out of the pack rather than as a
   card at all. Coming out face up, what emerges is the player. */
.op-card { width: min(46vw, 200px); aspect-ratio: 3 / 4; position: relative; display: block; }
.op-face { position: absolute; inset: 0; border-radius: 18px; overflow: hidden;
  box-shadow: 0 0 0 3px var(--r), 0 0 0 5px rgba(255,255,255,.22), 0 18px 34px -10px rgba(0,0,0,.8); }
.op-card-art { position: absolute; inset: 0; display: grid; place-items: center;
  background: linear-gradient(180deg, color-mix(in srgb, var(--c) 60%, #fff), var(--c)); }
.op-card-art img { width: 100%; height: 100%; object-fit: cover; transform: scale(var(--art-zoom, 1)); }
.op-card-rar { position: absolute; left: 8px; top: 8px; z-index: 2; font-weight: 900; font-size: 10px;
  letter-spacing: .1em; padding: 3px 8px; border-radius: 999px; background: var(--r); color: var(--ri); }
.op-card-name { position: absolute; left: 0; right: 0; bottom: 0; z-index: 2; padding: 16px 8px 8px;
  font-family: var(--display); font-size: 19px; text-align: center; text-shadow: 0 2px 0 rgba(0,0,0,.5);
  background: linear-gradient(transparent, rgba(8,12,34,.75)); }

/* The turn is rendered now, not faked here: a CSS rotateY only spins the flat picture, and a coin
   seen edge-on has a milled rim rather than nothing at all. See spinProp() in js/main.js. All this
   does is size the canvas and let the bob take over once the turn is done. */
.op-coins { display: block; }
/* No drop shadow. The prop is a render with its own lighting; a flat black blur under it reads as a
   sticker sitting on the screen, which is the opposite of coming out of the pack. */
.op-coins canvas { display: block; width: min(46vw, 190px); height: auto;
  animation: opBob 2.4s ease-in-out 1s infinite; }
/* The bag is the one prop that is taller than it is wide (304x409 against the coin's 436x438), and
   sizing it by width like the others made it half again as tall as the coin - a payout that arrived
   bigger than the screen expects. Sized by height instead, every prop fills the same box however it
   is shaped. */
.op-coins canvas[data-prop="bags"] { width: auto; height: min(41vw, 170px); }
.op-label { font-family: var(--display); font-size: 30px; color: #fff;
  text-shadow: 0 3px 0 rgba(0,0,0,.5), 0 2px 12px rgba(0,0,0,.65);
  animation: opLabelIn .5s .35s both; }

.op-hint { position: absolute; bottom: max(28px, var(--sab)); left: 0; right: 0; text-align: center;
  font-weight: 900; font-size: 12px; letter-spacing: .18em; color: rgba(255,255,255,.9); min-height: 15px;
  text-shadow: 0 1px 2px rgba(0,0,0,.9), 0 2px 10px rgba(0,0,0,.7); animation: opHint 1.4s ease-in-out infinite; }

@keyframes opDrop { from { transform: translateY(-80vh) rotate(-16deg); opacity: 0; } to { transform: none; opacity: 1; } }
/* Starts and ends on `none` - exactly where opDrop leaves the pack. It used to start 5 px up and
   tilted, so the pack jerked the moment it landed: the "stuck for a moment after landing". */
@keyframes opFloat { 0%, 100% { transform: none; } 25% { transform: translateY(-5px) rotate(-.8deg); }
  75% { transform: translateY(5px) rotate(.8deg); } }
@keyframes opPackOut { from { opacity: 1; transform: scale(1); } to { opacity: 0; transform: scale(1.35); } }
/* Two flashes to the revolution: the pack is edge-on and all but gone a quarter and three quarters
   of the way round, and that is where the light goes. Fast up, fast down and nothing in between. */
@keyframes opSweep {
  0%, 21%   { opacity: 0; translate: -45% 0; }
  25%       { opacity: .9; }
  37%       { opacity: 0; translate: 0 0; }
  71%       { opacity: 0; }
  75%       { opacity: .9; }
  87%, 100% { opacity: 0; translate: 45% 0; }
}
/* Starts the size of the tear and holds its brightness while it grows. Peaking at full brightness
   while still the size of a coin put the whole flash behind the pack, on artwork of the same colour,
   where none of it could be seen — it has to be lit on the way out, not only at the moment it goes. */
/* Out of the mouth, and not by fading in there.
   It starts down at the tear with all but its top edge clipped away, and the clip opens as it
   climbs — so what you watch is the object being drawn up out of the pack rather than a picture
   appearing in front of it. Fading in was the old version, and a fade reads as "arrived", never as
   "came out". --mouth is how far down the pack's tear sits from the middle of the stage. */
@keyframes opRewardIn {
  from { opacity: 1; scale: .62; translate: -50% calc(-50% + var(--mouth, 6vh) + 86px); }
  70%  { scale: 1.06; }
  to   { opacity: 1; scale: 1; translate: -50% -50%; }
}
@keyframes opLabelIn { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
@keyframes opBob { 0%, 100% { transform: translateY(-6px); } 50% { transform: translateY(6px); } }
@keyframes opHint { 0%, 100% { opacity: .5; } 50% { opacity: 1; } }

@media (prefers-reduced-motion: reduce) {
  .opening.waiting .op-stage, .opening.turning .op-sweep,
  .op-coins canvas { animation: none; }
}

/* ---------- stickers ---------- */
/* Sent during a match, bought in the shop. Each one is a looping WebP with a transparent
   background, cut out of a video by tools/ui/sticker.py - so it is an <img>, and it animates
   wherever it is put without a canvas, a sheet or a script. */

/* The lane a sent sticker plays in: the whole match screen, with nothing in it to catch a tap. */
.emote-lane { position: absolute; inset: 0; z-index: 12; pointer-events: none; }
.emote { position: absolute; width: 142px;          /* wide (2:1), and a little smaller than the 168 it was (the user) */
  filter: drop-shadow(0 7px 10px rgba(0,0,0,.55));
  animation: emoteIn .34s cubic-bezier(.2,1.5,.35,1) both; }
/* It goes when its clip has played once (sendSticker adds .leaving), not after a fixed time. */
.emote.leaving { animation: emoteOut .4s ease-in both; }
/* Out of the corner the sender is standing in, the way a taunt comes from a side of the pitch. */
.emote.you { left: 14px; bottom: calc(140px + var(--sab)); transform-origin: left bottom; }
.emote.ai { right: 14px; top: 78px; transform-origin: right top; }
@keyframes emoteIn { from { opacity: 0; transform: scale(.35) rotate(-10deg); } }
@keyframes emoteOut { to { opacity: 0; transform: scale(.86) translateY(-10px); } }

/* The button that opens the tray, over the dock in the corner. */
.emote-btn { position: absolute; left: 16px; bottom: calc(82px + var(--sab));
  z-index: 13; width: 44px; height: 44px; padding: 0; border-radius: 50%; overflow: hidden;
  background: linear-gradient(180deg, #4f9bff, #2b62d4);
  box-shadow: inset 0 0 0 2px rgba(255,255,255,.5), 0 4px 0 -1px rgba(0,0,0,.45),
              0 8px 14px -6px rgba(0,0,0,.8); transition: filter .12s, transform .1s; }
.emote-btn svg { width: 26px; height: 26px; display: block; margin: 9px auto 0; filter: drop-shadow(0 1px 0 rgba(0,0,0,.25)); }
.emote-btn:active { transform: translateY(2px); }
.emote-btn.open { filter: brightness(1.15); }
/* Spent: the cooldown is shown rather than explained, and the button cannot be tapped through it. */
.emote-btn.cooling { filter: grayscale(.8) brightness(.72); pointer-events: none; }
/* Nothing to say while the round is being decided: the result takes the whole screen (z 25) and a
   sticker sent under it would play where nobody can see it. */
#match:has(.cinema:not([hidden])) .emote-btn,
#match:has(.cinema:not([hidden])) .emote-tray { display: none; }

.emote-tray { position: absolute; left: 12px; bottom: calc(134px + var(--sab));
  z-index: 13; display: flex; gap: 8px; padding: 8px; border-radius: 18px;
  background: rgba(8,14,44,.82); backdrop-filter: blur(4px);
  box-shadow: inset 0 0 0 1.5px rgba(255,255,255,.22), 0 12px 22px -12px rgba(0,0,0,.9);
  animation: trayIn .16s ease-out both; }
@keyframes trayIn { from { opacity: 0; transform: translateY(8px) scale(.94); } }
.emote-pick { width: 74px; padding: 4px 3px 5px; border-radius: 14px; display: flex; flex-direction: column;
  align-items: center; gap: 3px; background: rgba(255,255,255,.08); box-shadow: inset 0 0 0 1.5px rgba(255,255,255,.12); }
.emote-pick img { width: 48px; height: 48px; object-fit: contain; display: block; }
.emote-pick .ep-name { max-width: 100%; font-size: 8.5px; font-weight: 800; letter-spacing: .02em; color: #fff;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.emote-empty { margin: 0; padding: 6px 8px; max-width: 220px; font-size: 13px; font-weight: 800; color: #fff; line-height: 1.3; }
.emote-empty small { font-size: 11px; font-weight: 600; opacity: .75; }
.emote-pick:active { transform: translateY(2px); }

/* The bubble the sticker is said from.
   The clip is a cartoon on a white card with a voice on it, and a speech bubble is white - so the
   card IS the bubble's paper and nothing has to be keyed out, which is also how the sound survived
   (a WebP could not have carried it). The tail is a rotated square tucked under the corner, the
   only shape that keeps its shadow on the same side as the bubble's. */
.sk-bubble { position: relative; display: block; width: 100%; padding: 5px; border-radius: 18px;
  background: #fff; box-shadow: inset 0 0 0 2px rgba(20,30,80,.10), 0 4px 10px -4px rgba(0,0,0,.5); }
.sk-bubble::after { content: ""; position: absolute; left: 14px; bottom: -5px; width: 15px; height: 15px;
  background: #fff; border-radius: 3px; transform: rotate(45deg); }
.sk-bubble video { position: relative; z-index: 1; display: block; width: 100%; height: auto;
  border-radius: 14px; background: #fff; }
/* Sent by the other side: the tail points back at them. */
.emote.ai .sk-bubble::after { left: auto; right: 14px; }

/* The shelf in the shop. The cards show the sticker moving, because that is what is being sold. */
.sticker-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 9px; }
.sticker-card { display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 10px 8px 9px; border-radius: var(--r-lg); color: var(--ink);
  background: var(--glass); border: 1px solid var(--glass-line);
  box-shadow: inset 0 1px 0 var(--glass-top), var(--drop); }
.sticker-card.done { opacity: .78; }
.sk-art { display: block; width: 100%; padding: 0 2px 4px; }
.sk-name { font-family: var(--display); font-weight: 400; font-size: 15px; color: var(--ink); max-width: 100%; overflow: hidden; }
/* Stickers are bought with coins, so the gem the buy button wears by default comes off; the price
   carries its own coin, and a free one carries nothing. */
.sticker-card .btn-buy { width: 100%; padding: 7px 0; font-size: 15px; }
.sticker-card .btn-buy::after { display: none; }
.sk-coin { width: 16px; height: 16px; object-fit: contain; vertical-align: -3px; margin-right: 4px; }


/* --- buying a sticker: the dialog --- */
.sticker-panel { align-items: center; text-align: center; }
.sk-preview { display: block; width: min(52vw, 210px); margin: 6px auto 2px; padding: 0; border: 0;
  background: none; cursor: pointer; }
.sk-preview:active { transform: scale(.96); }
.sk-hint { font-size: 12px; opacity: .7; margin-bottom: 8px; }
/* The sticker window's button when you own it: ADD in green, REMOVE in red. */
.btn.btn-add { color: #fff; background: linear-gradient(180deg, #7dea7d, #2fb84a 55%, #22963b); box-shadow: 0 5px 0 #16702a, inset 0 1px 0 rgba(255,255,255,.55);
  text-shadow: 0 2px 0 rgba(10,70,25,.45); }
.btn.btn-remove { color: #fff; background: linear-gradient(180deg, #ff8a8a, #e23b3b 55%, #c12a2a); box-shadow: 0 5px 0 #8e1b1b, inset 0 1px 0 rgba(255,255,255,.5);
  text-shadow: 0 2px 0 rgba(90,10,10,.45); }
#skGo { display: flex; align-items: center; justify-content: center; gap: 8px; }
#skGo .sk-coin { width: 22px; height: 22px; }
/* The shelf's price button, dimmed without `disabled`: a disabled button eats its own tap, and the
   whole card is the way into the dialog now. */
.sticker-card { cursor: pointer; }
.sticker-card .btn-buy.is-off { filter: grayscale(.8) brightness(.92); box-shadow: 0 5px 0 rgba(26,35,82,.25); }
/* The coin and gem balances lead to the shop. */
.wallet .pill { cursor: pointer; transition: transform .1s; }
.wallet .pill:active { transform: scale(.94); }

/* The player's own icon beside their name on the round result. */
.cinema-club .cn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; }
.cine-icon { width: 30px; height: 30px; flex: 0 0 auto; }
@media (max-height: 700px) { .cine-icon { width: 24px; height: 24px; } }

/* The round result's star card: the pack's card frame, sized for two of them on one screen. */
.res-card { width: 108px; flex: 0 0 auto; }
.res-card .op-face { border-radius: 14px; }
.cinema.result .cinema-club:has(.res-tag.won) .res-card .op-face {
  box-shadow: 0 0 0 3px var(--r), 0 0 0 5px rgba(255,255,255,.22), 0 0 30px 2px var(--res), 0 18px 34px -10px rgba(0,0,0,.8); }
@media (max-height: 700px) { .res-card { width: 88px; } }
/* Typing: the field sits on a band of its own over the answers it now covers, rather than floating
   on top of them. */
:root.typing #match .dock { margin-left: -16px; margin-right: -16px; padding: 10px 16px 8px;
  background: linear-gradient(180deg, rgba(8,12,34,.55), rgba(8,12,34,.92) 40%); }
/* Its power already used this match: the star goes grey. */
.res-card.spent .op-face { filter: grayscale(1) brightness(.72); }
/* A star with no art yet (the Professor, the Magician) shows its initials - big enough to read as
   the star's face on a card this size, not a stray letter in the middle of an empty tile. */
.res-card .op-card-art .mono { font-family: var(--display); font-size: 52px; line-height: 1; color: #fff;
  text-shadow: 0 3px 0 rgba(0,0,0,.35); }

/* --- the game's own keyboard --- */
#match { --kbh: 206px; }
.kb { flex: 0 0 var(--kbh); height: var(--kbh); margin: 8px -10px 0; padding: 6px 4px 4px;
  display: grid; grid-template-rows: repeat(4, 1fr); gap: 7px;
  touch-action: manipulation; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none;
  transition: opacity .15s; }
.kb.off { opacity: .45; }
.kb-row { display: flex; gap: 5px; justify-content: center; }
.kb-key { flex: 1 1 0; max-width: 40px; min-width: 0; padding: 0; border: 0; border-radius: 9px;
  font: 800 19px/1 var(--body); color: var(--ink); background: linear-gradient(180deg, #ffffff, #e6ebfb);
  box-shadow: inset 0 -3px 0 #c6cff0, 0 2px 0 rgba(10,16,48,.35); transition: transform .06s, filter .06s; }
.kb-key.down { transform: translateY(2px); filter: brightness(.88); box-shadow: inset 0 -1px 0 #c6cff0, 0 1px 0 rgba(10,16,48,.35); }
.kb-row:nth-child(2) { padding: 0 18px; }
.kb-key.kb-del { flex: 1.5 1 0; max-width: 62px; font-size: 20px; background: linear-gradient(180deg, #d9e0f7, #bfcaee); }
.kb-key.kb-space { flex: 6 1 0; max-width: none; font-size: 14px; letter-spacing: .12em; text-transform: uppercase; }
.kb-key.kb-mark { flex: 1 1 0; max-width: 46px; background: linear-gradient(180deg, #d9e0f7, #bfcaee); }
.kb { position: relative; }
.kb-key.down { background: linear-gradient(180deg, #dfe6ff, #c9d3f5); transition: none; }
/* The letter preview over a pressed key, like a phone keyboard's: the same white key, grown upward
   out of the one under the finger. */
.kb-pop { position: absolute; left: 0; top: 0; z-index: 3; pointer-events: none; width: 52px; height: 62px; margin-left: -26px;
  display: grid; place-items: center; padding-bottom: 8px; border-radius: 12px 12px 14px 14px;
  font: 800 32px/1 var(--body); color: var(--ink);
  background: linear-gradient(180deg, #ffffff, #eef2ff);
  box-shadow: 0 0 0 1px rgba(26,35,82,.12), 0 8px 16px -4px rgba(10,16,48,.55); }
.kb-pop[hidden] { display: none; }
/* The field is a display now: never a caret, never a selection, and the name reads capitalised. */
#answer { caret-color: transparent; text-transform: capitalize; cursor: default; }
/* The sticker button and its tray sit above the keyboard, not on it. */
#match .emote-btn { bottom: calc(82px + var(--kbh) + var(--sab)); }
#match .emote-tray { bottom: calc(134px + var(--kbh) + var(--sab)); }
#match .emote.you { bottom: calc(140px + var(--kbh) + var(--sab)); }

/* The round result's star: its own picture, its own shape, a frame that hugs it. */
.res-frame { display: block; height: 142px; border-radius: 14px; overflow: hidden; line-height: 0;
  box-shadow: 0 0 0 3px var(--r), 0 0 0 5px rgba(255,255,255,.22), 0 14px 28px -10px rgba(0,0,0,.8); }
.cinema-club .res-frame img { display: block; width: auto; height: 100%; object-fit: initial; filter: none; }
.cinema.result .cinema-club:has(.res-tag.won) .res-frame img { filter: none; }
.cinema.result .cinema-club:has(.res-tag.won) .res-frame {
  box-shadow: 0 0 0 3px var(--r), 0 0 0 5px rgba(255,255,255,.22), 0 0 30px 2px var(--res), 0 14px 28px -10px rgba(0,0,0,.8); }
.res-frame.res-mono { width: 106px; display: grid; place-items: center;
  background: linear-gradient(180deg, color-mix(in srgb, var(--c) 60%, #fff), var(--c)); }
.res-frame.res-mono .mono { font-family: var(--display); font-size: 52px; line-height: 1; color: #fff; text-shadow: 0 3px 0 rgba(0,0,0,.35); }
.res-frame.spent { filter: grayscale(1) brightness(.72); }
@media (max-height: 700px) { .res-frame { height: 118px; } .res-frame.res-mono { width: 88px; } }
/* Only a typed name is capitalised; the placeholder reads as written. */
#answer::placeholder { text-transform: none; }

/* A trophy count: the number with the cup beside it. Sized to the text it sits in. */
.tr-ico { height: 1.45em; width: auto; vertical-align: -0.38em; margin-right: 3px;
  filter: drop-shadow(0 2px 3px rgba(20,26,70,.35)); }
.ar-state .tr-ico, .ar-min .tr-ico { height: 1.6em; }

/* --- the match camera: the same render as the in-match backdrop, on a layer that can move --- */
.arena-cam { display: none; position: absolute; inset: -7%; z-index: 0; pointer-events: none;
  background: var(--arena-night, var(--arena, none)) center / cover no-repeat,
    url("../assets/stadium.webp") center / cover no-repeat;
  transform-origin: 50% 50%; will-change: transform; }
#app.in-match.cam .arena-cam { display: block; }
/* While the camera runs it IS the backdrop, so the still one underneath steps aside. */
#app.in-match.cam::before { opacity: 0; }
#app.in-match.cam .arena-fx { transform-origin: 50% 50%; will-change: transform; }
@media (prefers-reduced-motion: reduce) { .arena-cam { display: none !important; } #app.in-match.cam::before { opacity: 1; } }

/* The 360-degree match camera (js/arenaview.js). Its canvas lives in .arena-cam, fills the screen
   exactly (no overscan: it is a camera, not a picture being moved) and replaces the still backdrop
   and the lights layer, which were drawn for the fixed shot and would not line up with a moving one. */
.arena-pano { display: none; width: 100%; height: 100%; }
#app.in-match.pano .arena-cam { display: block; inset: 0; background: none; transform: none; }
#app.in-match.pano .arena-pano { display: block; }
#app.in-match.pano::before { opacity: 0; }
#app.in-match.pano .arena-fx { display: none; }
/* Arena 2's flying camera: a looping video filling the screen, and over it, now and then, the bench
   camera fading in (js/main.js arenaCam flyby). */
.arena-flyby { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: none; }
#app.in-match.flyby .arena-flyby { display: block; }
/* Behind the video, the arena's still in the same light: a phone that drops the video's frame for a
   moment (its decoder taken back under memory pressure, the loop's seam, a stall) showed plain black
   there mid-match (the user, 2026-09-29) - now it shows the ground the video was flying over. */
#app.in-match.flyby .arena-cam { background: var(--arena-night, var(--arena, none)) center / cover no-repeat,
  url("../assets/stadium.webp") center / cover no-repeat; }
/* The bench and the stars over the flying camera's video (js/flyby.js): sized and placed by script
   to the exact box the video is drawn in. */
.flyby-bench { position: absolute; z-index: 1; pointer-events: none; display: none; }
#app.in-match.flyby .flyby-bench { display: block; }
#app.in-match.flyby .arena-pano { position: absolute; inset: 0; z-index: 1; opacity: 0; transition: opacity .6s ease; }
#app.in-match.flyby.cutaway .arena-pano { opacity: 1; }

/* The name bar colour picker: each swatch is a little piece of the bar itself. */
.strip-row { display: grid; grid-template-columns: repeat(5, 1fr); gap: 8px; }
.strip-opt { height: 30px; border-radius: 999px; border: 0;
  background: linear-gradient(180deg, var(--me-a), var(--me-b) 78%, var(--me-c));
  box-shadow: inset 0 1px 0 rgba(255,255,255,.35), 0 3px 0 rgba(20,26,70,.25); }
.strip-opt.on { box-shadow: 0 0 0 3px #fff, 0 0 0 5px var(--ink), 0 3px 0 rgba(20,26,70,.25); }

/* --- the small "!" that opens a star's explanation --- */
.star-i, .slot-i { flex: none; width: 24px; height: 24px; border-radius: 50%; display: grid; place-items: center;
  font: 400 15px/1 var(--display); color: var(--ink); background: #fff; position: relative; z-index: 1;
  box-shadow: 0 2px 0 rgba(10,16,48,.35), inset 0 -2px 0 rgba(26,35,82,.12); }
.star-i:active, .slot-i:active { transform: translateY(1px); }
.slot-i { width: 20px; height: 20px; font-size: 13px; margin-left: auto; }

/* --- home: two stars side by side, from arena 6 --- */
.star-card.duo { gap: 8px; padding: 7px; }
.duo-star { flex: 1 1 0; min-width: 0; display: flex; align-items: center; gap: 7px; padding: 4px 6px 4px 4px;
  border-radius: 14px; background: rgba(8,12,40,.22); position: relative; z-index: 1;
  box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--c) 70%, #fff); }
.duo-star .star-face { width: 38px; height: 38px; font-size: 30px; }
.duo-star.empty { background: rgba(255,255,255,.14); box-shadow: inset 0 0 0 2px rgba(255,255,255,.55); }
.duo-star.empty .star-face { font: 400 26px/1 var(--display); color: #fff; background: rgba(255,255,255,.2); }
.duo-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.duo-txt .star-name { font-size: 15px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.duo-txt .star-power { font-size: 10px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* --- the stars page: a padlock on every card you do not own --- */
/* A locked card is a padlock and nothing else (the user's call: no "IN PACKS" text on it). */
.power-card.locked::after { content: ""; position: absolute; z-index: 4; top: calc(50% - 20px); left: calc(50% - 20px); width: 40px; height: 40px;
  border-radius: 50%; background-color: rgba(10,14,40,.82);
  box-shadow: 0 0 0 2px rgba(255,255,255,.85), 0 3px 6px rgba(0,0,0,.45);
  --lock: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="white" d="M12 2a5 5 0 0 0-5 5v3H6a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8a2 2 0 0 0-2-2h-1V7a5 5 0 0 0-5-5Zm-3 8V7a3 3 0 1 1 6 0v3H9Zm3 4a2 2 0 0 1 1 3.7V19h-2v-1.3A2 2 0 0 1 12 14Z"/></svg>');
  background-image: var(--lock); background-size: 22px 22px; background-position: center; background-repeat: no-repeat; }

/* --- the first-star pick: the lineup on the pitch --- */
.starter-overlay { position: absolute; inset: 0; z-index: 40; overflow: hidden; background: #9fc4ff; animation: fade .3s; }
.lineup { position: absolute; inset: 0; }
.lineup-canvas { display: block; width: 100%; height: 100%; opacity: 0; transition: opacity .6s ease; }
.lineup.on .lineup-canvas { opacity: 1; }
.lineup-top { position: absolute; left: 0; right: 0; top: 0; padding: max(18px, env(safe-area-inset-top)) 18px 26px;
  text-align: center; pointer-events: none;
  background: linear-gradient(180deg, rgba(10,18,60,.55), rgba(10,18,60,0)); }
.lineup-title { font-family: var(--display); font-size: 28px; color: #fff; letter-spacing: .02em;
  text-shadow: 0 3px 0 rgba(6,14,44,.5), 0 0 18px rgba(6,14,44,.45); }
.lineup-top .starter-sub { color: #fff; opacity: .92; margin: 2px 0 0; text-shadow: 0 1px 3px rgba(6,14,44,.8); }
.lineup-tags { position: absolute; inset: 0; pointer-events: none; }
/* A name tag under a star's feet. Invisible until that star has walked on. */
.lineup-tag { position: absolute; left: 0; top: 0; pointer-events: auto; border: 0; display: flex; align-items: center; gap: 4px;
  padding: 3px 7px 3px 3px; border-radius: 999px; opacity: 0; transition: opacity .35s, box-shadow .2s, background .2s;
  color: var(--ink); background: rgba(255,255,255,.92); box-shadow: 0 0 0 2px var(--r), 0 4px 10px rgba(6,14,44,.35); }
.lineup-tag.in { opacity: 1; }
/* A hidden tag must not catch a tap meant for the star standing behind it. */
.lineup-tags:not(.flat) .lineup-tag:not(.in) { pointer-events: none; }
.lineup-tag .starter-art { width: 20px; height: 20px; border-radius: 50%; box-shadow: none; }
.lineup-tag .starter-name { font-size: 10px; white-space: nowrap; max-width: 64px; overflow: hidden; text-overflow: ellipsis; }
.lineup-tag.on { background: linear-gradient(180deg, #fff6cf, #ffe27a); box-shadow: 0 0 0 3px var(--r), 0 0 18px var(--r), 0 4px 10px rgba(6,14,44,.35); }
.starter-art { overflow: hidden; display: grid; place-items: center;
  background: radial-gradient(circle at 50% 35%, color-mix(in srgb, var(--c) 45%, #fff), color-mix(in srgb, var(--c) 70%, #0b1060) 80%); }
.starter-art img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 12%;
  transform: scale(var(--art-zoom, 1)); transform-origin: 50% 0%; }
.starter-name { font-family: var(--display); line-height: 1.1; }
/* No WebGL: the tags become an ordinary row of cards in the middle of the screen. */
.lineup-tags.flat { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; align-content: center; padding: 0 18px; pointer-events: auto; }
.lineup-tags.flat .lineup-tag { position: static; opacity: 1; transform: none !important; flex-direction: column; border-radius: 18px; padding: 10px; }
.lineup-tags.flat .starter-art { width: 80px; height: 96px; border-radius: 14px; }
.lineup-tags.flat .starter-name { font-size: 15px; max-width: none; }
.lineup-bottom { position: absolute; left: 0; right: 0; bottom: 0; padding: 30px 16px max(16px, var(--sab));
  background: linear-gradient(180deg, rgba(10,18,60,0), rgba(10,18,60,.72) 38%); }
.starter-desc { min-height: 2.9em; margin: 0 2px 10px; font-weight: 800; font-size: 14px; color: #fff; text-align: center;
  text-shadow: 0 1px 3px rgba(6,14,44,.8); }
.starter-desc b { color: #ffe27a; }

/* --- one star's explanation --- */
.si-head { display: flex; flex-direction: column; align-items: center; gap: 4px; }
.si-face { width: 84px; height: 84px; border-radius: 20px; overflow: hidden; display: grid; place-items: center; font-size: 30px;
  background: radial-gradient(circle at 50% 35%, color-mix(in srgb, var(--c) 45%, #fff), color-mix(in srgb, var(--c) 70%, #0b1060) 80%);
  box-shadow: 0 0 0 3px var(--c), 0 0 0 6px #fff; margin-bottom: 4px; }
.si-panel .si-face { box-shadow: 0 0 0 3px var(--c), 0 0 0 6px #fff; }
.si-face img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 12%;
  transform: scale(var(--art-zoom, 1)); transform-origin: 50% 0%; }
.si-rarity { font-weight: 900; font-size: 10px; letter-spacing: .12em; text-transform: uppercase; padding: 2px 9px;
  border-radius: 999px; background: var(--c); color: var(--ri, #fff); }
.si-name { font-family: var(--display); font-size: 26px; line-height: 1.05; }
.si-power { font-weight: 900; font-size: 14px; color: var(--ink-2); }
.si-desc { margin: 10px 0 4px; font-weight: 800; font-size: 14px; color: var(--ink); }
.si-tip { margin: 0 0 12px; font-weight: 700; font-size: 12px; color: var(--ink-2); }

/* --- the lineup: the picked star's card over his head, and his power under him --- */
.lineup-card { position: absolute; left: 0; top: 0; pointer-events: none; opacity: 0;
  transition: opacity .3s; will-change: transform; }
.lineup-card.in { opacity: 1; }
.lineup-card .op-card:not(.show) { display: none; }
.lineup-card.in .op-card.show { animation: lcIn .45s cubic-bezier(.2,1.5,.4,1) both; }
@keyframes lcIn { from { transform: translateY(14px) scale(.6); } to { transform: none; } }
.lineup-card .op-card { display: block; width: 86px; }
.lineup-card .op-face { border-radius: 12px; }
.lineup-card .op-card-rar { left: 5px; top: 5px; font-size: 7px; padding: 2px 5px; }
.lineup-card .op-card-name { font-size: 11px; padding: 10px 3px 5px; }
.starter-desc { display: flex; flex-direction: column; align-items: center; gap: 3px; }
.starter-desc.on { margin: 0 6px 12px; padding: 10px 14px 9px; border-radius: 18px;
  background: linear-gradient(180deg, rgba(72,160,236,.95), rgba(34,108,204,.95));
  box-shadow: inset 0 0 0 1.5px rgba(255,255,255,.55), inset 0 2px 0 rgba(255,255,255,.45), 0 8px 18px -8px rgba(10,30,90,.6); }
.sd-power { font-family: var(--display); font-size: 19px; color: #fff; text-shadow: 0 0 12px var(--r), 0 2px 0 rgba(0,0,0,.35); }
.sd-text { font-weight: 800; font-size: 14px; color: #fff; }
.sd-hint { font-weight: 800; font-size: 10px; letter-spacing: .12em; text-transform: uppercase; color: rgba(255,255,255,.8); margin-top: 2px; }
.starter-desc.on .sd-text { text-shadow: 0 1px 2px rgba(10,40,110,.45); }
.starter-desc.on .sd-power { text-shadow: 0 2px 0 rgba(10,40,110,.35); }
.starter-overlay.confirmed .sd-hint { visibility: hidden; }

/* A star you do not own, on the Stars page stage: a padlock over his black silhouette. */
.stage.locked::after { content: ""; position: absolute; left: calc(50% - 29px); top: calc(46% - 29px); z-index: 2; width: 58px; height: 58px;
  border-radius: 50%; pointer-events: none;
  background-color: rgba(10,14,40,.82);
  box-shadow: 0 0 0 3px rgba(255,255,255,.9), 0 8px 18px rgba(0,0,0,.5);
  background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="white" d="M12 2a5 5 0 0 0-5 5v3H6a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8a2 2 0 0 0-2-2h-1V7a5 5 0 0 0-5-5Zm-3 8V7a3 3 0 1 1 6 0v3H9Zm3 4a2 2 0 0 1 1 3.7V19h-2v-1.3A2 2 0 0 1 12 14Z"/></svg>');
  background-size: 30px 30px; background-position: center; background-repeat: no-repeat;
  animation: pop .35s cubic-bezier(.2,1.6,.4,1); }


/* ---------- Kickies: creatures that ride a star (Stars page, third tab) ---------- */
.coll-tab[data-coll="kickies"] { --icon: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill-rule="evenodd" d="M12 2.5a9.5 9.5 0 1 0 0 19 9.5 9.5 0 0 0 0-19Zm0 4.2 3.4 2.5-1.3 4H9.9l-1.3-4L12 6.7Z"/></svg>'); }
.coll-tabs:has(.kickies-only:not([hidden])) .coll-tab { font-size: 15px; }   /* three tabs only with the Kickies on */
.kickie-shop { display: block; }
.kickie-card { position: relative; display: flex; align-items: center; gap: 10px; padding: 12px 12px 12px 8px; border-radius: 18px;
  background: radial-gradient(circle at 50% 28%, color-mix(in srgb, var(--r) 45%, #243a8f), #16266a 72%);
  box-shadow: inset 0 0 0 2px var(--r), inset 0 3px 8px rgba(0,0,0,.35), 0 6px 14px -6px rgba(0,0,0,.6); }
.kickie-card.bought, .ks-row.bought { animation: kc-hop .5s cubic-bezier(.3,1.6,.5,1); }
.kc-body { flex: 1; min-width: 0; display: flex; flex-direction: column; align-items: flex-start; gap: 3px; }
@keyframes kc-hop { 0% { transform: scale(1); } 40% { transform: scale(1.06) translateY(-4px); } 100% { transform: none; } }
.kc-rarity { font-weight: 900; font-size: 8px; letter-spacing: .3px; text-transform: uppercase;
  padding: 2px 6px; border-radius: 5px; background: var(--r); color: var(--ri); box-shadow: 0 2px 0 rgba(0,0,0,.35); }
.kc-art { flex: none; width: 118px; aspect-ratio: 120 / 124; filter: drop-shadow(0 6px 8px rgba(0,0,0,.45)); animation: kc-bob 2.4s ease-in-out infinite; }
@keyframes kc-bob { 0%, 100% { transform: translateY(0) rotate(-2deg); } 50% { transform: translateY(-5px) rotate(2deg); } }
@media (prefers-reduced-motion: reduce) { .kc-art { animation: none; } }
.kc-name { font-family: var(--display); font-size: 19px; color: #fff; text-shadow: 0 2px 0 rgba(0,0,0,.5); line-height: 1.05; }
.kc-power { font-weight: 900; font-size: 10px; letter-spacing: .08em; color: var(--r); }
.kc-desc { font-weight: 700; font-size: 12px; line-height: 1.25; color: rgba(255,255,255,.85); }
.kc-have { font-weight: 900; font-size: 9px; letter-spacing: .06em; color: rgba(255,255,255,.7); margin-top: 2px; }
.kc-have b { color: #fff; font-size: 11px; }
.kc-buy { margin-top: 6px; width: 100%; padding: 8px 4px; font-size: 14px; display: inline-flex; align-items: center; justify-content: center; gap: 2px;
  color: #4a2a00; background: linear-gradient(180deg, #ffe98d, #ffc21a); box-shadow: 0 4px 0 #b86e00, inset 0 2px 0 rgba(255,255,255,.6); }
.kc-buy .sk-coin { width: 16px; height: 16px; margin: 0 3px 0 6px; }
.kc-buy:disabled { filter: grayscale(.8) brightness(.8); font-size: 12px; }
.kickie-stars { display: flex; flex-direction: column; gap: 8px; padding-bottom: 16px; }
.ks-row { display: flex; align-items: center; gap: 10px; padding: 8px 10px 8px 8px; border-radius: 16px; background: #fff;
  box-shadow: 0 4px 0 rgba(0,0,0,.22); }
.ks-row.has { box-shadow: 0 0 0 2px var(--r), 0 4px 0 rgba(0,0,0,.22); }
.ks-face { position: relative; flex: none; width: 46px; height: 46px; border-radius: 12px; overflow: hidden;
  background: radial-gradient(circle at 50% 35%, color-mix(in srgb, var(--c) 45%, #fff), color-mix(in srgb, var(--c) 70%, #0b1060) 75%);
  box-shadow: 0 0 0 2px var(--r); }
.ks-face .portrait { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 50% 12%; }
.ks-face .mono { display: grid; place-items: center; height: 100%; font-family: var(--display); color: #fff; font-size: 16px; }
.ks-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.ks-name { font-family: var(--display); font-size: 15px; color: var(--ink); line-height: 1.05; }
.ks-line { font-weight: 700; font-size: 11px; line-height: 1.25; color: var(--ink-2); }
.ks-line b { font-weight: 900; color: var(--ink); letter-spacing: .02em; }
.ks-picks { flex: none; display: flex; gap: 6px; }
.ks-pick { position: relative; width: 44px; height: 44px; padding: 3px; border: 0; border-radius: 12px; cursor: pointer;
  background: #eef2fb; box-shadow: inset 0 0 0 2px #d5ddef; }
.ks-pick img { width: 100%; height: 100%; object-fit: contain; }
.ks-pick.rare.on { background: #d8ecff; box-shadow: inset 0 0 0 3px #2f8cff, 0 0 12px -2px #2f8cff; }
.ks-pick.legendary.on { background: #fff4c8; box-shadow: inset 0 0 0 3px #ffb300, 0 0 12px -2px #ffc21a; }
.ks-pick:disabled { cursor: default; opacity: .35; filter: grayscale(1); }
.ks-pick:not(:disabled):active { transform: translateY(2px); }
.ks-count { position: absolute; top: -6px; right: -6px; min-width: 17px; height: 17px; padding: 0 4px; border-radius: 9px;
  display: grid; place-items: center; font-weight: 900; font-size: 10px; color: #fff; background: #16266a; box-shadow: 0 2px 0 rgba(0,0,0,.25); }
.ks-on { position: absolute; left: 50%; bottom: -7px; transform: translateX(-50%); font-weight: 900; font-size: 8px; letter-spacing: .06em;
  padding: 1px 5px; border-radius: 6px; background: #19a54a; color: #fff; box-shadow: 0 2px 0 rgba(0,0,0,.25); }
.ks-buy { align-self: flex-start; margin-top: 4px; display: inline-flex; align-items: center; gap: 2px; padding: 3px 9px 3px 7px; border: 0; border-radius: 9px;
  font-weight: 900; font-size: 11px; color: #4a2a00; background: linear-gradient(180deg, #ffe98d, #ffc21a); box-shadow: 0 2px 0 #b86e00; cursor: pointer; }
.ks-buy .sk-coin { width: 13px; height: 13px; margin: 0 2px 0 4px; }
.ks-buy:disabled { filter: grayscale(.8) brightness(.9); cursor: default; }
.ks-buy:not(:disabled):active { transform: translateY(2px); box-shadow: none; }
.ks-none { color: #fff; font-weight: 800; text-align: center; padding: 18px 0; }
/* The Kickie riding a star, in the corner of its card and of its button in a match. */
.power-card .kick-badge { position: absolute; right: -6px; bottom: 22%; z-index: 2; width: 34%; aspect-ratio: 120 / 124;
  filter: drop-shadow(0 3px 3px rgba(0,0,0,.55)); pointer-events: none; }
.ability-btn .ab-kick { position: absolute; left: -8px; top: -9px; z-index: 2; width: 26px; height: 27px;
  filter: drop-shadow(0 2px 2px rgba(0,0,0,.6)); pointer-events: none; }
.ability-btn .ab-kick.two { left: auto; right: -8px; }
.power-card .kick-badge.two { right: auto; left: -6px; }
.ability-btn:has(.ab-kick) { overflow: visible; }
.ability-btn:has(.ab-kick) .portrait { border-radius: inherit; }
.pi-kick { display: flex; align-items: center; gap: 8px; margin: 8px 0 0; padding: 6px 8px; border-radius: 10px; background: rgba(255,255,255,.12);
  font-weight: 700; font-size: 12px; line-height: 1.3; }
.pi-kick img { flex: none; width: 34px; height: 35px; }
.pi-kick b { font-weight: 900; letter-spacing: .04em; }

/* The shop's Kickies: a tile each, the Legendary first. */
.kickie-row { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 9px; padding-bottom: 16px; }
.shop-kickie { display: flex; flex-direction: column; align-items: center; gap: 2px; padding: 8px 6px 8px; border-radius: 16px; text-align: center;
  background: radial-gradient(circle at 50% 30%, color-mix(in srgb, var(--r) 40%, #243a8f), #16266a 75%);
  box-shadow: inset 0 0 0 2px var(--r), 0 6px 12px -6px rgba(0,0,0,.6); }
.shop-kickie.bought { animation: kc-hop .5s cubic-bezier(.3,1.6,.5,1); }
.shop-kickie img { width: 78%; aspect-ratio: 120 / 124; filter: drop-shadow(0 4px 5px rgba(0,0,0,.45)); }
.sk-kname { font-family: var(--display); font-size: 13px; line-height: 1.05; color: #fff; display: grid; place-items: center;
  text-shadow: 0 2px 0 rgba(0,0,0,.5); }
.sk-who { font-weight: 800; font-size: 9px; line-height: 1.2; color: rgba(255,255,255,.72); min-height: 2.4em; }
.sk-have { font-weight: 900; font-size: 10px; color: #fff; }
.sk-kbuy { margin-top: 3px; width: 100%; padding: 5px 0; border: 0; border-radius: 10px; cursor: pointer; display: inline-flex; align-items: center; justify-content: center;
  font-weight: 900; font-size: 12px; color: #073d1c; background: linear-gradient(180deg, #6bf59a, var(--green)); box-shadow: 0 3px 0 var(--green-d); }
.sk-kbuy .sk-coin { width: 13px; height: 13px; margin-right: 3px; }
.sk-kbuy:disabled { filter: grayscale(.8) brightness(.85); cursor: default; }
.sk-kbuy:not(:disabled):active { transform: translateY(2px); box-shadow: none; }
/* Kickie art comes in two shapes (the drawn stand-ins, the user's taller pictures): never stretch one. */
.kc-art, .shop-kickie img, .ks-pick img, .kick-badge, .ab-kick, .pi-kick img { object-fit: contain; }
/* The Rare Kickies' tile is the Time Kickie's own studio backdrop (the user): deep blue at the edges,
   a brighter middle, and a pool of light on the floor under the creature's boots - drawn on the
   image's own box, so it sits under the feet whatever size the tile is. Colours sampled from
   tools/ui/src/kickies/time_src.webp. */
.shop-kickie.rare, .ks-pick.rare {
  background:
    radial-gradient(ellipse 75% 50% at 50% 32%, #2a8aff, rgba(20,112,255,0) 72%),
    linear-gradient(180deg, #0051dd, #0766f3 45%, #0060ee 62%, #0052de); }
.shop-kickie.rare img, .ks-pick.rare img {
  background: radial-gradient(ellipse 48% 9% at 50% 96%, rgba(120,205,255,.9), rgba(40,150,255,0) 100%); }
.ks-pick.rare { box-shadow: inset 0 0 0 2px #0a3fa8; }
.ks-pick.rare.on { background:
    radial-gradient(ellipse 75% 50% at 50% 32%, #2a8aff, rgba(20,112,255,0) 72%),
    linear-gradient(180deg, #0051dd, #0766f3 45%, #0052de);
  box-shadow: inset 0 0 0 3px #ffffff, 0 0 12px -2px #2f8cff; }
.kickies-only[hidden] { display: none !important; }   /* the Kickies are shelved (KICKIES_ON) */
/* The sticker's buy button when the wallet is short: a shake, not a message (the price stays on it). */
#skGo.short, #bpGo.short, #deckUp.short { animation: shake .35s; }
/* The deck's upgrade to eight slots, under it; the price on the gem. */
.deck-up { margin-top: 10px; font-size: 18px; padding: 11px 14px; display: flex; align-items: center; justify-content: center; gap: 10px; }
.deck-up .du-price { display: inline-flex; align-items: center; gap: 4px; padding: 2px 10px 2px 6px; border-radius: 999px;
  background: rgba(8,20,70,.35); }
.deck-up .du-price img { width: 20px; height: 20px; }
.sticker-deck.grown { animation: kc-hop .5s cubic-bezier(.3,1.6,.5,1); }
/* Eight stickers in the match's tray: two rows of four rather than one row off the screen. */
.emote-tray { flex-wrap: wrap; max-width: min(calc(100% - 24px), 344px); }

/* The two new tabs' glyphs: a cup and two people, masks like the rest so the bar stays emoji-free. */
.tabbar button[data-tab="tournaments"] { --icon: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill-rule="evenodd" d="M7 3h10v2h3a1 1 0 0 1 1 1v2a5 5 0 0 1-4.6 5A5 5 0 0 1 13 15.9V18h3a1 1 0 0 1 1 1v2H7v-2a1 1 0 0 1 1-1h3v-2.1A5 5 0 0 1 7.6 13 5 5 0 0 1 3 8V6a1 1 0 0 1 1-1h3V3Zm10 4v4.7A3 3 0 0 0 19 8V7h-2ZM5 7v1a3 3 0 0 0 2 2.7V7H5Z"/></svg>'); }
.tabbar button[data-tab="friends"] { --icon: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8Zm7.5-1a3 3 0 1 0 0-6 3 3 0 0 0 0 6ZM2 19.5C2 16 5 13.5 9 13.5s7 2.5 7 6V21H2v-1.5Zm15.5 1.5h4.5v-1.2c0-2.8-2.2-4.8-5.3-5 1.1 1.2 1.8 2.8 1.8 4.7V21Z"/></svg>'); }
/* Five tabs on a phone, and still big tiles (the user: "too small"): a taller bar, bigger glyphs and
   labels; the columns meet edge to edge, and TOURNAMENTS, the one long word, is set a little tighter. */
.tabbar { gap: 3px; padding: 4px 5px max(4px, var(--sab)); }
.tabbar button { min-width: 0; white-space: nowrap; padding: 8px 0 7px; gap: 4px; border-radius: 13px;
  font-size: 10.5px; letter-spacing: .04em; }
.tabbar button::before { width: 27px; height: 27px; }
.tabbar button[data-tab="tournaments"] { font-size: 9.5px; letter-spacing: 0; }
/* The pages still to come: one card in the game's own panel style. */
.soon-page { padding-top: max(64px, calc(env(safe-area-inset-top) + 52px)); }
.soon-card { margin-top: 14px; display: flex; flex-direction: column; align-items: center; gap: 8px; padding: 26px 20px 22px;
  border-radius: 22px; text-align: center; background: linear-gradient(180deg, #243a8f, #16266a);
  box-shadow: inset 0 0 0 2px rgba(255,210,63,.55), inset 0 3px 8px rgba(0,0,0,.35), 0 10px 22px -10px rgba(0,0,0,.7); }
.soon-icon { width: 76px; height: 76px; background: linear-gradient(180deg, #ffe98d, #ffc21a 55%, #e09a00);
  -webkit-mask: var(--icon) center / contain no-repeat; mask: var(--icon) center / contain no-repeat;
  filter: drop-shadow(0 4px 6px rgba(0,0,0,.5)); }
.soon-trophy { --icon: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill-rule="evenodd" d="M7 3h10v2h3a1 1 0 0 1 1 1v2a5 5 0 0 1-4.6 5A5 5 0 0 1 13 15.9V18h3a1 1 0 0 1 1 1v2H7v-2a1 1 0 0 1 1-1h3v-2.1A5 5 0 0 1 7.6 13 5 5 0 0 1 3 8V6a1 1 0 0 1 1-1h3V3Zm10 4v4.7A3 3 0 0 0 19 8V7h-2ZM5 7v1a3 3 0 0 0 2 2.7V7H5Z"/></svg>'); }
.soon-friends { --icon: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8Zm7.5-1a3 3 0 1 0 0-6 3 3 0 0 0 0 6ZM2 19.5C2 16 5 13.5 9 13.5s7 2.5 7 6V21H2v-1.5Zm15.5 1.5h4.5v-1.2c0-2.8-2.2-4.8-5.3-5 1.1 1.2 1.8 2.8 1.8 4.7V21Z"/></svg>');
  background: linear-gradient(180deg, #9fd2ff, #4a92f2 55%, #2b62d4); }
.soon-title { font-family: var(--display); font-size: 24px; color: #fff; text-shadow: 0 2px 0 rgba(0,0,0,.4); }
.soon-text { font-weight: 700; font-size: 14px; line-height: 1.35; color: rgba(255,255,255,.82); max-width: 280px; }
.soon-chip { margin-top: 6px; padding: 5px 14px; border-radius: 999px; font-weight: 900; font-size: 11px; letter-spacing: .12em;
  color: #3a2600; background: linear-gradient(180deg, #ffe98d, #ffc21a); box-shadow: 0 3px 0 #b86e00; }
/* Arena 4's model a little bigger on the home screen (the user): its tower makes it tall for its width,
   so the height cap drew the court small. Scaled in place - the tile's layout is untouched - and the
   float animation's transform composes with it. */
.arena-hero[data-arena="4"] img { scale: 1.2; }

/* ---------- tournaments (js/main.js renderCups) ----------
   Football arcade (the user: "less blue, more arcade, a football feel"): each cup is a pitch - mown
   stripes (no chalk across it: the user) - the name on a stadium scoreboard, the six stages a chalk
   line of numbered stops, chunky shadows under everything like an arcade cabinet's buttons.
   THE STARTER is a daytime pitch; THE CHAMPIONS a night one under the floodlights, framed in gold. */
.round-label { position: relative; }
.round-label[data-cup]::after { content: attr(data-cup); position: absolute; top: 100%; left: 50%; translate: -50% 5px;
  padding: 3px 9px; border-radius: 999px; font: 900 10px/1 var(--body); letter-spacing: .08em; white-space: nowrap;
  color: #3a2600; background: linear-gradient(180deg, #ffe98d, #ffc21a); box-shadow: 0 2px 0 #b86e00, 0 4px 10px -4px rgba(0,0,0,.6); }
#tournaments { overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; }
.cup-list { flex: 0 0 auto; display: flex; flex-direction: column; gap: 18px; margin-top: 14px; padding-bottom: 14px; }

.cup-card { --g1: #3fae4f; --g2: #36a045; --edge: #fff; --base: #1d6b2a;
  position: relative; isolation: isolate; display: flex; flex-direction: column; gap: 10px; padding: 14px 14px 16px;
  border-radius: 20px; overflow: hidden; border: 3px solid var(--edge);
  background:
    radial-gradient(120% 60% at 50% -10%, rgba(255,255,255,.28), transparent 60%),
    repeating-linear-gradient(90deg, var(--g1) 0 38px, var(--g2) 38px 76px);
  box-shadow: 0 6px 0 var(--base), 0 14px 24px -10px rgba(0,0,0,.75), inset 0 0 0 3px rgba(0,0,0,.12); }
/* THE CHAMPIONS on the user's own background (tools/ui/src/cup_champions_bg_original.png): deep blue,
   glass stars with neon edges, 2CLUBS in outline - the grand night of the game. */
.cup-champions { --edge: #9fd0ff; --base: #0b2a8a;
  background: linear-gradient(180deg, rgba(0,10,60,.15), rgba(0,10,60,.35)), url("../assets/ui/cup_champions_bg.webp?v=1") center / cover no-repeat; }

/* The scoreboard the name is lit on. */
.cup-head { display: flex; align-items: center; gap: 10px; padding: 8px 10px 8px 8px; border-radius: 14px;
  background: linear-gradient(180deg, #1b1f1c, #0b0d0c); border: 2px solid #3a403c;
  box-shadow: 0 4px 0 rgba(0,0,0,.45), inset 0 1px 0 rgba(255,255,255,.08); }
.cup-name { flex: 1; font-family: var(--display); font-size: 20px; line-height: 1.05; letter-spacing: .02em; color: #fff;
  text-shadow: 0 0 10px rgba(255,255,255,.35); }
.cup-champions .cup-name { color: #ffd23f; text-shadow: 0 0 12px rgba(255,210,63,.55); }
.cup-wins { flex: 0 0 auto; padding: 5px 9px; border-radius: 8px; font: 900 11px/1 var(--body); letter-spacing: .06em;
  color: #3a2600; background: linear-gradient(180deg, #ffe98d, #ffc21a); box-shadow: 0 3px 0 #b86e00; }
.cup-blurb { font-weight: 800; font-size: 13px; line-height: 1.3; color: #fff; text-align: center; text-shadow: 0 2px 3px rgba(0,0,0,.5); }

.cup-now { font-weight: 900; font-size: 13.5px; color: #fff; text-align: center; text-shadow: 0 2px 3px rgba(0,0,0,.55); }
.cup-now b { color: #ffe066; }
.cup-prize { display: flex; align-items: center; justify-content: center; gap: 10px; padding: 6px 12px; margin: 0 auto;
  border-radius: 12px; background: rgba(0,0,0,.38); font: 900 11px/1 var(--body); letter-spacing: .1em; color: #ffe066; }
.cup-prize .rw { font-size: 17px; color: #fff; text-shadow: 0 2px 0 rgba(0,0,0,.4); }
/* The arcade buttons: PLAY in gold; ENTER a white match ticket with its price. */
.cup-go { width: 100%; margin: 2px 0 0; white-space: nowrap; font-size: 22px; }
.cup-buy.btn { display: flex; align-items: center; justify-content: center; gap: 8px; color: #1b3a22; text-shadow: none;
  background: linear-gradient(180deg, #ffffff, #e3e8e4); box-shadow: 0 5px 0 #7c8a80, inset 0 1px 0 #fff;
  border: 3px dashed rgba(27,58,34,.35); }
.cup-buy .sk-coin { width: 26px; height: 26px; margin-left: 4px; }
.cup-go.short { animation: shake .35s; }
.cup-locked.btn { font-size: 17px; color: rgba(255,255,255,.85); text-shadow: none;
  background: linear-gradient(180deg, #5b635e, #3d443f); box-shadow: 0 5px 0 #262b28, inset 0 1px 0 rgba(255,255,255,.2); }
/* The cup's own trophy (tools/model/build_trophies.py), turning on the scoreboard. */
.cup-cup { flex: 0 0 auto; width: auto; height: 58px; margin: -9px 0; object-fit: contain; filter: drop-shadow(0 3px 5px rgba(0,0,0,.4)); }

/* The way in to the trophy room: a walnut plaque with a brass edge. */
.tr-open { display: flex; align-items: center; gap: 12px; width: 100%; padding: 10px 14px; border-radius: 16px; text-align: left;
  background: linear-gradient(180deg, #7a4a28, #4e2c15); border: 2px solid #d9a646;
  box-shadow: 0 5px 0 #2e190b, 0 12px 20px -10px rgba(0,0,0,.7), inset 0 1px 0 rgba(255,255,255,.2); color: #fff; }
.tr-open:active { translate: 0 3px; box-shadow: 0 2px 0 #2e190b; }
.tr-open-cup { flex: 0 0 auto; width: auto; height: 54px; margin: -6px 0; object-fit: contain; }
.tr-open-text { flex: 1; display: flex; flex-direction: column; gap: 3px; }
.tr-open-text b { font-family: var(--display); font-weight: 400; font-size: 21px; color: #ffe08a; text-shadow: 0 2px 0 rgba(0,0,0,.4); }
.tr-open-text small { font-weight: 800; font-size: 12px; color: rgba(255,255,255,.8); }
.tr-open-go { width: 12px; height: 12px; border-top: 4px solid #ffe08a; border-right: 4px solid #ffe08a; rotate: 45deg; margin-right: 6px; }

/* The room itself: the cabinet is the whole screen; only the close button floats over it. */
.overlay.trophy-overlay { padding: 0; display: block; background: #2a1a10; }
.tr-stage { position: absolute; inset: 0; }
.tr-stage canvas { display: block; }
.tr-close { position: absolute; z-index: 2; top: max(12px, env(safe-area-inset-top)); right: 12px; width: 42px; height: 42px;
  border-radius: 50%; display: grid; place-items: center; color: #fff; background: rgba(0,0,0,.45);
  box-shadow: inset 0 0 0 2px rgba(255,255,255,.35); }
.tr-close svg { width: 24px; height: 24px; }

/* A tournament on its own screen: the cup's pitch full screen, its trophy, the climb to the final. */
.overlay.cup-overlay { padding: 0; display: block; overflow-y: auto;
  background:
    radial-gradient(120% 50% at 50% -5%, rgba(255,255,255,.25), transparent 60%),
    repeating-linear-gradient(90deg, #3fae4f 0 44px, #36a045 44px 88px); }
.overlay.cup-overlay.cup-champions { background: linear-gradient(180deg, rgba(0,10,60,.1), rgba(0,10,60,.4)), url("../assets/ui/cup_champions_bg.webp?v=1") center / cover no-repeat #0a2bb0; }
.cup-screen { min-height: 100%; display: flex; flex-direction: column; align-items: stretch; gap: 14px;
  padding: max(56px, calc(env(safe-area-inset-top) + 44px)) 18px max(20px, calc(var(--sab) + 12px)); }
.cs-top { display: flex; flex-direction: column; align-items: center; gap: 10px; }
.cs-trophy { height: 150px; width: auto; filter: drop-shadow(0 12px 18px rgba(0,0,0,.55)); }
.cs-board { display: flex; align-items: center; justify-content: center; gap: 10px; width: 100%; padding: 10px 12px; border-radius: 14px;
  background: linear-gradient(180deg, #1b1f1c, #0b0d0c); border: 2px solid #3a403c; box-shadow: 0 4px 0 rgba(0,0,0,.45); }
.cs-board .cup-name { flex: 0 1 auto; text-align: center; font-size: 24px; }
.cup-champions .cs-board .cup-name { color: #ffd23f; text-shadow: 0 0 12px rgba(255,210,63,.55); }
/* The climb: the final at the top, a chalk line down through the stops. */
.cs-ladder { position: relative; display: flex; flex-direction: column; gap: 8px; }
.cs-ladder::before { content: ""; position: absolute; left: 36px; top: 20px; bottom: 20px; border-left: 4px dashed rgba(255,255,255,.7); }
.cs-row { position: relative; display: flex; align-items: center; gap: 12px; padding: 6px 14px 6px 14px; border-radius: 14px;
  background: rgba(0,0,0,.32); box-shadow: inset 0 0 0 1.5px rgba(255,255,255,.18); }
.cs-dot { flex: 0 0 auto; display: grid; place-items: center; width: 44px; height: 44px; border-radius: 50%;
  font: 400 16px/1 var(--display); color: #1b3a22; background: #fff; border: 3px solid #1b3a22; box-shadow: 0 3px 0 rgba(0,0,0,.35); }
.cs-row.final .cs-dot { color: #7a5200; border-color: #b87c00; background: linear-gradient(180deg, #fff6c8, #ffe07a); }
.cs-name { flex: 1; font-family: var(--display); font-size: 19px; color: rgba(255,255,255,.75); text-shadow: 0 2px 0 rgba(0,0,0,.35); }
.cs-state { font: 900 11px/1 var(--body); letter-spacing: .1em; color: #fff; }
.cs-row.done .cs-dot { background: linear-gradient(180deg, #5ef08a, #1fa847); border-color: #0f5a26; }
.cs-row.done .cs-dot::after { content: ""; width: 14px; height: 8px; margin-top: -3px; rotate: -45deg; border-left: 4px solid #fff; border-bottom: 4px solid #fff; }
.cs-row.done .cs-name { color: #fff; }
.cs-row.done .cs-state { color: #7dff9f; }
.cs-row.now { background: rgba(0,0,0,.5); box-shadow: inset 0 0 0 2.5px #ffd23f, 0 0 18px rgba(255,210,63,.35); }
.cs-row.now .cs-dot { color: #3a2600; border-color: #3a2600; background: linear-gradient(180deg, #ffe98d, #ffc21a);
  box-shadow: 0 4px 0 #8a5a00, 0 0 18px rgba(255,210,63,.8); animation: cupPulse 1.6s ease-in-out infinite; }
.cs-row.now .cs-name { color: #ffe066; }
.cs-row.now .cs-state { padding: 5px 9px; border-radius: 8px; color: #3a2600; background: linear-gradient(180deg, #ffe98d, #ffc21a); box-shadow: 0 2px 0 #b86e00; }
.cs-play { width: 100%; white-space: nowrap; font-size: 22px; margin-top: auto; }

/* ---- the cup's bracket (js/main.js cupBracket): a match per stage, stepping down to the trophy ---- */
.cb-scroll { margin: 0 -14px; padding: 4px 14px 2px; overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: none;
  -webkit-overflow-scrolling: touch; }
.cb-scroll::-webkit-scrollbar { display: none; }
.cb-track { display: flex; gap: 18px; width: max-content; padding-bottom: calc(5 * 17px); }
.cb-col { --slot: 30px; position: relative; display: flex; flex-direction: column; align-items: stretch; gap: 4px; width: 104px;
  translate: 0 calc(var(--i) * 17px); }
.cb-stage { font: 900 10.5px/1 var(--body); letter-spacing: .1em; color: rgba(255,255,255,.85); text-align: center; text-shadow: 0 1px 2px rgba(0,0,0,.5); }
.cb-match { position: relative; display: flex; flex-direction: column; gap: 4px; }
/* the bracket's joint: the two slots meet in a bar that runs on to the next stage */
.cb-col:not(.cb-win) .cb-match::after { content: ""; position: absolute; right: -11px; top: calc(var(--slot) / 2); height: calc(var(--slot) + 4px);
  width: 8px; border: 3px solid rgba(255,255,255,.75); border-left: 0; border-radius: 0 6px 6px 0; }
.cb-col:not(.cb-win) .cb-match::before { content: ""; position: absolute; right: -19px; top: calc(var(--slot) + 1px); width: 8px; height: 3px;
  background: rgba(255,255,255,.75); }
.cb-slot { height: var(--slot); display: flex; align-items: center; padding: 0 7px; border-radius: 8px; overflow: hidden;
  background: rgba(0,0,0,.4); box-shadow: inset 0 0 0 1.5px rgba(255,255,255,.2); }
.cb-me { display: flex; align-items: center; gap: 6px; min-width: 0; }
.cb-me .fake-badge { width: 20px; height: 20px; font-size: 6.5px; box-shadow: 0 0 0 1.5px #fff; }
.cb-me b { font-family: var(--display); font-weight: 400; font-size: 14px; color: #fff; letter-spacing: .03em; }
.cb-foe { font: 800 11px/1 var(--body); color: rgba(255,255,255,.55); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  text-decoration: line-through; text-decoration-color: rgba(255,120,120,.8); }
.cb-empty { font: 400 14px/1 var(--display); color: rgba(255,255,255,.45); }
.cb-col.done .cb-slot.top { background: linear-gradient(180deg, #37c763, #1c9a44); box-shadow: inset 0 0 0 1.5px rgba(255,255,255,.4); }
.cb-col.now .cb-slot.top { background: linear-gradient(180deg, #ffe98d, #ffc21a); box-shadow: 0 0 16px rgba(255,210,63,.8), inset 0 0 0 2px #8a5a00; }
.cb-col.now .cb-me b { color: #3a2600; }
.cb-col.now .cb-slot:not(.top) { box-shadow: inset 0 0 0 1.5px rgba(255,210,63,.7); }
.cb-col.next .cb-slot { background: rgba(0,0,0,.25); }
.cb-pay { display: flex; align-items: center; justify-content: center; gap: 3px; font: 900 11.5px/1 var(--body); color: #ffe066;
  text-shadow: 0 1px 2px rgba(0,0,0,.6); }
.cb-pay img { width: 14px; height: 14px; object-fit: contain; }
.cb-col.done .cb-pay { opacity: .55; }
.cb-win { width: 70px; }
.cb-cupbox { height: calc(var(--slot) * 2 + 4px); display: grid; place-items: center; }
.cb-cupbox img { height: 70px; width: auto; filter: drop-shadow(0 4px 8px rgba(0,0,0,.5)) drop-shadow(0 0 12px rgba(255,255,255,.3)); }

/* ---- the cup screen's extras: each stage's pay ---- */
.cs-pay { display: flex; align-items: center; gap: 2px; font: 900 12px/1 var(--body); color: #ffe066; }
.cs-pay img { width: 14px; height: 14px; object-fit: contain; margin-right: 3px; }
@keyframes cupPulse { 50% { box-shadow: 0 4px 0 #8a5a00, 0 0 0 7px rgba(255,210,63,.18), 0 0 30px rgba(255,210,63,.95); } }
/* The cup screen never wider than the phone: the star row scrolls inside it rather than stretching it. */
.cup-screen { width: 100%; max-width: 100%; box-sizing: border-box; }
.cup-screen > * { min-width: 0; max-width: 100%; }

/* Picking a cup match's star on the Stars page: the tab bar steps aside for START GAME. */
#app.cup-pick #tabbar { display: none; }
.cup-start { position: absolute; z-index: 40; left: 0; right: 0; bottom: 0; display: flex; align-items: center; gap: 10px;
  padding: 8px 14px max(10px, var(--sab)); background: linear-gradient(180deg, rgba(10,14,50,0), rgba(10,14,50,.85) 35%); }
.cup-start-back { flex: 0 0 auto; width: 50px; height: 50px; border-radius: 50%; display: grid; place-items: center; color: #fff;
  background: rgba(0,0,0,.45); box-shadow: inset 0 0 0 2px rgba(255,255,255,.35); }
.cup-start-back svg { width: 28px; height: 28px; }
.cup-start-go { flex: 1; white-space: nowrap; font-size: 21px; padding: 13px 12px; }

/* The cards a size down (the user), and the note that more cups are on the way. */
.cup-card { gap: 8px; padding: 11px 12px 12px; }
.cup-head { padding: 6px 10px 6px 8px; }
.cup-name { font-size: 18px; }
.cup-cup { height: 50px; margin: -7px 0; }
.cup-blurb { font-size: 12px; }
.cup-now { font-size: 12.5px; }
.cup-go { font-size: 20px; padding-top: 12px; padding-bottom: 12px; }
.cb-col { --slot: 27px; width: 96px; }
.cup-soon { display: flex; align-items: center; justify-content: center; gap: 10px; padding: 14px 12px; border-radius: 16px;
  border: 2px dashed rgba(255,255,255,.45); background: rgba(10,14,50,.45); color: #fff; }
.cup-soon b { font-family: var(--display); font-weight: 400; font-size: 17px; letter-spacing: .03em; }
.cup-soon-cup { width: 26px; height: 26px; background: rgba(255,255,255,.75);
  -webkit-mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill-rule="evenodd" d="M7 3h10v2h3a1 1 0 0 1 1 1v2a5 5 0 0 1-4.6 5A5 5 0 0 1 13 15.9V18h3a1 1 0 0 1 1 1v2H7v-2a1 1 0 0 1 1-1h3v-2.1A5 5 0 0 1 7.6 13 5 5 0 0 1 3 8V6a1 1 0 0 1 1-1h3V3Zm10 4v4.7A3 3 0 0 0 19 8V7h-2ZM5 7v1a3 3 0 0 0 2 2.7V7H5Z"/></svg>') center / contain no-repeat;
  mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill-rule="evenodd" d="M7 3h10v2h3a1 1 0 0 1 1 1v2a5 5 0 0 1-4.6 5A5 5 0 0 1 13 15.9V18h3a1 1 0 0 1 1 1v2H7v-2a1 1 0 0 1 1-1h3v-2.1A5 5 0 0 1 7.6 13 5 5 0 0 1 3 8V6a1 1 0 0 1 1-1h3V3Zm10 4v4.7A3 3 0 0 0 19 8V7h-2ZM5 7v1a3 3 0 0 0 2 2.7V7H5Z"/></svg>') center / contain no-repeat; }

/* ============ tournaments, the quiet version (the user, 2026-09-30: "the name and the trophy not in a box,
   no yellow in these tiles - more luxurious, more crafted, less AI") ============
   White and silver only, fine hairlines instead of chunky arcade edges, the name set like a title on
   the card itself. Later rules, same selectors: they override the arcade look above. */
.cup-card { border: 1px solid rgba(255,255,255,.35); border-radius: 18px;
  box-shadow: 0 18px 30px -16px rgba(0,0,0,.8), inset 0 1px 0 rgba(255,255,255,.25); }
/* THE STARTER on the user's own picture (2026-10-01, tools/ui/src/cup_starter_bg_original.png): Starboy,
   The Wall and the Ninja Turtle on the ball - darkened top and bottom so the name and the buttons read. */
.cup-starter { background:
    linear-gradient(180deg, rgba(0,12,30,.55), rgba(0,12,30,.18) 30%, rgba(0,12,30,.25) 60%, rgba(0,12,30,.7)),
    url("../assets/ui/cup_starter_bg.webp?v=1") center 30% / cover no-repeat, #1f7a37; }
.cup-champions { border-color: rgba(200,220,255,.45); }
.cup-head { background: none; border: 0; box-shadow: none; padding: 2px 2px 0; gap: 12px; }
.cup-name, .cup-champions .cup-name { font-size: 19px; letter-spacing: .06em; color: #fff; text-shadow: 0 2px 10px rgba(0,0,0,.45); }
.cup-wins { background: none; color: #fff; box-shadow: inset 0 0 0 1px rgba(255,255,255,.7); border-radius: 999px;
  font-size: 10px; letter-spacing: .12em; padding: 5px 9px; }
.cup-blurb { font-weight: 700; color: rgba(255,255,255,.78); text-shadow: 0 1px 3px rgba(0,0,0,.4); }
.cup-now { font-weight: 800; color: rgba(255,255,255,.85); }
.cup-now b { color: #fff; }
.cup-prize { background: none; color: rgba(255,255,255,.65); letter-spacing: .16em; padding: 0; }
.cup-prize .rw { color: #fff; }
/* the bracket: white on glass - YOU in solid white, stages won a quiet green tick */
.cb-track { padding-bottom: calc(5 * 9px); }
.cb-col { translate: 0 calc(var(--i) * 9px); }
.cb-stage { color: rgba(255,255,255,.7); letter-spacing: .14em; }
.cb-slot { background: rgba(0,0,0,.28); box-shadow: inset 0 0 0 1px rgba(255,255,255,.16); border-radius: 7px; }
.cb-col.now .cb-slot.top { background: #fff; box-shadow: 0 6px 16px -6px rgba(0,0,0,.6); }
.cb-col.now .cb-me b { color: #13203f; }
.cb-col.now .cb-slot:not(.top) { box-shadow: inset 0 0 0 1px rgba(255,255,255,.55); }
.cb-col.done .cb-slot.top { background: rgba(255,255,255,.16); box-shadow: inset 0 0 0 1px rgba(255,255,255,.35); }
.cb-col.done .cb-me b::after { content: ""; display: inline-block; width: 9px; height: 5px; margin: 0 0 3px 6px; rotate: -45deg;
  border-left: 2.5px solid #7dffa4; border-bottom: 2.5px solid #7dffa4; }
.cb-col:not(.cb-win) .cb-match::after { border-color: rgba(255,255,255,.45); border-width: 2px; }
.cb-col:not(.cb-win) .cb-match::before { background: rgba(255,255,255,.45); height: 2px; }
.cb-pay { color: rgba(255,255,255,.8); font-weight: 800; }
/* the buttons: solid white to open a cup, clear glass to buy in */
.btn.cup-open { color: #13203f; text-shadow: none; background: linear-gradient(180deg, #ffffff, #e4e9f2);
  box-shadow: 0 10px 20px -10px rgba(0,0,0,.7), inset 0 -2px 0 rgba(19,32,63,.12); border: 0; }
.cup-buy.btn { color: #fff; background: rgba(255,255,255,.12); border: 1px solid rgba(255,255,255,.7);
  box-shadow: 0 10px 20px -12px rgba(0,0,0,.7); backdrop-filter: blur(4px); }
.cup-locked.btn { background: rgba(0,0,0,.35); box-shadow: inset 0 0 0 1px rgba(255,255,255,.22); color: rgba(255,255,255,.7); }
/* the way into the trophy room: walnut and silver, no gold */
.tr-open { border: 1px solid rgba(255,255,255,.28); background: linear-gradient(180deg, #5a3a24, #3a2415);
  box-shadow: 0 16px 26px -16px rgba(0,0,0,.85), inset 0 1px 0 rgba(255,255,255,.18); }
.tr-open-text b { color: #fff; letter-spacing: .05em; }
.tr-open-go { border-color: rgba(255,255,255,.85); }
.cup-soon { border: 1px solid rgba(255,255,255,.3); border-style: dashed; }
/* the cup's own screen, in the same key */
.cs-board { background: none; border: 0; box-shadow: none; padding: 0; }
.cs-board .cup-name, .cup-champions .cs-board .cup-name { font-size: 25px; color: #fff; text-shadow: 0 3px 14px rgba(0,0,0,.5); }
.cs-row { background: rgba(0,0,0,.26); box-shadow: inset 0 0 0 1px rgba(255,255,255,.14); }
.cs-dot, .cs-row.final .cs-dot { color: #13203f; background: #fff; border: 0; box-shadow: none; }
.cs-row.now { background: rgba(255,255,255,.14); box-shadow: inset 0 0 0 1.5px rgba(255,255,255,.85); }
.cs-row.now .cs-dot { background: #fff; box-shadow: 0 0 0 4px rgba(255,255,255,.25); animation: none; }
.cs-row.now .cs-name { color: #fff; }
.cs-row.now .cs-state { color: #13203f; background: #fff; box-shadow: none; }
.cs-row.done .cs-dot { background: rgba(255,255,255,.2); }
.cs-row.done .cs-dot::after { border-color: #7dffa4; }
.cs-row.done .cs-state { color: #7dffa4; }
.cs-pay { color: rgba(255,255,255,.85); }
.cs-ladder::before { border-left: 2px dashed rgba(255,255,255,.45); }

.tr-empty { position: absolute; z-index: 1; left: 0; right: 0; top: 24%; display: flex; flex-direction: column; align-items: center; gap: 8px;
  pointer-events: none; font-family: var(--display); font-size: 30px; letter-spacing: .08em; color: rgba(255,255,255,.9);
  text-shadow: 0 3px 14px rgba(0,0,0,.6); }
.tr-empty small { font-family: var(--body); font-weight: 800; font-size: 13px; letter-spacing: .02em; color: rgba(255,255,255,.65); }

/* A sticker's rarity (config stickerRarity): the Clash Royale emote frame the user pointed at - a white
   card with a strong black line round it, in a gradient ring of the rarity's colours (a transparent
   border painted by the background's border-box layer), lit by a glow of the ring's two ends. */
.sticker-card .sk-bubble, #skPreview .sk-bubble, .coll-sticker .cs-art, .deck-slot.filled, .emote-pick {
  border: 4px solid transparent; border-radius: 16px;
  background: linear-gradient(#fff, #fff) padding-box, var(--ring) border-box;
  box-shadow: inset 0 0 0 2.5px #15171d, -3px 0 12px -2px var(--g1), 3px 0 12px -2px var(--g2), 0 0 22px -6px var(--g2);
  animation: skRing 2.8s ease-in-out infinite; }
.sticker-card .sk-bubble::after, #skPreview .sk-bubble::after { display: none; }     /* no speech-bubble tail in a frame */
.emote-pick .ep-name { color: #15171d; }
.coll-sticker.locked .cs-art { animation: none; box-shadow: inset 0 0 0 2.5px #15171d; opacity: .9;
  background: linear-gradient(#fff, #fff) padding-box, linear-gradient(135deg, #b8bec9, #8a919e) border-box; }
@keyframes skRing { 50% { box-shadow: inset 0 0 0 2.5px #15171d, -4px 0 16px -1px var(--g1), 4px 0 16px -1px var(--g2), 0 0 28px -4px var(--g2); } }
/* The collection's picture frame stays square whatever the picture (RED CARD's tall still stretched it
   and its whole row), and the rarity sits in the frame's top corner, clear of the name. */
.coll-sticker .cs-art { min-height: 0; overflow: hidden; }
.coll-sticker .cs-art img { display: block; min-height: 0; }
.cb-me .cb-icon { flex: 0 0 auto; width: 20px; height: 20px; box-shadow: 0 0 0 1.5px rgba(255,255,255,.8); }
/* The deck's slots carry the picture only (the user: no name under it), so no room is kept for one. */
.deck-slot.filled { padding: 5px; }

/* The sticker card: a wider rounded card (the Clash shape), the character kept whole INSIDE it - the user:
   "the character must not come out of its box". */
.coll-sticker .cs-art { position: relative; aspect-ratio: 1.18 / 1; overflow: hidden; border-radius: 14px; }
.coll-sticker .cs-art img { position: absolute; inset: 4px; width: calc(100% - 8px); height: calc(100% - 8px);
  object-fit: contain; object-position: 50% 100%; }
.deck-slot { aspect-ratio: 1.18 / 1; }
.deck-slot.filled { overflow: hidden; border-radius: 14px; }
.deck-slot.filled img { position: absolute; inset: 4px; width: calc(100% - 8px); height: calc(100% - 8px);
  object-fit: contain; object-position: 50% 100%; }
.emote-pick { overflow: hidden; }
.emote-pick img { object-position: 50% 100%; }

/* ---- the cup's own screen, dressed up (the user: "more festive and cool; the background the next arena") ---- */
.overlay.cup-overlay, .overlay.cup-overlay.cup-champions {
  background: linear-gradient(180deg, rgba(6,10,28,.25) 0%, rgba(6,10,28,.55) 45%, rgba(6,10,28,.88) 100%),
    var(--venue, none) center / cover no-repeat, #0b1a36; }
.cup-screen { position: relative; isolation: isolate; }
.cs-beams, .cs-confetti { position: absolute; inset: 0; z-index: -1; pointer-events: none; overflow: hidden; }
.cs-beams i { position: absolute; top: -10%; width: 60%; height: 80%; opacity: .55;
  background: conic-gradient(from 180deg at 50% 0%, transparent 0 172deg, rgba(255,255,255,.55) 180deg, transparent 188deg 360deg);
  filter: blur(6px); transform-origin: 50% 0%; animation: csBeam 7s ease-in-out infinite alternate; }
.cs-beams i:first-child { left: -8%; }
.cs-beams i:last-child { right: -8%; animation-delay: -3.5s; animation-direction: alternate-reverse; }
@keyframes csBeam { from { rotate: -24deg; } to { rotate: 24deg; } }
.cs-confetti { perspective: 700px; }
.cs-confetti i { position: absolute; top: -6%; left: var(--x); width: var(--w); height: var(--h);
  animation: csFall var(--d) linear var(--dl) infinite, csSway var(--s) ease-in-out var(--dl) infinite alternate; }
.cs-confetti i b { display: block; width: 100%; height: 100%; border-radius: 1px; transform-style: preserve-3d;
  background: linear-gradient(115deg, var(--c1, #f4f6fa) 0 40%, #fff 50%, var(--c1, #f4f6fa) 60% 100%);
  animation: csFlip var(--f) linear var(--dl) infinite; opacity: .92; }
.cs-confetti i:nth-child(3n) b { --c1: var(--cup-accent, #9fd0ff); }
.cs-confetti i:nth-child(5n) b { --c1: #c9ced8; }
.cs-confetti i.far { filter: blur(.7px); opacity: .55; }
@keyframes csFall { from { transform: translateY(0); } to { transform: translateY(108vh); } }
@keyframes csSway { from { translate: calc(var(--sx) * -1) 0; } to { translate: var(--sx) 0; } }
@keyframes csFlip { from { transform: rotate3d(var(--ax), var(--ay), .3, 0deg); } to { transform: rotate3d(var(--ax), var(--ay), .3, 360deg); } }
.cs-row.now { overflow: hidden; }
.cs-row.now::after { content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(100deg, transparent 30%, rgba(255,255,255,.28) 50%, transparent 70%);
  translate: -100% 0; animation: csSheen 2.8s ease-in-out infinite; }
@keyframes csSheen { 60%, 100% { translate: 100% 0; } }
.cs-play { animation: csPulse 1.8s ease-in-out infinite; }
@keyframes csPulse { 50% { transform: scale(1.03); box-shadow: 0 14px 28px -10px rgba(0,0,0,.7), 0 0 0 6px rgba(255,255,255,.18); } }
@media (prefers-reduced-motion: reduce) { .cs-beams i, .cs-confetti i, .cs-row.now::after, .cs-play { animation: none; } }
.cs-name { font-size: 17px; white-space: nowrap; }

/* The ladder's words with a bit more life (the user): WON! as a green stamp, a little askew; UP NEXT as
   a white tag in the display face that gives a small hop now and then. */
.cs-state { font-family: var(--display); font-weight: 400; font-size: 13px; letter-spacing: .06em; }
.cs-row.done .cs-state { padding: 3px 8px; border-radius: 7px; color: #7dffa4; rotate: -6deg;
  box-shadow: inset 0 0 0 2px #7dffa4, 0 0 12px -2px rgba(125,255,164,.6); text-shadow: 0 0 8px rgba(125,255,164,.6); }
.cs-row.now .cs-state { padding: 6px 10px; font-size: 14px; animation: csHop 2.2s ease-in-out infinite; }
@keyframes csHop { 0%, 70%, 100% { transform: translateY(0); } 80% { transform: translateY(-4px) scale(1.06); } 90% { transform: translateY(0); } }
@media (prefers-reduced-motion: reduce) { .cs-row.now .cs-state { animation: none; } }
.cup-starter { --cup-accent: #c98c5a; }
.cup-champions { --cup-accent: #8fc4ff; }
@media (prefers-reduced-motion: reduce) { .cs-confetti i b { animation: none; } }
/* No shadow or glow on the crests while the reel spins (the user: "a square round the clubs"): the
   window crops its strip to a 128 px square, and each crest's glow (26 px of blue) was cut off at the
   window's edges - on a phone, where the strip is its own layer, that drew a visible square. The crest
   that lands gets its glow back with the spotlight. */
.cinema-club .reel-strip img, .cinema-club .reel-strip img:not(.cine-flag) { filter: none; }

/* The reel's painted cells (reelCell): the same size as the pictures they stand in for. */
.cinema-club .reel-strip canvas.reel-cv { display: block; flex: none; width: var(--reel-h); height: var(--reel-h); }
.cinema-club .reel-strip canvas.reel-cv.cine-flag { width: 150px; height: var(--reel-h); border-radius: 10px; }

/* ---- the cup's screen as an occasion (the user, 2026-09-30: "more exciting, festive") ----
   A brighter stadium behind; the trophy lit from behind by a soft halo and slow-turning rays, floating;
   fireworks in the sky (cupFireworks, js/main.js); and a walk in each time the screen opens - the trophy
   drops in, the title shines, the stages climb in from round 1, each WON! stamped as it lands, and a lit
   line runs up the ladder to the stage you are on. */
.overlay.cup-overlay, .overlay.cup-overlay.cup-champions {
  background: radial-gradient(90% 38% at 50% 12%, color-mix(in srgb, var(--cup-accent, #9fd0ff) 22%, transparent), transparent 70%),
    radial-gradient(130% 60% at 50% 22%, transparent 45%, rgba(6,10,28,.5) 100%),
    linear-gradient(180deg, rgba(6,10,28,.08) 0%, rgba(6,10,28,.42) 45%, rgba(6,10,28,.86) 100%),
    var(--venue, none) center / cover no-repeat, #0b1a36; }
.cs-fireworks { position: absolute; inset: 0; width: 100%; height: 100%; z-index: -1; pointer-events: none; }
.cs-trophy-wrap { position: relative; display: grid; place-items: center; width: 220px; height: 170px; }
.cs-trophy-wrap .cs-trophy { position: relative; z-index: 1; animation: csFloat 4.5s ease-in-out infinite; }
.cs-halo { position: absolute; inset: -30px; border-radius: 50%; pointer-events: none;
  background: radial-gradient(closest-side, rgba(255,246,220,.55), color-mix(in srgb, var(--cup-accent, #9fd0ff) 30%, transparent) 45%, transparent 75%); }
.cs-rays { position: absolute; left: 50%; top: 50%; width: 360px; height: 360px; margin: -180px 0 0 -180px; pointer-events: none; opacity: .5;
  background: repeating-conic-gradient(from 0deg, rgba(255,255,255,.34) 0 5deg, transparent 5deg 22deg);
  -webkit-mask: radial-gradient(closest-side, #000 20%, transparent 100%); mask: radial-gradient(closest-side, #000 20%, transparent 100%);
  animation: csRays 40s linear infinite; }
@keyframes csRays { to { rotate: 360deg; } }
@keyframes csFloat { 50% { translate: 0 -6px; } }
/* the title in metal, with a shine going over it now and then */
.cs-board .cup-name, .cup-champions .cs-board .cup-name { font-size: 27px; color: transparent; letter-spacing: .02em;
  background: linear-gradient(100deg, #fff 0 40%, color-mix(in srgb, var(--cup-accent, #9fd0ff) 55%, #fff) 48%, #fff 52%, #fff 100%) 0 0 / 260% 100%;
  -webkit-background-clip: text; background-clip: text; filter: drop-shadow(0 3px 10px rgba(0,0,0,.55));
  animation: csTitleShine 5s ease-in-out 1.2s infinite; }
@keyframes csTitleShine { 0% { background-position: 100% 0; } 35%, 100% { background-position: 0 0; } }
/* the walk in */
.cs-enter .cs-trophy-wrap { animation: csDrop .7s cubic-bezier(.2, 1.5, .4, 1) both; }
.cs-enter .cs-halo, .cs-enter .cs-rays { animation: csHaloIn 1.1s ease-out .25s both, csRays 40s linear infinite; }
.cs-enter .cs-halo { animation: csHaloIn 1.1s ease-out .25s both; }
.cs-enter .cs-board { animation: csTitleIn .5s cubic-bezier(.2, 1.4, .4, 1) .35s both; }
.cs-enter .cs-play { animation: csRowIn .45s cubic-bezier(.2, 1.3, .4, 1) 1.35s both, csPulse 1.8s ease-in-out 1.8s infinite; }
@keyframes csDrop { from { opacity: 0; transform: translateY(-60px) scale(.7); } }
@keyframes csHaloIn { from { opacity: 0; transform: scale(.4); } }
@keyframes csTitleIn { from { opacity: 0; transform: scale(1.6); } }
@keyframes csRowIn { from { opacity: 0; transform: translateY(26px) scale(.96); } }
@keyframes csStamp { from { opacity: 0; transform: scale(2.4); } 70% { opacity: 1; transform: scale(.92); } }
@media (prefers-reduced-motion: reduce) {
  .cs-rays, .cs-trophy-wrap .cs-trophy, .cs-board .cup-name, .cs-enter .cs-trophy-wrap, .cs-enter .cs-halo, .cs-enter .cs-rays,
  .cs-enter .cs-board, .cs-enter .cs-play { animation: none; } }



/* ---- the cup's screen: the stage you are on, in detail; the whole draw a tap away (the user, 2026-09-30) ---- */
/* Stage badges as game badges, not app circles ("QF, SF... too much like an app"): a bevelled metal shield
   - its rim (i) and its face (b) - the letters cut in the display face and outlined. Steel for stages to
   come, gold and red and glowing for the one you are on, green with a tick for those won, and the final's
   shield holds the tournament's own trophy. */
.cup-screen .cs-dot { position: relative; display: block; flex: 0 0 auto; width: 46px; height: 52px; border: 0; border-radius: 0; background: none;
  box-shadow: none; animation: none; filter: drop-shadow(0 3px 0 rgba(0,0,0,.45)) drop-shadow(0 6px 8px rgba(0,0,0,.4)); }
.cup-screen .cs-dot i, .cup-screen .cs-dot b { position: absolute; clip-path: polygon(50% 0%, 97% 13%, 93% 60%, 50% 100%, 7% 60%, 3% 13%); }
.cup-screen .cs-dot i { inset: 0; background: linear-gradient(160deg, #eef2fa 0%, #9aa5bb 38%, #5a6479 62%, #c6cedd 100%); }
.cup-screen .cs-dot b { inset: 3px 3px 4px; display: grid; place-items: center; padding-bottom: 5px;
  background: radial-gradient(120% 70% at 50% 0%, rgba(255,255,255,.22), transparent 55%), linear-gradient(180deg, #34415f, #141b30);
  font: 400 18px/1 var(--display); letter-spacing: .02em; color: #f2f5ff; -webkit-text-stroke: 1px rgba(0,0,0,.55); text-shadow: 0 2px 0 rgba(0,0,0,.6); }
.cup-screen .cs-dot b img { width: 62%; height: 62%; object-fit: contain; margin-top: 2px; filter: drop-shadow(0 2px 2px rgba(0,0,0,.6)); }
.cup-screen .cs-dot.now { filter: drop-shadow(0 3px 0 rgba(0,0,0,.45)) drop-shadow(0 0 10px rgba(255,205,80,.75)); }
.cup-screen .cs-dot.now i, .cup-screen .cs-dot.final i { background: linear-gradient(160deg, #fff6c9 0%, #f1c24a 35%, #a86c0c 62%, #ffe28a 100%); }
.cup-screen .cs-dot.now b { color: #fff; background: radial-gradient(120% 70% at 50% 0%, rgba(255,255,255,.3), transparent 55%), linear-gradient(180deg, #c8321e, #6d130b); }
.cup-screen .cs-dot.final:not(.now) b { background: radial-gradient(120% 70% at 50% 0%, rgba(255,255,255,.22), transparent 55%), linear-gradient(180deg, #2b2a3f, #121226); }
.cup-screen .cs-dot.done i { background: linear-gradient(160deg, #eafff0 0%, #8fe3a8 35%, #2c8a4b 62%, #b9f5cb 100%); }
.cup-screen .cs-dot.done b { background: radial-gradient(120% 70% at 50% 0%, rgba(255,255,255,.28), transparent 55%), linear-gradient(180deg, #2fbf62, #0f6a2e); }
.cup-screen .cs-dot.done::after { content: ""; position: absolute; left: 50%; top: 44%; width: 15px; height: 8px; margin: -6px 0 0 -8px; rotate: -45deg;
  border-left: 4px solid #fff; border-bottom: 4px solid #fff; filter: drop-shadow(0 1px 0 rgba(0,0,0,.4)); }

/* the road: six small shields on a line, lit up to where you are */
.cs-strip { position: relative; display: flex; justify-content: space-between; align-items: center; padding: 0 4px; }
.cs-strip::before { content: ""; position: absolute; left: 24px; right: 24px; top: 50%; height: 3px; margin-top: -2px; border-radius: 2px; background: rgba(255,255,255,.28); }
.cs-strip::after { content: ""; position: absolute; left: 24px; top: 50%; height: 5px; margin-top: -3px; border-radius: 3px;
  width: calc((100% - 48px) * var(--done) / 5); background: linear-gradient(90deg, #7dffa4, #fff);
  box-shadow: 0 0 10px rgba(125,255,164,.8); transform-origin: 0 50%; }
.cs-strip .cs-dot { z-index: 1; width: 34px; height: 38px; }
.cs-strip .cs-dot b { font-size: 13px; padding-bottom: 4px; }
.cs-strip .cs-dot.done::after { width: 11px; height: 6px; border-width: 3px; margin: -5px 0 0 -6px; }
.cs-strip .cs-dot.now { animation: csBadge 1.8s ease-in-out infinite; }
@keyframes csBadge { 50% { transform: scale(1.12); } }

/* the stage: its big shield, its name, which of the six */
.cs-stage { display: flex; flex-direction: column; align-items: center; gap: 2px; margin-top: 2px; }
.cs-stage-badge .cs-dot { width: 74px; height: 84px; }
.cs-stage-badge .cs-dot b { font-size: 30px; padding-bottom: 8px; -webkit-text-stroke: 1.5px rgba(0,0,0,.55); }
.cs-stage-badge .cs-dot.now { animation: csBadge 1.8s ease-in-out infinite; }
.cs-stage-name { font: 400 32px/1 var(--display); color: #fff; letter-spacing: .02em; margin-top: 6px;
  -webkit-text-stroke: 1.5px rgba(0,0,0,.45); text-shadow: 0 3px 0 rgba(0,0,0,.55), 0 0 22px rgba(255,205,80,.35); }
.cs-stage-sub { font: 900 11px/1 var(--body); letter-spacing: .22em; color: rgba(255,255,255,.7); }

/* where, when, how long */
.cs-facts { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }
.cs-facts span { display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 8px 4px; border-radius: 12px; min-width: 0;
  background: rgba(0,0,0,.34); box-shadow: inset 0 0 0 1px rgba(255,255,255,.12); font: 900 9px/1 var(--body); letter-spacing: .18em; color: rgba(255,255,255,.6); }
.cs-facts b { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font: 400 14px/1 var(--display); letter-spacing: .02em; color: #fff; }

/* what it pays */
.cs-prize { display: flex; align-items: center; justify-content: center; gap: 12px; }
.cs-prize-label { font: 900 11px/1 var(--body); letter-spacing: .22em; color: rgba(255,255,255,.7); }
.cs-prize-val { display: flex; align-items: center; gap: 3px; font: 400 26px/1 var(--display); color: #fff; text-shadow: 0 2px 0 rgba(0,0,0,.6); }
.cs-prize-val img { width: 24px; height: 24px; object-fit: contain; margin-right: 4px; }

.cs-actions { display: flex; flex-direction: column; gap: 10px; margin-top: auto; }

/* the walk in: the road lights up badge by badge, then the stage lands */
.cs-enter .cs-strip .cs-dot { animation: csPop .4s cubic-bezier(.2, 1.6, .4, 1) calc(.45s + var(--k, 0) * .09s) both; }
.cs-enter .cs-strip .cs-dot.now { animation: csPop .4s cubic-bezier(.2, 1.6, .4, 1) calc(.45s + var(--k, 0) * .09s) both, csBadge 1.8s ease-in-out 1.4s infinite; }
.cs-enter .cs-strip::after { animation: csFill .7s ease-out .5s both; }
.cs-enter .cs-stage { animation: csTitleIn .55s cubic-bezier(.2, 1.4, .4, 1) .9s both; }
.cs-enter .cs-facts, .cs-enter .cs-prize { animation: csRowIn .45s cubic-bezier(.2, 1.3, .4, 1) 1.2s both; }
.cs-enter .cs-actions { animation: csRowIn .45s cubic-bezier(.2, 1.3, .4, 1) 1.3s both; }
@keyframes csPop { from { opacity: 0; transform: scale(.3); } }
@keyframes csFill { from { transform: scaleX(0); } }
.cs-enter .cs-play { animation: csPulse 1.8s ease-in-out 1.8s infinite; }

@media (prefers-reduced-motion: reduce) {
  .cs-strip .cs-dot.now, .cs-stage-badge .cs-dot.now, .cs-enter .cs-strip .cs-dot, .cs-enter .cs-strip::after, .cs-enter .cs-stage,
  .cs-enter .cs-facts, .cs-enter .cs-prize, .cs-enter .cs-actions { animation: none; } }
/* the whole screen on one phone screen, with the stage card in it: a slightly smaller trophy */
.cup-screen .cs-trophy-wrap { height: 146px; }
.cup-screen .cs-trophy-wrap .cs-trophy { height: 132px; }
.cup-screen { gap: 12px; }
/* The star's rarity, back on the Stars page where its power is explained (the user, 2026-09-30) - the
   one place it is named, in its own colours; the cards and the name under the stage stay without it. */
.pi-top .tags .tag.rar { color: var(--ri); background: var(--r); box-shadow: 0 2px 0 rgba(0,0,0,.25), inset 0 1px 0 rgba(255,255,255,.45); }

/* The stage as a 3D shield (js/stagebadge.js): a canvas the size of a big badge, a soft light behind it */
.cs-stage-badge { position: relative; display: grid; place-items: center; }
.cs-stage-badge::before { content: ""; position: absolute; inset: -18px -40px; border-radius: 50%; pointer-events: none;
  background: radial-gradient(closest-side, rgba(255,215,110,.38), transparent 75%); }
.cs-badge3d { position: relative; display: block; width: 176px; height: 196px; }
.cs-stage-badge .cs-dot { width: 110px; height: 124px; }
.cs-stage-badge .cs-dot b { font-size: 42px; }

/* CHOOSE YOUR STAR glowing like a Legendary sticker (the user, 2026-09-30) - yellow, with a white glow
   round it and no rim (the user: "not the white rim, only the glow"). */
.cup-screen .cs-play { position: relative; border: 0; color: #3a2600;
  background: linear-gradient(180deg, #ffe774, #ffc21a 60%, #f0a800);
  box-shadow: inset 0 2px 0 rgba(255,255,255,.55), inset 0 -3px 0 rgba(150,90,0,.35), 0 0 22px 2px rgba(255,255,255,.7),
    0 0 44px -4px rgba(255,255,255,.55), 0 10px 22px -10px rgba(0,0,0,.8);
  animation: csRingGlow 2.2s ease-in-out infinite; }
.cs-enter .cs-play { animation: csRowIn .45s cubic-bezier(.2, 1.3, .4, 1) 1.3s both, csRingGlow 2.2s ease-in-out 1.8s infinite; }
@keyframes csRingGlow { 50% { box-shadow: inset 0 2px 0 rgba(255,255,255,.55), inset 0 -3px 0 rgba(150,90,0,.35), 0 0 30px 6px rgba(255,255,255,.9),
  0 0 60px 0 rgba(255,255,255,.65), 0 10px 22px -10px rgba(0,0,0,.8); } }
@media (prefers-reduced-motion: reduce) { .cup-screen .cs-play, .cs-enter .cs-play { animation: none; } }

/* (the user, 2026-09-30) The way out is the game's own back button, as on the pass - not an X; the
   small words (WIN IT, VENUE, STAGE 4 OF 6...) are in the game's display face, not the app's body text. */
.cup-overlay .cup-back { position: fixed; top: max(12px, calc(env(safe-area-inset-top) + 6px)); left: 12px; width: 40px; height: 40px; font-size: 30px; line-height: 34px; z-index: 3; }
.cs-stage-sub, .cs-prize-label { font: 400 14px/1 var(--display); letter-spacing: .08em; color: rgba(255,255,255,.85); text-shadow: 0 2px 0 rgba(0,0,0,.5); }
.cs-facts span { font: 400 11px/1 var(--display); letter-spacing: .1em; color: rgba(255,255,255,.62); }
.cs-facts b { font-size: 15px; }

/* The Viking's and the Ninja Turtle's count (0/3, 1/2, x2) could not be seen (the user, 2026-09-30/10-01):
   a tiny tag in the bottom corner, which the button's rounded clip cut away - and hanging it outside,
   with the star dimmed, only looked worse. The buttons look like every other star's now, and the count
   is written ACROSS the bottom of the portrait: big white figures on a dark band, inside the button. */
.ability-btn.charging { opacity: 1; }
.ability-btn[data-meter]:not([data-meter=""])::after { left: 0; right: 0; bottom: 0; translate: none; padding: 9px 0 5px; border-radius: 0;
  text-align: center; font: 400 17px/1 var(--display); letter-spacing: .04em; color: #fff; white-space: nowrap;
  background: linear-gradient(180deg, rgba(0,0,0,0), rgba(0,0,0,.72) 45%); text-shadow: 0 1px 0 #000, 0 0 4px rgba(0,0,0,.8); box-shadow: none; }

/* The whole bracket on the card at once (the user, 2026-09-30: "see all of it, no moving it, no
   scrolling"): six stages and the trophy share the card's width. YOU is your icon alone, a stage won
   puts a tick on it, the prizes are in small figures, and nothing scrolls or can be dragged. */
.cb-scroll { margin: 0; padding: 4px 0 2px; overflow: hidden; touch-action: pan-y; }
.cb-track { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)) 38px; gap: 8px; width: 100%; padding-bottom: calc(5 * 7px); }
.cb-col { --slot: 24px; width: auto; min-width: 0; gap: 3px; translate: 0 calc(var(--i) * 7px); }
.cb-win { width: auto; }
.cb-stage { font: 400 11px/1 var(--display); letter-spacing: .06em; }
.cb-slot { justify-content: center; padding: 0; border-radius: 6px; }
.cb-me { gap: 0; }
.cb-me b { display: none; }
.cb-me .cb-icon { width: 18px; height: 18px; }
.cb-col.done .cb-slot.top { position: relative; }
.cb-col.done .cb-slot.top::after { content: ""; position: absolute; right: 3px; top: 50%; width: 7px; height: 4px; margin-top: -4px; rotate: -45deg;
  border-left: 2px solid #7dffa4; border-bottom: 2px solid #7dffa4; }
.cb-foe { display: none; }
.cb-empty { font-size: 12px; }
.cb-col:not(.cb-win) .cb-match::after { right: -6px; width: 5px; border-width: 2px; border-radius: 0 4px 4px 0; }
.cb-col:not(.cb-win) .cb-match::before { right: -9px; width: 3px; }
.cb-pay { flex-direction: column; gap: 1px; font: 400 10px/1 var(--display); letter-spacing: .02em; }
.cb-pay img { width: 11px; height: 11px; }
.cb-cupbox img { height: 46px; }

/* The menu's PLAY glows like the cup's CHOOSE YOUR STAR (the user, 2026-10-01), and both carry white
   lettering instead of the dark brown - white on the yellow, held by a dark gold edge underneath. */
#home #playBtn { box-shadow: 0 6px 0 var(--gold-d), inset 0 2px 0 rgba(255,255,255,.75), inset 0 0 0 2px rgba(255,255,255,.28),
    0 0 22px 2px rgba(255,255,255,.7), 0 0 44px -4px rgba(255,255,255,.55), 0 12px 22px -8px rgba(0,0,0,.6);
  animation: playGlow 2.2s ease-in-out infinite; }
@keyframes playGlow { 50% { box-shadow: 0 6px 0 var(--gold-d), inset 0 2px 0 rgba(255,255,255,.75), inset 0 0 0 2px rgba(255,255,255,.28),
    0 0 30px 6px rgba(255,255,255,.9), 0 0 60px 0 rgba(255,255,255,.65), 0 12px 22px -8px rgba(0,0,0,.6); } }
#home #playBtn:active { animation: none; box-shadow: 0 2px 0 var(--gold-d), inset 0 2px 0 rgba(255,255,255,.7), 0 0 22px 2px rgba(255,255,255,.7); }
#home #playBtn, .cup-screen .cs-play { color: #fff; text-shadow: 0 2px 0 #a45f00, 0 0 2px rgba(120,60,0,.9); -webkit-text-stroke: .5px rgba(120,60,0,.35); }
@media (prefers-reduced-motion: reduce) { #home #playBtn { animation: none; } }

/* The sticker names on the Stickers page had a dark shadow 2 px under dark letters on a white card, which
   read as a doubled, ghosted name (the user, 2026-10-01: "an unneeded reflection on the texts"). Flat now. */
.coll-sticker .cs-name { text-shadow: none; }

/* The pass's free lane in a bluish steel rather than grey (the user, 2026-10-01): still the plain lane
   beside the gold one, but with some colour of its own. Header, tiles, a ready tile and the track's
   own paint under them all move together. */
.pc-head.free { background: linear-gradient(180deg, #5b8fd6, #3f6db3); }
.pt-cell.free { background: linear-gradient(180deg, #4d7fc4, #3a64a4); }
.pt-cell.free.ready { background: linear-gradient(180deg, #74a6ea, #4d7fc4); }
.pass-track { background: linear-gradient(90deg, #3a64a4 0 50%, rgba(226,144,15,.45) 50%); }

/* A sticker on the pass wears its rarity's frame - the gradient ring, the dark line, the glow - the same
   as in the collection and the shop (the user, 2026-10-01). */
.pt-art .pt-sticker { border: 3px solid transparent; border-radius: 11px; padding: 1px;
  background: linear-gradient(#fff, #fff) padding-box, var(--ring) border-box;
  box-shadow: inset 0 0 0 2px #15171d, -2px 0 9px -2px var(--g1), 2px 0 9px -2px var(--g2), 0 0 16px -5px var(--g2);
  animation: skRing 2.8s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) { .pt-art .pt-sticker { animation: none; } }

/* A Legendary sticker sent in a match arrives in its rarity's ring - the turquoise-to-pink gradient, the
   dark line, the glow - as it is framed everywhere else (the user, 2026-10-01). Only a Legendary: the
   others come in the plain bubble. */
.emote.legend .sk-bubble { border: 4px solid transparent;
  background: linear-gradient(#fff, #fff) padding-box, var(--ring) border-box;
  box-shadow: inset 0 0 0 2.5px #15171d, -4px 0 16px -2px var(--g1), 4px 0 16px -2px var(--g2), 0 0 26px -4px var(--g2);
  animation: skRing 2.8s ease-in-out infinite; }
.emote.legend .sk-bubble::after { display: none; }
@media (prefers-reduced-motion: reduce) { .emote.legend .sk-bubble { animation: none; } }

/* The handshake behind the result board (js/handshake.js): the two stars on a canvas under the board,
   which comes up as always, over them. */
#matchOverlay .hs-stage { position: absolute; inset: 0; z-index: 0; pointer-events: none; }
.hs-canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.hs-video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; transition: opacity .2s; }
#matchOverlay .panel { position: relative; z-index: 1; }
/* over the softened arena: the match's own buttons and keyboard melt away behind them */
#matchOverlay.hs-soft { background: rgba(14,18,36,.34); backdrop-filter: blur(12px); }
/* on the court itself the canvas IS the arena (the video drawn into it): nothing over it but the board */
#matchOverlay.hs-arena { background: none; backdrop-filter: none; }

/* The Prince's Royal Swap (js/main.js princeUi, princeSwapFx). Choosing: both crests ringed in white and
   breathing, waiting for a tap; the chosen one lifts, the other dims. The clubs that fit come up as a
   list over the dock. The swap: the old crest spins away in a gold flash, the new one drops in, and a
   sweep of gold light crosses the card. */
.pair-card.prince-pick .club { cursor: pointer; }
.pair-card.prince-pick .badge { box-shadow: 0 0 0 3px #fff, 0 0 22px 2px rgba(80,160,255,.6); animation: prBreath 1.1s ease-in-out infinite; }
.pair-card.pp-a #clubB, .pair-card.pp-b #clubA { opacity: .28; filter: grayscale(.85); transition: opacity .2s, filter .2s; }
.pair-card.pp-a #clubB .badge, .pair-card.pp-b #clubA .badge { animation: none; box-shadow: none; }
/* the chosen one, unmistakable (the user, 2026-10-02: "mark the chosen club a bit more clearly"): a thick
   white ring in a strong blue glow, and a SWAP OUT tag - its own size, so it stays on the screen */
.pair-card.pp-a #clubA .badge, .pair-card.pp-b #clubB .badge { animation: prChosen 1s ease-in-out infinite; transform: none;   /* not bigger: it ran off the screen (the user) */
  box-shadow: 0 0 0 4px #fff, 0 0 0 7px #2f7bff, 0 0 34px 10px rgba(80,160,255,.9); }
@keyframes prChosen { 50% { box-shadow: 0 0 0 4px #fff, 0 0 0 7px #2f7bff, 0 0 46px 16px rgba(80,160,255,1); } }
/* ...its name turned into a blue SWAP OUT tag, so the crest itself stays clear */
.pair-card.pp-a #clubA .club-name, .pair-card.pp-b #clubB .club-name { font-size: 0; }
.pair-card.pp-a #clubA .club-name::after, .pair-card.pp-b #clubB .club-name::after { content: "SWAP OUT"; display: inline-block;
  padding: 4px 10px; border-radius: 999px; white-space: nowrap; font: 400 13px/1 var(--display); letter-spacing: .08em;
  color: #fff; background: #2f7bff; box-shadow: 0 2px 6px rgba(0,0,0,.3); }
@keyframes prBreath { 50% { box-shadow: 0 0 0 3px #fff, 0 0 34px 8px rgba(80,160,255,.8); } }
.prince-list { list-style: none; margin: 6px 0 0; padding: 6px; display: grid; gap: 5px; border-radius: 16px;
  background: linear-gradient(180deg, rgba(20,48,130,.86), rgba(8,22,72,.9)); border: 1px solid rgba(140,190,255,.55);
  box-shadow: 0 0 24px -6px rgba(80,160,255,.6), inset 0 1px 0 rgba(255,255,255,.18); animation: pop .35s; }
.prince-list[hidden] { display: none; }
.prince-list .pl-tip { text-align: center; font: 400 15px/1.2 var(--display); letter-spacing: .06em; color: #cfe3ff; padding: 6px; }
.pl-club { width: 100%; display: flex; align-items: center; gap: 10px; padding: 6px 10px; border: 0; border-radius: 11px; cursor: pointer;
  background: linear-gradient(180deg, #ffffff, #e2ecfb); color: #14306e; font: 400 17px/1 var(--display); text-align: left;
  box-shadow: inset 0 -2px 0 rgba(40,80,160,.35), 0 2px 0 rgba(0,0,0,.3); }
.pl-club:active { transform: translateY(1px); filter: brightness(.95); }
.pl-club img { width: 28px; height: 28px; object-fit: contain; flex: none; }
.pl-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pl-n { font: 700 12px/1 var(--ui, system-ui); color: #2f6fd6; flex: none; }
.club.pr-out .badge { animation: prOut .52s cubic-bezier(.55,0,.8,.4) forwards; }
.club.pr-in .badge { animation: prIn .7s cubic-bezier(.2,1.5,.4,1) both; }
@keyframes prOut { 30% { transform: scale(1.15) rotateY(0); filter: brightness(1.6); box-shadow: 0 0 40px 14px rgba(255,212,0,.9); }
  to { transform: scale(.2) rotateY(540deg); opacity: 0; filter: brightness(3); } }
@keyframes prIn { from { transform: translateY(-70px) scale(1.6); opacity: 0; filter: brightness(2.5); }
  60% { filter: brightness(1.4); box-shadow: 0 0 40px 12px rgba(255,212,0,.85); } }
.club.pr-in::before { content: ""; position: absolute; width: 34px; height: 22px; margin-top: -26px; pointer-events: none;
  background: linear-gradient(180deg, #fff3a0, #ffc400); filter: drop-shadow(0 2px 3px rgba(0,0,0,.4));
  clip-path: polygon(0 100%, 0 25%, 22% 60%, 50% 0, 78% 60%, 100% 25%, 100% 100%); animation: prCrown 1.6s ease-out both; }
.club { position: relative; }
@keyframes prCrown { from { transform: translateY(-30px) scale(.4); opacity: 0; } 25% { transform: translateY(0) scale(1.1); opacity: 1; }
  80% { opacity: 1; } to { transform: translateY(-6px); opacity: 0; } }
.pair-card.royal::after { content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(105deg, transparent 30%, rgba(255,230,120,.0) 38%, rgba(255,230,120,.75) 50%, rgba(255,230,120,0) 62%, transparent 70%);
  animation: prSweep 1.3s .35s ease-in-out both; }
@keyframes prSweep { from { transform: translateX(-110%); } to { transform: translateX(110%); } }
@media (prefers-reduced-motion: reduce) { .pair-card.prince-pick .badge, .pair-card.pp-a #clubA .badge, .pair-card.pp-b #clubB .badge, .club.pr-out .badge, .club.pr-in .badge, .club.pr-in::before, .pair-card.royal::after { animation: none; } }

/* The end of a match over the arena (js/main.js, match-end): the match's own screen steps aside - it
   sits over the arena, the flyby under it - and the board stands on the moving arena itself, unblurred. */
#match.ended > * { visibility: hidden; }
#matchOverlay.over-arena { background: linear-gradient(180deg, rgba(8,12,40,.18), rgba(8,12,40,.38)); backdrop-filter: none; }

/* THE STARTER's bracket over its busy picture (the user, 2026-10-02: "show the bracket more clearly - no
   tile under it, as it is in the other tournament"): the same bracket, only its slots darker and edged,
   the joints in full white and every label with a shadow. */
.cup-starter .cb-slot { background: rgba(0,0,0,.55); box-shadow: inset 0 0 0 1px rgba(255,255,255,.45), 0 2px 6px rgba(0,0,0,.45); }
.cup-starter .cb-col.now .cb-slot.top { background: #fff; }
.cup-starter .cb-col.done .cb-slot.top { background: rgba(255,255,255,.25); box-shadow: inset 0 0 0 1px rgba(255,255,255,.65); }
.cup-starter .cb-col:not(.cb-win) .cb-match::after { border-color: #fff; filter: drop-shadow(0 1px 2px rgba(0,0,0,.8)); }
.cup-starter .cb-col:not(.cb-win) .cb-match::before { background: #fff; box-shadow: 0 1px 2px rgba(0,0,0,.8); }
.cup-starter .cb-stage, .cup-starter .cb-pay { color: #fff; text-shadow: 0 1px 2px #000, 0 0 6px rgba(0,0,0,.8); }
.cup-starter .cup-blurb, .cup-starter .cup-now { color: #fff; text-shadow: 0 1px 3px #000, 0 0 10px rgba(0,0,0,.7); }

/* The next tier for gems, on the track between two numbers (js/main.js passSkip): only the price and
   the gem, small, sitting on the join; tapped once it lights up to ask for the second tap. */
.pt-skip { position: absolute; left: 50%; top: 0; z-index: 3; translate: -50% -50%; display: inline-flex; align-items: center; gap: 2px;
  padding: 3px 7px 3px 8px; border-radius: 999px; font: 900 12px/1 var(--body); color: #fff;
  background: rgba(8,12,40,.82); box-shadow: inset 0 0 0 1px rgba(255,255,255,.35), 0 2px 6px rgba(0,0,0,.5); }
.pt-skip img { width: 14px; height: 14px; object-fit: contain; }
.pt-skip.armed { color: #13203f; background: #fff; box-shadow: 0 0 14px rgba(150,200,255,.9); }
.pt-skip.short { animation: shake .35s; }

/* PACKS TO GLORY (js/main.js renderPtg / openPtg).
   On the menu: a banner beside the pass's dot - midnight blue with a gold edge, the open mission's
   pack standing out of its top corner, the name in gold, the mission, and a gold bar with the count.
   When the pack is waiting it turns gold all over and says OPEN! */
.home-dots { display: flex; align-items: flex-end; gap: 10px; align-self: stretch; }
.home-dots .pass-dot { margin-left: auto; }
.ptg-btn { position: relative; flex: 0 1 236px; min-width: 0; display: grid; grid-template-columns: 50px 1fr; grid-template-rows: auto auto;
  column-gap: 8px; row-gap: 5px; align-items: center; margin: 12px 0 -2px; padding: 8px 12px 9px 8px; border-radius: 18px; text-align: left; color: #fff;
  overflow: visible; isolation: isolate;
  background: radial-gradient(120% 90% at 0% 0%, #3b6cf0 0%, transparent 55%), linear-gradient(160deg, #1d3a9e, #0d1b5c 70%);
  box-shadow: inset 0 0 0 2px #ffd34d, inset 0 0 0 4px rgba(10,20,70,.6), 0 10px 18px -8px rgba(0,0,0,.75); }
.ptg-btn:active { transform: scale(.97); }
.ptg-shine { position: absolute; inset: 0; border-radius: inherit; overflow: hidden; z-index: -1; pointer-events: none;
  background: repeating-linear-gradient(115deg, rgba(255,255,255,.06) 0 10px, transparent 10px 22px); }
.ptg-pack { grid-row: 1 / 3; width: 50px; height: 70px; margin-top: -26px; object-fit: contain; rotate: -9deg;
  filter: drop-shadow(0 6px 6px rgba(0,0,0,.55)); }
.ptg-text { display: grid; gap: 1px; min-width: 0; }
.ptg-text b { font: 400 16px/1 var(--display); letter-spacing: .03em; color: #ffd34d;
  text-shadow: 0 2px 0 #7a4a00, 0 0 10px rgba(255,200,60,.35); white-space: nowrap; }
.ptg-text b i { font-style: normal; font-size: 12px; color: #fff; text-shadow: 0 2px 0 rgba(0,0,0,.5); }
.ptg-text small { font: 800 11px/1.2 var(--body); color: rgba(255,255,255,.88); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ptg-foot { display: flex; align-items: center; gap: 6px; }
.ptg-bar { flex: 1; height: 8px; border-radius: 999px; overflow: hidden; background: rgba(0,0,0,.4); box-shadow: inset 0 0 0 1px rgba(255,255,255,.18); }
.ptg-bar > span { display: block; height: 100%; width: 0; border-radius: inherit; background: linear-gradient(180deg, #fff3b0, #ffc21a); transition: width .5s; }
.ptg-foot em { font: 900 11px/1 var(--body); font-style: normal; color: #fff; }
.ptg-open { display: none; position: absolute; top: -10px; right: -6px; padding: 4px 9px; border-radius: 999px; rotate: 8deg;
  font: 400 13px/1 var(--display); color: #fff; background: #e8344a; box-shadow: 0 3px 0 #8e1525, 0 0 12px rgba(232,52,74,.6); }
.ptg-btn.ready { background: radial-gradient(120% 90% at 0% 0%, #fff3b0 0%, transparent 55%), linear-gradient(160deg, #ffd34d, #f09a00 75%);
  animation: ptgReady 1.6s ease-in-out infinite; }
.ptg-btn.ready .ptg-text b { color: #fff; text-shadow: 0 2px 0 #9a5a00; }
.ptg-btn.ready .ptg-text small, .ptg-btn.ready .ptg-foot em { color: #4a2c00; }
.ptg-btn.ready .ptg-bar > span { background: #fff; }
.ptg-btn.ready .ptg-open { display: block; animation: ptgPop 1.6s ease-in-out infinite; }
@keyframes ptgReady { 50% { box-shadow: inset 0 0 0 2px #fff, 0 0 24px 5px rgba(255,200,40,.75); } }
@keyframes ptgPop { 50% { scale: 1.12; } }
@media (prefers-reduced-motion: reduce) { .ptg-btn.ready, .ptg-btn.ready .ptg-open { animation: none; } }

/* The page: a night-blue screen of its own. At the top three packs fanned over the name; below, the road
   - a gold line running down the left with a numbered stop for every mission and the mission's card
   beside it: ticked off behind, lit and lifted where you are, locked and dim ahead. */
.overlay.ptg-overlay { padding: 0; display: block; overflow-y: auto; background:
  radial-gradient(90% 40% at 50% 0%, rgba(80,130,255,.35), transparent 70%), linear-gradient(180deg, #0f1f63, #070d2e 70%); backdrop-filter: none; }
.ptg-panel { position: relative; max-width: 460px; margin: 0 auto; padding: max(14px, env(safe-area-inset-top)) 14px 40px; color: #fff; }
.ptg-back { position: absolute; top: max(12px, env(safe-area-inset-top)); left: 12px; }
.ptg-hero { display: grid; justify-items: center; gap: 4px; padding: 18px 0 14px; text-align: center; }
.ptg-fan { position: relative; display: block; width: 170px; height: 112px; margin-bottom: 4px; }
.ptg-fan img { position: absolute; bottom: 0; left: 50%; width: 74px; height: 104px; object-fit: contain; translate: -50% 0;
  filter: drop-shadow(0 8px 10px rgba(0,0,0,.6)); }
.ptg-fan img:nth-child(1) { rotate: -16deg; translate: -110% 6px; }
.ptg-fan img:nth-child(2) { z-index: 1; translate: -50% -6px; scale: 1.08; }
.ptg-fan img:nth-child(3) { rotate: 16deg; translate: 10% 6px; }
.ptg-title { font: 400 36px/1 var(--display); letter-spacing: .03em; color: #ffd34d;
  text-shadow: 0 3px 0 #7a4a00, 0 0 22px rgba(255,200,60,.4); }
.ptg-title i { font-style: normal; font-size: 24px; color: #fff; text-shadow: 0 3px 0 rgba(0,0,0,.5); }
.ptg-tag { font: 800 12.5px/1.3 var(--body); color: rgba(255,255,255,.8); }
.ptg-total { margin-top: 6px; padding: 5px 12px; border-radius: 999px; font: 900 11px/1 var(--body); letter-spacing: .12em;
  color: #ffd34d; box-shadow: inset 0 0 0 1.5px rgba(255,211,77,.6); }
.ptg-road { position: relative; list-style: none; margin: 6px 0 0; padding: 0 0 0 34px; display: grid; gap: 12px; }
.ptg-road::before { content: ""; position: absolute; left: 14px; top: 14px; bottom: 14px; width: 4px; border-radius: 2px;
  background: linear-gradient(180deg, #ffd34d, rgba(255,211,77,.25)); }
.ptg-stop { position: relative; }
.ptg-node { position: absolute; left: -34px; top: 50%; translate: 0 -50%; width: 32px; height: 32px; border-radius: 50%; display: grid; place-items: center;
  font: 400 15px/1 var(--display); color: #fff; background: #1a2b78; box-shadow: inset 0 0 0 2px rgba(255,255,255,.35), 0 0 0 4px #0b1440; }
.ptg-card { display: grid; grid-template-columns: 50px 1fr auto; align-items: center; gap: 10px; padding: 10px 12px 10px 8px; border-radius: 16px;
  background: linear-gradient(180deg, rgba(255,255,255,.12), rgba(255,255,255,.05)); box-shadow: inset 0 0 0 1px rgba(255,255,255,.2); }
.ptg-icon { width: 50px; height: 70px; object-fit: contain; rotate: -6deg; filter: drop-shadow(0 4px 5px rgba(0,0,0,.5)); }
.ptg-what { display: grid; gap: 4px; min-width: 0; }
.ptg-what b { font: 900 14px/1.2 var(--body); color: #fff; }
.ptg-what small { font: 800 11px/1 var(--body); letter-spacing: .06em; text-transform: uppercase; color: var(--r); }
.ptg-meter { height: 9px; border-radius: 999px; overflow: hidden; background: rgba(0,0,0,.4); box-shadow: inset 0 0 0 1px rgba(255,255,255,.18); }
.ptg-meter > span { display: block; height: 100%; border-radius: inherit; background: linear-gradient(180deg, #fff3b0, #ffc21a); }
.ptg-badge { display: grid; place-items: center; min-width: 46px; height: 30px; padding: 0 8px; border-radius: 999px; font: 900 12px/1 var(--body); }
.ptg-badge.num { color: #ffd34d; box-shadow: inset 0 0 0 1.5px rgba(255,211,77,.7); }
.ptg-badge.ok { color: #0d3d1f; background: linear-gradient(180deg, #7dffa4, #2fbf63); }
.ptg-badge.lock { color: rgba(255,255,255,.6); }
.ptg-badge.lock svg { width: 18px; height: 18px; }
.ptg-claim { padding: 10px 14px; font-size: 17px; background: linear-gradient(180deg, #ffe98d, #ffc21a); color: #3a2600; box-shadow: 0 4px 0 #b86e00;
  animation: ptgPop 1.4s ease-in-out infinite; }
.ptg-stop.done .ptg-card { opacity: .62; }
.ptg-stop.done .ptg-node { background: #2fbf63; }
.ptg-stop.done .ptg-node::after { content: ""; width: 11px; height: 6px; margin-top: -3px; rotate: -45deg; border-left: 3px solid #fff; border-bottom: 3px solid #fff; }
.ptg-stop.next .ptg-card { opacity: .45; filter: grayscale(.7); }
.ptg-stop.next .ptg-node { color: rgba(255,255,255,.5); background: #141f55; }
.ptg-stop.open .ptg-card, .ptg-stop.ready .ptg-card { scale: 1.02; background: linear-gradient(180deg, rgba(60,110,255,.45), rgba(30,60,170,.35));
  box-shadow: inset 0 0 0 2px #ffd34d, 0 10px 22px -10px rgba(0,0,0,.8), 0 0 22px -4px rgba(255,211,77,.45); }
.ptg-stop.open .ptg-node, .ptg-stop.ready .ptg-node { color: #3a2600; background: linear-gradient(180deg, #ffe98d, #ffc21a); box-shadow: 0 0 0 4px #0b1440, 0 0 16px rgba(255,211,77,.8); }
.ptg-stop.ready .ptg-card { box-shadow: inset 0 0 0 2px #fff, 0 0 26px rgba(255,200,40,.75); }
@media (prefers-reduced-motion: reduce) { .ptg-claim { animation: none; } }

/* A pass star and, under it, the season of the pass it came from. */
.pass-card-wrap { display: grid; gap: 16px; min-width: 0; }   /* clear of the card's own edge and shadow */
.pc-season { justify-self: center; padding: 3px 9px; border-radius: 999px; font: 400 11px/1 var(--display); letter-spacing: .08em;
  color: #3a2f14; background: linear-gradient(180deg, #fffaf0, #f5efdc); box-shadow: 0 2px 0 rgba(0,0,0,.25), inset 0 0 0 1px rgba(58,47,20,.25); }

/* PACKS TO GLORY, bright and alive (the user, 2026-10-02: "lighter, not blue, cooler - less dry").
   The banner: cream to sunshine with a burst of rays turning slowly behind the pack, three sparkles
   twinkling, a shine that sweeps across now and then, the name in hot orange on a white edge and a
   striped gold bar that crawls. */
.ptg-btn { color: #3a2600; overflow: visible;   /* the pack stands out of the top; the rays are clipped by .ptg-shine */
  background: radial-gradient(90% 120% at 12% 30%, #fff 0%, #fff7d6 45%, #ffd65a 100%);
  box-shadow: inset 0 0 0 2px #fff, inset 0 0 0 4px #ffb81f, 0 10px 18px -8px rgba(0,0,0,.6); }
.ptg-shine { background: linear-gradient(105deg, transparent 35%, rgba(255,255,255,.85) 48%, transparent 60%);
  background-size: 260% 100%; animation: ptgSweep 3.6s ease-in-out infinite; }
@keyframes ptgSweep { 0%, 55% { background-position: 130% 0; } 100% { background-position: -40% 0; } }
.ptg-rays { position: absolute; left: -30px; top: -40px; width: 120px; height: 120px; pointer-events: none; border-radius: 50%;
  background: repeating-conic-gradient(from 0deg, rgba(255,170,0,.35) 0 10deg, transparent 10deg 22deg);
  -webkit-mask: radial-gradient(closest-side, #000 30%, transparent 100%); mask: radial-gradient(closest-side, #000 30%, transparent 100%);
  animation: ptgSpin 14s linear infinite; }
@keyframes ptgSpin { to { rotate: 360deg; } }
.ptg-spark { position: absolute; width: 10px; height: 10px; pointer-events: none; background: #fff;
  clip-path: polygon(50% 0, 62% 38%, 100% 50%, 62% 62%, 50% 100%, 38% 62%, 0 50%, 38% 38%);
  filter: drop-shadow(0 0 3px #ffb81f); animation: ptgTwinkle 2.4s ease-in-out infinite; }
.ptg-spark.s1 { left: 46px; top: 6px; }
.ptg-spark.s2 { right: 14px; top: 8px; width: 8px; height: 8px; animation-delay: -.8s; }
.ptg-spark.s3 { right: 58px; bottom: 6px; width: 7px; height: 7px; animation-delay: -1.6s; }
@keyframes ptgTwinkle { 0%, 100% { scale: .3; opacity: 0; } 40%, 60% { scale: 1; opacity: 1; rotate: 45deg; } }
.ptg-pack { filter: drop-shadow(0 6px 6px rgba(120,60,0,.45)); animation: ptgFloat 3s ease-in-out infinite; }
@keyframes ptgFloat { 50% { translate: 0 -3px; rotate: -5deg; } }
.ptg-text b { color: #ff5a1f; text-shadow: 0 1.5px 0 #fff, 0 -1px 0 #fff, 1px 0 0 #fff, -1px 0 0 #fff, 0 3px 0 rgba(150,60,0,.35); }
.ptg-text b i { color: #3a2600; text-shadow: none; }
.ptg-text small { color: #5a3a00; }
.ptg-foot em { color: #5a3a00; }
.ptg-bar { background: rgba(120,70,0,.18); box-shadow: inset 0 0 0 1px rgba(120,70,0,.2); }
.ptg-bar > span { background: repeating-linear-gradient(115deg, #ffb81f 0 8px, #ff8a00 8px 16px); background-size: 200% 100%;
  animation: ptgCrawl 1.2s linear infinite; }
@keyframes ptgCrawl { to { background-position: -36px 0; } }
.ptg-btn.ready { background: radial-gradient(90% 120% at 12% 30%, #fff 0%, #ffe36b 40%, #ff9d00 100%); }
.ptg-btn.ready .ptg-text b { color: #fff; text-shadow: 0 2px 0 #b34a00, 0 0 10px rgba(255,120,0,.6); }
@media (prefers-reduced-motion: reduce) { .ptg-shine, .ptg-rays, .ptg-spark, .ptg-pack, .ptg-bar > span { animation: none; } }

/* The page on the arena's own backdrop, as every other screen is: the menu under it steps aside
   (#app.ptg-on), a light veil keeps the road readable, and the stops are white cards. */
#app.ptg-on > .screen:not([hidden]) > * { visibility: hidden; }
.overlay.ptg-overlay { background: linear-gradient(180deg, rgba(255,255,255,.12), rgba(10,20,60,.28)); backdrop-filter: none; }
.ptg-title { color: #fff; text-shadow: 0 3px 0 #b34a00, 0 0 18px rgba(255,140,0,.55), 0 0 2px #000; }
.ptg-title i { color: #ffd34d; }
.ptg-tag { color: #fff; text-shadow: 0 1px 3px rgba(0,0,0,.8); }
.ptg-total { color: #3a2600; background: linear-gradient(180deg, #fff3b0, #ffc21a); box-shadow: 0 3px 0 #b86e00; }
.ptg-road::before { background: linear-gradient(180deg, #fff, rgba(255,255,255,.4)); box-shadow: 0 0 8px rgba(0,0,0,.4); }
.ptg-node { color: #13203f; background: #fff; box-shadow: 0 0 0 4px rgba(255,255,255,.35), 0 2px 6px rgba(0,0,0,.4); }
.ptg-card { background: rgba(255,255,255,.94); box-shadow: 0 8px 16px -8px rgba(0,0,0,.7); }
.ptg-what b { color: #13203f; }
.ptg-meter { background: rgba(19,32,63,.14); box-shadow: none; }
.ptg-meter > span { background: repeating-linear-gradient(115deg, #ffb81f 0 8px, #ff8a00 8px 16px); }
.ptg-badge.num { color: #8a5a00; box-shadow: inset 0 0 0 1.5px #f0a800; }
.ptg-badge.lock { color: rgba(19,32,63,.45); }
.ptg-stop.done .ptg-card { opacity: .8; }
.ptg-stop.next .ptg-card { opacity: .62; filter: grayscale(.6); }
.ptg-stop.next .ptg-node { color: rgba(19,32,63,.5); background: rgba(255,255,255,.7); }
.ptg-stop.open .ptg-card, .ptg-stop.ready .ptg-card { background: #fff;
  box-shadow: inset 0 0 0 3px #ffc21a, 0 10px 22px -10px rgba(0,0,0,.8), 0 0 24px -4px rgba(255,190,40,.9); }
.ptg-stop.open .ptg-node, .ptg-stop.ready .ptg-node { color: #3a2600; background: linear-gradient(180deg, #ffe98d, #ffc21a); box-shadow: 0 0 0 4px rgba(255,255,255,.5), 0 0 16px rgba(255,190,40,.9); }
#app.ptg-on > .tabbar, #app.ptg-on > .wallet { visibility: hidden; }

/* PACKS TO GLORY toned down (the user, 2026-10-02: "it glows too much"): a softer cream, the rays and
   the shine faint, one quiet sparkle, no glow round the name or the open card. */
.ptg-btn { background: linear-gradient(160deg, #fffaf0, #ffeab0);
  box-shadow: inset 0 0 0 1.5px #fff, inset 0 0 0 3px #f0c45a, 0 8px 14px -8px rgba(0,0,0,.5); }
.ptg-shine { background: linear-gradient(105deg, transparent 40%, rgba(255,255,255,.4) 50%, transparent 60%);
  background-size: 260% 100%; animation-duration: 6s; }
.ptg-rays { opacity: .35; }
.ptg-spark.s2, .ptg-spark.s3 { display: none; }
.ptg-spark { filter: none; opacity: .8; }
.ptg-pack { filter: drop-shadow(0 4px 4px rgba(90,50,0,.3)); }
.ptg-text b { text-shadow: 0 1px 0 #fff, 0 2px 0 rgba(150,60,0,.2); }
.ptg-btn.ready { background: linear-gradient(160deg, #fff6d6, #ffd36b); animation: none; }
.ptg-btn.ready .ptg-text b { color: #e2430f; text-shadow: 0 1px 0 #fff; }
.ptg-title { text-shadow: 0 3px 0 #b34a00, 0 0 2px #000; }
.ptg-stop.open .ptg-card, .ptg-stop.ready .ptg-card { box-shadow: inset 0 0 0 3px #ffc21a, 0 10px 22px -10px rgba(0,0,0,.8); }
.ptg-stop.open .ptg-node, .ptg-stop.ready .ptg-node { box-shadow: 0 0 0 4px rgba(255,255,255,.5), 0 2px 6px rgba(0,0,0,.4); }

/* PACKS TO GLORY in blue after all (the user, 2026-10-02: "better in blue") - calm, as toned down above:
   a clear game blue with a thin gold edge, white lettering, the gold bar. */
.ptg-btn { color: #fff; background: linear-gradient(160deg, #5a95ff, #2c62e0);
  box-shadow: inset 0 0 0 1.5px rgba(255,255,255,.6), inset 0 0 0 3px #f0c45a, 0 8px 14px -8px rgba(0,0,0,.55); }
.ptg-rays { opacity: .18; background: repeating-conic-gradient(from 0deg, rgba(255,255,255,.6) 0 10deg, transparent 10deg 22deg); }
.ptg-shine { background: linear-gradient(105deg, transparent 40%, rgba(255,255,255,.25) 50%, transparent 60%); background-size: 260% 100%; }
.ptg-pack { filter: drop-shadow(0 4px 5px rgba(0,20,80,.45)); }
.ptg-text b { color: #fff; text-shadow: 0 2px 0 rgba(10,30,100,.55); }
.ptg-text b i { color: #ffd34d; }
.ptg-text small, .ptg-foot em { color: rgba(255,255,255,.9); }
.ptg-bar { background: rgba(0,15,60,.35); box-shadow: inset 0 0 0 1px rgba(255,255,255,.2); }
.ptg-btn.ready { background: linear-gradient(160deg, #6aa2ff, #2c62e0); box-shadow: inset 0 0 0 2px #ffd34d, 0 8px 14px -8px rgba(0,0,0,.55); }
.ptg-btn.ready .ptg-text b { color: #ffd34d; text-shadow: 0 2px 0 rgba(10,30,100,.55); }
/* The page's title in its first colours again (the user, 2026-10-02): gold, with TO in white. */
.ptg-title { color: #ffd34d; text-shadow: 0 3px 0 #7a4a00, 0 0 22px rgba(255,200,60,.4); }
.ptg-title i { color: #fff; text-shadow: 0 3px 0 rgba(0,0,0,.5); }

/* The page's banner: the user's picture across the top, in place of the fanned packs. */
.ptg-hero { padding-top: 44px; }
.ptg-banner { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; border-radius: 18px; margin-bottom: 8px;
  box-shadow: 0 0 0 2px rgba(255,255,255,.75), 0 14px 26px -12px rgba(0,0,0,.8); }

/* PACKS TO GLORY's page built like the pass's (the user, 2026-10-02): the banner full width across the
   top at its own shape, the kicker, the name and a meter of packs won written over its foot - the
   pass's own hero rules - and the road under it. */
.ptg-panel { padding: 0 0 40px; max-width: 520px; }
.ptg-hero { display: flex; justify-items: normal; gap: 0; text-align: left; padding: max(12px, env(safe-area-inset-top)) 14px 12px; }
.ptg-hero .pass-back { position: absolute; }
.ptg-road { margin: 16px 14px 0; }
/* ...and like the pass, the banner stays put: only the road scrolls under it (the user, 2026-10-02). */
.overlay.ptg-overlay { overflow: hidden; }
.ptg-panel { height: 100%; display: flex; flex-direction: column; padding-bottom: 0; }
.ptg-hero { flex: none; }
.ptg-road { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
  margin: 0; padding: 16px 14px 40px 48px; }
/* the road's line drawn stop by stop (one line on the scroller itself would stay put while it scrolls) */
.ptg-road::before { content: none; }
.ptg-stop::before { content: ""; position: absolute; left: -20px; top: -12px; bottom: 0; width: 4px; border-radius: 2px;
  background: rgba(255,255,255,.85); box-shadow: 0 0 6px rgba(0,0,0,.35); }
.ptg-stop:first-child::before { top: 50%; }
.ptg-stop:last-child::before { bottom: 50%; }
/* the numbers sit ON the road: above its line, on solid discs it cannot show through */
.ptg-stop::before { z-index: 0; }
.ptg-node { z-index: 1; }
.ptg-stop.next .ptg-node { color: #8a93ad; background: #e4e8f2; }
/* Under the banner, a ground of its own instead of the arena (the user, 2026-10-02: "a cooler background
   where the packs' tiers are"): the banner's own night-purple and gold - stadium light fanning down from
   the top, a gold haze at the foot, a fine scatter of glitter - so the road reads as part of the picture. */
.overlay.ptg-overlay { background:
  radial-gradient(3px 3px at 12% 22%, rgba(255,220,120,.7), transparent 60%),
  radial-gradient(2px 2px at 78% 34%, rgba(255,255,255,.75), transparent 60%),
  radial-gradient(2.5px 2.5px at 34% 61%, rgba(255,220,120,.6), transparent 60%),
  radial-gradient(2px 2px at 88% 72%, rgba(255,255,255,.6), transparent 60%),
  radial-gradient(3px 3px at 22% 86%, rgba(255,200,90,.6), transparent 60%),
  radial-gradient(2px 2px at 60% 92%, rgba(255,255,255,.55), transparent 60%),
  repeating-conic-gradient(from 180deg at 50% -10%, rgba(255,255,255,.07) 0 4deg, transparent 4deg 13deg),
  radial-gradient(90% 40% at 50% 100%, rgba(255,170,40,.35), transparent 70%),
  radial-gradient(80% 60% at 15% 40%, rgba(160,70,255,.45), transparent 70%),
  linear-gradient(180deg, #3a1677 0%, #241056 45%, #140a38 100%); }
.ptg-stop::before { background: linear-gradient(180deg, #ffd34d, #f0a800); box-shadow: 0 0 8px rgba(255,190,40,.5); }

/* PACKS TO GLORY's progress, plainer and more grown-up (the user, 2026-10-02: "simpler, less childish"):
   no road, no numbered discs, no tilted packs or striped bars - a clean list of rows on dark glass, the
   pack small and straight, a thin solid bar, the count in plain figures; the open mission marked by a
   single gold edge, the finished ones ticked quietly, the rest dimmed. */
.ptg-road { padding: 14px 14px 40px; gap: 8px; }
.ptg-stop::before, .ptg-node { display: none; }
.ptg-card { grid-template-columns: 34px 1fr auto; gap: 12px; padding: 10px 12px; border-radius: 12px; scale: none;
  background: rgba(10,6,30,.55); box-shadow: inset 0 0 0 1px rgba(255,255,255,.12); backdrop-filter: blur(6px); }
.ptg-icon { width: 34px; height: 46px; rotate: none; filter: none; }
.ptg-what { gap: 5px; }
.ptg-what b { font: 800 14px/1.25 var(--body); color: #fff; }
.ptg-what small { font: 700 10.5px/1 var(--body); letter-spacing: .08em; color: rgba(255,255,255,.55); }
.ptg-meter { height: 4px; border-radius: 2px; background: rgba(255,255,255,.14); box-shadow: none; }
.ptg-meter > span { background: #ffd34d; }
.ptg-badge { min-width: 0; height: auto; padding: 0; border-radius: 0; background: none; box-shadow: none; }
.ptg-badge.num { color: #fff; font: 800 13px/1 var(--body); box-shadow: none; }
.ptg-badge.ok { color: #7dffa4; font: 800 11px/1 var(--body); letter-spacing: .08em; background: none; }
.ptg-badge.lock { color: rgba(255,255,255,.4); }
.ptg-stop.done .ptg-card { opacity: .55; }
.ptg-stop.next .ptg-card { opacity: .45; filter: none; }
.ptg-stop.open .ptg-card, .ptg-stop.ready .ptg-card { background: rgba(10,6,30,.7); scale: none;
  box-shadow: inset 0 0 0 1.5px #ffd34d; }
.ptg-claim { animation: none; padding: 8px 14px; font-size: 15px; box-shadow: 0 3px 0 #b86e00; }
/* the menu's banner: the same plain bar */
.ptg-bar { height: 5px; border-radius: 3px; box-shadow: none; }
.ptg-bar > span { background: #ffd34d; animation: none; }
.ptg-spark, .ptg-rays { display: none; }

/* SPECIAL EVENTS, under the regular tournaments (the user, 2026-10-02): a heading of its own and, until
   the first one arrives, a quiet note saying how they will work. */
.cup-section { margin: 10px 2px -6px; font: 400 20px/1 var(--display); letter-spacing: .06em; color: #ffd34d;
  text-shadow: 0 2px 0 rgba(0,0,0,.45); }
.cup-special-empty { padding: 18px 14px; border-radius: 16px; text-align: center; font: 800 13px/1.5 var(--body); color: rgba(255,255,255,.85);
  background: linear-gradient(160deg, rgba(120,60,220,.35), rgba(20,10,60,.55)); box-shadow: inset 0 0 0 1px rgba(255,211,77,.45); }

/* A sticker out of the Legendary Pack: its picture sits whole on the card, on white like its bubble. */
.op-sticker-card .op-card-art { display: grid; place-items: center; background: #fff; }
.op-sticker-card .op-sticker { width: 88%; height: auto; object-fit: contain; }

/* The ladder of arenas, full screen (js/main.js renderArenaList): a night-blue ground, a header with the
   way back and your trophies, and a card per arena on its own picture, joined by a gold thread. */
.overlay.arenas-overlay { padding: 0; display: block; background:
  radial-gradient(90% 40% at 50% 0%, rgba(90,130,255,.35), transparent 70%), linear-gradient(180deg, #16205a, #0a0e2c); backdrop-filter: none; }
.arenas-screen { width: 100%; height: 100%; max-width: 520px; margin: 0 auto; display: flex; flex-direction: column; }
.arenas-head { position: relative; flex: none; display: flex; align-items: center; justify-content: center;
  padding: max(14px, env(safe-area-inset-top)) 14px 10px; }
.arenas-head .pass-back { position: absolute; left: 12px; top: max(10px, env(safe-area-inset-top)); }
.arenas-head b { font: 400 30px/1 var(--display); letter-spacing: .04em; color: #fff; text-shadow: 0 3px 0 rgba(0,0,0,.45); }
.arenas-trophies { position: absolute; right: 14px; display: inline-flex; align-items: center; gap: 4px; padding: 5px 10px; border-radius: 999px;
  font: 900 13px/1 var(--body); color: #fff; background: rgba(255,255,255,.12); box-shadow: inset 0 0 0 1px rgba(255,255,255,.25); }
.arenas-trophies .tr-ico { width: 16px; height: 16px; }
.arena-list { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; display: grid; gap: 22px;
  margin: 0; padding: 8px 14px 40px; }
.arena-row { position: relative; display: block; min-height: 132px; padding: 0; border-radius: 18px; overflow: visible; isolation: isolate;
  background: #1a2468; box-shadow: 0 0 0 2px rgba(255,255,255,.35), 0 12px 22px -10px rgba(0,0,0,.8); text-align: left; }
/* the thread from one arena down to the next */
.arena-row + .arena-row::before { content: ""; position: absolute; left: 50%; top: -22px; width: 4px; height: 22px; translate: -50% 0;
  background: linear-gradient(180deg, #ffd34d, #f0a800); border-radius: 2px; }
.ar-bg { position: absolute; inset: 0; z-index: -1; border-radius: inherit; background: center / cover no-repeat;
  -webkit-mask: linear-gradient(90deg, #000, #000); }
.ar-bg::after { content: ""; position: absolute; inset: 0; border-radius: inherit;
  background: linear-gradient(90deg, rgba(8,12,40,.9) 0%, rgba(8,12,40,.6) 48%, rgba(8,12,40,.05) 100%); }
.ar-hero { position: absolute; right: -6px; top: 50%; translate: 0 -50%; width: 52%; max-height: 120%; object-fit: contain;
  filter: drop-shadow(0 10px 12px rgba(0,0,0,.6)); pointer-events: none; }
.ar-text { position: relative; display: flex; flex-direction: column; align-items: flex-start; gap: 3px; width: 58%; padding: 14px 0 14px 14px; }
.ar-tier { font: 900 10.5px/1 var(--body); letter-spacing: .16em; text-transform: uppercase; color: #ffd34d; }
.ar-name { font: 400 22px/1.02 var(--display); color: #fff; text-shadow: 0 2px 0 rgba(0,0,0,.5); }
.ar-min { display: inline-flex; align-items: center; gap: 3px; font: 800 12px/1 var(--body); color: rgba(255,255,255,.85); }
.ar-min .tr-ico, .ar-next .tr-ico, .ar-chip .tr-ico { width: 14px; height: 14px; }
.ar-chip { margin-top: 6px; display: inline-flex; align-items: center; gap: 4px; padding: 5px 10px; border-radius: 999px;
  font: 900 10.5px/1 var(--body); letter-spacing: .08em; }
.ar-chip svg { width: 13px; height: 13px; }
.ar-chip.here { color: #3a2600; background: linear-gradient(180deg, #ffe98d, #ffc21a); box-shadow: 0 2px 0 #b86e00; }
.ar-chip.done { color: #073d1c; background: linear-gradient(180deg, #a6ffc2, #2fbf63); }
.ar-chip.locked { color: #fff; background: rgba(255,255,255,.16); box-shadow: inset 0 0 0 1px rgba(255,255,255,.3); }
.ar-next { display: grid; gap: 4px; width: 100%; margin-top: 6px; }
.ar-bar { height: 6px; border-radius: 3px; overflow: hidden; background: rgba(255,255,255,.18); }
.ar-bar > span { display: block; height: 100%; background: #ffd34d; border-radius: inherit; }
.ar-next small { display: inline-flex; align-items: center; gap: 3px; font: 800 11px/1.2 var(--body); color: rgba(255,255,255,.9); }
.arena-row.here { box-shadow: 0 0 0 3px #ffd34d, 0 0 26px -2px rgba(255,200,40,.7), 0 12px 22px -10px rgba(0,0,0,.8); }
.arena-row.locked { opacity: 1; }
.arena-row.locked .ar-bg, .arena-row.locked .ar-hero { filter: grayscale(.9) brightness(.6); }
.arena-row.locked .ar-name { color: rgba(255,255,255,.75); }

/* The ladder, a little more room between the arenas and no gold thread (the user, 2026-10-02); and each
   arena's reward for getting there on a frosted glass tile in its top-right corner. */
.arena-list { gap: 30px; }
.arena-row + .arena-row::before { content: none; }
.ar-reward { position: absolute; top: 10px; right: 10px; z-index: 2; display: grid; justify-items: center; gap: 2px; width: 82px;
  padding: 6px 6px 7px; border-radius: 14px; color: #fff; text-align: center;
  background: rgba(255,255,255,.14); -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.4), 0 6px 14px -8px rgba(0,0,0,.7); }
.arw-art { display: grid; place-items: center; height: 34px; }
.arw-art img { max-height: 34px; max-width: 46px; object-fit: contain; filter: drop-shadow(0 3px 3px rgba(0,0,0,.45)); }
.arw-what { font: 800 10.5px/1.15 var(--body); }
.arw-state { font: 900 8.5px/1 var(--body); letter-spacing: .1em; color: rgba(255,255,255,.75); }
.ar-reward.ready { background: rgba(255,211,77,.28); box-shadow: inset 0 0 0 1.5px #ffd34d, 0 0 16px rgba(255,200,40,.6); animation: arwReady 1.8s ease-in-out infinite; }
.ar-reward.ready .arw-state { color: #ffe680; }
.ar-reward.taken { opacity: .6; }
.ar-reward.taken .arw-state { color: #7dffa4; }
.ar-reward:not([disabled]):active { transform: scale(.95); }
@keyframes arwReady { 50% { box-shadow: inset 0 0 0 1.5px #fff, 0 0 22px rgba(255,200,40,.85); } }
@media (prefers-reduced-motion: reduce) { .ar-reward.ready { animation: none; } }
/* the model moves down a little so the tile and it share the corner */
.ar-hero { top: 58%; }

/* ...the reward between the arenas instead (the user, 2026-10-02: "the rewards between the arenas,
   always"): a frosted glass strip centred in the gap, the prize, its name and its state in a row. */
.arena-list { gap: 12px; }
.ar-reward { position: relative; top: auto; right: auto; justify-self: center; width: auto; min-width: 200px;
  display: flex; align-items: center; gap: 10px; padding: 7px 14px 7px 8px; border-radius: 999px; text-align: left; }
.arw-art { height: 30px; width: 30px; }
.arw-art img { max-height: 30px; max-width: 30px; }
.arw-what { font: 800 12.5px/1.1 var(--body); }
.arw-state { margin-left: auto; font-size: 9px; }
.ar-hero { top: 50%; }

/* The arenas' page on your own arena, softened and darkened, with light falling from the top - not a
   flat blue (the user, 2026-10-02: "a better background"). */
.overlay.arenas-overlay { background: #0a0e2c; isolation: isolate; }
.overlay.arenas-overlay::before { content: ""; position: absolute; inset: -30px; z-index: -1;
  background: var(--arena-bg) center / cover no-repeat; filter: blur(10px) brightness(.75) saturate(1.25); }
.overlay.arenas-overlay::after { content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: radial-gradient(80% 45% at 50% 0%, rgba(255,240,200,.18), transparent 70%),
              linear-gradient(180deg, rgba(10,10,20,.1), rgba(10,10,20,.5)); }

/* ...and each arena's reward between the cards as a prize, not a control (the user: "the tiles feel a
   bit robotic"): no box - the prize itself, big, on a soft glow, its name in the game's lettering,
   and only a small note under it: what it takes, a gold "tap to collect", or a quiet tick. */
.ar-reward { min-width: 0; padding: 2px 6px; flex-direction: column; gap: 3px; border-radius: 0; text-align: center;
  background: none; -webkit-backdrop-filter: none; backdrop-filter: none; box-shadow: none; animation: none; }
.arw-art { position: relative; width: 56px; height: 44px; }
.arw-art::before { content: ""; position: absolute; inset: -10px -14px; z-index: -1; border-radius: 50%;
  background: radial-gradient(closest-side, rgba(255,220,120,.45), transparent); }
.arw-art img { max-height: 44px; max-width: 52px; filter: drop-shadow(0 5px 6px rgba(0,0,0,.55)); }
.arw-what { font: 400 15px/1 var(--display); letter-spacing: .03em; color: #fff; text-shadow: 0 2px 0 rgba(0,0,0,.55); }
.arw-state { margin: 0; display: inline-flex; align-items: center; gap: 3px; font: 800 10px/1 var(--body); letter-spacing: .08em; color: rgba(255,255,255,.7); }
.arw-state .tr-ico { width: 13px; height: 13px; }
.ar-reward.ready { background: none; box-shadow: none; animation: arwBob 2.2s ease-in-out infinite; }
.ar-reward.ready .arw-state { padding: 4px 9px; border-radius: 999px; color: #3a2600; background: linear-gradient(180deg, #ffe98d, #ffc21a); box-shadow: 0 2px 0 #b86e00; }
.ar-reward.ready .arw-art::before { background: radial-gradient(closest-side, rgba(255,210,80,.75), transparent); }
.ar-reward.taken { opacity: .55; }
.ar-reward.taken .arw-state { color: #7dffa4; }
.ar-reward.ahead .arw-art img { filter: grayscale(.4) drop-shadow(0 5px 6px rgba(0,0,0,.55)); }
@keyframes arwBob { 50% { translate: 0 -3px; } }
@media (prefers-reduced-motion: reduce) { .ar-reward.ready { animation: none; } }

/* Trophies on the arenas page after the user's reference (2026-10-02): the gold cup leaning over the
   left end of a soft dark plate, the count in the game's lettering, yellow with a dark brown edge. */
.cup-count { display: inline-flex; align-items: center; }
.cup-count img { position: relative; z-index: 1; width: 1.9em; height: 1.9em; margin-right: -.55em;
  filter: drop-shadow(0 2px 2px rgba(0,0,0,.35)); }
.cup-count b { padding: .2em .65em .2em .75em; border-radius: .45em; font: 400 1em/1 var(--display); letter-spacing: .02em;
  color: #ffd52e; -webkit-text-stroke: .14em #3d2300; paint-order: stroke fill; text-shadow: 0 .09em 0 #3d2300;
  background: rgba(0,0,0,.28); box-shadow: inset 0 2px 4px rgba(0,0,0,.25), inset 0 -1px 0 rgba(255,255,255,.08); }
.arenas-trophies { padding: 0; border-radius: 0; background: none; box-shadow: none; font-size: 22px; }
.ar-min .cup-count { font-size: 17px; }
.arw-state .cup-count { font-size: 13px; letter-spacing: 0; }
.arena-row.locked .cup-count b { color: #e9ecf5; }
/* the grid squeezed the arena you are in under its own bar and caption: rows as tall as their card */
.arena-list { grid-auto-rows: max-content; }
/* ...with the game's real trophy instead of a drawn cup (the user: "put the real trophy model"): it is
   tall and slim, so it stands taller than the plate and narrower */
.cup-count img { width: auto; height: 2.3em; margin-right: -.35em; filter: drop-shadow(0 2px 3px rgba(0,0,0,.5)); }
/* the count in white, not gold (the user, 2026-10-02), with a dark edge so it still reads on the picture */
.cup-count b { color: #fff; -webkit-text-stroke-color: #141a3a; text-shadow: 0 .09em 0 #141a3a; }
/* ...gold after all, but metal gold, not yellow (the user, 2026-10-02): a polished gradient through the
   figures, its dark edge from drop-shadows on the figures alone (a stroke would eat the gradient) */
.cup-count b { -webkit-text-stroke: 0; text-shadow: none; }
.cup-count b i { font-style: normal; color: transparent; -webkit-background-clip: text; background-clip: text;
  background-image: linear-gradient(180deg, #fff3c4 0%, #f3cf6e 30%, #c98f22 55%, #e9b850 75%, #fbe39a 100%);
  filter: drop-shadow(0 1.5px 0 #2e1c00) drop-shadow(0 0 .6px #2e1c00); }
.arena-row.locked .cup-count b i { background-image: linear-gradient(180deg, #ffffff, #c9cedb 55%, #eef0f6); }

/* The rewards between the arenas, made exciting (the user, 2026-10-03): one waiting to be taken turns
   in place on a slow wheel of gold rays with sparkles winking round it, over a big gold COLLECT with a
   shine running across it; taking it pops it with a flash. Ones still ahead and ones taken stay still. */
.ar-reward.ready { gap: 6px; padding-top: 14px; animation: none; }
.ar-reward.ready .arw-art { width: 104px; height: 78px; isolation: isolate; }
.ar-reward.ready .arw-art img { max-height: 70px; max-width: 80px; }
.arw-spin { position: absolute; left: 50%; top: 50%; translate: -50% -50%; height: 76px; width: auto; max-width: 100px;
  opacity: 0; pointer-events: none; filter: drop-shadow(0 6px 6px rgba(0,0,0,.5)); }
.arw-spin.on { opacity: 1; }
.arw-art:has(.arw-spin.on) img { visibility: hidden; }
.arw-rays { position: absolute; left: 50%; top: 50%; width: 170px; height: 170px; translate: -50% -50%; z-index: -1; border-radius: 50%;
  background: repeating-conic-gradient(from 0deg, rgba(255,226,130,.55) 0deg 9deg, rgba(255,226,130,0) 9deg 24deg);
  -webkit-mask: radial-gradient(closest-side, #000 18%, rgba(0,0,0,.6) 45%, transparent 100%);
  mask: radial-gradient(closest-side, #000 18%, rgba(0,0,0,.6) 45%, transparent 100%);
  animation: arwRays 10s linear infinite; }
.ar-reward.ready .arw-art::before { inset: -18px -22px; background: radial-gradient(closest-side, rgba(255,214,90,.85), rgba(255,170,30,.25) 60%, transparent); }
.arw-spark { position: absolute; z-index: 2; width: 14px; height: 14px; background: #fffbe6;
  clip-path: polygon(50% 0, 61% 39%, 100% 50%, 61% 61%, 50% 100%, 39% 61%, 0 50%, 39% 39%);
  filter: drop-shadow(0 0 4px #ffd84a); transform: scale(0); animation: arwSpark 2.4s ease-in-out infinite; }
.arw-spark:nth-of-type(1) { left: -6px; top: 6px; }
.arw-spark:nth-of-type(2) { right: -8px; top: 30px; width: 18px; height: 18px; animation-delay: .8s; }
.arw-spark:nth-of-type(3) { left: 14px; bottom: -6px; width: 10px; height: 10px; animation-delay: 1.6s; }
.ar-reward.ready .arw-what { font-size: 18px; }
.ar-reward.ready .arw-state { position: relative; overflow: hidden; padding: 8px 30px 7px; border-radius: 12px;
  font: 400 17px/1 var(--display); letter-spacing: .06em; color: #fff; -webkit-text-stroke: 3.5px #7a3d00; paint-order: stroke fill;
  background: linear-gradient(180deg, #ffef9a, #ffc527 50%, #f09a00); border: 2px solid #7a3d00;
  box-shadow: inset 0 2px 0 rgba(255,255,255,.6), 0 4px 0 #7a3d00, 0 0 18px rgba(255,190,40,.55); animation: arwPulse 1.6s ease-in-out infinite; }
.ar-reward.ready .arw-state::after { content: ""; position: absolute; top: -10%; bottom: -10%; left: -40%; width: 30%; transform: skewX(-20deg);
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.75), transparent); animation: arwShine 2.6s ease-in-out infinite; }
.ar-reward.ready:active .arw-state { translate: 0 3px; box-shadow: inset 0 2px 0 rgba(255,255,255,.6), 0 1px 0 #7a3d00; }
/* taken: it swells, flashes white and goes */
.ar-reward.claiming .arw-art > :is(img, canvas) { animation: arwTake .5s cubic-bezier(.3,1.6,.5,1) forwards; }
.ar-reward.claiming .arw-art::after { content: ""; position: absolute; left: 50%; top: 50%; width: 30px; height: 30px; translate: -50% -50%;
  border-radius: 50%; border: 4px solid #fff6c2; animation: arwBurst .5s ease-out forwards; }
.ar-reward.claiming .arw-state, .ar-reward.claiming .arw-what { opacity: .4; transition: opacity .2s; }
@keyframes arwRays { to { rotate: 360deg; } }
@keyframes arwSpark { 0%, 100% { transform: scale(0) rotate(0deg); } 25% { transform: scale(1) rotate(45deg); } 45% { transform: scale(0) rotate(90deg); } }
@keyframes arwPulse { 50% { scale: 1.06; } }
@keyframes arwShine { 0% { left: -40%; } 55%, 100% { left: 130%; } }
@keyframes arwTake { 40% { scale: 1.45; filter: brightness(2) drop-shadow(0 0 12px #fff); } 100% { scale: 1.6; opacity: 0; translate: 0 -24px; } }
@keyframes arwBurst { to { width: 190px; height: 190px; opacity: 0; border-width: 1px; } }
@media (prefers-reduced-motion: reduce) { .arw-rays, .arw-spark, .ar-reward.ready .arw-state, .ar-reward.ready .arw-state::after { animation: none; } }
/* a pack stands taller than a coin: its turn gets the room it needs */
.ar-reward.ready .arw-art:has(.arw-spin[data-sheet*="pack_"]) { height: 96px; }
.arw-spin[data-sheet*="pack_"] { height: 96px; }

/* A sticker out of a pack, made an event (the user, 2026-10-03): its clip plays on the card, and round
   it a slow wheel of rainbow rays, a glow, a burst of confetti and a frame whose colour keeps moving.
   All of it for a Legendary; an Epic gets the glow and the burst in its own colour, a Rare the glow. */
.op-sticker-card .op-sticker-clip { width: 100%; height: 100%; object-fit: contain; background: #fff; }
.op-aura { position: absolute; left: 50%; top: 50%; width: 0; height: 0; z-index: -1; pointer-events: none; }
.op-aura-rays, .op-aura-glow { position: absolute; left: 50%; top: 50%; translate: -50% -50%; border-radius: 50%; }
.op-aura-rays { width: 560px; height: 560px; opacity: 0; animation: opAuraIn .6s .25s ease-out forwards, opAuraTurn 14s linear infinite;
  -webkit-mask: radial-gradient(closest-side, #000 22%, rgba(0,0,0,.55) 50%, transparent 100%);
  mask: radial-gradient(closest-side, #000 22%, rgba(0,0,0,.55) 50%, transparent 100%); }
.op-aura-glow { width: 360px; height: 360px; opacity: 0; animation: opAuraIn .5s .2s ease-out forwards, opGlowPulse 2.2s 1s ease-in-out infinite;
  background: radial-gradient(closest-side, color-mix(in srgb, var(--r) 85%, #fff), color-mix(in srgb, var(--r) 45%, transparent) 55%, transparent); }
.op-conf { position: absolute; left: 0; top: 0; width: 10px; height: 16px; border-radius: 2px; opacity: 0;
  background: hsl(var(--h) 95% 60%); animation: opConf 1.5s var(--t) cubic-bezier(.15,.7,.3,1) forwards; }
.op-conf:nth-child(3n) { width: 12px; height: 12px; border-radius: 50%; }
.op-conf:nth-child(4n) { clip-path: polygon(50% 0, 61% 39%, 100% 50%, 61% 61%, 50% 100%, 39% 61%, 0 50%, 39% 39%); width: 18px; height: 18px; background: #fff6c2; }
/* the Legendary: rainbow rays, and the card's edge running through the colours */
.op-sticker-card.r-legendary .op-aura-rays { background: repeating-conic-gradient(from 0deg,
  hsl(0 95% 62% / .75) 0deg 8deg, transparent 8deg 15deg, hsl(45 100% 60% / .75) 15deg 23deg, transparent 23deg 30deg,
  hsl(120 85% 55% / .7) 30deg 38deg, transparent 38deg 45deg, hsl(195 95% 60% / .75) 45deg 53deg, transparent 53deg 60deg,
  hsl(275 90% 66% / .75) 60deg 68deg, transparent 68deg 75deg, hsl(320 95% 64% / .75) 75deg 83deg, transparent 83deg 90deg); }
.op-sticker-card.r-legendary .op-aura-glow { background: radial-gradient(closest-side, #fff8d6, rgba(255,200,60,.65) 40%, rgba(255,90,200,.25) 70%, transparent); }
.op-sticker-card.r-legendary .op-face { box-shadow: 0 18px 34px -10px rgba(0,0,0,.8); }
.op-sticker-card.r-legendary .op-face::after { content: ""; position: absolute; inset: 0; z-index: 3; border-radius: inherit; padding: 4px;
  background: conic-gradient(from var(--edge-a, 0deg), #ff4d4d, #ffd23f, #4dff88, #3fd2ff, #b06bff, #ff5ed2, #ff4d4d);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
  animation: opEdge 3s linear infinite; pointer-events: none; }
@property --edge-a { syntax: "<angle>"; inherits: false; initial-value: 0deg; }
/* the Epic: its own colour, no rainbow; a Rare: the glow alone */
.op-sticker-card.r-epic .op-aura-rays { background: repeating-conic-gradient(from 0deg, color-mix(in srgb, var(--r) 70%, transparent) 0deg 8deg, transparent 8deg 22deg); }
.op-sticker-card.r-rare .op-aura-rays, .op-sticker-card.r-rare .op-conf, .op-sticker-card.r-common .op-aura-rays, .op-sticker-card.r-common .op-conf { display: none; }
@keyframes opAuraIn { to { opacity: 1; } }
@keyframes opAuraTurn { to { rotate: 360deg; } }
@keyframes opGlowPulse { 50% { scale: 1.12; } }
@keyframes opConf { 0% { opacity: 1; transform: translate(0, 0) scale(.3) rotate(0deg); }
  70% { opacity: 1; } 100% { opacity: 0; transform: translate(var(--x), var(--y)) scale(1) rotate(540deg); } }
@keyframes opEdge { to { --edge-a: 360deg; } }
@media (prefers-reduced-motion: reduce) { .op-aura-rays, .op-aura-glow, .op-sticker-card .op-face::after { animation: opAuraIn .3s forwards; } }

/* ...and the sticker that comes out is the sticker as it is in a match: its own wide picture at its
   own proportions in its white bubble, a Legendary in its ring (the user, 2026-10-03), with the aura
   behind it. Replaces the portrait card it used to be cropped onto. */
.op-stk { position: relative; display: flex; flex-direction: column; align-items: center; gap: 10px; width: min(78vw, 320px); }
.op-stk .sk-bubble { width: 100%; }
.op-stk .sk-bubble::after { display: none; }
.op-stk .sk-bubble img { display: block; width: 100%; height: auto; border-radius: 14px; }
.op-stk.legend .sk-bubble { border: 4px solid transparent;
  background: linear-gradient(#fff, #fff) padding-box, var(--ring) border-box;
  box-shadow: inset 0 0 0 2.5px #15171d, -4px 0 16px -2px var(--g1), 4px 0 16px -2px var(--g2), 0 0 26px -4px var(--g2);
  animation: skRing 2.8s ease-in-out infinite; }
.op-stk-name { font: 400 22px/1 var(--display); color: #fff; text-shadow: 0 3px 0 rgba(0,0,0,.5), 0 2px 12px rgba(0,0,0,.6); }
.op-stk .op-aura { top: 38%; }
.op-stk.r-legendary .op-aura-rays { background: repeating-conic-gradient(from 0deg,
  hsl(0 95% 62% / .75) 0deg 8deg, transparent 8deg 15deg, hsl(45 100% 60% / .75) 15deg 23deg, transparent 23deg 30deg,
  hsl(120 85% 55% / .7) 30deg 38deg, transparent 38deg 45deg, hsl(195 95% 60% / .75) 45deg 53deg, transparent 53deg 60deg,
  hsl(275 90% 66% / .75) 60deg 68deg, transparent 68deg 75deg, hsl(320 95% 64% / .75) 75deg 83deg, transparent 83deg 90deg); }
.op-stk.r-legendary .op-aura-glow { background: radial-gradient(closest-side, #fff8d6, rgba(255,200,60,.65) 40%, rgba(255,90,200,.25) 70%, transparent); }
.op-stk.r-epic .op-aura-rays { background: repeating-conic-gradient(from 0deg, color-mix(in srgb, var(--r) 70%, transparent) 0deg 8deg, transparent 8deg 22deg); }
.op-stk:is(.r-rare, .r-common) :is(.op-aura-rays, .op-conf) { display: none; }
@media (prefers-reduced-motion: reduce) { .op-stk.legend .sk-bubble { animation: none; } }

/* PACKS TO GLORY's lights, moving (the user, 2026-10-03: "an animation for the background, the lights
   there moving a little"): two stadium beams from the top swaying slowly to and fro, and a fine glitter
   drifting up through them and twinkling. Behind everything, nothing to tap. */
.overlay.ptg-overlay { isolation: isolate; }
.overlay.ptg-overlay::before, .overlay.ptg-overlay::after { content: ""; position: absolute; z-index: -1; pointer-events: none; }
.overlay.ptg-overlay::before { left: -40%; right: -40%; top: -10%; height: 120%; transform-origin: 50% 0;
  background:
    conic-gradient(from 162deg at 32% 0%, transparent 0deg, rgba(255,226,150,.20) 7deg, rgba(255,226,150,.06) 13deg, transparent 18deg),
    conic-gradient(from 182deg at 68% 0%, transparent 0deg, rgba(205,160,255,.22) 7deg, rgba(205,160,255,.06) 13deg, transparent 18deg);
  will-change: transform; animation: ptgBeams 9s ease-in-out infinite alternate; }
.overlay.ptg-overlay::after { left: 0; right: 0; top: 0; height: calc(100% + 260px); will-change: transform, opacity;
  background:
    radial-gradient(2px 2px at 20px 40px, rgba(255,236,170,.9), transparent 70%),
    radial-gradient(1.5px 1.5px at 120px 90px, rgba(255,255,255,.85), transparent 70%),
    radial-gradient(2.5px 2.5px at 70px 170px, rgba(255,214,110,.8), transparent 70%),
    radial-gradient(1.5px 1.5px at 180px 220px, rgba(255,255,255,.75), transparent 70%),
    radial-gradient(2px 2px at 150px 10px, rgba(220,190,255,.8), transparent 70%);
  background-size: 210px 260px;
  animation: ptgGlitter 22s linear infinite, ptgTwinkle 2.8s ease-in-out infinite alternate; }
@keyframes ptgBeams { from { transform: rotate(-7deg); } to { transform: rotate(7deg); } }
@keyframes ptgGlitter { to { transform: translateY(-260px); } }
@keyframes ptgTwinkle { from { opacity: .45; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .overlay.ptg-overlay::before, .overlay.ptg-overlay::after { animation: none; } }

/* The trophy count on the menu in the same polished gold as the arenas page (the user, 2026-10-03:
   "show the trophies on the menu page in gold too"): a metal gradient through the figures, its dark
   edge from drop-shadows on the figures alone (a text-shadow would sit on top of the clipped gold). */
#trophies { color: transparent; text-shadow: none; -webkit-background-clip: text; background-clip: text;
  background-image: linear-gradient(180deg, #fff3c4 0%, #f3cf6e 30%, #c98f22 55%, #e9b850 75%, #fbe39a 100%);
  filter: drop-shadow(0 1.5px 0 #2e1c00) drop-shadow(0 0 .6px #2e1c00); }

/* The Opening Tournament on the user's own picture (2026-10-03): the 2CLUBS opening - darkened top and
   bottom so the name and the buttons read, like the Starter's. */
.cup-opening { background:
    linear-gradient(180deg, rgba(0,10,40,.7), rgba(0,10,40,.42) 30%, rgba(0,10,40,.5) 60%, rgba(0,10,40,.82)),
    url("../assets/ui/cup_opening_bg.webp?v=1") center 35% / cover no-repeat, #1b3fa8; }
/* A stage's prize as pictures: coins, gems, a pack, a sticker (cupPrizeHTML) */
.cup-prizes { display: inline-flex; align-items: center; gap: 6px; }
.cp-bit { display: inline-flex; align-items: center; gap: 2px; }
.cp-bit img { width: 14px; height: 14px; object-fit: contain; }
.cp-pack img { width: auto; height: 22px; }
.cp-sticker img { width: auto; height: 18px; border-radius: 4px; background: #fff; box-shadow: 0 0 0 1.5px var(--g1, #fff); }
.cup-prizes.cp-big .cp-bit img { width: 20px; height: 20px; }
.cup-prizes.cp-big .cp-pack img { width: auto; height: 34px; }
.cup-prizes.cp-big .cp-sticker img { width: auto; height: 26px; }

/* The Opening Tournament's bracket over its busy picture (the user, 2026-10-03: "show the bracket more
   clearly in the new tournament"): THE STARTER's treatment - no tile under it, the slots darker and
   edged, the joints in full white, every label with a shadow - and the prizes on a dark pill of their own. */
.cup-opening .cb-slot { background: rgba(0,0,0,.62); box-shadow: inset 0 0 0 1px rgba(255,255,255,.5), 0 2px 6px rgba(0,0,0,.5); }
.cup-opening .cb-col.now .cb-slot.top { background: #fff; }
.cup-opening .cb-col.done .cb-slot.top { background: rgba(255,255,255,.25); box-shadow: inset 0 0 0 1px rgba(255,255,255,.65); }
.cup-opening .cb-col:not(.cb-win) .cb-match::after { border-color: #fff; filter: drop-shadow(0 1px 2px rgba(0,0,0,.8)); }
.cup-opening .cb-col:not(.cb-win) .cb-match::before { background: #fff; box-shadow: 0 1px 2px rgba(0,0,0,.8); }
.cup-opening .cb-stage, .cup-opening .cb-pay { color: #fff; text-shadow: 0 1px 2px #000, 0 0 6px rgba(0,0,0,.8); }
.cup-opening .cb-pay .cup-prizes { padding: 2px 7px; border-radius: 999px; background: rgba(0,0,0,.6); box-shadow: inset 0 0 0 1px rgba(255,255,255,.3); }
.cup-opening .cup-blurb, .cup-opening .cup-now, .cup-opening .cup-prize { color: #fff; text-shadow: 0 1px 3px #000, 0 0 10px rgba(0,0,0,.7); }

/* PACKS TO GLORY's banner floodlights, alive (the user, 2026-10-03: "an animation for those lights in
   the background too"): a star of light on each lamp in the picture, flaring and fading in turn, and a
   slow shimmer of light passing over the stands. Above the picture, under the scrim and the words. */
#ptgOverlay .pass-hero > .ph-glints { position: absolute; inset: 0; z-index: 0; pointer-events: none; overflow: hidden; }
.ph-glints i { position: absolute; left: var(--x); top: var(--y); width: 78px; height: 78px; translate: -50% -50%;
  background:
    radial-gradient(closest-side, #fff 0, rgba(255,255,255,.9) 18%, rgba(200,220,255,.35) 45%, transparent 75%),
    linear-gradient(90deg, transparent 0 46%, rgba(255,255,255,.85) 50%, transparent 54% 100%) center / 100% 3px no-repeat,
    linear-gradient(0deg, transparent 0 46%, rgba(255,255,255,.85) 50%, transparent 54% 100%) center / 3px 100% no-repeat;
  opacity: 0; scale: .4; will-change: transform, opacity;
  animation: phGlint 2.6s var(--t) ease-in-out infinite; }
.ph-glints::after { content: ""; position: absolute; top: -20%; bottom: -20%; left: -40%; width: 35%; transform: skewX(-18deg);
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.14), transparent); will-change: transform;
  animation: phSweep 7s 1s ease-in-out infinite; }
@keyframes phGlint { 0%, 100% { opacity: 0; scale: .4; rotate: 0deg; } 40% { opacity: 1; scale: 1; rotate: 20deg; } 60% { opacity: .85; scale: .9; } }
@keyframes phSweep { 0% { translate: 0 0; } 45%, 100% { translate: 485% 0; } }
@media (prefers-reduced-motion: reduce) { .ph-glints i, .ph-glints::after { animation: none; } }

/* A cut clock drops to its new length at the start of the turn, in red (renderClock, clockFull). */
#timerFill.cut { transition: transform .5s cubic-bezier(.2,.9,.3,1);
  background: linear-gradient(180deg, #ffb3bb, var(--red) 55%, #c32333); box-shadow: 0 0 18px rgba(255,77,94,.85); }

/* PACKS TO GLORY smooth and in its own colours (the user, 2026-10-03: "the banner sticks and everything
   is stuck there", "the yellow does not fit", "the OPEN button is ugly"):
   - no backdrop blur on the ten cards: each one re-blurred the moving lights behind it on every frame,
     which is what froze the page on the phone. A solid dark glass instead, the same look.
   - no gold edge on every card now that every mission is open - a quiet hairline; the bars in the
     banner's violet; only a card whose pack is waiting lights up, in violet.
   - OPEN as a real game button in those colours, with a shine across it. */
.ptg-card { backdrop-filter: none; -webkit-backdrop-filter: none; background: rgba(14,8,42,.78); }
.ptg-stop.open .ptg-card { background: rgba(14,8,42,.78); box-shadow: inset 0 0 0 1px rgba(255,255,255,.14); }
.ptg-meter > span { background: linear-gradient(90deg, #8e5bff, #e05cff); }
.ptg-badge.num { color: #fff; }
.ptg-stop.ready .ptg-card { background: linear-gradient(180deg, rgba(80,30,150,.85), rgba(30,10,70,.85));
  box-shadow: inset 0 0 0 1.5px #d9a8ff, 0 0 18px rgba(190,90,255,.55); }
.ptg-claim { position: relative; overflow: hidden; padding: 9px 18px 8px; border-radius: 12px; border: 2px solid #3d0d6b;
  font: 400 16px/1 var(--display); letter-spacing: .06em; color: #fff; -webkit-text-stroke: 3px #3d0d6b; paint-order: stroke fill;
  background: linear-gradient(180deg, #f6c9ff, #c04dff 50%, #8a2be2);
  box-shadow: inset 0 2px 0 rgba(255,255,255,.55), 0 3px 0 #3d0d6b, 0 0 14px rgba(200,90,255,.6); }
.ptg-claim::after { content: ""; position: absolute; top: -10%; bottom: -10%; left: -40%; width: 30%; transform: skewX(-20deg);
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.7), transparent); animation: arwShine 2.6s ease-in-out infinite; }
.ptg-claim:active { translate: 0 2px; box-shadow: inset 0 2px 0 rgba(255,255,255,.55), 0 1px 0 #3d0d6b; }
/* ...and the line over its name in the banner's violet, not the pass's yellow */
.ptg-hero .ph-kicker { color: #e6c2ff; }

/* Locked stars with a lock worth looking at (the user, 2026-10-03: "something more interesting, with
   colour"): a gold padlock with a polished steel shackle and a keyhole, on a dark disc ringed and lit in
   the star's own rarity colour, giving a small rattle now and then (each card on its own beat) - as if
   it were being tried. The same lock on the pedestal, bigger. */
.power-card.locked::after, .stage.locked::after {
  background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><defs><linearGradient id="b" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="%23ffef9a"/><stop offset=".5" stop-color="%23ffc233"/><stop offset="1" stop-color="%23d98200"/></linearGradient><linearGradient id="s" x1="0" y1="0" x2="1" y2="0"><stop offset="0" stop-color="%238f9fc8"/><stop offset=".5" stop-color="%23ffffff"/><stop offset="1" stop-color="%237d8db8"/></linearGradient></defs><path d="M10.5 14V10a5.5 5.5 0 0 1 11 0v4" fill="none" stroke="%231d1240" stroke-width="5.6" stroke-linecap="round"/><path d="M10.5 14V10a5.5 5.5 0 0 1 11 0v4" fill="none" stroke="url(%23s)" stroke-width="3" stroke-linecap="round"/><rect x="6" y="13" width="20" height="16" rx="4.2" fill="url(%23b)" stroke="%235a3500" stroke-width="1.5"/><rect x="8.4" y="15.2" width="15.2" height="2.2" rx="1.1" fill="%23fff8d0" opacity=".75"/><circle cx="16" cy="20.6" r="2.4" fill="%233a2200"/><path d="M14.9 21.6h2.2l.7 4.2h-3.6z" fill="%233a2200"/></svg>') center / 64% no-repeat, radial-gradient(circle at 50% 32%, #353c86, #10143a 72%);
  box-shadow: 0 0 0 2.5px var(--r, #ffd34d), 0 0 14px color-mix(in srgb, var(--r, #ffd34d) 70%, transparent), 0 4px 8px rgba(0,0,0,.55); }
.power-card.locked::after { width: 46px; height: 46px; top: calc(50% - 23px); left: calc(50% - 23px);
  animation: lockRattle 4.2s ease-in-out infinite; animation-delay: calc(var(--i, 0) * -0.7s); }
.power-card.locked:nth-child(3n+1)::after { animation-delay: -1.3s; }
.power-card.locked:nth-child(3n+2)::after { animation-delay: -2.6s; }
.stage.locked::after { width: 66px; height: 66px; left: calc(50% - 33px); top: calc(46% - 33px);
  box-shadow: 0 0 0 3px var(--r, #ffd34d), 0 0 22px color-mix(in srgb, var(--r, #ffd34d) 75%, transparent), 0 8px 18px rgba(0,0,0,.5);
  animation: pop .35s cubic-bezier(.2,1.6,.4,1), lockRattle 4.2s 1s ease-in-out infinite; }
@keyframes lockRattle { 0%, 82%, 100% { rotate: 0deg; } 85% { rotate: -11deg; } 88% { rotate: 9deg; } 91% { rotate: -6deg; } 94% { rotate: 3deg; } }
@media (prefers-reduced-motion: reduce) { .power-card.locked::after, .stage.locked::after { animation: none; } }

/* the flag that turns over (flipReel): a card in the frame the flag lands in, turned in depth */
.cine-art.reel-win.flag.flipper { overflow: visible; perspective: 600px; }
.cine-art.flipper .reel-strip { transform-style: preserve-3d; will-change: transform; }
.cinema-club .cine-art.flipper canvas.reel-cv.cine-flag { width: 150px; height: 100px; border-radius: 10px; }

/* PACKS TO GLORY with a pack waiting (the user, 2026-10-03: "when a pack is won everything sticks, the
   banner and the page lag"): the OPEN button's shine moved with a transform, not by its `left` (a layout
   of the page on every frame, on top of the moving lights), and the button no longer pops in and out. */
.ptg-claim::after { left: 0; translate: -140% 0; animation: ptgShine 2.6s ease-in-out infinite; will-change: translate; }
@keyframes ptgShine { 0% { translate: -140% 0; } 55%, 100% { translate: 440% 0; } }
.ptg-btn.ready .ptg-open { animation: none; }
/* ...and the banner fading out in an oval into the page's violet, rather than ending on a hard edge
   (the user, 2026-10-03: "an oval fade on the banner"). The words over it are untouched. */
.ptg-hero { background: none; box-shadow: none; }
/* (a mask that faded the picture itself out looked cut off - the user: "the banner is cut": the picture
   stays whole, and an oval of the page's violet closes in over its edges instead) */
.ptg-hero::after { background:
  radial-gradient(ellipse 72% 88% at 50% 40%, transparent 52%, rgba(36,16,86,.55) 78%, rgba(36,16,86,.92) 100%),
  linear-gradient(180deg, transparent 50%, rgba(20,8,50,.3) 80%, rgba(20,8,50,.5) 100%); }

/* the flag reel: a little air between the flags (spinReel, n = 11) */
.cine-art.reel-win.flag .reel-strip { gap: 12px; }

/* a cup prize turning (cupPrizeHTML, spinSheets): the canvas over the flat picture, the picture gone once it turns */
.cp-art { position: relative; display: inline-grid; place-items: center; }
.cp-art .cp-spin { position: absolute; left: 50%; top: 50%; translate: -50% -50%; height: 100%; width: auto; opacity: 0; pointer-events: none; }
.cp-art .cp-spin.on { opacity: 1; }
.cp-art:has(.cp-spin.on) > img { visibility: hidden; }
.cp-pack .cp-art .cp-spin { height: 115%; }

/* The Opening Tournament's prizes in the bracket, laid out as prizes rather than boxed (the user,
   2026-10-04: "arrange the prize models better in the bracket - not inside tiles and circles"): no pill
   behind them, no ring round the sticker - each stage's prize stands under its match, the picture over
   its figure, a little bigger, the figure in the game's lettering with a shadow to carry it. */
.cup-opening .cb-pay .cup-prizes { padding: 0; border-radius: 0; background: none; box-shadow: none;
  flex-direction: column; align-items: center; gap: 4px; }
.cup-opening .cb-pay .cp-bit { flex-direction: column-reverse; align-items: center; gap: 2px;
  font: 400 13px/1 var(--display); color: #fff; text-shadow: 0 1px 2px #000, 0 0 6px rgba(0,0,0,.85); }
.cup-opening .cb-pay .cp-bit img { width: 22px; height: 22px; filter: drop-shadow(0 2px 3px rgba(0,0,0,.6)); }
.cup-opening .cb-pay .cp-pack img { width: auto; height: 36px; }
.cup-opening .cb-pay .cp-sticker img { width: auto; height: 26px; border-radius: 5px; background: none; box-shadow: none;
  filter: drop-shadow(0 2px 4px rgba(0,0,0,.7)); }

/* a pack prize's count (×2) */
.cp-count { font: 400 13px/1 var(--display); color: #ffd84a; text-shadow: 0 1px 2px #000; }

/* The Legendary Pack's tile in the shop (renderPacks): the width of the shelf, under the other three,
   gold on gold - a rolled gold rim, a slow wheel of light turning behind the pack, sparkles winking
   round it, a shine passing over the whole tile now and then, and the name in the game's lettering.
   Everything that moves is a transform or an opacity, so the shop stays smooth on a phone. */
.pack.pack-legend { grid-column: 1 / -1; position: relative; overflow: hidden; isolation: isolate;
  flex-direction: row; align-items: center; justify-content: flex-start; gap: 14px;
  min-height: 140px; padding: 10px 18px 10px 22px; border-radius: 18px; border: 3px solid transparent;
  background: radial-gradient(120% 150% at 22% 45%, #fff6c6 0%, #ffd84a 24%, #eba514 52%, #a96500 100%) padding-box,
              linear-gradient(135deg, #fff7c8, #c98a10 38%, #fff1a0 58%, #8f5200) border-box;
  box-shadow: 0 5px 0 #6e3c00, 0 0 26px rgba(255,190,40,.55), 0 16px 24px -12px rgba(0,0,0,.65); }
.pack.pack-legend:active { transform: translateY(3px); box-shadow: 0 2px 0 #6e3c00, 0 0 20px rgba(255,190,40,.5); }
.pl-rays { position: absolute; left: 70px; top: 50%; width: 300px; height: 300px; translate: -50% -50%; z-index: -1; border-radius: 50%;
  background: repeating-conic-gradient(from 0deg, rgba(255,255,255,.55) 0deg 7deg, rgba(255,255,255,0) 7deg 20deg);
  -webkit-mask: radial-gradient(closest-side, #000 15%, rgba(0,0,0,.5) 45%, transparent 100%);
  mask: radial-gradient(closest-side, #000 15%, rgba(0,0,0,.5) 45%, transparent 100%);
  will-change: transform; animation: plRays 16s linear infinite; }
.pl-shine { position: absolute; top: -20%; bottom: -20%; left: 0; width: 22%; z-index: 2; pointer-events: none;
  transform: skewX(-20deg); translate: -160% 0;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.75), transparent);
  will-change: translate; animation: plShine 3.8s 1s ease-in-out infinite; }
.pl-spark { position: absolute; z-index: 1; width: 14px; height: 14px; background: #fffbe6;
  clip-path: polygon(50% 0, 61% 39%, 100% 50%, 61% 61%, 50% 100%, 39% 61%, 0 50%, 39% 39%);
  scale: 0; will-change: transform; animation: plSpark 2.6s ease-in-out infinite; }
.pl-spark:nth-of-type(1) { left: 18px; top: 16px; }
.pl-spark:nth-of-type(2) { left: 112px; top: 26px; width: 18px; height: 18px; animation-delay: .7s; }
.pl-spark:nth-of-type(3) { left: 26px; bottom: 18px; width: 10px; height: 10px; animation-delay: 1.4s; }
.pl-spark:nth-of-type(4) { right: 22px; top: 18px; width: 12px; height: 12px; animation-delay: 2s; }
.pack-legend .pl-art { position: relative; z-index: 1; width: auto; max-width: none; height: 122px; aspect-ratio: auto;
  filter: drop-shadow(0 8px 10px rgba(90,40,0,.6)); will-change: transform; animation: plFloat 3.2s ease-in-out infinite; }
.pl-text { position: relative; z-index: 1; display: grid; justify-items: start; gap: 10px; }
.pack-legend .pack-name { font: 400 27px/1 var(--display); color: #fff; letter-spacing: .02em; text-align: left;
  -webkit-text-stroke: 5px #6b3a00; paint-order: stroke fill; text-shadow: 0 4px 0 #6b3a00; }
.pack-legend .pack-price { width: auto; margin: 0; padding: 6px 18px; font-size: 17px; color: #ffe58a;
  background: rgba(70,32,0,.78); box-shadow: inset 0 0 0 1.5px rgba(255,230,140,.6); }
.pack-legend .pack-price .pack-free { color: #ffe58a; }
@keyframes plRays { to { rotate: 360deg; } }
@keyframes plShine { 0% { translate: -160% 0; } 45%, 100% { translate: 560% 0; } }
@keyframes plSpark { 0%, 100% { scale: 0; rotate: 0deg; } 30% { scale: 1; rotate: 45deg; } 55% { scale: 0; rotate: 90deg; } }
@keyframes plFloat { 50% { translate: 0 -5px; rotate: -2deg; } }
@media (prefers-reduced-motion: reduce) { .pl-rays, .pl-shine, .pl-spark, .pack-legend .pl-art { animation: none; } }

/* Tournaments before arena 2 (renderCups): a notice above the cups, and each one's button locked. */
.cup-gate { display: flex; align-items: center; gap: 12px; margin: 4px 0 12px; padding: 12px 14px; border-radius: 16px; color: #fff;
  background: linear-gradient(180deg, rgba(20,24,70,.85), rgba(10,12,40,.85)); box-shadow: inset 0 0 0 1.5px rgba(255,211,77,.6); }
.cup-gate > svg { width: 34px; height: 34px; flex: none; }
.cup-gate b { display: block; font: 400 17px/1.1 var(--display); letter-spacing: .03em; }
.cup-gate small { display: inline-flex; align-items: center; gap: 4px; margin-top: 4px; font: 800 12px/1 var(--body); color: #ffd84a; }
.cup-gate .tr-ico { width: auto; height: 18px; }
.cup-go.cup-locked svg { width: 18px; height: 18px; vertical-align: -3px; }

/* ...on the premium pass's own moving clip (the user, 2026-10-04: "behind the Legendary Pack's tile, the
   same video as behind every premium pass tier"), inside the gold rim, lightly warmed so it belongs to
   the tile and the white name still reads. */
.pl-video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; z-index: -2; pointer-events: none; }
.pack.pack-legend { background: linear-gradient(90deg, rgba(120,60,0,.25), rgba(60,25,0,.45)) padding-box,
  linear-gradient(135deg, #fff7c8, #c98a10 38%, #fff1a0 58%, #8f5200) border-box; }
.pack.pack-legend::after { content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: linear-gradient(90deg, rgba(255,200,60,.15), rgba(70,30,0,.45)); }

/* A sticker on a pass rung in its own shape (the user, 2026-10-04: "the sticker shown whole on the
   tier, in its original form, not in a square"): the cut-out itself - no white square, no ring - a
   little larger than the 38px box it stands in, on a soft shadow. */
.pt-art .pt-sticker { width: auto; height: 46px; max-width: 54px; object-fit: contain; padding: 0; border: 0; border-radius: 0;
  background: none; box-shadow: none; animation: none; filter: drop-shadow(0 2px 3px rgba(0,0,0,.45)); }

/* ...and the lock itself an icon, not a picture of a padlock (the user, 2026-10-04: "an icon, not a
   smelly emoji"): a clean white line padlock on the dark disc, the ring still in the rarity's colour. */
.power-card.locked::after, .stage.locked::after {
  background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M7.5 11V8.2a4.5 4.5 0 0 1 9 0V11" fill="none" stroke="white" stroke-width="2.2" stroke-linecap="round"/><rect x="5" y="11" width="14" height="10" rx="2.6" fill="none" stroke="white" stroke-width="2.2"/><path d="M12 14.6v3" stroke="white" stroke-width="2.4" stroke-linecap="round"/></svg>') center / 52% no-repeat, radial-gradient(circle at 50% 35%, #262c66, #0d1033 75%); }

/* The tournaments page before arena 2 (renderCups): locked as a whole - arena 2 standing behind a big
   lock, where they open, and a bar of the trophies still to win (the user, 2026-10-04). */
.cup-locked-page { position: relative; display: grid; justify-items: center; gap: 10px; margin-top: 18px; padding: 26px 18px 24px;
  border-radius: 22px; text-align: center; color: #fff; overflow: hidden;
  background: radial-gradient(90% 70% at 50% 20%, rgba(90,120,255,.35), transparent 70%), linear-gradient(180deg, #1a2468, #0b1036);
  box-shadow: inset 0 0 0 1.5px rgba(255,255,255,.25), 0 16px 30px -14px #000; }
.clp-arena { width: 86%; max-height: 150px; object-fit: contain; filter: grayscale(.7) brightness(.55) drop-shadow(0 10px 14px rgba(0,0,0,.6)); }
.clp-lock { display: grid; place-items: center; width: 72px; height: 72px; margin-top: -54px; border-radius: 50%;
  background: radial-gradient(circle at 50% 35%, #262c66, #0d1033 75%); box-shadow: 0 0 0 3px #ffd34d, 0 0 22px rgba(255,200,40,.5), 0 6px 12px rgba(0,0,0,.5); }
.clp-lock svg { width: 40px; height: 40px; }
.clp-title { font: 400 28px/1 var(--display); letter-spacing: .06em; text-shadow: 0 3px 0 rgba(0,0,0,.45); }
.clp-sub { font: 800 14px/1.2 var(--body); color: #cdd6ff; }
.clp-bar { width: 80%; height: 12px; border-radius: 6px; overflow: hidden; background: rgba(0,0,0,.45); box-shadow: inset 0 0 0 1px rgba(255,255,255,.2); }
.clp-bar > span { display: block; height: 100%; border-radius: inherit; background: linear-gradient(180deg, #fff3b0, #ffc21a 55%, #e08a00); }
.clp-left { display: inline-flex; align-items: center; gap: 5px; font: 800 13px/1 var(--body); color: #ffd84a; }
.clp-left b { font: 400 17px/1 var(--display); color: #fff; }
.clp-left .tr-ico { width: auto; height: 20px; }

/* The PLAY button the same, full size in every arena (the user, 2026-10-04: "PLAY is squashed in some
   arenas - make it a good size, clear and the same in all of them, and just say PLAY"): it no longer
   gives way when the arena's model is tall - nothing on the menu does but the model, which takes the
   room that is left in every arena the way arenas 2-5 already did. */
#home > *:not(.arena-hero) { flex-shrink: 0; }
#home .arena-hero { flex: 1 1 0; min-height: 60px; }
#home .arena-hero img { height: 100%; max-height: min(50vh, 64vw); }
#home #playBtn { flex: none; min-height: 64px; padding-top: 0; padding-bottom: 0; font-size: 32px; letter-spacing: .06em; }

/* The lock as a modelled padlock (tools/model/build_lock.py, the user 2026-10-04: "a proper 3D model of a
   lock"): on every star you do not have, on the pedestal, and on the locked tournaments page - the
   render itself on a soft glow of the star's rarity colour, no disc and no drawn icon. */
.power-card.locked::after, .stage.locked::after {
  background: url("../assets/ui/lock3d.png?v=3") center / contain no-repeat,
              radial-gradient(closest-side, color-mix(in srgb, var(--r, #ffd34d) 55%, transparent), transparent);
  border-radius: 0; box-shadow: none; filter: drop-shadow(0 4px 6px rgba(0,0,0,.6)); }
.power-card.locked::after { width: 46px; height: 60px; top: calc(50% - 30px); left: calc(50% - 23px); }
.stage.locked::after { width: 70px; height: 94px; left: calc(50% - 35px); top: calc(46% - 47px); }
.cup-locked-page { padding-top: 30px; }
.cup-locked-page .clp-lock { display: block; width: 92px; height: auto; margin: 0 0 4px; border-radius: 0; background: none; box-shadow: none;
  filter: drop-shadow(0 8px 12px rgba(0,0,0,.6)) drop-shadow(0 0 18px rgba(255,200,60,.35)); }

/* PACKS TO GLORY's lights moving for real (the user, 2026-10-04: "the lights should animate, actually
   move"): the stadium rays that fanned down from the top were painted into the page's background and
   never moved, and the two beams over them swayed so little it read as still. The rays now live on the
   moving layer - a fan of light from above, swinging wide and slow, breathing brighter and dimmer - and
   the background keeps only its colours and its glow. */
.overlay.ptg-overlay { background:
  radial-gradient(90% 40% at 50% 100%, rgba(255,170,40,.35), transparent 70%),
  radial-gradient(80% 60% at 15% 40%, rgba(160,70,255,.45), transparent 70%),
  linear-gradient(180deg, #3a1677 0%, #241056 45%, #140a38 100%); }
.overlay.ptg-overlay::before { left: -60%; right: -60%; top: -8%; height: 125%; transform-origin: 50% 0;
  background:
    repeating-conic-gradient(from 168deg at 50% 0%, rgba(255,255,255,.13) 0deg 4deg, transparent 4deg 11deg),
    conic-gradient(from 160deg at 32% 0%, transparent 0deg, rgba(255,226,150,.26) 8deg, rgba(255,226,150,.08) 15deg, transparent 21deg),
    conic-gradient(from 180deg at 68% 0%, transparent 0deg, rgba(205,160,255,.28) 8deg, rgba(205,160,255,.08) 15deg, transparent 21deg);
  -webkit-mask: linear-gradient(180deg, #000 30%, transparent 92%); mask: linear-gradient(180deg, #000 30%, transparent 92%);
  animation: ptgSwing 7s ease-in-out infinite alternate, ptgBreathe 3.4s ease-in-out infinite alternate; }
@keyframes ptgSwing { from { transform: rotate(-13deg); } to { transform: rotate(13deg); } }
@keyframes ptgBreathe { from { opacity: .6; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .overlay.ptg-overlay::before { animation: none; } }
/* ...on its white card as a sticker always is (the user, 2026-10-04: "in white as usual, and not over
   the words"): white with rounded corners round the picture at its own shape, held inside the rung's
   38px art box so it never reaches the name under it. */
.pt-art .pt-sticker { height: 38px; width: auto; max-width: 46px; padding: 2px; box-sizing: border-box; object-fit: contain;
  background: #fff; border-radius: 8px; filter: none; box-shadow: 0 2px 0 rgba(0,0,0,.25), 0 0 0 1px rgba(20,30,80,.12); }

/* No lock over the black silhouette on the pedestal (the user, 2026-10-04): the shadow of the star says
   it already - the lock stays on the cards. */
.stage.locked::after { content: none; display: none; }

/* The flag lands where it spun (the user, 2026-10-04: "the flags' animation always has a quick switch
   that ruins it"): the reel's window for a flag is 100px tall, but the box a landed picture sits in was
   at least 128 - so at the very moment the reel stopped, the flag was lifted out of a 100px window into
   a 128px box and jumped 14px down and was laid out again. That jump was the switch. A landed flag's box
   is now the reel's own height; crests on short screens (a 104px reel) get the same. */
.cinema-club .cine-art.flag { min-height: 100px; }
@media (max-height: 660px) { .cinema-club .cine-art:not(.flag) { min-height: 104px; min-width: 104px; } }

/* The STICKERS and KICKIES tabs end with room to spare (the user, 2026-10-04: "why can't the stickers
   screen scroll?"): on the iPhone - status bar on top, home-indicator padding under the tab bar - the
   last row of stickers came out a hair short of the screen, flush against the tab bar, with nothing
   to scroll. A cushion under it lets the page scroll and the last row clear the bar. */
#collStickers, #collKickies { padding-bottom: 40px; }


/* The Legendary Pack's tile, dressed up further (the user, 2026-10-04: "LEGENDARY in a far more lavish,
   luxurious font, and sparkles round the pack - on the tile only"). The name in Cinzel Decorative, cut
   in gold: a bright-to-deep gold face, a dark bronze outline and drop under it, PACK small and spaced
   below. Round the pack, nine glinting stars with a soft halo and gold dust rising off it - transform
   and opacity only, so the shop stays smooth on a phone. */
.pack-legend .pack-name.pl-title { display: grid; justify-items: start; gap: 3px; -webkit-text-stroke: 0; text-shadow: none; }
.pl-title b { font: 900 29px/1 "Cinzel Decorative", "Times New Roman", serif; letter-spacing: .01em;
  background: linear-gradient(180deg, #fffbe0 0%, #ffe680 30%, #f2b51e 52%, #fff2a8 66%, #c47a06 100%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
  filter: drop-shadow(0 0 1px #4a2400) drop-shadow(0 0 1px #4a2400) drop-shadow(0 3px 0 #5a2e00) drop-shadow(0 0 10px rgba(255,214,90,.7)); }
.pl-title small { padding-left: 3px; font: 900 13px/1 "Cinzel Decorative", "Times New Roman", serif; letter-spacing: .5em; color: #fff3c0;
  text-shadow: 0 1px 0 #5a2e00, 0 0 6px rgba(255,200,60,.8); }
.pl-pack { position: relative; z-index: 1; display: block; flex: none; }
.pack-legend .pl-pack .pl-art { display: block; }
.pl-glints { position: absolute; inset: -14px -22px; pointer-events: none; }
.plg { position: absolute; width: 22px; height: 22px; translate: -50% -50%; opacity: 0; scale: .2;
  background: radial-gradient(closest-side, rgba(255,250,210,.95), rgba(255,215,90,.45) 45%, transparent);
  will-change: transform, opacity; animation: plGlint 2.4s ease-in-out infinite; }
.plg b { position: absolute; inset: -6px; background: #fffef2;
  clip-path: polygon(50% 0, 56% 44%, 100% 50%, 56% 56%, 50% 100%, 44% 56%, 0 50%, 44% 44%); }
.plg:nth-child(1) { left: 12%; top: 14%; }
.plg:nth-child(2) { left: 86%; top: 22%; width: 16px; height: 16px; animation-delay: .5s; }
.plg:nth-child(3) { left: 6%;  top: 62%; width: 14px; height: 14px; animation-delay: 1.1s; }
.plg:nth-child(4) { left: 92%; top: 70%; animation-delay: 1.6s; }
.plg:nth-child(5) { left: 50%; top: 4%;  width: 18px; height: 18px; animation-delay: .9s; }
.plg:nth-child(6) { left: 30%; top: 92%; width: 12px; height: 12px; animation-delay: 2s; }
.plg:nth-child(7) { left: 72%; top: 48%; width: 12px; height: 12px; animation-delay: .25s; animation-duration: 1.9s; }
.plg:nth-child(8) { left: 24%; top: 38%; width: 10px; height: 10px; animation-delay: 1.4s; animation-duration: 2s; }
.plg:nth-child(9) { left: 66%; top: 88%; width: 16px; height: 16px; animation-delay: .7s; animation-duration: 2.8s; }
.pld { position: absolute; bottom: 14%; width: 4px; height: 4px; border-radius: 50%; opacity: 0;
  background: #fff4b8; box-shadow: 0 0 6px 2px rgba(255,205,70,.8);
  will-change: transform, opacity; animation: plDust 3s ease-out infinite; }
.pld:nth-of-type(1) { left: 22%; }
.pld:nth-of-type(2) { left: 40%; animation-delay: .4s; animation-duration: 3.4s; }
.pld:nth-of-type(3) { left: 58%; animation-delay: .9s; }
.pld:nth-of-type(4) { left: 76%; animation-delay: 1.3s; animation-duration: 2.6s; }
.pld:nth-of-type(5) { left: 30%; animation-delay: 1.7s; width: 3px; height: 3px; }
.pld:nth-of-type(6) { left: 66%; animation-delay: 2.1s; animation-duration: 3.6s; width: 3px; height: 3px; }
.pld:nth-of-type(7) { left: 48%; animation-delay: 2.5s; }
.pld:nth-of-type(8) { left: 14%; animation-delay: 2.8s; animation-duration: 2.8s; width: 3px; height: 3px; }
@keyframes plGlint { 0%, 100% { opacity: 0; scale: .2; rotate: 0deg; } 35% { opacity: 1; scale: 1; rotate: 45deg; } 60% { opacity: 0; scale: .3; rotate: 90deg; } }
@keyframes plDust { 0% { opacity: 0; translate: 0 0; } 15% { opacity: 1; } 100% { opacity: 0; translate: 6px -110px; } }
@media (prefers-reduced-motion: reduce) { .plg, .pld { animation: none; } }
/* ...larger and brighter than the first cut, which the gold swallowed: a white-hot star on a warm halo. */
.plg { width: 30px; height: 30px;
  background: radial-gradient(closest-side, #fff 0%, rgba(255,240,170,.95) 25%, rgba(255,190,40,.55) 55%, transparent); }
.plg b { inset: -9px; background: #fff; }
.plg:nth-child(2), .plg:nth-child(9) { width: 24px; height: 24px; }
.plg:nth-child(3), .plg:nth-child(5) { width: 22px; height: 22px; }
.plg:nth-child(6), .plg:nth-child(7) { width: 18px; height: 18px; }
.plg:nth-child(8) { width: 16px; height: 16px; }
.pld { width: 5px; height: 5px; box-shadow: 0 0 8px 3px rgba(255,200,60,.9); }

/* The Legendary tile, take three (the user, 2026-10-04: "too luxurious, it doesn't suit the game - and
   the tile is too wide: 1:1, and above the ordinary packs"). A square in the middle of the shelf, ahead
   of the three others; the pack standing in the middle with its sparkles, the name in the game's own
   lettering under it - LEGENDARY in gold with the game's dark outline, PACK in white - and the price. */
.pack.pack-legend { order: -1; justify-self: center; width: 62%; aspect-ratio: 1; min-height: 0;
  flex-direction: column; justify-content: center; align-items: center; gap: 6px; padding: 12px 10px 12px; }
.pl-rays { left: 50%; top: 40%; }
.pack-legend .pl-art { height: 118px; }
.pl-glints { inset: -12px -26px; }
.pl-text { justify-items: center; gap: 7px; }
.pack-legend .pack-name.pl-title { justify-items: center; gap: 1px; text-align: center; }
.pl-title b { font: 400 25px/1 var(--display); letter-spacing: .02em; color: #ffd84a;
  background: linear-gradient(180deg, #fff6b8 0%, #ffd84a 45%, #f3a10e 100%); -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
  filter: drop-shadow(0 0 0 #5a2e00) drop-shadow(1.5px 0 0 #5a2e00) drop-shadow(-1.5px 0 0 #5a2e00) drop-shadow(0 1.5px 0 #5a2e00)
          drop-shadow(0 -1.5px 0 #5a2e00) drop-shadow(0 3px 0 #5a2e00); }
.pl-title small { padding: 0; font: 400 15px/1 var(--display); letter-spacing: .12em; color: #fff;
  -webkit-text-stroke: 4px #5a2e00; paint-order: stroke fill; text-shadow: 0 2px 0 #5a2e00; }
.pack-legend .pack-price { padding: 5px 16px; font-size: 16px; }
.pl-spark:nth-of-type(1) { left: 14px; top: 14px; }
.pl-spark:nth-of-type(2) { left: auto; right: 16px; top: 40px; }
.pl-spark:nth-of-type(3) { left: 18px; bottom: 60px; }
.pl-spark:nth-of-type(4) { right: 26px; top: auto; bottom: 70px; }

/* The locked 2ND STAR slot wears the game's 3D padlock (the user, 2026-10-04), not the flat one. */
.slot-art.slot-lock img.lock3d { width: 26px; height: 26px; object-fit: contain; filter: drop-shadow(0 2px 2px rgba(0,0,0,.45)); }

/* The locked tournaments tile in the game's own bright blue (the user, 2026-10-04: "change its colour
   from the dark blue") - the tab bar's and the STARS/STICKERS tabs' blue, with their 3D foot. */
.cup-locked-page { background: radial-gradient(90% 70% at 50% 18%, rgba(255,255,255,.28), transparent 70%),
    linear-gradient(180deg, #4f9bff, #2b62d4 78%, #2454bd);
  box-shadow: 0 5px 0 #1b3f99, 0 16px 26px -14px rgba(16,34,96,.8), inset 0 1px 0 rgba(255,255,255,.45), inset 0 0 0 1.5px rgba(255,255,255,.3); }
.cup-locked-page .clp-sub { color: #eaf1ff; }
.cup-locked-page .clp-bar { background: rgba(10,30,90,.5); }
.cup-locked-page .clp-title { text-shadow: 0 3px 0 #1b3f99; }


/* The Legendary Pack's banner, take four (the user, 2026-10-04: "a section of its own, apart from the
   packs, 3:2"): above the PACKS shelf, the whole width, 3 wide by 2 high - the pack on the left with its
   sparkles, the name and price beside it. Its clip is legend_tile_bg.mp4: the pass's gold clip turned on
   its side (so the wide banner uses its long edge), cleaned of grain and smoothly enlarged - cropping the
   288px-wide portrait clip and blowing it up 4x was the "strange roughness" the user saw. */
.legend-row { margin: 2px 0 6px; }
.legend-row:empty { display: none; }
.legend-row .pack.pack-legend { order: 0; justify-self: auto; width: 100%; aspect-ratio: 3 / 2; min-height: 0;
  flex-direction: row; justify-content: center; align-items: center; gap: 22px; padding: 14px 18px; }
.legend-row .pl-rays { left: 32%; top: 50%; width: 380px; height: 380px; }
.legend-row .pack-legend .pl-art { height: 170px; }
.legend-row .pl-glints { inset: -16px -30px; }
.legend-row .pl-text { justify-items: center; gap: 10px; }
.legend-row .pl-title b { font-size: 31px; }
.legend-row .pl-title small { font-size: 18px; }
.legend-row .pack-legend .pack-price { padding: 7px 20px; font-size: 19px; }
.legend-row .pl-spark:nth-of-type(1) { left: 16px; top: 16px; }
.legend-row .pl-spark:nth-of-type(2) { left: auto; right: 20px; top: 22px; }
.legend-row .pl-spark:nth-of-type(3) { left: 20px; top: auto; bottom: 20px; }
.legend-row .pl-spark:nth-of-type(4) { right: 30px; top: auto; bottom: 26px; }

/* Buying a star, dressed up (the user, 2026-10-04: "improve the confirmation a bit"): the star's rarity
   colour glowing over the top of the panel with a slow wheel of light behind the card, the title in
   white on it with the game's outline, the card floating, the panel popping in, and what you have
   under the BUY button. Transform and opacity only. */
#starBuyOverlay .sb-panel { position: relative; overflow: hidden; isolation: isolate; animation: sbIn .34s cubic-bezier(.2,1.4,.4,1); }
.sb-glow { position: absolute; left: 0; right: 0; top: 0; height: 64%; z-index: -1; overflow: hidden;
  background: radial-gradient(75% 85% at 50% 48%, color-mix(in srgb, var(--r) 55%, #fff) 0%, var(--r) 48%, color-mix(in srgb, var(--r) 55%, #0a1040) 100%);
  -webkit-mask: linear-gradient(180deg, #000 78%, transparent); mask: linear-gradient(180deg, #000 78%, transparent); }
.sb-rays { position: absolute; left: 50%; top: 56%; width: 460px; height: 460px; translate: -50% -50%; border-radius: 50%;
  background: repeating-conic-gradient(from 0deg, rgba(255,255,255,.32) 0deg 8deg, rgba(255,255,255,0) 8deg 22deg);
  -webkit-mask: radial-gradient(closest-side, #000 20%, transparent 100%); mask: radial-gradient(closest-side, #000 20%, transparent 100%);
  will-change: transform; animation: plRays 18s linear infinite; }
.sb-panel .panel-title { color: #fff; -webkit-text-stroke: 6px #1a2050; paint-order: stroke fill; text-shadow: 0 4px 0 #1a2050; }
.sb-panel .reveal-card .rv-art { width: 150px; box-shadow: 0 0 0 4px #fff, 0 0 26px 4px color-mix(in srgb, var(--r) 70%, #fff), 0 14px 22px -8px rgba(0,0,0,.55);
  will-change: transform; animation: sbFloat 3.2s ease-in-out infinite; }
.sb-have { display: flex; align-items: center; justify-content: center; gap: 5px; margin: 8px 0 -2px;
  font: 800 13px/1 var(--body); color: #4a5280; }
.sb-have img { width: 18px; height: 18px; object-fit: contain; }
.sb-have b { font: 400 16px/1 var(--display); color: #1a2050; }
@keyframes sbIn { from { opacity: 0; scale: .86; } }
@keyframes sbFloat { 50% { translate: 0 -6px; } }
@media (prefers-reduced-motion: reduce) { .sb-rays, .sb-panel .reveal-card .rv-art, #starBuyOverlay .sb-panel { animation: none; } }

/* The pack on the banner a little bigger (the user, 2026-10-04), under its SPECIAL OFFERS heading. */
.legend-row .pack-legend .pl-art { height: 196px; }
.legend-row .pack.pack-legend { gap: 18px; padding: 10px 16px; }

/* Buying a star, take two (the user, 2026-10-04: "the card a little further from the title, and the
   whole message in the rarity's colour all round"): the panel is the rarity from top to bottom - bright
   where the card glows, deep at the foot - with a lighter rim and a halo of the same colour round it;
   the words go white to stay readable on it. */
#starBuyOverlay .sb-panel { color: #fff; border: 3px solid color-mix(in srgb, var(--r) 45%, #fff);
  background: radial-gradient(90% 55% at 50% 30%, color-mix(in srgb, var(--r) 50%, #fff) 0%, var(--r) 55%, color-mix(in srgb, var(--r) 55%, #0a1040) 100%);
  box-shadow: 0 8px 0 color-mix(in srgb, var(--r) 50%, #0a1040), 0 0 34px 6px color-mix(in srgb, var(--r) 65%, transparent),
    0 26px 50px -12px rgba(0,0,0,.75), inset 0 2px 0 rgba(255,255,255,.45); }
.sb-glow { background: none; height: 72%; -webkit-mask: none; mask: none; }
.sb-panel .reveal-card { margin-top: 24px; }
.sb-panel .rv-rarity { background: #fff; color: var(--r); box-shadow: 0 2px 0 rgba(0,0,0,.25); }
.sb-panel .rv-name { color: #fff; -webkit-text-stroke: 5px #1a2050; paint-order: stroke fill; text-shadow: 0 3px 0 #1a2050; }
.sb-panel .rv-power { color: #fff3b0; text-shadow: 0 1px 2px rgba(0,0,0,.45); }
.sb-panel .rv-desc { color: rgba(255,255,255,.92); text-shadow: 0 1px 2px rgba(0,0,0,.45); }
.sb-panel .sb-have { color: rgba(255,255,255,.85); }
.sb-panel .sb-have b { color: #fff; }
.sb-panel #sbNo { color: #fff; opacity: .9; }


/* The shop's prices without a button (the user, 2026-10-04: "no green tile to show the price - no tile at
   all; tapping the whole card buys"): the price written on the card, the card itself pressable. */
.shop-card[data-buy] { cursor: pointer; transition: transform .1s; }
.shop-card[data-buy]:active, .sticker-card:active { transform: scale(.97); }
.sc-cost { display: inline-flex; align-items: center; gap: 6px; margin-top: 4px;
  font: 400 26px/1 var(--display); color: var(--ink); }
.sc-cost img, .sc-cost .sk-coin { width: 24px; height: 24px; object-fit: contain; }
.sticker-card .sc-cost { margin-top: 0; font-size: 19px; }
.sticker-card .sc-cost img, .sticker-card .sc-cost .sk-coin { width: 19px; height: 19px; }
.sc-cost.is-off, .shop-card.poor .sc-cost { opacity: .55; }

/* Every window in the game on the same white as the shop's sticker cards (the user, 2026-10-04:
   "everything in that cream-white - the window when you tap a sticker, for one - in the white of the
   stickers' cards in the shop"): white falling to the faintest blue, a bluish foot instead of the tan. */
.panel { background: var(--glass);
  box-shadow: 0 8px 0 #b7c3e3, 0 26px 50px -12px rgba(0,0,0,.75), inset 0 2px 0 rgba(255,255,255,.95), inset 0 0 0 2px rgba(255,255,255,.6); }


/* The Legendary offer once it is taken: still on show, greyed and still, CLAIMED in place of the price. */
.pack.pack-legend.taken { filter: grayscale(.85) brightness(.8); cursor: default; }
.pack.pack-legend.taken :is(.pl-rays, .pl-shine, .pl-spark, .plg, .pld, .pl-art) { animation: none; }
.pack.pack-legend.taken .plg, .pack.pack-legend.taken .pld, .pack.pack-legend.taken .pl-shine { display: none; }
.pack.pack-legend.taken:active { transform: none; }

/* SPECIAL OFFERS in the Legendary stickers' colours (the user, 2026-10-04: "in the Legendary stickers'
   colours, with an exciting animation"): turquoise through periwinkle to pink, a light running across
   the letters, a beat every couple of seconds, and the rules either side lit in the same colours. */
.section-title.special-title { text-shadow: none; }
.special-title span { display: inline-block; font-size: 23px;
  background: linear-gradient(100deg, #5ff3e1 0%, #9ab8ff 30%, #ff5fcf 50%, #9ab8ff 70%, #5ff3e1 100%);
  background-size: 200% 100%; -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
  filter: drop-shadow(0 2px 0 #1a1446) drop-shadow(0 0 8px rgba(255,95,207,.55));
  animation: spShimmer 2.4s linear infinite, spBeat 2.4s ease-in-out infinite; }
.special-title::before, .special-title::after { height: 3px;
  background: linear-gradient(90deg, transparent, #5ff3e1 40%, #ff5fcf);
  box-shadow: 0 0 8px rgba(255,95,207,.6); animation: spGlow 2.4s ease-in-out infinite; }
@keyframes spShimmer { to { background-position: -200% 0; } }
@keyframes spBeat { 0%, 70%, 100% { scale: 1; } 80% { scale: 1.09; } 90% { scale: .98; } }
@keyframes spGlow { 0%, 70%, 100% { opacity: .75; } 80% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .special-title span, .special-title::before, .special-title::after { animation: none; } }

/* On the menu (the user, 2026-10-04): PACKS TO GLORY a touch smaller, the arena a touch bigger - in
   every arena. The arena grows with `scale`, which leaves its floating `transform` alone. */
.ptg-btn { flex-basis: 216px; grid-template-columns: 44px 1fr; column-gap: 7px; row-gap: 4px; padding: 7px 11px 8px 7px; }
.ptg-pack { width: 44px; height: 62px; margin-top: -22px; }
.ptg-text b { font-size: 14.5px; }
.ptg-text b i { font-size: 11px; }
.ptg-text small { font-size: 10.5px; }
#home .arena-hero img { scale: 1.12; }

/* The arena's name under the model a size smaller (the user, 2026-10-04): the name and its ARENA badge. */
#home .arena-name { font-size: 16px; }
@media (max-height: 600px) { #home .arena-name { font-size: 14px; } }

/* PACKS TO GLORY on the menu in purple (the user, 2026-10-04), the thin gold edge, the white lettering
   and the gold bar as before. */
.ptg-btn { background: linear-gradient(160deg, #a873ff, #6a2fd6);
  box-shadow: inset 0 0 0 1.5px rgba(255,255,255,.6), inset 0 0 0 3px #f0c45a, 0 8px 14px -8px rgba(0,0,0,.55); }
.ptg-pack { filter: drop-shadow(0 4px 5px rgba(40,0,90,.45)); }
.ptg-text b { text-shadow: 0 2px 0 rgba(50,10,110,.6); }
.ptg-bar { background: rgba(40,0,90,.4); }
.ptg-btn.ready { background: linear-gradient(160deg, #b98aff, #6a2fd6); }
.ptg-btn.ready .ptg-text b { text-shadow: 0 2px 0 rgba(50,10,110,.6); }

/* ...and the arena model clear of it (the user: "the model must not touch PACKS TO GLORY"): a gap above
   the arena, and the model grows from its lower part, so its larger size goes downwards. */
#home .arena-hero { margin-top: 20px; }       /* clear even at the top of its float (7px) */
#home .arena-hero img { transform-origin: 50% 70%; }

/* SPECIAL EVENTS and TOURNAMENTS on the tournaments page in white (the user, 2026-10-04). */
.cup-section { color: #fff; text-shadow: 0 2px 0 rgba(20,28,66,.55); }

/* The arena bigger (the user, 2026-10-04: "my problem is just that the arena model is too small"). The
   pictures are about 3:2, so the model is held by the HEIGHT the column leaves it, not by the phone's
   width - it was drawn about 300px wide on a 402px screen. So the menu's other rows give it their spare
   air (tighter gaps, smaller margins) and the model is drawn larger inside its box, growing mostly
   downwards (its lower corner is a point, and the arena card's corners are clear of it). */
#home.screen.with-tabs { gap: 6px; }
#home .head { margin-bottom: 4px; }
#home .star-card { margin-top: 2px; margin-bottom: 2px; }
#home .arena-hero { margin-top: 10px; }
#home .arena-hero img { scale: 1.05; transform-origin: 50% 70%; }
#home .arena-card { margin-top: 0; margin-bottom: 4px; }
#home .modes { margin-bottom: 4px; }
#home .btn-play { margin-bottom: 10px; }

/* The scrolling pages end in a real spacer, not in padding (the user, 2026-10-04: "the stickers page
   still won't scroll"). Safari on the iPhone leaves a scroll container's bottom padding out of what can
   be scrolled to: there the STICKERS tab "fitted" the screen with its last row under the tab bar, and
   would not move. A spacer at the end is content, which every browser scrolls to. */
#powers, #shop { padding-bottom: 0; }
#powers::after, #shop::after { content: ""; display: block; flex: none; height: calc(78px + max(4px, var(--sab))); }
#collStickers, #collKickies { padding-bottom: 12px; }


/* The arena's plaque under the model (the user, 2026-10-04: "the arena's name and the way to the next one,
   more beautiful and designed"): the game's blue, edged in gold like PACKS TO GLORY; the arena's number
   on a gold shield at the left; the name in white; a chunky gold bar with the trophies written on it -
   so many of so many - and the next arena under it. */
#home .arena-card { display: grid; grid-template-columns: 50px 1fr; align-items: center; gap: 12px;
  padding: 8px 14px 9px 10px; border: 0; border-radius: 18px; text-align: left; color: #fff;
  background: radial-gradient(120% 100% at 0% 0%, rgba(255,255,255,.22), transparent 55%), linear-gradient(160deg, #4f8fff, #2453c9 70%, #1d43a8);
  box-shadow: inset 0 0 0 1.5px rgba(255,255,255,.55), inset 0 0 0 3px #f0c45a, 0 5px 0 #173a8f, 0 12px 18px -10px rgba(0,0,0,.6); }
.arena-badge { position: relative; display: grid; justify-items: center; align-content: center; width: 50px; height: 56px;
  color: #4a2a00; background: linear-gradient(180deg, #fff3b0, #ffd23f 45%, #e79a00);
  clip-path: polygon(50% 0, 100% 14%, 100% 64%, 50% 100%, 0 64%, 0 14%);
  filter: drop-shadow(0 3px 0 #9a5a00); }
.arena-badge::before { content: ""; position: absolute; inset: 3px; z-index: -1;
  clip-path: inherit; background: linear-gradient(180deg, #ffe680, #f3b10f); }
.arena-badge small { font: 900 8px/1 var(--body); letter-spacing: .14em; margin-top: -4px; }
.arena-badge b { font: 400 25px/1 var(--display); color: #fff; text-shadow: 0 2px 0 #9a5a00, 0 0 1px #9a5a00; }
.arena-body { display: grid; gap: 4px; min-width: 0; }
#home .arena-name { font-size: 18px; line-height: 1.05; color: #fff; text-shadow: 0 2px 0 rgba(10,30,100,.6);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#home .arena-bar { position: relative; height: 17px; margin: 0; border: 0; border-radius: 999px; overflow: hidden;
  background: rgba(8,22,80,.55); box-shadow: inset 0 2px 3px rgba(0,0,0,.45), 0 1px 0 rgba(255,255,255,.25); }
#home #arenaFill { position: absolute; inset: 0; border-radius: inherit;
  background: repeating-linear-gradient(115deg, rgba(255,255,255,.18) 0 6px, transparent 6px 12px),
              linear-gradient(180deg, #fff3b0, #ffc21a 55%, #e08a00);
  box-shadow: inset 0 -2px 0 rgba(150,80,0,.35), 0 0 10px rgba(255,200,40,.5); }
.arena-count { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; gap: 3px;
  font: 400 12px/1 var(--display); color: #fff; letter-spacing: .02em;
  text-shadow: 0 1px 0 #3a2400, 1px 0 0 #3a2400, -1px 0 0 #3a2400, 0 -1px 0 #3a2400; }
.arena-count .tr-ico { width: auto; height: 13px; margin-right: 2px; }
.arena-count b { font-weight: 400; }
.arena-count i { font-style: normal; opacity: .8; margin: 0 1px; }
#home .arena-next { font: 900 9.5px/1 var(--body); letter-spacing: .12em; color: rgba(255,255,255,.75); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#home .arena-next em { font: 400 13px/1 var(--display); font-style: normal; letter-spacing: .02em; color: #ffd84a; margin-left: 3px; }
@media (max-height: 600px) { #home .arena-name { font-size: 15px; } .arena-badge { height: 48px; width: 44px; } }


/* The plaque in the colours of the flag its arena is drawn from (the user, 2026-10-04: "in the colours of
   the flag the arena is inspired by - something beautiful and cool"): Italy, Brazil, Mexico, France,
   Japan, Nigeria; the Legends Arena in black and gold. The flag runs the whole plaque with soft seams, a
   dusk laid over its left side so the white lettering reads, and a light sweeps across it now and then
   like a flag catching the sun. Transform and opacity only for the moving part. */
#home .arena-card { position: relative; overflow: hidden; isolation: isolate; background: var(--flag, linear-gradient(160deg, #4f8fff, #1d43a8)); }
#home .arena-card::before { content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: linear-gradient(90deg, rgba(6,10,36,.48), rgba(6,10,36,.2) 55%, rgba(6,10,36,.04)),
              linear-gradient(180deg, rgba(255,255,255,.18), transparent 45%, rgba(0,0,0,.18)); }
#home .arena-card::after { content: ""; position: absolute; top: -20%; bottom: -20%; left: 0; width: 28%; z-index: -1; pointer-events: none;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.28), transparent);
  transform: translateX(-120%) skewX(-18deg); will-change: transform; animation: flagSweep 5.5s 1.2s ease-in-out infinite; }
@keyframes flagSweep { 0% { transform: translateX(-120%) skewX(-18deg); } 40%, 100% { transform: translateX(420%) skewX(-18deg); } }
@media (prefers-reduced-motion: reduce) { #home .arena-card::after { animation: none; opacity: 0; } }
#home .arena-name { text-shadow: 0 2px 0 rgba(0,0,0,.55), 0 0 8px rgba(0,0,0,.45); }
#home .arena-next { color: rgba(255,255,255,.9); text-shadow: 0 1px 2px rgba(0,0,0,.7); }
#home .arena-next em { text-shadow: 0 1px 0 rgba(0,0,0,.7), 0 0 6px rgba(0,0,0,.5); }
#home .arena-bar { background: rgba(0,0,0,.5); }

/* (the plaque's foot dark rather than the old blue, so it suits every flag) */
#home .arena-card { box-shadow: inset 0 0 0 1.5px rgba(255,255,255,.55), inset 0 0 0 3px #f0c45a, 0 5px 0 rgba(0,0,0,.4), 0 12px 18px -10px rgba(0,0,0,.6); }


/* The plaque carries the country's real flag (the user, 2026-10-04: "put the country's flag there, with a
   fade - what do you think?"): the flag picture on the right two thirds, fading out to the left into a
   deep navy where the shield and the name sit, a little light on its top and shade at its foot, and the
   light still sweeping over it. The Legends Arena has no country: black and gold. */
#home .arena-card { background: linear-gradient(160deg, #1f2f6e, #0e1638); }
#home .arena-card::before { left: auto; right: 0; width: 74%;
  background: linear-gradient(180deg, rgba(255,255,255,.16), transparent 40%, rgba(0,0,0,.28)), var(--flag-img, none) center / cover no-repeat;
  -webkit-mask: linear-gradient(90deg, transparent, rgba(0,0,0,.75) 45%, #000 80%); mask: linear-gradient(90deg, transparent, rgba(0,0,0,.75) 45%, #000 80%); }
.arena-card[data-arena="1"] { --flag-img: url("../assets/ui/flag_hd_it.png"); }
.arena-card[data-arena="2"] { --flag-img: url("../assets/ui/flag_hd_br.png"); }   /* the whole flag, emblem and all, behind the name (the user, 2026-10-05); the shield keeps the plain colours */
.arena-card[data-arena="3"] { --flag-img: url("../assets/ui/flag_hd_mx.png"); }   /* the whole flag, emblem and all, behind the name (the user, 2026-10-05); the shield keeps the plain colours */
.arena-card[data-arena="4"] { --flag-img: url("../assets/ui/flag_hd_fr.png"); }
.arena-card[data-arena="5"] { --flag-img: url("../assets/ui/flag_hd_jp.png"); }
.arena-card[data-arena="6"] { --flag-img: url("../assets/ui/flag_hd_za.png"); }   /* South Africa (the user, 2026-10-05) */
.pack.short { animation: shake .35s; }          /* a pack you cannot pay for shakes, and the wallet shows */

/* ALL STICKERS as they are (the user, 2026-10-04: "not on a white tile - just as they are, in their
   original frame"): no card behind them, only the sticker in its rarity frame - the ones you have not
   got too, a little faded rather than greyed. */
.coll-sticker { padding: 0; gap: 4px; background: none; box-shadow: none; }
.coll-sticker.locked .cs-art { animation: none; opacity: .72; filter: none;
  background: linear-gradient(#fff, #fff) padding-box, var(--ring) border-box;
  box-shadow: inset 0 0 0 2.5px #15171d, -3px 0 12px -2px var(--g1), 3px 0 12px -2px var(--g2); }
.coll-sticker.locked .cs-art img { filter: none; }

/* JOIN PREMIUM PASS in its own blue again: the white given to every window (.panel, above) had covered it. */
.panel.bp-panel { background: radial-gradient(120% 80% at 50% 0%, #2f5bd8 0%, #1a2f8a 45%, #0d1552 100%);
  box-shadow: 0 8px 0 #b8860b, 0 26px 50px -12px rgba(0,0,0,.8), inset 0 0 0 3px #ffd34d, inset 0 2px 0 rgba(255,255,255,.35); }


/* Buying a pack, asked first (askBuyPack): the star window's dress - the pack's rarity all round, the
   slow wheel of light - with the pack floating in the middle and its name under it. */
#packBuyOverlay .sb-panel { position: relative; overflow: hidden; isolation: isolate; color: #fff; animation: sbIn .34s cubic-bezier(.2,1.4,.4,1);
  border: 3px solid color-mix(in srgb, var(--r) 45%, #fff);
  background: radial-gradient(90% 55% at 50% 34%, color-mix(in srgb, var(--r) 50%, #fff) 0%, var(--r) 55%, color-mix(in srgb, var(--r) 55%, #0a1040) 100%);
  box-shadow: 0 8px 0 color-mix(in srgb, var(--r) 50%, #0a1040), 0 0 34px 6px color-mix(in srgb, var(--r) 65%, transparent),
    0 26px 50px -12px rgba(0,0,0,.75), inset 0 2px 0 rgba(255,255,255,.45); }
#packBuyOverlay .sb-panel .panel-title { color: #fff; -webkit-text-stroke: 6px #1a2050; paint-order: stroke fill; text-shadow: 0 4px 0 #1a2050; }
.pk-art { display: grid; place-items: center; margin: 18px 0 8px; }
.pk-art img { height: 230px; max-width: 70%; object-fit: contain; filter: drop-shadow(0 14px 16px rgba(0,0,0,.5));
  will-change: transform; animation: sbFloat 3.2s ease-in-out infinite; }
.pk-name { margin-bottom: 14px; font: 400 26px/1 var(--display); color: #fff; -webkit-text-stroke: 5px #1a2050; paint-order: stroke fill; text-shadow: 0 3px 0 #1a2050; }
#packBuyOverlay .sb-have { color: rgba(255,255,255,.85); }
#packBuyOverlay .sb-have b { color: #fff; }
#pkNo { color: #fff; opacity: .9; }
@media (max-height: 640px) { .pk-art img { height: 170px; } }

/* MORE ARENAS COMING SOON at the top of the ladder (the user, 2026-10-04). */
.ar-soon { display: grid; justify-items: center; gap: 4px; padding: 18px 12px; border-radius: var(--r-md); text-align: center;
  border: 2px dashed rgba(255,255,255,.45); background: rgba(10,16,50,.45); }
.ar-soon b { font: 400 22px/1 var(--display); letter-spacing: .06em; color: #fff; text-shadow: 0 2px 0 rgba(0,0,0,.5); }
.ar-soon span { font: 900 12px/1 var(--body); letter-spacing: .2em; color: #ffd84a; }


/* What a new name costs, said plainly (the user, 2026-10-04): a chip with the gem by the label, the
   gem and the number in the note under the field. */
.rn-chip { display: inline-flex; align-items: center; gap: 4px; margin-left: 6px; padding: 3px 9px 3px 8px; border-radius: 999px;
  font: 900 11px/1 var(--body); font-style: normal; letter-spacing: .06em; color: #fff;
  background: linear-gradient(180deg, #34d27a, #12924a); box-shadow: 0 2px 0 #0b5e30; vertical-align: 1px; }
.rn-chip img { width: 15px; height: 15px; object-fit: contain; }
.rn-chip.free { background: linear-gradient(180deg, #6fb4ff, #2b6fe0); box-shadow: 0 2px 0 #1b4aa8; }
#renameNote { display: inline-flex; align-items: center; flex-wrap: wrap; gap: 4px; font-weight: 900; }
#renameNote img { width: 17px; height: 17px; object-fit: contain; }
#renameNote b { font: 400 16px/1 var(--display); }

/* The rename's confirmation: old name to new, the gem turning in the middle, the price. */
.rn-names { display: flex; align-items: center; justify-content: center; gap: 10px; margin: 12px 0 6px; flex-wrap: wrap;
  font: 400 20px/1.1 var(--display); }
.rn-names span { color: #8a93b8; text-decoration: line-through; text-decoration-thickness: 2px; }
.rn-names b { font-weight: 400; color: var(--ink); }
.rn-arrow { width: 22px; height: 14px; flex: none; background: #8a93b8;
  clip-path: polygon(0 40%, 62% 40%, 62% 0, 100% 50%, 62% 100%, 62% 60%, 0 60%); }
.rn-gem { position: relative; width: 130px; margin: 6px auto 4px; aspect-ratio: 390 / 287; }
.rn-gem img, .rn-gem canvas { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain;
  filter: drop-shadow(0 8px 10px rgba(20,120,70,.35)); }
.rn-gem canvas { opacity: 0; }
.rn-gem canvas.on { opacity: 1; }
.rn-gem:has(canvas.on) img { opacity: 0; }
.rn-cost { margin: 2px 0 14px; font: 900 13px/1 var(--body); letter-spacing: .14em; color: #4a5280; }
.rn-cost b { font: 400 24px/1 var(--display); letter-spacing: 0; color: #12924a; vertical-align: -3px; margin: 0 2px; }

/* The manager's icon - the coloured ball picked at the start and changed later - as a real ball (the
   user, 2026-10-04: "improve the icons a bit"): the colour shaded into a sphere, the panels on it, a
   gloss and a darker rim over them, a shadow under it; the one you have picked lifts, ringed in gold. */
.icon-row { gap: 10px; flex-wrap: wrap; }
.icon-opt, .me-icon { isolation: isolate;
  background: radial-gradient(circle at 36% 30%, color-mix(in srgb, var(--t, #fff) 45%, #fff) 0%, var(--t, #fff) 52%, color-mix(in srgb, var(--t, #fff) 70%, #0a1030) 100%); }
.icon-opt { box-shadow: 0 4px 0 rgba(20,26,70,.22), 0 8px 12px -6px rgba(0,0,0,.45);
  transition: transform .18s cubic-bezier(.2,1.4,.4,1), box-shadow .18s; }
.icon-opt::after, .me-icon::after { z-index: 1; opacity: .92; }
.icon-opt::before, .me-icon::before { content: ""; position: absolute; inset: 0; z-index: 2; border-radius: 50%; pointer-events: none;
  background: radial-gradient(circle at 32% 25%, rgba(255,255,255,.9) 0 7%, rgba(255,255,255,.35) 17%, transparent 38%),
              radial-gradient(circle at 50% 50%, transparent 56%, rgba(0,0,20,.32) 100%); }
.icon-opt.on { outline: 0; transform: translateY(-3px) scale(1.12);
  box-shadow: 0 0 0 3px #fff, 0 0 0 6px var(--gold), 0 0 18px 4px rgba(255,200,40,.6), 0 10px 14px -6px rgba(0,0,0,.5); }
.icon-opt:active { transform: scale(.94); }
.me-icon { box-shadow: 0 0 0 2px rgba(255,255,255,.85), 0 3px 6px rgba(0,0,0,.35); }
.icon-row { margin-top: 6px; padding-bottom: 2px; }
.rn-chip { background: linear-gradient(180deg, #34428f, #1a2463); box-shadow: 0 2px 0 #0d1440; }   /* the green gem reads on navy, not on green */


/* The manager's icon as a real ball (the user, 2026-10-04: "really improve the icon's shape - not that
   sorry ball"): a rendered 32-panel football per colour (tools/model/build_ball_icons.py ->
   assets/ui/ball_icon_<n>.png), in place of the flat ball drawing on a tinted circle - in the profile,
   on the name bar, on the match's HUD and in the cup's bracket alike. The colour is read off the
   element's own --t, so every place that already tints the icon gets its ball. */
.av-icon, .icon-opt, .me-icon { background: url("../assets/ui/ball_icon_0.png") center / 112% no-repeat; }
.av-icon::after, .icon-opt::after, .me-icon::after, .icon-opt::before, .me-icon::before { display: none; }
.av-icon { box-shadow: 0 5px 0 -1px rgba(0,0,0,.35), 0 8px 14px -6px rgba(0,0,0,.8); }
.me-icon { box-shadow: 0 3px 6px rgba(0,0,0,.35); }
.icon-opt { box-shadow: 0 6px 10px -5px rgba(0,0,0,.55); }
.icon-opt.on { box-shadow: 0 0 0 3px #fff, 0 0 0 6px var(--gold), 0 0 18px 4px rgba(255,200,40,.6), 0 10px 14px -6px rgba(0,0,0,.5); }
:is(.av-icon, .icon-opt, .me-icon)[style*="--t:#ffd23f"], :is(.av-icon, .icon-opt, .me-icon)[style*="--t: #ffd23f"] { background-image: url("../assets/ui/ball_icon_1.png"); }
:is(.av-icon, .icon-opt, .me-icon)[style*="--t:#4fb4ff"], :is(.av-icon, .icon-opt, .me-icon)[style*="--t: #4fb4ff"] { background-image: url("../assets/ui/ball_icon_2.png"); }
:is(.av-icon, .icon-opt, .me-icon)[style*="--t:#ff7a8a"], :is(.av-icon, .icon-opt, .me-icon)[style*="--t: #ff7a8a"] { background-image: url("../assets/ui/ball_icon_3.png"); }
:is(.av-icon, .icon-opt, .me-icon)[style*="--t:#3ddc6b"], :is(.av-icon, .icon-opt, .me-icon)[style*="--t: #3ddc6b"] { background-image: url("../assets/ui/ball_icon_4.png"); }
:is(.av-icon, .icon-opt, .me-icon)[style*="--t:#b65cff"], :is(.av-icon, .icon-opt, .me-icon)[style*="--t: #b65cff"] { background-image: url("../assets/ui/ball_icon_5.png"); }


/* The arena's number as a 3D gold shield on its plaque (the user, 2026-10-04: "a 3D model where it says
   ARENA 7, like the tournaments") - a render per arena, in place of the shield drawn in CSS. */
#home .arena-card { grid-template-columns: 56px 1fr; }
.arena-badge3d { display: grid; place-items: center; width: 56px; height: 60px; }
.arena-badge3d img { width: 70px; height: 70px; max-width: none; object-fit: contain; margin: -5px;
  filter: drop-shadow(0 4px 4px rgba(0,0,0,.5)); }
@media (max-height: 600px) { .arena-badge3d img { width: 58px; height: 58px; } }


/* Every arena in the list wears its 3D shield - its country's flag and its number (the user, 2026-10-05),
   the same as the menu's plaque, beside its name. */
.ar-head { display: flex; align-items: center; gap: 8px; min-width: 0; }
.ar-badge { flex: none; width: 46px; height: 46px; margin: -4px -2px -4px -6px; object-fit: contain;
  filter: drop-shadow(0 3px 3px rgba(0,0,0,.5)); }
.ar-titles { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.arena-row.locked .ar-badge { filter: grayscale(.7) brightness(.75) drop-shadow(0 3px 3px rgba(0,0,0,.5)); }


/* Three of the icons are the user's 2CLUBS crests (2026-10-05: "put these three in place of the blue, green
   and red balls, background removed") - blue, red, green; tools/ui/src/emblems has the originals. A crest
   is a shield, not a ball: no round clip, its shadow follows its outline. */
:is(.av-icon, .icon-opt, .me-icon)[style*="--t:#4fb4ff"], :is(.av-icon, .icon-opt, .me-icon)[style*="--t: #4fb4ff"] { background-image: url("../assets/ui/club_icon_2.png"); background-size: contain; border-radius: 0;
  box-shadow: none; filter: drop-shadow(0 3px 4px rgba(0,0,0,.45)); }   /* the blue 2CLUBS crest */
:is(.av-icon, .icon-opt, .me-icon)[style*="--t:#ff7a8a"], :is(.av-icon, .icon-opt, .me-icon)[style*="--t: #ff7a8a"] { background-image: url("../assets/ui/club_icon_3.png"); background-size: contain; border-radius: 0;
  box-shadow: none; filter: drop-shadow(0 3px 4px rgba(0,0,0,.45)); }   /* the red 2CLUBS crest */
:is(.av-icon, .icon-opt, .me-icon)[style*="--t:#3ddc6b"], :is(.av-icon, .icon-opt, .me-icon)[style*="--t: #3ddc6b"] { background-image: url("../assets/ui/club_icon_4.png"); background-size: contain; border-radius: 0;
  box-shadow: none; filter: drop-shadow(0 3px 4px rgba(0,0,0,.45)); }   /* the green 2CLUBS crest */
.icon-opt.on:is([style*="--t:#4fb4ff"], [style*="--t:#ff7a8a"], [style*="--t:#3ddc6b"]) { outline: 3px solid var(--gold); outline-offset: 4px;
  border-radius: 12px; box-shadow: none; filter: drop-shadow(0 0 10px rgba(255,200,40,.7)) drop-shadow(0 3px 4px rgba(0,0,0,.45)); }


/* The background clips are scenery, never something to press (the user, 2026-10-05: "why is there a play
   button on it?"): a paused video on the iPhone draws its own big play button - the claimed Legendary
   tile had one. The claimed tile now has no clip at all, and Safari's start button is hidden on every
   decorative clip in case one is ever held still (Low Power Mode stops autoplay). */
.pl-video::-webkit-media-controls, .pl-video::-webkit-media-controls-start-playback-button,
.pt-clip::-webkit-media-controls, .pt-clip::-webkit-media-controls-start-playback-button,
.arena-flyby::-webkit-media-controls, .arena-flyby::-webkit-media-controls-start-playback-button {
  display: none !important; -webkit-appearance: none; opacity: 0; }


/* GEMS in the shop (renderGemShop): six cards, three to a row, a heap of gems that grows with the tier,
   the amount, and the price in a green pill - the whole card is the button. */
.gem-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 9px; }
.gem-card { position: relative; display: grid; justify-items: center; gap: 4px; padding: 10px 6px 9px; border-radius: var(--r-lg);
  cursor: pointer; background: var(--glass); border: 1px solid var(--glass-line); box-shadow: inset 0 1px 0 var(--glass-top), var(--drop);
  transition: transform .1s; }
.gem-card:active { transform: scale(.96); }
.gm-heap { position: relative; display: block; width: 74px; height: 56px; }
.gm-heap img { position: absolute; width: 34px; height: 34px; object-fit: contain; filter: drop-shadow(0 3px 3px rgba(0,60,30,.35)); }
.gm-heap img:nth-child(1) { left: 20px; top: 14px; width: 38px; height: 38px; z-index: 3; }
.gm-heap img:nth-child(2) { left: 4px; top: 22px; z-index: 2; }
.gm-heap img:nth-child(3) { left: 38px; top: 22px; z-index: 2; }
.gm-heap img:nth-child(4) { left: 12px; top: 2px; z-index: 1; width: 30px; height: 30px; }
.gm-heap img:nth-child(5) { left: 34px; top: 0; z-index: 1; width: 30px; height: 30px; }
.gm-heap img:nth-child(6) { left: 24px; top: -10px; z-index: 0; width: 28px; height: 28px; }
.gm-heap.n1 img:nth-child(1) { left: 16px; top: 6px; width: 44px; height: 44px; }
.gm-n { font: 400 21px/1 var(--display); color: var(--ink); }
.gm-price { min-width: 76%; padding: 6px 8px; border-radius: 999px; text-align: center; font: 400 15px/1 var(--display); color: #fff;
  background: linear-gradient(180deg, #49dd84, #17a454); box-shadow: 0 3px 0 #0d7a3c, inset 0 1px 0 rgba(255,255,255,.4); }

/* Its confirmation: the green of the gems all round, the heap large, the amount, BUY with the price. */
#gemBuyOverlay .sb-panel { position: relative; overflow: hidden; isolation: isolate; color: #fff; animation: sbIn .34s cubic-bezier(.2,1.4,.4,1);
  border: 3px solid color-mix(in srgb, var(--r) 45%, #fff);
  background: radial-gradient(90% 55% at 50% 34%, color-mix(in srgb, var(--r) 50%, #fff) 0%, var(--r) 55%, color-mix(in srgb, var(--r) 55%, #0a1040) 100%);
  box-shadow: 0 8px 0 color-mix(in srgb, var(--r) 50%, #0a1040), 0 0 34px 6px color-mix(in srgb, var(--r) 65%, transparent),
    0 26px 50px -12px rgba(0,0,0,.75), inset 0 2px 0 rgba(255,255,255,.45); }
#gemBuyOverlay .panel-title { color: #fff; -webkit-text-stroke: 6px #0b3d22; paint-order: stroke fill; text-shadow: 0 4px 0 #0b3d22; }
.gm-art { display: grid; place-items: center; margin: 18px 0 6px; }
.gm-art .gm-heap { transform: scale(2.1); transform-origin: 50% 70%; margin: 30px 0 22px; }
.gm-amount { display: flex; align-items: center; justify-content: center; gap: 6px; margin-bottom: 14px; font: 400 26px/1 var(--display); color: #fff;
  -webkit-text-stroke: 5px #0b3d22; paint-order: stroke fill; text-shadow: 0 3px 0 #0b3d22; }
.gm-amount img { width: 28px; height: 28px; object-fit: contain; }
.gm-note { margin: 8px 0 -2px; font: 900 12px/1.2 var(--body); letter-spacing: .06em; color: #fff; }
#gmNo { color: #fff; opacity: .9; }


/* COINS for gems (renderCoinShop): the gem cards' shape, a heap of coins, the price on a gem. */
.coin-card .gm-heap img { filter: drop-shadow(0 3px 3px rgba(90,50,0,.35)); }
.cn-price { display: inline-flex; align-items: center; justify-content: center; gap: 5px; }
.cn-price img { width: 17px; height: 17px; object-fit: contain; }
.gem-card.short { animation: shake .35s; }
#gemBuyOverlay .gm-heap img { filter: drop-shadow(0 3px 3px rgba(0,0,0,.35)); }


/* Two more crests (the user, 2026-10-05): the white (silver) one for the white ball, the yellow for the
   yellow - only the purple is still a ball. */
:is(.av-icon, .icon-opt, .me-icon)[style*="--t:#ffffff"], :is(.av-icon, .icon-opt, .me-icon)[style*="--t: #ffffff"] { background-image: url("../assets/ui/club_icon_0.png"); background-size: contain; border-radius: 0;
  box-shadow: none; filter: drop-shadow(0 3px 4px rgba(0,0,0,.45)); }   /* the white 2CLUBS crest */
:is(.av-icon, .icon-opt, .me-icon)[style*="--t:#ffd23f"], :is(.av-icon, .icon-opt, .me-icon)[style*="--t: #ffd23f"] { background-image: url("../assets/ui/club_icon_1.png"); background-size: contain; border-radius: 0;
  box-shadow: none; filter: drop-shadow(0 3px 4px rgba(0,0,0,.45)); }   /* the yellow 2CLUBS crest */
.icon-opt.on:is([style*="--t:#ffffff"], [style*="--t:#ffd23f"]) { outline: 3px solid var(--gold); outline-offset: 4px;
  border-radius: 12px; box-shadow: none; filter: drop-shadow(0 0 10px rgba(255,200,40,.7)) drop-shadow(0 3px 4px rgba(0,0,0,.45)); }


/* The offers' 3D pictures on their cards, and larger, floating, in the purchase window. */
.gm-pic { display: block; width: 92px; height: 92px; margin: -6px 0 -4px; object-fit: contain;
  filter: drop-shadow(0 6px 6px rgba(10,20,60,.35)); }
.gm-art .gm-pic { width: 200px; height: 200px; margin: 4px 0 0; filter: drop-shadow(0 12px 14px rgba(0,0,0,.45));
  will-change: transform; animation: sbFloat 3.2s ease-in-out infinite; }

.gm-pic.gm-sack { width: 104px; height: 64px; margin: -2px 0 -2px; }        /* a wide picture: the sack on its side */
.gm-art .gm-pic.gm-sack { width: 260px; height: 160px; }


/* The plaque's lettering sharp on the phone (the user, 2026-10-05: "why is the arena's name, the way to
   the next one and the trophy count in such low quality?"):
   - the count's outline was four 1px text-shadows - jagged at 3x; now a real stroke under the fill;
   - the light sweeping over the plaque was its own GPU layer (will-change), and Safari drew the text
     under it softer; it still moves with a transform, just without forcing a layer;
   - the flags were 320px pictures stretched over the plaque; now 1500px (assets/ui/flag_hd_*). */
/* (no dark outline round the letters - the user, 2026-10-05: "not with the black around the letters";
   a soft, blurred shadow keeps them readable on the flag without the jagged 1px-offset copies) */
.arena-count { font-size: 13px; -webkit-text-stroke: 0; text-shadow: 0 1px 3px rgba(0,0,0,.75); }
.arena-count .tr-ico { height: 15px; }
#home .arena-name { font-size: 18px; -webkit-text-stroke: 0; filter: none; text-shadow: 0 1px 4px rgba(0,0,0,.7); }
#home .arena-next { font-size: 10px; color: #fff; text-shadow: 0 1px 3px rgba(0,0,0,.7); }
#home .arena-next em { font-size: 14px; -webkit-text-stroke: 0; text-shadow: 0 1px 3px rgba(0,0,0,.75); }
#home .arena-card::after { will-change: auto; }



/* The 500 coins: the user's photo on its own gold backdrop (2026-10-05), a picture in a rounded frame. */
.gm-pic.gm-photo { width: 100%; height: auto; aspect-ratio: 600 / 520; margin: 0 0 2px; border-radius: 12px; object-fit: cover;
  filter: none; box-shadow: 0 0 0 2px rgba(255,255,255,.7), 0 4px 10px -4px rgba(0,0,0,.45); }
.gm-art .gm-pic.gm-photo { width: 240px; border-radius: 18px; }

/* no frame round the pictures (the user, 2026-10-05) - only their rounded corners */
.gm-pic.gm-photo { box-shadow: none; }

/* No box round the chosen crest (the user, 2026-10-06: "remove the background from these icons"): the
   square gold outline and its fill read as a tile behind the crest. The chosen one is now just larger,
   with a gold glow that follows the shield's own outline; the others a little smaller and quieter. */
.icon-opt, .icon-opt.on { outline: 0 !important; border-radius: 0 !important; background-color: transparent !important; box-shadow: none !important; }
.icon-opt { filter: drop-shadow(0 3px 4px rgba(0,0,0,.35)) saturate(.85) brightness(.95); transform: scale(.92); }
.icon-opt.on { transform: translateY(-3px) scale(1.14) !important;
  filter: drop-shadow(0 0 3px #ffd34d) drop-shadow(0 0 9px rgba(255,200,40,.85)) drop-shadow(0 4px 5px rgba(0,0,0,.4)) !important; }


/* The Season 1 crest (premium pass, tier 4; the user, 2026-10-06), wherever the icon shows. */
:is(.av-icon, .icon-opt, .me-icon)[style*="--t:#0a0a0a"], :is(.av-icon, .icon-opt, .me-icon)[style*="--t: #0a0a0a"] {
  background-image: url("../assets/ui/club_icon_s1.png?v=1"); background-size: contain; border-radius: 0;
  box-shadow: none; filter: drop-shadow(0 3px 4px rgba(0,0,0,.45)); }
.pt-art .pt-icon { width: 46px; height: 46px; object-fit: contain; filter: drop-shadow(0 2px 3px rgba(0,0,0,.45)); }
.rv-crest { width: 170px; height: 170px; object-fit: contain; margin: 6px 0 4px; filter: drop-shadow(0 8px 10px rgba(0,0,0,.4)); }


/* BUY on a star you have not got, in its details on the Stars page (the user, 2026-10-06). */
.pi-buy { display: flex; align-items: center; justify-content: center; gap: 6px; width: 100%; margin-top: 10px; padding: 11px;
  font: 400 19px/1 var(--display); color: #fff; background: linear-gradient(180deg, #49dd84, #17a454);
  box-shadow: 0 4px 0 #0d7a3c, inset 0 1px 0 rgba(255,255,255,.4); border-radius: 14px; }
.pi-buy .sk-coin { width: 20px; height: 20px; }

.bp-price.bp-usd { padding: 6px 18px; font: 400 26px/1 var(--display); }
.bp-note { margin: 8px 0 -4px; font: 900 12px/1.2 var(--body); letter-spacing: .06em; color: #fff; text-align: center; }


/* The Premium Pass offer as it was - blue, gold rim, gold button (the user, 2026-10-06: "back to the original,
   with the yellow") - with the price only on the button, in white letters on the gold. */
#bpCost { display: none; }
#bpGo.btn-play { color: #fff; text-shadow: 0 2px 0 #8a5200, 0 0 2px #8a5200; }

/* The amount at the top of the picture (the user, 2026-10-06: "write the amount at the top"), over the
   gem and coin pictures, white on their glow. */
.gem-card { position: relative; }
.gem-card .gm-n { position: absolute; top: 13px; left: 0; right: 0; z-index: 2; text-align: center; font-size: 22px; color: #fff;
  text-shadow: 0 2px 0 rgba(0,0,0,.45), 0 0 8px rgba(0,0,0,.55); pointer-events: none; }
/* ...above the picture rather than on it (the user: "the number hides part of the picture"): its own line at
   the top of the card, the picture whole under it. */
.gem-card .gm-n { position: static; order: -1; margin: -2px 0 2px; font-size: 19px; color: var(--ink); text-shadow: none; }

/* A star's reveal film out of the pack (js/main.js, playRevealFilm): full screen over the opening. */
.op-film-reveal { position: fixed; inset: 0; width: 100%; height: 100%; object-fit: cover; background: #000;
  z-index: 50; opacity: 0; transition: opacity .3s ease; pointer-events: none; }
.op-film-reveal.on { opacity: 1; }
/* ...with its "TAP TO CONTINUE" over the film's last frame, not under it. */
.opening:has(.op-film-reveal) #opHint { z-index: 51; }

/* ---------- the account and friends (js/online.js; js/main.js renderAccount, renderFriends) ---------- */
.acct-box { display: flex; flex-direction: column; gap: 8px; align-items: stretch; width: 100%; }
.acct-google, .acct-apple { display: flex; align-items: center; justify-content: center; gap: 10px; height: 46px; border-radius: 14px;
  font-weight: 900; font-size: 14px; letter-spacing: .04em; border: 0; }
.acct-google { background: #fff; color: #1f1f1f; box-shadow: 0 3px 0 #b9c3d6, 0 6px 14px -6px rgba(0,0,0,.5); }
.acct-google:active { transform: translateY(2px); box-shadow: 0 1px 0 #b9c3d6; }
.g-logo { width: 20px; height: 20px; }
.acct-apple { background: #000; color: #fff; opacity: .55; }
.acct-apple em { font-style: normal; font-size: 10px; padding: 2px 7px; border-radius: 999px; background: rgba(255,255,255,.2); }
.acct-note { font-weight: 700; font-size: 12px; color: rgba(255,255,255,.7); text-align: center; }
.acct-who { font-weight: 700; font-size: 14px; color: #fff; text-align: center; }
.acct-who b { font-weight: 900; }
.acct-out { align-self: center; height: 34px; padding: 0 18px; border-radius: 999px; border: 0; font-weight: 900; font-size: 12px;
  letter-spacing: .08em; color: #fff; background: rgba(255,255,255,.16); }
.soon-card .acct-box { margin-top: 6px; max-width: 290px; }

.fr-card { margin-top: 14px; display: flex; flex-direction: column; align-items: center; gap: 8px; padding: 18px 16px 16px;
  border-radius: 22px; text-align: center; background: linear-gradient(180deg, #243a8f, #16266a);
  box-shadow: inset 0 0 0 2px rgba(255,210,63,.55), inset 0 3px 8px rgba(0,0,0,.35), 0 10px 22px -10px rgba(0,0,0,.7); }
.fr-label { font-weight: 900; font-size: 11px; letter-spacing: .14em; color: rgba(255,255,255,.75); }
.fr-code { font-family: var(--display); font-size: 38px; letter-spacing: .14em; color: #ffd23f; background: none; border: 0;
  text-shadow: 0 3px 0 rgba(0,0,0,.45); padding: 0 6px; }
.fr-hint { font-weight: 700; font-size: 12px; color: rgba(255,255,255,.7); }
.fr-add { display: flex; gap: 8px; width: 100%; margin-top: 4px; }
.fr-add input { flex: 1; min-width: 0; height: 44px; border-radius: 12px; border: 0; padding: 0 12px; font-weight: 900; font-size: 16px;
  letter-spacing: .12em; text-transform: uppercase; text-align: center; color: #10204f; background: #fff; }
.fr-add-btn { height: 44px; padding: 0 18px; border-radius: 12px; border: 0; font-weight: 900; font-size: 14px; color: #3a2600;
  background: linear-gradient(180deg, #ffe98d, #ffc21a); box-shadow: 0 3px 0 #b86e00; }
.fr-msg { min-height: 16px; font-weight: 800; font-size: 13px; color: #ffd23f; }
.fr-list { display: flex; flex-direction: column; gap: 8px; margin-top: 12px; }
.fr-empty { text-align: center; font-weight: 700; font-size: 13px; color: rgba(255,255,255,.7); padding: 14px 0; }
.fr-row { display: flex; align-items: center; gap: 10px; padding: 9px 10px; border-radius: 16px; background: rgba(12,24,70,.82);
  box-shadow: inset 0 0 0 1.5px rgba(255,255,255,.12); }
.fr-row .club-badge, .fr-row .fake-badge { flex: none; width: 34px; height: 34px; }
.fr-name { flex: 1; min-width: 0; display: flex; flex-direction: column; font-weight: 900; font-size: 15px; color: #fff;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fr-name em { font-style: normal; font-weight: 700; font-size: 11px; color: rgba(255,255,255,.6); }
.fr-name em.on { color: #3ddc6b; }
.fr-play { display: flex; flex-direction: column; align-items: center; height: 38px; justify-content: center; padding: 0 12px;
  border-radius: 12px; border: 0; font-weight: 900; font-size: 12px; color: #fff; background: #3a4a7a; opacity: .7; }
.fr-play em { font-style: normal; font-size: 8px; letter-spacing: .1em; opacity: .8; }
/* ...on the profile page's light panels the account's small print goes dark */
.setup .acct-note, .setup .acct-who { color: #4a5880; }
.setup .acct-out { color: #10204f; background: rgba(16,32,79,.1); }
.setup .acct-apple { opacity: .35; }

/* ---------- the welcome screen (js/main.js openWelcome) ---------- */
.screen.welcome { justify-content: space-between; align-items: stretch; padding-bottom: max(22px, calc(var(--sab) + 10px));
  background: radial-gradient(120% 70% at 50% 28%, rgba(40,70,190,.35), rgba(8,14,48,.82) 70%); }
.wl-hero { position: relative; flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px;
  padding-top: 18px; }
.wl-rays { position: absolute; top: 50%; left: 50%; width: 560px; height: 560px; margin: -330px 0 0 -280px; pointer-events: none;
  background: repeating-conic-gradient(from 0deg, rgba(255,210,63,.16) 0 9deg, transparent 9deg 22deg);
  -webkit-mask: radial-gradient(circle, #000 18%, transparent 62%); mask: radial-gradient(circle, #000 18%, transparent 62%);
  animation: wlSpin 40s linear infinite; }
@keyframes wlSpin { to { transform: rotate(360deg); } }
.wl-crest { position: relative; width: min(52vw, 220px); filter: drop-shadow(0 12px 22px rgba(0,0,0,.55)) drop-shadow(0 0 26px rgba(255,210,63,.35));
  animation: wlFloat 3.6s ease-in-out infinite; }
@keyframes wlFloat { 50% { transform: translateY(-8px) rotate(-1.5deg); } }
.wl-title { position: relative; margin: 2px 0 0; font-family: var(--display); font-weight: 400; font-size: 64px; letter-spacing: 4px; line-height: 1;
  color: #ffd23f; background: linear-gradient(180deg, #fff6c9 8%, #ffd23f 48%, #f0a000 92%); -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; filter: drop-shadow(0 4px 0 #8a5200) drop-shadow(0 8px 14px rgba(0,0,0,.55)); }
.wl-tag { position: relative; margin: 6px 0 0; font-weight: 900; font-size: 14px; letter-spacing: .02em; color: #e6edff;
  text-shadow: 0 2px 0 rgba(0,0,0,.45); }
.wl-panel { display: flex; flex-direction: column; gap: 10px; padding: 16px 14px 14px; border-radius: 26px;
  background: linear-gradient(180deg, rgba(36,58,143,.92), rgba(18,30,92,.94));
  box-shadow: inset 0 0 0 2px rgba(255,210,63,.5), inset 0 2px 0 rgba(255,255,255,.18), 0 14px 30px -10px rgba(0,0,0,.75); }
.wl-btn { position: relative; display: flex; align-items: center; justify-content: center; gap: 11px; height: 56px; border-radius: 17px; border: 0;
  font-family: var(--display); font-size: 19px; letter-spacing: .5px; }
.wl-btn:active { transform: translateY(3px); }
.wl-google { color: #1f1f1f; background: linear-gradient(180deg, #fff, #e9eef8); box-shadow: 0 5px 0 #a9b6d2, 0 10px 18px -8px rgba(0,0,0,.6); }
.wl-google:active { box-shadow: 0 2px 0 #a9b6d2; }
.wl-ico { display: grid; place-items: center; width: 24px; height: 24px; }
.wl-ico .g-logo { width: 24px; height: 24px; }
.wl-apple { color: #fff; background: linear-gradient(180deg, #2b2b2b, #050505); box-shadow: 0 5px 0 #000, 0 10px 18px -8px rgba(0,0,0,.6); }
.wl-apple:disabled { opacity: .6; }
.wl-apple-ico { background: #fff; -webkit-mask: var(--apple) center / 20px no-repeat; mask: var(--apple) center / 20px no-repeat;
  --apple: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M16.4 12.7c0-2.5 2-3.7 2.1-3.8-1.2-1.7-3-1.9-3.6-2-1.5-.2-3 .9-3.8.9-.8 0-2-.9-3.3-.9-1.7 0-3.3 1-4.2 2.5-1.8 3.1-.5 7.7 1.3 10.2.9 1.2 1.9 2.6 3.2 2.6 1.3-.1 1.8-.8 3.3-.8s2 .8 3.3.8c1.4 0 2.3-1.3 3.1-2.5 1-1.4 1.4-2.8 1.4-2.9 0 0-2.8-1.1-2.8-4.1ZM14 5.2c.7-.8 1.2-2 1-3.2-1 .1-2.2.7-2.9 1.5-.6.7-1.2 1.9-1.1 3.1 1.1.1 2.3-.6 3-1.4Z"/></svg>'); }
.wl-btn em { position: absolute; right: 12px; font-style: normal; font-family: var(--body); font-weight: 900; font-size: 10px; letter-spacing: .1em;
  padding: 3px 8px; border-radius: 999px; color: #3a2600; background: linear-gradient(180deg, #ffe98d, #ffc21a); }
.wl-or { display: flex; align-items: center; gap: 10px; color: rgba(255,255,255,.55); font-weight: 900; font-size: 12px; letter-spacing: .14em; text-transform: uppercase; }
.wl-or::before, .wl-or::after { content: ""; flex: 1; height: 1.5px; background: rgba(255,255,255,.2); }
.wl-guest { height: 46px; border-radius: 15px; border: 0; font-family: var(--display); font-size: 18px; letter-spacing: .5px; color: #fff;
  background: rgba(255,255,255,.12); box-shadow: inset 0 0 0 1.5px rgba(255,255,255,.25); }
.wl-guest:active { background: rgba(255,255,255,.2); }
.wl-small { margin: 2px 4px 0; text-align: center; font-weight: 700; font-size: 11.5px; line-height: 1.4; color: rgba(255,255,255,.66); }
.wl-wait { display: flex; align-items: center; justify-content: center; gap: 12px; height: 120px; font-family: var(--display); font-size: 20px; color: #fff;
  text-shadow: 0 2px 0 rgba(0,0,0,.4); }
.wl-wait[hidden] { display: none; }
.wl-spin { width: 26px; height: 26px; border-radius: 50%; border: 4px solid rgba(255,255,255,.25); border-top-color: #ffd23f; animation: wlSpin .8s linear infinite; }

/* ---------- the profile form, redone with the welcome (the user, 2026-10-08) ---------- */
.setup-head { display: flex; flex-direction: column; align-items: center; gap: 0; padding-top: 4px; }
.setup-head .sh-crest { width: 64px; filter: drop-shadow(0 6px 10px rgba(0,0,0,.5)); }
.setup-head h1 { margin-top: 2px; font-size: 32px; color: #ffd23f; background: linear-gradient(180deg, #fff6c9 8%, #ffd23f 50%, #f0a000 92%);
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
  filter: drop-shadow(0 3px 0 #8a5200) drop-shadow(0 6px 10px rgba(0,0,0,.45)); text-shadow: none; }
.field-label .step { display: inline-grid; place-items: center; width: 17px; height: 17px; margin-right: 6px; border-radius: 50%;
  font-style: normal; font-size: 10px; letter-spacing: 0; color: #3a2600; background: linear-gradient(180deg, #ffe98d, #ffc21a);
  box-shadow: 0 1.5px 0 #b86e00; vertical-align: -3px; }

/* ---------- the account in the settings ---------- */
.settings-panel .acct-box { margin-bottom: 4px; }
.settings-panel .acct-who { color: #fff; }
.acct-row { display: flex; gap: 8px; justify-content: center; }
.acct-row .acct-out { flex: 1; }
.wl-btn em { top: -8px; right: 10px; box-shadow: 0 2px 0 #b86e00; }
/* the settings panel is light: the account's words go dark there */
.settings-panel .acct-who { color: var(--ink); }
.settings-panel .acct-note { color: #6b6450; }
.settings-panel .acct-out { color: var(--ink); background: rgba(26,35,82,.1); }
.settings-panel .acct-apple { opacity: .35; }
.settings-panel .acct-google { box-shadow: 0 3px 0 #c9b98f, 0 0 0 1.5px #e3d6b4; }
/* the smoke out of the torn pack (js/main.js puffSmoke): above the reveal film too */
.op-smoke { position: absolute; z-index: 53; pointer-events: none; }
.op-smoke[hidden] { display: none; }
.op-film-reveal { transition: opacity .6s ease; }

/* ---------- the favourite star (js/main.js renderPowers) ---------- */
.pi-fav { display: flex; align-items: center; justify-content: center; gap: 8px; width: 100%; height: 44px; margin-top: 10px; border: 0;
  border-radius: 14px; font-family: var(--display); font-size: 17px; letter-spacing: .5px; color: #fff;
  background: rgba(255,255,255,.12); box-shadow: inset 0 0 0 1.5px rgba(255,210,63,.55); }
.pi-fav img { width: 26px; height: 26px; object-fit: contain; filter: grayscale(1) brightness(1.4) drop-shadow(0 2px 2px rgba(0,0,0,.4)); }
.pi-fav.on { color: #3a2600; background: linear-gradient(180deg, #fff1a8, #ffd23f 50%, #f0a800);
  box-shadow: 0 4px 0 #b86e00, 0 0 18px rgba(255,210,63,.6); }
.pi-fav.on img { filter: drop-shadow(0 2px 2px rgba(0,0,0,.35)); }
.pi-fav.pop { animation: favPop .55s cubic-bezier(.2,1.8,.4,1); }
@keyframes favPop { 0% { transform: scale(.85); } 60% { transform: scale(1.08); } 100% { transform: scale(1); } }
.pc-fav { position: absolute; z-index: 3; top: -12px; left: 50%; width: 34px; translate: -50% 0; pointer-events: none;
  filter: drop-shadow(0 3px 3px rgba(0,0,0,.6)) drop-shadow(0 0 8px rgba(255,210,63,.7)); animation: favBob 2.4s ease-in-out infinite; }
@keyframes favBob { 50% { translate: -50% -3px; } }

/* ---------- a friend's card (js/main.js openFriendCard) ---------- */
.fp-panel { position: relative; width: min(100%, 380px); max-height: 92%; overflow-y: auto; padding: 18px 16px 16px; border-radius: 28px;
  color: #fff; text-align: center; background: radial-gradient(120% 60% at 50% 0%, #3552c4, #1a2a80 55%, #101a58);
  box-shadow: inset 0 0 0 2.5px rgba(255,210,63,.7), inset 0 2px 0 rgba(255,255,255,.25), 0 26px 50px -12px rgba(0,0,0,.8);
  animation: pop .45s cubic-bezier(.2,1.6,.4,1); }
.fp-wait { display: grid; place-items: center; min-height: 180px; font-weight: 800; color: rgba(255,255,255,.8); }
.fp-close { position: absolute; top: 10px; right: 12px; width: 34px; height: 34px; border-radius: 50%; border: 0; font-size: 24px; line-height: 1;
  color: #fff; background: rgba(255,255,255,.14); }
.fp-head { display: flex; align-items: center; gap: 10px; text-align: left; padding-right: 34px; }
.fp-crest { width: 58px; flex: none; filter: drop-shadow(0 4px 6px rgba(0,0,0,.5)); }
.fp-id { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.fp-name { font-family: var(--display); font-size: 26px; line-height: 1.05; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  text-shadow: 0 2px 0 rgba(0,0,0,.4); }
.fp-seen { font-weight: 800; font-size: 12px; color: rgba(255,255,255,.65); }
.fp-seen.on { color: #3ddc6b; }
.fp-club .club-badge { width: 40px; height: 40px; }
.fp-band { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 14px; padding: 10px 12px; border-radius: 18px;
  background: rgba(8,14,50,.55); box-shadow: inset 0 0 0 1.5px rgba(255,255,255,.1); }
.fp-tr { display: flex; align-items: center; gap: 6px; font-family: var(--display); font-size: 30px; color: #ffd23f; text-shadow: 0 2px 0 #8a5200; }
.fp-tr img { width: 34px; height: 34px; object-fit: contain; }
.fp-arena { display: flex; align-items: center; gap: 7px; text-align: left; }
.fp-arena img { width: 40px; height: 40px; object-fit: contain; }
.fp-arena span { display: flex; flex-direction: column; font-weight: 900; font-size: 11px; letter-spacing: .1em; color: rgba(255,255,255,.7); }
.fp-arena em { font-style: normal; font-family: var(--display); font-size: 15px; letter-spacing: .3px; color: #fff; }
.fp-fav-label { display: flex; align-items: center; justify-content: center; gap: 6px; margin: 16px 0 8px; font-weight: 900; font-size: 12px;
  letter-spacing: .16em; color: #ffd23f; }
.fp-fav-label img { width: 22px; }
.fp-star { position: relative; width: 62%; margin: 0 auto; aspect-ratio: 3 / 4; border-radius: 18px; overflow: hidden;
  box-shadow: 0 0 0 3px var(--r), 0 0 0 5px rgba(255,255,255,.2), 0 0 32px color-mix(in srgb, var(--r) 70%, transparent), 0 12px 22px -8px rgba(0,0,0,.8);
  animation: fpGlow 2.6s ease-in-out infinite; }
@keyframes fpGlow { 50% { box-shadow: 0 0 0 3px var(--r), 0 0 0 5px rgba(255,255,255,.3), 0 0 46px var(--r), 0 12px 22px -8px rgba(0,0,0,.8); } }
.fp-star-art, .fp-star-art > * { position: absolute; inset: 0; width: 100%; height: 100%; }
.fp-star-art .portrait { transform: scale(var(--art-zoom, 1)); transform-origin: 50% 0%; }
.fp-star::after { content: ""; position: absolute; inset: 0; background: linear-gradient(105deg, transparent 30%, rgba(255,255,255,.35) 45%, transparent 60%);
  background-size: 250% 100%; animation: fpShine 3.2s ease-in-out infinite; pointer-events: none; }
@keyframes fpShine { 0% { background-position: 130% 0; } 60%, 100% { background-position: -60% 0; } }
.fp-star-name { position: absolute; left: 0; right: 0; bottom: 0; z-index: 1; display: flex; flex-direction: column; padding: 22px 6px 8px;
  font-family: var(--display); font-size: 20px; text-shadow: 0 2px 0 rgba(0,0,0,.6); background: linear-gradient(180deg, transparent, rgba(6,8,30,.9)); }
.fp-star-name em { font-style: normal; font-family: var(--body); font-weight: 900; font-size: 10px; letter-spacing: .14em; color: var(--r); }
.fp-star.none { display: grid; place-items: center; aspect-ratio: auto; height: 90px; font-weight: 800; font-size: 13px;
  color: rgba(255,255,255,.65); background: rgba(8,14,50,.45); box-shadow: inset 0 0 0 1.5px rgba(255,255,255,.12); animation: none; }
.fp-star.none::after { display: none; }
.fp-stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 7px; margin-top: 16px; }
.fp-stat { display: flex; flex-direction: column; gap: 1px; padding: 9px 4px; border-radius: 14px; background: rgba(8,14,50,.5);
  box-shadow: inset 0 0 0 1.5px rgba(255,255,255,.08); }
.fp-stat b { font-family: var(--display); font-weight: 400; font-size: 22px; color: #fff; }
.fp-stat span { font-weight: 900; font-size: 8.5px; letter-spacing: .1em; color: rgba(255,255,255,.6); }
.fp-play { display: flex; align-items: center; justify-content: center; gap: 8px; width: 100%; height: 48px; margin-top: 14px; border: 0; border-radius: 16px;
  font-family: var(--display); font-size: 20px; color: #fff; background: #3a4a7a; opacity: .75; }
.fp-play em { font-style: normal; font-family: var(--body); font-weight: 900; font-size: 9px; letter-spacing: .12em; padding: 2px 7px; border-radius: 999px;
  color: #3a2600; background: #ffd23f; }
.fr-row { cursor: pointer; }
.fr-row:active { transform: scale(.98); }
/* MAKE FAVOURITE readable on the light panel (the user, 2026-10-08): a solid button in the star's rarity colour */
.pi-fav:not(.on) { color: #fff; text-shadow: 0 2px 0 rgba(0,0,0,.35);
  background: linear-gradient(180deg, color-mix(in srgb, var(--c) 70%, #fff), var(--c) 55%, color-mix(in srgb, var(--c) 80%, #000));
  box-shadow: 0 4px 0 color-mix(in srgb, var(--c) 55%, #000), 0 8px 14px -6px rgba(0,0,0,.45); }
.pi-fav:not(.on) img { filter: drop-shadow(0 2px 2px rgba(0,0,0,.35)); }
.pi-fav:active { transform: translateY(3px); }

/* ---------- a friend's card, the pro layout (the user, 2026-10-08) ---------- */
.fp-panel { padding: 0 0 14px; overflow-x: hidden; }
.fp-arena-top { position: relative; height: 196px; border-radius: 28px 28px 0 0; overflow: hidden;
  background: linear-gradient(180deg, rgba(10,18,60,.15), rgba(16,26,88,.2) 55%, #1a2a80 100%), var(--bg) center / cover; }
.fp-arena-top::before { content: ""; position: absolute; inset: 0; backdrop-filter: blur(3px) saturate(1.2); -webkit-backdrop-filter: blur(3px) saturate(1.2);
  background: radial-gradient(60% 55% at 50% 45%, rgba(255,226,140,.35), transparent 70%); }
.fp-arena-top::after { content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg, transparent 60%, #1a2a80); }
.fp-arena-model { position: absolute; left: 50%; top: 12px; width: 62%; translate: -50% 0; z-index: 1;
  filter: drop-shadow(0 14px 16px rgba(0,0,0,.55)); animation: fpModel 4s ease-in-out infinite; }
@keyframes fpModel { 50% { transform: translateY(-6px); } }
.fp-arena-chip { position: absolute; left: 50%; bottom: 10px; translate: -50% 0; z-index: 2; display: flex; align-items: center; gap: 7px;
  padding: 4px 14px 4px 5px; border-radius: 999px; white-space: nowrap; background: rgba(8,14,50,.82);
  box-shadow: inset 0 0 0 1.5px rgba(255,210,63,.6), 0 6px 14px -6px rgba(0,0,0,.7); }
.fp-arena-chip img { width: 34px; height: 34px; object-fit: contain; }
.fp-arena-chip span { display: flex; flex-direction: column; align-items: flex-start; font-weight: 900; font-size: 9.5px; letter-spacing: .14em;
  color: #ffd23f; line-height: 1.15; }
.fp-arena-chip b { font-family: var(--display); font-weight: 400; font-size: 16px; letter-spacing: .3px; color: #fff; }
.fp-close { z-index: 3; background: rgba(8,14,50,.6); }
.fp-head { margin: 12px 14px 0; padding: 0; }
.fp-seen i { display: inline-block; width: 8px; height: 8px; margin-right: 5px; border-radius: 50%; background: #3ddc6b; box-shadow: 0 0 6px #3ddc6b; }
.fp-head .fp-tr { flex: none; font-size: 26px; }
.fp-head .fp-tr img { width: 28px; height: 28px; }
.fp-body { display: grid; grid-template-columns: 44% 1fr; gap: 10px; margin: 14px 14px 0; align-items: start; }
.fp-fav { display: flex; flex-direction: column; }
.fp-fav .fp-fav-label { margin: 0 0 7px; font-size: 10.5px; }
.fp-fav .fp-star { width: 100%; }
.fp-fav .fp-star-name { font-size: 15px; padding: 18px 4px 6px; }
.fp-fav .fp-star.none { height: auto; aspect-ratio: 3 / 4; font-size: 12px; line-height: 1.3; }
.fp-body .fp-stats { grid-template-columns: 1fr; gap: 5px; margin-top: 0; }
.fp-body .fp-stat { flex-direction: row; align-items: center; justify-content: space-between; padding: 7px 10px; border-radius: 11px; text-align: left; }
.fp-body .fp-stat span { font-size: 9px; }
.fp-body .fp-stat b { font-size: 18px; }
.fp-club-row { display: flex; align-items: center; gap: 9px; margin: 12px 14px 0; padding: 7px 10px; border-radius: 14px; background: rgba(8,14,50,.45);
  font-weight: 900; font-size: 10px; letter-spacing: .12em; color: rgba(255,255,255,.6); }
.fp-club-row .club-badge { width: 30px; height: 30px; flex: none; }
.fp-club-row b { font-family: var(--display); font-weight: 400; font-size: 15px; letter-spacing: .3px; color: #fff; margin-left: 3px; }
.fp-play { width: calc(100% - 28px); margin: 12px 14px 0; }
.fr-crest { flex: none; width: 40px; height: 44px; object-fit: contain; filter: drop-shadow(0 3px 4px rgba(0,0,0,.5)); }

/* ---------- challenges (js/main.js showInvite, challenge) ---------- */
.inv-overlay { z-index: 60; }
.inv-panel { display: flex; flex-direction: column; align-items: center; gap: 4px; width: min(100%, 330px); padding: 20px 18px 16px; border-radius: 26px;
  color: #fff; text-align: center; background: radial-gradient(120% 70% at 50% 0%, #3552c4, #1a2a80 60%, #101a58);
  box-shadow: inset 0 0 0 2.5px rgba(255,210,63,.75), 0 0 40px rgba(255,210,63,.25), 0 26px 50px -12px rgba(0,0,0,.8);
  animation: pop .45s cubic-bezier(.2,1.6,.4,1); }
.inv-crest { width: 84px; filter: drop-shadow(0 6px 10px rgba(0,0,0,.5)); animation: wlFloat 2.4s ease-in-out infinite; }
.inv-kicker { margin-top: 4px; font-weight: 900; font-size: 12px; letter-spacing: .2em; color: #ffd23f; }
.inv-name { font-family: var(--display); font-size: 30px; line-height: 1.05; text-shadow: 0 3px 0 rgba(0,0,0,.4); }
.inv-sub { font-weight: 800; font-size: 13px; color: rgba(255,255,255,.75); }
.inv-sub b { color: #fff; }
.inv-btns { display: flex; gap: 10px; width: 100%; margin-top: 14px; }
.inv-btns button { flex: 1; height: 50px; border: 0; border-radius: 16px; font-family: var(--display); font-size: 19px; letter-spacing: .5px; }
.inv-no { color: #fff; background: rgba(255,255,255,.14); box-shadow: inset 0 0 0 1.5px rgba(255,255,255,.25); }
.inv-yes { color: #3a2600; background: linear-gradient(180deg, #ffe98d, #ffc21a 55%, #f0a800); box-shadow: 0 5px 0 #b86e00, 0 0 18px rgba(255,210,63,.5); }
.inv-yes:active, .inv-no:active { transform: translateY(3px); }
.inv-panel .wl-spin { width: 38px; height: 38px; margin-bottom: 4px; }
.net-toast { position: fixed; left: 50%; top: max(70px, calc(env(safe-area-inset-top) + 56px)); z-index: 70; translate: -50% 0; padding: 10px 18px;
  border-radius: 999px; font-weight: 900; font-size: 14px; color: #fff; background: rgba(8,14,50,.92); white-space: nowrap;
  box-shadow: inset 0 0 0 1.5px rgba(255,210,63,.6), 0 10px 20px -8px rgba(0,0,0,.7); }
.net-toast.in { animation: pop .4s cubic-bezier(.2,1.6,.4,1); }
.net-toast[hidden] { display: none; }
.fp-play:not(:disabled) { color: #3a2600; opacity: 1; background: linear-gradient(180deg, #ffe98d, #ffc21a 55%, #f0a800); box-shadow: 0 5px 0 #b86e00; }
.fr-play:not(:disabled) { opacity: 1; color: #3a2600; background: linear-gradient(180deg, #ffe98d, #ffc21a); box-shadow: 0 3px 0 #b86e00; }
.trophy-delta.friendly { font-size: 24px; }
.trophy-delta.friendly::before { display: none; }

/* ---------- the friends page in the game's white glass (the user, 2026-10-08: "our white design, not dark blue") ---------- */
#friends .soon-card, #friends .fr-card { background: var(--glass); color: var(--ink);
  border: 1px solid var(--glass-line); box-shadow: inset 0 1px 0 var(--glass-top), var(--drop); }
#friends .soon-title { color: var(--ink); text-shadow: none; }
#friends .soon-text { color: var(--ink-2); }
#friends .acct-note { color: var(--ink-2); }
#friends .acct-google { box-shadow: 0 3px 0 #b9c3d6, 0 0 0 1.5px #dfe6f5; }
#friends .acct-apple { opacity: .35; }
#friends .fr-label { color: var(--ink-2); }
#friends .fr-code { color: #f0a800; text-shadow: 0 3px 0 #8a5200, 0 6px 10px rgba(138,82,0,.25); }
#friends .fr-hint { color: var(--ink-2); }
#friends .fr-add input { background: #fff; color: var(--ink); box-shadow: inset 0 0 0 2px rgba(26,35,82,.12); }
#friends .fr-msg { color: #d99a00; }
#friends .fr-empty { color: var(--ink-2); }
#friends .fr-row { background: var(--glass); border: 1px solid var(--glass-line);
  box-shadow: inset 0 1px 0 var(--glass-top), 0 8px 16px -10px rgba(20,26,70,.45); }
#friends .fr-name { color: var(--ink); }
#friends .fr-name em { color: var(--ink-2); }
#friends .fr-name em.on { color: #1fa64a; }
#friends .fr-row .lb-tr { color: var(--ink); }

/* ---------- a friend's card in the game's white glass (the user, 2026-10-08) ---------- */
.fp-panel { color: var(--ink); background: linear-gradient(180deg, #ffffff, #eef3ff 60%, #e2eaff);
  box-shadow: inset 0 0 0 2.5px rgba(255,210,63,.85), inset 0 2px 0 #fff, 0 26px 50px -12px rgba(0,0,0,.75); }
.fp-arena-top { background: linear-gradient(180deg, rgba(10,18,60,.05), rgba(16,26,88,.1) 55%, rgba(255,255,255,0) 100%), var(--bg) center / cover; }
.fp-arena-top::after { background: linear-gradient(180deg, transparent 55%, #ffffff); }
.fp-arena-chip { background: rgba(255,255,255,.94); box-shadow: inset 0 0 0 1.5px rgba(255,210,63,.9), 0 6px 14px -6px rgba(20,26,70,.5); }
.fp-arena-chip span { color: #d99a00; }
.fp-arena-chip b { color: var(--ink); }
.fp-name { color: var(--ink); text-shadow: none; }
.fp-seen { color: var(--ink-2); }
.fp-seen.on { color: #1fa64a; }
.fp-head .fp-tr { color: #f0a800; text-shadow: 0 2px 0 #8a5200; }
.fp-fav .fp-fav-label { color: #d99a00; }
.fp-star.none { color: var(--ink-2); background: rgba(26,35,82,.06); box-shadow: inset 0 0 0 1.5px rgba(26,35,82,.1); }
.fp-body .fp-stat { background: #fff; box-shadow: inset 0 0 0 1.5px rgba(26,35,82,.08), 0 3px 8px -5px rgba(20,26,70,.3); }
.fp-body .fp-stat span { color: var(--ink-2); }
.fp-body .fp-stat b { color: var(--ink); }
.fp-club-row { background: #fff; color: var(--ink-2); box-shadow: inset 0 0 0 1.5px rgba(26,35,82,.08); }
.fp-club-row b { color: var(--ink); }
.fp-wait { color: var(--ink-2); }
.fp-play:disabled { color: var(--ink-2); background: rgba(26,35,82,.1); }
.fp-star-name { color: #fff; }
.mp-modes { display: flex; flex-direction: column; gap: 9px; width: 100%; margin-top: 12px; }
.mp-mode { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; padding: 12px 14px; border: 0; border-radius: 16px; text-align: left;
  color: var(--ink-2); background: var(--glass); box-shadow: inset 0 1px 0 var(--glass-top), 0 4px 0 #9fb0d6, 0 10px 18px -8px rgba(0,0,0,.6); }
.mp-mode:active { transform: translateY(3px); }
.mp-mode-name { font-family: var(--display); font-size: 21px; color: var(--ink); }
.mp-mode-blurb { font-weight: 800; font-size: 12px; }
.mp-mode.on { box-shadow: inset 0 0 0 2.5px #ffc21a, 0 4px 0 #b86e00, 0 10px 18px -8px rgba(0,0,0,.6); }
.inv-mode { margin-top: 6px; padding: 4px 12px; border-radius: 999px; font-weight: 900; font-size: 12px; letter-spacing: .12em;
  color: #3a2600; background: linear-gradient(180deg, #ffe98d, #ffc21a); }
.inv-mode:empty { display: none; }

/* ---------- the sticker button, redone (the user, 2026-10-08) ---------- */
.emote-btn { width: 54px; height: 54px; overflow: visible; isolation: isolate;
  background: radial-gradient(120% 90% at 50% 15%, #7cc0ff, #3d86f5 45%, #2353c4 100%);
  box-shadow: 0 0 0 3px #ffd23f, 0 0 0 5px rgba(138,82,0,.55), 0 6px 0 2px #8a5200, 0 12px 18px -6px rgba(0,0,0,.75);
  animation: emoteIdle 3.2s ease-in-out infinite; }
.emote-btn::before { content: ""; position: absolute; inset: 3px 7px auto; height: 42%; border-radius: 50% 50% 45% 45%; z-index: 1;
  background: linear-gradient(180deg, rgba(255,255,255,.55), rgba(255,255,255,0)); pointer-events: none; }
.emote-btn svg { position: relative; z-index: 2; width: 34px; height: 34px; margin: 10px auto 0; filter: drop-shadow(0 2px 0 rgba(10,30,90,.45)); }
@keyframes emoteIdle { 0%, 82%, 100% { transform: none; } 87% { transform: rotate(-8deg) scale(1.06); } 92% { transform: rotate(7deg) scale(1.06); } }
.emote-btn:active { transform: translateY(3px) scale(.96); animation: none; }
.emote-btn.open { filter: none; box-shadow: 0 0 0 3px #fff3a6, 0 0 0 5px #ffd23f, 0 0 18px rgba(255,210,63,.8), 0 6px 0 2px #8a5200; animation: none; }
/* the wait between stickers drawn as a ring running out, not just a grey button */
.emote-btn.cooling { filter: none; animation: none; }
.emote-btn.cooling::after { content: ""; position: absolute; inset: -5px; z-index: 3; border-radius: 50%; pointer-events: none;
  background: conic-gradient(rgba(8,14,50,.62) var(--cd, 100%), transparent 0);
  animation: emoteCool 4s linear forwards; }
@property --cd { syntax: "<percentage>"; inherits: false; initial-value: 100%; }
@keyframes emoteCool { from { --cd: 100%; } to { --cd: 0%; } }
#match .emote-btn { bottom: calc(78px + var(--kbh) + var(--sab)); }

/* ---------- the real crest in the HUD and on the round board (the user, 2026-10-08) ---------- */
.av-icon.crest { background: var(--crest) center / contain no-repeat !important; border-radius: 0 !important; box-shadow: none !important;
  filter: drop-shadow(0 4px 5px rgba(0,0,0,.55)); }
.side .av-icon { width: 46px; height: 50px; }
.av-stars { margin-top: -6px; }
/* ---------- finding an opponent ---------- */
.seek-ring { position: relative; display: grid; place-items: center; width: 74px; height: 74px; }
.seek-ring .wl-spin { position: absolute; inset: 0; width: 74px; height: 74px; border-width: 5px; margin: 0; }
.seek-ring b { font-family: var(--display); font-weight: 400; font-size: 30px; color: #fff; }

/* ---------- the challenge windows in the game's white (the user, 2026-10-08) ---------- */
.inv-panel.light { position: relative; overflow: hidden; color: var(--ink); background: linear-gradient(180deg, #ffffff, #eef3ff 60%, #e2eaff);
  box-shadow: inset 0 0 0 2.5px rgba(255,210,63,.9), inset 0 2px 0 #fff, 0 0 40px rgba(255,210,63,.25), 0 26px 50px -12px rgba(0,0,0,.75); }
.inv-panel.light > * { position: relative; }
.inv-rays { position: absolute !important; top: -150px; left: 50%; width: 420px; height: 420px; margin-left: -210px; pointer-events: none;
  background: repeating-conic-gradient(from 0deg, rgba(255,200,40,.16) 0 9deg, transparent 9deg 22deg);
  -webkit-mask: radial-gradient(circle, #000 15%, transparent 60%); mask: radial-gradient(circle, #000 15%, transparent 60%);
  animation: wlSpin 30s linear infinite; }
.inv-panel.light .inv-kicker { color: #d99a00; }
.inv-panel.light .inv-name { color: var(--ink); text-shadow: none; }
.inv-panel.light .inv-sub { color: var(--ink-2); }
.inv-facts { display: flex; gap: 8px; justify-content: center; flex-wrap: wrap; margin-top: 8px; }
.inv-fact { display: flex; align-items: center; gap: 6px; padding: 5px 12px 5px 6px; border-radius: 999px; background: #fff;
  font-family: var(--display); font-size: 15px; color: var(--ink); box-shadow: inset 0 0 0 1.5px rgba(26,35,82,.1), 0 3px 8px -5px rgba(20,26,70,.35); }
.inv-fact:not(:has(img)) { padding-left: 12px; }
.inv-fact img { width: 26px; height: 26px; object-fit: contain; }
.inv-fact b { font-weight: 400; }
.inv-stake { display: flex; flex-direction: column; align-items: center; gap: 2px; margin-top: 10px; padding: 8px 18px; border-radius: 16px;
  background: linear-gradient(180deg, #fff6c9, #ffe27a); box-shadow: inset 0 0 0 2px #ffc21a, 0 4px 0 #d99a00; }
.inv-stake[hidden] { display: none; }
.inv-stake span { font-weight: 900; font-size: 10px; letter-spacing: .16em; color: #8a5200; }
.inv-stake b { display: flex; align-items: center; gap: 5px; font-family: var(--display); font-weight: 400; font-size: 26px; color: #5a3500; }
.inv-stake b img { width: 26px; height: 26px; object-fit: contain; }
.inv-stake em { font-style: normal; font-weight: 900; font-size: 11px; color: #d22b3d; }
.inv-timer { width: 100%; height: 5px; margin-top: 12px; border-radius: 999px; overflow: hidden; background: rgba(26,35,82,.1); }
.inv-timer i { display: block; height: 100%; background: linear-gradient(90deg, #ffc21a, #f0a800); transform-origin: left; animation: invTime 30s linear forwards; }
@keyframes invTime { to { transform: scaleX(0); } }
.inv-panel.light .inv-no { color: var(--ink); background: #fff; box-shadow: inset 0 0 0 2px rgba(26,35,82,.14), 0 4px 0 #b9c3d6; }
.inv-panel.light .inv-yes { color: #fff; text-shadow: 0 2px 0 #1a6b2c; background: linear-gradient(180deg, #6ee87e, #2fbf4d 55%, #1f9a3a);
  box-shadow: 0 5px 0 #157a2c, 0 0 18px rgba(61,220,107,.45); }
.inv-yes:disabled { filter: grayscale(.8); opacity: .6; }
.inv-panel.light .seek-ring b { color: var(--ink); }
.inv-panel.light .wl-spin { border-color: rgba(26,35,82,.15); border-top-color: #ffc21a; }
/* the game and the stake, picked before the challenge goes out */
.mp-label { align-self: flex-start; margin-top: 12px; font-weight: 900; font-size: 10.5px; letter-spacing: .14em; color: var(--ink-2); }
.mp-label em { font-style: normal; font-weight: 800; letter-spacing: 0; text-transform: none; color: #d99a00; margin-left: 4px; }
.mp-modes { margin-top: 6px; }
.inv-panel.light .mp-mode { background: #fff; box-shadow: inset 0 0 0 1.5px rgba(26,35,82,.12), 0 4px 0 #c9d3ea; }
.inv-panel.light .mp-mode.on { box-shadow: inset 0 0 0 2.5px #ffc21a, 0 4px 0 #d99a00, 0 0 14px rgba(255,194,26,.35); }
.mp-stakes { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; width: 100%; margin-top: 6px; }
.mp-stake { display: flex; align-items: center; justify-content: center; gap: 3px; height: 40px; border: 0; border-radius: 12px; font-family: var(--display);
  font-size: 15px; color: var(--ink); background: #fff; box-shadow: inset 0 0 0 1.5px rgba(26,35,82,.12), 0 3px 0 #c9d3ea; }
.mp-stake img { width: 18px; height: 18px; object-fit: contain; }
.mp-stake.on { background: linear-gradient(180deg, #fff6c9, #ffe27a); box-shadow: inset 0 0 0 2px #ffc21a, 0 3px 0 #d99a00; }
.mp-stake:disabled { opacity: .35; }
.mp-stake:first-child { font-size: 12px; }
.stake-lost { display: inline-flex; align-items: center; gap: 4px; font-family: var(--display); font-size: 24px; color: #d22b3d; }
.stake-lost img { width: 24px; height: 24px; }
/* between rounds in a net match: NEXT ROUND counting down, and the opponent's READY */
.nx-btn { position: relative; overflow: hidden; }
.nx-btn::after { content: ""; position: absolute; left: 0; bottom: 0; height: 5px; width: var(--nx, 100%); background: rgba(255,255,255,.75);
  transition: width 1s linear; }
.nx-count { display: inline-grid; place-items: center; width: 30px; height: 30px; margin-left: 8px; border-radius: 50%;
  font-size: 18px; background: rgba(0,0,0,.22); vertical-align: 2px; }
.nx-btn.ready { filter: saturate(.6) brightness(.95); }
.nx-opp { display: block; margin-top: 8px; font-weight: 900; font-size: 13px; letter-spacing: .06em; color: rgba(255,255,255,.55); text-align: center; }
.nx-opp::before { content: ""; display: inline-block; width: 9px; height: 9px; margin-right: 6px; border-radius: 50%; background: rgba(255,255,255,.35); }
.nx-opp.on { color: #3ddc6b; }
.nx-opp.on::before { background: #3ddc6b; box-shadow: 0 0 8px #3ddc6b; }
/* the crest clear of the stars under it (the user, 2026-10-08: "I can't see the crests at all") */
.side .av-stars { margin-top: -2px; }

/* ---------- the welcome screen, in the game's own look, with the mascot (the user, 2026-10-08) ---------- */
.screen.welcome { background: linear-gradient(180deg, rgba(20,40,120,.45) 0%, rgba(20,40,120,.12) 40%, rgba(255,255,255,.05) 70%, rgba(10,20,70,.35) 100%); }
.wl-hero { gap: 0; padding-top: 6px; }
.wl-rays { margin-top: -360px; background: repeating-conic-gradient(from 0deg, rgba(255,255,255,.22) 0 8deg, transparent 8deg 20deg); }
.wl-mascot { position: relative; z-index: 1; height: min(40vh, 330px); max-width: 82vw; object-fit: contain;
  filter: drop-shadow(0 14px 18px rgba(10,20,70,.45)); animation: wlMascot 2.8s ease-in-out infinite; transform-origin: 50% 100%; }
@keyframes wlMascot { 0%, 100% { transform: translateY(0) rotate(0); } 25% { transform: translateY(-6px) rotate(-2deg); } 50% { transform: translateY(0) rotate(0); }
  75% { transform: translateY(-4px) rotate(1.5deg); } }
.wl-shadow { width: 46%; height: 18px; margin-top: -14px; border-radius: 50%; background: radial-gradient(closest-side, rgba(10,20,70,.45), transparent);
  animation: wlShadow 2.8s ease-in-out infinite; }
@keyframes wlShadow { 25%, 75% { transform: scaleX(.9); opacity: .8; } }
.wl-title { margin-top: 2px; font-size: 60px; }
.wl-tag { margin-top: 4px; padding: 5px 14px; border-radius: 999px; font-size: 13px; color: var(--ink); text-shadow: none;
  background: rgba(255,255,255,.88); box-shadow: 0 6px 14px -8px rgba(10,20,70,.6); }
.wl-panel { color: var(--ink); background: var(--glass); border: 1px solid var(--glass-line);
  box-shadow: inset 0 1px 0 var(--glass-top), var(--drop), 0 0 0 2.5px rgba(255,210,63,.7); }
.wl-google { background: #fff; box-shadow: inset 0 0 0 2px rgba(26,35,82,.1), 0 5px 0 #b9c3d6, 0 10px 18px -8px rgba(10,20,70,.45); }
.wl-or { color: var(--ink-2); }
.wl-or::before, .wl-or::after { background: rgba(26,35,82,.15); }
.wl-guest { height: 52px; color: #fff; text-shadow: 0 2px 0 rgba(0,0,0,.3); background: linear-gradient(180deg, #6fb8ff, #3d86f5 55%, #2a63d6);
  box-shadow: 0 5px 0 #1d4aa8, 0 10px 18px -8px rgba(10,20,70,.6); }
.wl-guest:active { transform: translateY(3px); box-shadow: 0 2px 0 #1d4aa8; background: linear-gradient(180deg, #6fb8ff, #3d86f5 55%, #2a63d6); }
.wl-small { color: var(--ink-2); }
.wl-wait { color: var(--ink); text-shadow: none; }
/* the welcome's two steps */
.wl-go { flex: none; margin: 0 4px 6px; font-size: 30px; padding: 17px 20px; }
.wl-go[hidden] { display: none; }
.welcome.step-login .wl-mascot { height: min(28vh, 230px); }
.welcome.step-login .wl-title { font-size: 48px; }
.welcome.step-login .wl-panel { animation: pop .45s cubic-bezier(.2,1.6,.4,1); }
.wl-panel[hidden] { display: none; }

/* ---------- the profile form, see-through (the user, 2026-10-08: "the white tiles should be transparent here") ---------- */
.setup .field { background: rgba(255,255,255,.16); border-color: rgba(255,255,255,.35);
  -webkit-backdrop-filter: blur(10px) saturate(1.2); backdrop-filter: blur(10px) saturate(1.2);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.35), 0 10px 22px -12px rgba(0,0,0,.55); color: #fff; }
.setup .field-label { color: #fff; text-shadow: 0 1px 2px rgba(0,0,0,.45); }
.setup .field-note { color: rgba(255,255,255,.85); }
.setup .club-opt { background: rgba(255,255,255,.2); color: #fff; box-shadow: inset 0 0 0 1.5px rgba(255,255,255,.3); text-shadow: 0 1px 2px rgba(0,0,0,.5); }
.setup .club-opt.on { background: rgba(255,210,63,.35); box-shadow: inset 0 0 0 2.5px #ffd23f, 0 0 14px rgba(255,210,63,.5); }
.setup #clubSearch { background: rgba(255,255,255,.92); }
.setup .stat-grid > * { background: rgba(255,255,255,.18); color: #fff; }
/* the crests: no tile, no tap flash */
.icon-opt { -webkit-appearance: none; appearance: none; border: 0; padding: 0; -webkit-tap-highlight-color: transparent; transition: transform .15s; }
.icon-opt:focus { outline: 0; }
/* START / SAVE: white letters */
#setupDone { color: #fff; text-shadow: 0 2px 0 #8a5200, 0 0 2px #8a5200; }
.setup .stat-grid > *, .setup .stat-grid > * * { color: #fff; }
.setup .stat-grid > * > :not(b) { color: rgba(255,255,255,.8); }
/* The club list scrolls with the page, not in a box of its own (the user, 2026-10-08: "why can't I scroll the clubs"):
   a scroller inside a scroller, under a backdrop blur, would not take the finger on the iPhone. And no blur on these
   panels - the see-through is a plain tint, which also keeps the scrolling smooth. */
.setup .field { -webkit-backdrop-filter: none; backdrop-filter: none; background: rgba(20,32,90,.32); }
.setup .field.grow { height: auto; min-height: 0; flex: none; }
.setup .club-grid { overflow: visible; flex: none; min-height: 0; }
.setup .club-opt-name { color: #fff; }
[data-signin].going { opacity: .75; pointer-events: none; }

/* the sticker button, square and plain (the user, 2026-10-08) */
.emote-btn { width: 50px; height: 50px; border-radius: 14px; animation: none;
  background: linear-gradient(180deg, #4f9bff, #2b62d4);
  box-shadow: inset 0 0 0 2px rgba(255,255,255,.45), 0 4px 0 #1d4aa8, 0 8px 14px -6px rgba(0,0,0,.7); }
.emote-btn::before { display: none; }
.emote-btn svg { width: 30px; height: 30px; margin: 10px auto 0; filter: none; }
.emote-btn.open { box-shadow: inset 0 0 0 2px #fff, 0 4px 0 #1d4aa8, 0 0 12px rgba(79,155,255,.7); }
.emote-btn.cooling::after { inset: 0; border-radius: 14px; }

/* ---------- GOAT (the user, 2026-10-08): above Legendary - Argentina's sky blue (it was a festive orange until the
   user's new La Pulga picture the same evening), the foil faster and icier, a glow that breathes and a white rim ---------- */
.power-card[data-rarity="goat"] { box-shadow: 0 0 0 2px #1cb2ff, 0 0 0 3.5px #e6f9ff, 0 5px 0 3px #00467f, 0 0 18px 2px rgba(40,180,255,.7), 0 12px 18px -8px rgba(0,0,0,.85);
  animation: goatGlow 2.4s ease-in-out infinite; }
@keyframes goatGlow { 50% { box-shadow: 0 0 0 2px #5fd0ff, 0 0 0 3.5px #ffffff, 0 5px 0 3px #00467f, 0 0 30px 6px rgba(80,205,255,.9), 0 12px 18px -8px rgba(0,0,0,.85); } }
.power-card[data-rarity="goat"]::before {
  background:
    linear-gradient(150deg, rgba(255,255,255,.38) 0 14%, transparent 34%),
    linear-gradient(115deg, transparent 38%, rgba(225,250,255,.9) 46%, rgba(60,190,255,.6) 50%, transparent 58%);
  background-size: 100% 100%, 320% 100%; background-repeat: no-repeat;
  animation: foil 3.2s ease-in-out infinite; }
.power-card[data-rarity="goat"]:not(.locked) .pc-name { color: #fff; text-shadow: 0 2px 0 #00467f, 0 0 8px rgba(40,180,255,.9); }
.power-card[data-rarity="goat"].sel { box-shadow: 0 0 0 3px #1cb2ff, 0 0 0 6px #ffffff, 0 5px 0 6px #00467f, 0 0 28px 8px #1cb2ff; }

/* Arena 6 a size smaller on the PLAY page (the user, 2026-10-08: "too wide"): its picture is about 2:1 where
   the others are about 3:2, so at the same height it filled the phone from edge to edge. Scaled back to the
   others' drawn width (about 370px of 402). */
#home .arena-hero[data-arena="6"] img { scale: .9; }

/* A star's picture lifted inside its card (the user, 2026-10-08: La Pulga "too low in his card picture, it makes him
   small"): config's artY moves it up on top of the zoom, which grows from the top edge and so pushes him down.
   `translate` composes with the zoom's `transform` instead of replacing it. Cards only - never the small squares. */
.power-card .card-art .portrait, .sc-art .portrait, .rv-art .portrait, .op-card-art img, .starter-art img,
.fp-star-art .portrait { translate: 0 var(--art-y, 0%); }

/* Friends: SORT BY, and an empty list that says what to do (the user, 2026-10-08). */
.fr-sort { display: flex; align-items: center; gap: 6px; margin-top: 14px; }
.fr-sort[hidden] { display: none; }
.fr-sort span { font-weight: 900; font-size: 11px; letter-spacing: .12em; color: var(--ink-2); margin-right: 2px; }
.fr-sort button { flex: 1; padding: 8px 6px; border: 0; border-radius: 999px; font: 900 11px/1 var(--body, inherit); letter-spacing: .06em;
  color: var(--ink-2); background: var(--glass); box-shadow: inset 0 0 0 1px var(--glass-line), 0 3px 0 rgba(20,26,70,.12); }
.fr-sort button.on { color: #3a2600; background: linear-gradient(180deg, #ffe98d, #ffc21a); box-shadow: 0 3px 0 #b86e00; }
.fr-empty-card { display: flex; flex-direction: column; align-items: center; gap: 8px; padding: 22px 20px 20px; text-align: center;
  border-radius: 22px; background: var(--glass); border: 1px solid var(--glass-line); box-shadow: inset 0 1px 0 var(--glass-top), var(--drop); }
.fr-empty-card .soon-icon { width: 58px; height: 58px; }
.fr-empty-card b { font-family: var(--display); font-weight: 400; font-size: 22px; color: var(--ink); }
.fr-empty-card span:not(.soon-icon) { font-weight: 700; font-size: 13.5px; line-height: 1.4; color: var(--ink-2); max-width: 290px; }
.fr-share { margin-top: 6px; padding: 11px 22px; border: 0; border-radius: 999px; font: 900 13px/1 var(--body, inherit); letter-spacing: .1em;
  color: #fff; background: linear-gradient(180deg, #4fa3ff, #1f6fe0); box-shadow: 0 4px 0 #1450a8, 0 8px 14px -6px rgba(20,60,160,.5); }
.fr-share:active { transform: translateY(2px); box-shadow: 0 2px 0 #1450a8; }

/* The arena's flyby coming onto the phone (js/flybycache.js, the user 2026-10-09): a small line on the arena picture. */
.arena-dl { position: absolute; left: 50%; bottom: 6%; z-index: 2; translate: -50% 0; white-space: nowrap; pointer-events: none;
  padding: 4px 10px; border-radius: 999px; font: 900 10px/1 var(--body); letter-spacing: .1em; color: var(--ink-2);
  background: rgba(255,255,255,.88); box-shadow: inset 0 0 0 1px var(--glass-line), 0 4px 10px -4px rgba(20,26,70,.4); }
.arena-dl[hidden] { display: none; }
