:root {
  --bg: #070b14;
  --card: rgba(15, 20, 34, 0.8);
  --line: rgba(255, 255, 255, 0.1);
  --text: #f5f7ff;
  --muted: #9fb0d9;
  --accent: #7cf0c6;
}
* { box-sizing: border-box; }
html, body {
  /* Stop iOS Safari pull-to-refresh / rubber-band bounce (e.g. flicking the Cache wheel). */
  overscroll-behavior: none;
}
body {
  margin: 0;
  min-height: 100vh;
  font-family: "Outfit", sans-serif;
  background: radial-gradient(circle at 20% 20%, #202d57, var(--bg));
  color: var(--text);
  /* Kill the iOS double-tap-to-zoom gesture on rapid taps. */
  touch-action: manipulation;
  -webkit-text-size-adjust: 100%;
}
/* ------------------------------------------------------------------
   Native app feel.

   This is a game, not a document — nothing on screen is meant to be
   read as selectable text. Left alone, iOS treats a long press anywhere
   as "select some text": magnifier, blue selection, and the Copy / Look
   Up / Share callout. Same press on a sprite or a map tile gets the
   "Save Image" sheet, and every tap flashes grey. Those are the tells
   that give the web view away, so kill them app-wide and opt the few
   places that genuinely need selection back in below.
   ------------------------------------------------------------------ */
html {
  -webkit-user-select: none;
  user-select: none;
  /* No long-press Copy / Save Image / link-preview sheet. */
  -webkit-touch-callout: none;
  /* No grey flash on tap — buttons have their own :active states. */
  -webkit-tap-highlight-color: transparent;
}
/* Long-pressing a sprite, map tile or the Leaflet attribution link
   shouldn't start a drag with a translucent ghost image. */
img, a, canvas, svg {
  -webkit-user-drag: none;
}
/* Text entry is the exception: a field still needs a caret, selection
   handles and the callout menu, and iOS won't hand them back unless the
   element opts in explicitly. `.selectable` is the escape hatch for any
   future copy-me text (share codes and the like). */
input, textarea, [contenteditable="true"], .selectable {
  -webkit-user-select: text;
  user-select: text;
  -webkit-touch-callout: default;
}
/* Status-bar scrim (native only).

   capacitor.config.json pins the status bar to light glyphs, because most of
   the app — splash, auth card, every sheet and modal — is near-black. The map
   screen is the exception: OSM tiles are pale, and `.hud-top` starts *below*
   the safe-area inset, so the clock and battery would otherwise sit on bare
   light tiles and vanish. This lays a dark gradient across exactly the inset
   so the glyphs always have something dark behind them, and the top edge
   reads as app chrome rather than a page that happens to start there.

   Gated on .is-native (set by identity.js) so the web build is untouched —
   the insets are 0 in a browser and a stray dark bar would just look wrong.
   Deliberately no backdrop-filter: this strip sits over a map that repaints
   as the player walks, and a live blur there costs battery for no real gain. */
body.is-native::before {
  content: "";
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  /* Fade out just past the inset so it blends instead of ending in a hard line. */
  height: calc(env(safe-area-inset-top, 0px) + 8px);
  background: linear-gradient(
    180deg,
    rgba(7, 11, 20, .95) 0%,
    rgba(7, 11, 20, .82) 55%,
    rgba(7, 11, 20, 0) 100%
  );
  /* Above the map, HUD and every sheet/modal, below the update banner. */
  z-index: 9998;
  pointer-events: none;
}
.bg-orb { position: fixed; border-radius: 50%; filter: blur(60px); opacity: .35; z-index: -1; }
.orb-1 { width: 260px; height: 260px; background: #60f7d4; top: 6%; left: 8%; }
.orb-2 { width: 300px; height: 300px; background: #b57cff; bottom: 8%; right: 10%; }
.app-shell {
  --shell-pad: 2rem;
  max-width: 1100px;
  margin: 0 auto;
  min-height: 100dvh;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: center;
  /* Keep in-flow content (the auth card) clear of the notch / Dynamic Island
     and the home indicator in the native app. max() composes the responsive
     --shell-pad with the safe-area insets, so the media-query overrides below
     (which only change --shell-pad) never drop below the inset. On the web the
     insets are 0, so this is just --shell-pad. */
  padding:
    max(var(--shell-pad), env(safe-area-inset-top))
    max(var(--shell-pad), env(safe-area-inset-right))
    max(var(--shell-pad), env(safe-area-inset-bottom))
    max(var(--shell-pad), env(safe-area-inset-left));
}
/* The auth card is the only in-flow shell child — centre it. Auto margins
   collapse to 0 when it's taller than the viewport, so the top never clips
   (the page scrolls instead of hiding the heading above the screen edge). */
.app-shell > .card { width: min(440px, 100%); margin: auto; }
.card { backdrop-filter: blur(16px); border: 1px solid var(--line); border-radius: 24px; background: var(--card); padding: 2rem; box-shadow: 0 20px 70px rgba(0,0,0,.35); }
.hidden { display: none; }
.eyebrow { text-transform: uppercase; letter-spacing: .12em; color: var(--muted); font-size: .72rem; margin-bottom: .3rem; }
h1, h2, h3 { margin: .2rem 0 .6rem; }
.auth-form { display: grid; gap: 1rem; max-width: 400px; margin-top: 1rem; }
/* `.auth-form` sets display:grid after the global `.hidden`, so `.hidden`
   alone can't hide it (equal specificity, later wins). This restores it, so
   app.js can toggle the form vs the Sign in with Apple gate on native. */
.auth-form.hidden { display: none; }
label { display: grid; gap: .5rem; color: var(--muted); }
input, select, button { border-radius: 12px; border: 1px solid var(--line); padding: .8rem .95rem; font: inherit; touch-action: manipulation; }
input, select { background: rgba(255,255,255,.06); color: var(--text); }
button { background: linear-gradient(90deg,#6df0c4,#4bb7ff); color: #031423; font-weight: 700; cursor: pointer; border: none; }
button.ghost { background: transparent; border: 1px solid var(--line); color: var(--text); }
/* Sign in with Apple. Native runs the sheet; web runs the same flow as a
   redirect, where it sits above the name form as the optional multiplayer
   half. app.js toggles .hidden — :not(.hidden) so the global
   `.hidden { display:none }` still wins despite equal specificity. */
.apple-signin-btn:not(.hidden) {
  width: 100%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .55rem;
  margin-top: 1rem;
  padding: .9rem 1rem;
  border: none;
  border-radius: 12px;
  background: #000;
  color: #fff;
  font: 600 1.02rem/1 "Outfit", -apple-system, system-ui, sans-serif;
  cursor: pointer;
}
.apple-signin-btn[disabled] { opacity: .55; cursor: progress; }
/* Why the button is there, or why the last attempt didn't work. Apple's own
   error page says nothing about this game, so without this a failed sign-in
   just silently returns you to the form. */
.auth-note {
  margin: .9rem 0 0;
  font-size: .86rem;
  line-height: 1.4;
  color: var(--muted, #9fb2c4);
}
.auth-note.is-error { color: #ffbfbf; }
.apple-logo {
  width: 15px;
  height: 18px;
  background: #fff;
  /* Apple logo, masked so it takes the button's white fill. */
  -webkit-mask: var(--apple-logo) center / contain no-repeat;
  mask: var(--apple-logo) center / contain no-repeat;
}
:root {
  --apple-logo: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 384 512'%3E%3Cpath d='M318.7 268.7c-.2-36.7 16.4-64.4 50-84.8-18.8-26.9-47.2-41.7-84.7-44.6-35.5-2.8-74.3 20.7-88.5 20.7-15 0-49.4-19.7-76.4-19.7C63.3 141.2 4 184.8 4 273.5q0 39.3 14.4 81.2c12.8 36.7 59 126.7 107.2 125.2 25.2-.6 43-17.9 75.8-17.9 31.8 0 48.3 17.9 76.4 17.9 48.6-.7 90.4-82.5 102.6-119.3-65.2-30.7-61.7-90-61.7-91.9zm-56.6-164.2c27.3-32.4 24.8-61.9 24-72.5-24.1 1.4-52 16.4-67.9 34.9-17.5 19.8-27.8 44.3-25.6 71.9 26.1 2 49.9-11.4 69.5-34.3z'/%3E%3C/svg%3E");
}
.loc-pill { color: var(--muted); font-size: .72rem; letter-spacing: .04em; padding: .18rem .55rem; border-radius: 999px; background: rgba(255,255,255,.05); border: 1px solid var(--line); }
.loc-pill.live { color: #8afdd8; border-color: rgba(124, 240, 198, .35); }
.loc-pill.error { color: #ffb1c1; border-color: rgba(255, 138, 168, .35); }
.cards { display: grid; grid-template-columns: repeat(auto-fit,minmax(160px,1fr)); gap: .8rem; }
.poke-card { border: 1px solid var(--line); border-radius: 14px; padding: .8rem; background: rgba(255,255,255,.04); display: flex; flex-direction: column; gap: .35rem; }
.poke-card button { width: 100%; margin-top: .35rem; }
.poke-card small { color: var(--muted); display: block; }
.poke-card-top { display: flex; align-items: center; justify-content: space-between; gap: .4rem; }
.poke-card-top strong { font-size: .95rem; }
.poke-card-mid { display: flex; align-items: center; flex-wrap: wrap; gap: .35rem; }
.power-chip {
  display: inline-flex;
  align-items: center;
  gap: .2rem;
  padding: .12rem .5rem;
  border-radius: 999px;
  font-size: .68rem;
  font-weight: 800;
  letter-spacing: .03em;
  background: rgba(255, 255, 255, .07);
  border: 1px solid rgba(255, 255, 255, .14);
  color: #e6ecff;
  white-space: nowrap;
}
.power-chip.rookie { background: rgba(159, 176, 217, .14); border-color: rgba(159, 176, 217, .35); color: #cdd7ee; }
.power-chip.steady { background: rgba(124, 240, 198, .14); border-color: rgba(124, 240, 198, .45); color: #b6ffe1; }
.power-chip.strong { background: rgba(255, 200, 120, .14); border-color: rgba(255, 200, 120, .45); color: #ffe0b3; }
.power-chip.elite { background: linear-gradient(90deg, rgba(255, 132, 200, .25), rgba(181, 124, 255, .25)); border-color: rgba(220, 160, 255, .6); color: #ffe1ff; box-shadow: 0 0 10px rgba(220, 160, 255, .3); }
.motion-tag {
  font-size: .62rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .12em;
  color: var(--muted);
  padding: .1rem .45rem;
  border-radius: 999px;
  background: rgba(255, 255, 255, .04);
  border: 1px solid rgba(255, 255, 255, .08);
}
.hit-dots { display: inline-flex; gap: 3px; align-items: center; }
.hit-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: radial-gradient(circle at 30% 30%, #ffd1d6, #ff5d6e 70%);
  border: 1px solid rgba(11, 18, 38, .65);
  box-shadow: 0 0 4px rgba(255, 93, 110, .5);
}
.hit-dot.spent {
  background: rgba(255, 255, 255, .12);
  border-color: rgba(255, 255, 255, .2);
  box-shadow: none;
}
.challenge-meta {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: .5rem;
  flex-wrap: wrap;
  margin: .15rem 0 .55rem;
}
.hits-meter {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  padding: .15rem .55rem;
  border-radius: 999px;
  background: rgba(255, 255, 255, .05);
  border: 1px solid rgba(255, 255, 255, .12);
}
.hits-meter .meta-label {
  font-size: .62rem;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--muted);
}
.ball-chip {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  padding: .3rem .65rem;
  border-radius: 999px;
  /* Dark glassy backing so the chip stays visible over light map tiles. */
  background: rgba(9, 14, 28, .86);
  border: 1px solid rgba(255, 255, 255, .28);
  /* Smaller blur radius: backdrop-filter re-blurs the live map behind it every
     frame the map pans — the dominant iOS heat source for the always-on HUD.
     A more opaque backing keeps the frosted look while halving the blur cost. */
  backdrop-filter: blur(5px);
  box-shadow: 0 4px 14px rgba(0, 0, 0, .35);
  color: var(--text);
  font-size: .78rem;
  letter-spacing: .02em;
  transition: background .2s ease, border-color .2s ease, transform .25s ease;
}
.ball-chip strong { font-weight: 800; font-size: .92rem; }
.ball-chip.empty { border-color: rgba(255, 132, 162, .7); color: #ffcad6; background: rgba(40, 12, 24, .85); }
.ball-chip.flash { transform: scale(1.08); border-color: #ff85a6; box-shadow: 0 0 14px rgba(255, 133, 166, .6); }
.ball-chip-label { color: var(--muted); margin-left: .15rem; }
.ball-icon {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  /* Energy orb (matches the in-game capture orb; no longer a pokeball). */
  background: radial-gradient(circle at 35% 30%, #eafcff 0 14%, #4fc9e0 46%, #0c6d8a 100%);
  border: 1.5px solid rgba(230, 252, 255, .55);
  position: relative;
  display: inline-block;
  box-shadow: 0 0 8px rgba(94, 214, 234, .5);
}
.ball-icon::after {
  content: "";
  position: absolute;
  left: 26%; top: 22%;
  width: 4px; height: 4px;
  border-radius: 50%;
  background: rgba(255, 255, 255, .9);
}
.poi-marker {
  position: relative;
  width: 54px;
  height: 64px;
  display: grid;
  grid-template-rows: 42px auto;
  justify-items: center;
  align-items: end;
  gap: 2px;
  color: #06101e;
}
.poi-marker .poi-ball {
  width: 46px;
  height: 42px;
  /* Supply-cache chest (replaces the old pokeball look). Baked as an inline
     SVG sprite so it decodes once and composites cheaply while the .near pulse
     scales it — no per-frame re-raster. */
  background: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 48 42'><rect x='7' y='9' width='34' height='12' rx='6' fill='%23c47a2c' stroke='%233a2510' stroke-width='2'/><rect x='6' y='20' width='36' height='16' rx='3' fill='%23a8611f' stroke='%233a2510' stroke-width='2'/><rect x='6' y='19' width='36' height='5' fill='%23f5c451' stroke='%233a2510' stroke-width='1'/><rect x='13' y='9' width='5' height='27' fill='%23f5c451' stroke='%233a2510' stroke-width='1'/><rect x='30' y='9' width='5' height='27' fill='%23f5c451' stroke='%233a2510' stroke-width='1'/><rect x='21' y='18' width='6' height='8' rx='1' fill='%23ffd873' stroke='%233a2510' stroke-width='1'/><circle cx='24' cy='22' r='1.5' fill='%233a2510'/></svg>") center/contain no-repeat;
  position: relative;
  /* Static grounding shadow. Only .near markers animate (rule below), so this
     base filter composites once. */
  filter: drop-shadow(0 3px 4px rgba(0, 0, 0, .5));
}
.poi-marker small {
  font-size: .58rem;
  font-weight: 700;
  color: #f5f7ff;
  padding: 1px 6px;
  border-radius: 999px;
  background: rgba(11, 18, 38, .85);
  border: 1px solid rgba(255, 255, 255, .15);
  letter-spacing: .04em;
  text-transform: uppercase;
  white-space: nowrap;
}
.poi-marker.near .poi-ball {
  filter: drop-shadow(0 0 10px rgba(245, 196, 81, .95)) drop-shadow(0 0 4px rgba(255, 240, 200, .8)) drop-shadow(0 3px 4px rgba(0, 0, 0, .5));
  animation: poi-pulse 1.6s ease-in-out infinite;
}
.poi-marker.cooldown {
  filter: grayscale(0.85) brightness(0.65) drop-shadow(0 4px 6px rgba(0, 0, 0, .45));
  opacity: 0.7;
}
@keyframes poi-pulse {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.08); }
}
/* ============================================================
   App-shell game layout
   The map is the stage: a fixed, full-viewport, always-live
   surface. Everything else floats over it as HUD chips, a
   bottom nav bar, or bottom-sheets. The page itself never
   scrolls — only sheet bodies do.

   z-index scale (gameplay modals/toasts stay >= 10, untouched):
     map-layer 0 · hud / ticker / recenter 4 · sheet-scrim 5
     sheet 6 · bottom-bar 7
   The bottom bar stays *above* the scrim + sheet so you can tap
   another tab to switch sheets directly (app-like), and it never
   gets dimmed.
   ============================================================ */
.game {
  position: fixed;
  inset: 0;
  overflow: hidden;
  z-index: 1;
}
.game.hidden { display: none; }

.map-layer { position: absolute; inset: 0; z-index: 0; }
.map {
  background: linear-gradient(160deg, rgba(70,90,150,.28), rgba(13,20,45,.9));
  z-index: 0;
  touch-action: none;
}
.map-layer .map {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  border-radius: 0;
  overflow: hidden;
}
.map.leaflet-active { background: #0b1530; }
.map .leaflet-container { background: #0b1530; font-family: inherit; }
.map .leaflet-control-attribution { background: rgba(7, 11, 20, 0.75); color: #c7d6ff; font-size: 10px; }
.map .leaflet-control-attribution a { color: #9bd2ff; }
/* Keep Leaflet's own controls clear of the HUD and bottom bar. */
.map .leaflet-top { top: calc(env(safe-area-inset-top, 0px) + 4.6rem); }
.map .leaflet-left { left: 8px; }
.map .leaflet-control-zoom { box-shadow: 0 8px 20px rgba(0, 0, 0, .45); }
/* Lift the OSM attribution above the full-width ticker so it isn't
   clipped behind it (the recenter/far-hint sit higher still). */
.map .leaflet-bottom.leaflet-right { right: 2px; bottom: calc(env(safe-area-inset-bottom, 0px) + 7.4rem); }

.map-hint {
  position: absolute;
  left: 50%;
  top: 46%;
  transform: translate(-50%,-50%);
  color: #c7d6ff;
  font-size: .9rem;
  text-align: center;
  width: 78%;
  max-width: 22rem;
  padding: .7rem 1rem;
  border-radius: 14px;
  background: rgba(7, 11, 20, .55);
  backdrop-filter: blur(4px);
  pointer-events: none;
  z-index: 4;
}
.map-hint.hidden { display: none; }
.map-bucket {
  position: absolute;
  right: .6rem;
  top: calc(env(safe-area-inset-top, 0px) + 3.4rem);
  padding: .25rem .55rem;
  border-radius: 999px;
  background: rgba(7, 11, 20, .8);
  border: 1px solid var(--line);
  color: #d6e1ff;
  font-size: .72rem;
  z-index: 4;
  pointer-events: none;
  margin: 0;
}
.map-bucket:empty { display: none; }
.map-recenter {
  position: absolute;
  right: .7rem;
  bottom: calc(env(safe-area-inset-bottom, 0px) + 8.4rem);
  z-index: 4;
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  padding: .6rem .9rem;
  border-radius: 999px;
  border: 1px solid rgba(124, 240, 198, .55);
  background: linear-gradient(135deg, rgba(124, 240, 198, .95), rgba(75, 183, 255, .95));
  color: #04243a;
  font-weight: 800;
  letter-spacing: .03em;
  font-size: .78rem;
  cursor: pointer;
  box-shadow: 0 10px 22px rgba(0, 0, 0, .35), 0 0 18px rgba(124, 240, 198, .35);
  font-family: inherit;
  transition: transform .15s ease, box-shadow .15s ease, opacity .2s ease;
}
.map-recenter:hover { transform: translateY(-1px); box-shadow: 0 14px 26px rgba(0, 0, 0, .4), 0 0 22px rgba(124, 240, 198, .45); }
.map-recenter:active { transform: translateY(0); }
.map-recenter.hidden { display: none; }
.map-recenter-icon { font-size: 1rem; line-height: 1; }
.map-far-hint {
  position: absolute;
  left: 50%;
  bottom: calc(env(safe-area-inset-bottom, 0px) + 8.6rem);
  transform: translateX(-50%);
  margin: 0;
  padding: .32rem .7rem;
  border-radius: 999px;
  background: rgba(7, 11, 20, .82);
  border: 1px solid var(--line);
  color: #cdd7ee;
  font-size: .7rem;
  letter-spacing: .02em;
  pointer-events: none;
  z-index: 4;
  max-width: 80vw;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.map-far-hint.hidden { display: none; }

/* ---- Top HUD ---- */
.hud-top {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 4;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: .5rem;
  padding: calc(env(safe-area-inset-top, 0px) + .55rem) .65rem 0;
  pointer-events: none; /* let the map pan in the gaps between chips */
}
.hud-top > * { pointer-events: auto; }
.hud-trainer {
  display: flex;
  align-items: center;
  gap: .5rem;
  padding: .4rem .5rem;
  border-radius: 14px;
  background: rgba(9, 14, 28, .82);
  border: 1px solid var(--line);
  backdrop-filter: blur(5px);
  max-width: 60vw;
}
.hud-team-dot {
  flex: none;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 10px var(--accent);
}
.hud-trainer-text { display: grid; min-width: 0; line-height: 1.15; }
.hud-eyebrow {
  font-size: .56rem;
  text-transform: uppercase;
  letter-spacing: .14em;
  color: var(--muted);
}
.hud-trainer-text h2 {
  margin: 0;
  font-size: .92rem;
  font-weight: 700;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.hud-switch {
  flex: none;
  width: 30px;
  height: 30px;
  padding: 0;
  border-radius: 9px;
  font-size: 1rem;
  line-height: 1;
  display: grid;
  place-items: center;
}
.hud-right {
  display: flex;
  align-items: center;
  gap: .4rem;
  flex-wrap: wrap;
  justify-content: flex-end;
  max-width: 38vw;
}
.loc-pill {
  position: absolute;
  top: calc(env(safe-area-inset-top, 0px) + 3.75rem);
  left: 50%;
  transform: translateX(-50%);
  z-index: 4;
  /* Tappable: the location pill is the debug-location multi-tap target. */
  pointer-events: auto;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  white-space: nowrap;
  /* Dark glassy backdrop so the status (esp. the pink error state) stays
     legible over light map tiles — the .live/.error rules only recolour
     the text + border on top of this. */
  background: rgba(9, 14, 28, .86);
  backdrop-filter: blur(5px);
  box-shadow: 0 4px 14px rgba(0, 0, 0, .35);
}

/* ---- Ambient world-feed ticker ---- */
.feed-ticker {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  bottom: calc(env(safe-area-inset-bottom, 0px) + 4.6rem);
  z-index: 4;
  display: flex;
  align-items: center;
  gap: .5rem;
  width: calc(100% - 1.3rem);
  max-width: 560px;
  padding: .42rem .8rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(9, 14, 28, .86);
  backdrop-filter: blur(5px);
  color: #dce4ff;
  font: inherit;
  text-align: left;
  cursor: pointer;
  overflow: hidden;
}
.feed-ticker.hidden { display: none; }
.feed-ticker-dot {
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 8px var(--accent);
  animation: ticker-pulse 1.8s ease-in-out infinite;
}
.feed-ticker-viewport {
  flex: 1;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent);
}
.feed-ticker-track {
  display: inline-block;
  white-space: nowrap;
  font-size: .8rem;
  will-change: transform;
  animation: ticker-scroll var(--ticker-dur, 30s) linear infinite;
}
.feed-ticker-track span { padding: 0 1.3rem; color: #cdd9ff; }
.feed-ticker-track strong { color: #fff; }
.feed-ticker:hover .feed-ticker-track,
.feed-ticker:focus-visible .feed-ticker-track { animation-play-state: paused; }
@keyframes ticker-scroll {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); } /* JS duplicates the run, so -50% loops seamlessly */
}
@keyframes ticker-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: .35; }
}

/* ---- Bottom navigation bar ---- */
.bottom-bar {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  bottom: 0;
  z-index: 7;
  display: flex;
  justify-content: space-around;
  gap: .25rem;
  width: 100%;
  max-width: 560px;
  padding: .35rem .5rem calc(env(safe-area-inset-bottom, 0px) + .35rem);
  background: rgba(7, 11, 22, .94);
  backdrop-filter: blur(8px);
  border-top: 1px solid var(--line);
  border-radius: 20px 20px 0 0;
}
.nav-btn {
  position: relative;
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: .45rem .3rem;
  background: transparent;
  border: 0;
  border-radius: 14px;
  color: var(--muted);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
  transition: color .15s ease, background .15s ease;
}
.nav-btn .nav-ico {
  font-size: 1.15rem;
  line-height: 1;
  filter: grayscale(.45);
  transition: filter .15s ease, transform .15s ease;
}
.nav-btn .nav-label { font-size: .66rem; letter-spacing: .03em; }
.nav-btn.is-active { color: var(--text); background: rgba(255, 255, 255, .07); }
.nav-btn.is-active .nav-ico { filter: none; transform: translateY(-1px); }
.nav-badge {
  position: absolute;
  top: 1px;
  right: calc(50% - 24px);
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: 999px;
  background: linear-gradient(135deg, #ff6b9d, #ff3d6e);
  color: #fff;
  font-size: .62rem;
  font-weight: 800;
  line-height: 16px;
  text-align: center;
  box-shadow: 0 0 10px rgba(255, 61, 110, .6);
}
.nav-badge.hidden { display: none; }

/* ---- Bottom-sheets ---- */
.sheet-scrim {
  position: absolute;
  inset: 0;
  z-index: 5;
  background: rgba(3, 6, 14, .5);
  backdrop-filter: blur(2px);
  opacity: 0;
  transition: opacity .25s ease;
}
.sheet-scrim.show { opacity: 1; }
.sheet-scrim.hidden { display: none; }
.sheet {
  position: absolute;
  left: 50%;
  bottom: 0;
  z-index: 6;
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 560px;
  max-height: 82%;
  background: linear-gradient(180deg, rgba(20, 27, 48, .98), rgba(10, 15, 30, .99));
  border: 1px solid var(--line);
  border-bottom: 0;
  border-radius: 22px 22px 0 0;
  box-shadow: 0 -20px 60px rgba(0, 0, 0, .5);
  transform: translate(-50%, 102%);
  transition: transform .32s cubic-bezier(.22, 1, .36, 1);
  will-change: transform;
}
.sheet.show { transform: translate(-50%, 0); }
.sheet.hidden { display: none; }
.sheet-head {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .6rem;
  padding: 1rem 1rem .55rem;
  flex: none;
}
.sheet-grip {
  position: absolute;
  top: .4rem;
  left: 50%;
  transform: translateX(-50%);
  width: 38px;
  height: 4px;
  border-radius: 999px;
  background: rgba(255, 255, 255, .22);
}
.sheet-head h3 { margin: 0; font-size: 1.05rem; }
.sheet-close {
  flex: none;
  width: 32px;
  height: 32px;
  padding: 0;
  border-radius: 10px;
  display: grid;
  place-items: center;
  font-size: .85rem;
}
.sheet-body {
  flex: 1;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  /* Clear the persistent bottom bar (z-index 7) which renders over the
     sheet's lower edge so tab-switching stays available. */
  padding: 0 1rem calc(env(safe-area-inset-bottom, 0px) + 4.6rem);
}
.sheet-sub { margin: 0 0 .7rem; color: var(--muted); font-size: .85rem; }
.sheet-body .feed { max-height: none; overflow: visible; }
.sheet-body .stats { margin-top: .2rem; }
.sheet-body .collection-toolbar { margin-top: .2rem; }
@media (prefers-reduced-motion: reduce) {
  .feed-ticker-track { animation: none; }
  .sheet { transition: none; }
  .sheet-scrim { transition: none; }
}
@media (max-width: 640px) {
  .map-recenter { padding: .5rem .7rem; font-size: .72rem; }
  .map-recenter-label { display: none; }
  .map-far-hint { font-size: .66rem; padding: .3rem .6rem; }
}
.player-marker, .trainer-marker { display: grid; place-items: center; border-radius: 50%; font-weight: 700; color: #06263c; }
.player-marker { width: 38px; height: 38px; font-size: .62rem; background: radial-gradient(circle, #d6ffff, #77f2d2); box-shadow: 0 0 18px rgba(119,242,210,.6); border: 2px solid rgba(255,255,255,.65); }
.trainer-marker { width: 30px; height: 30px; font-size: .58rem; color: #f5f7ff; background: radial-gradient(circle, #6a7ff8, #243a95); border: 1px solid rgba(181, 194, 255, 0.7); box-shadow: 0 0 12px rgba(122, 149, 255, .55); }

.spawn-marker {
  width: 78px;
  display: flex;
  flex-direction: column;
  align-items: center;
  font-weight: 700;
  color: #f4f9ff;
  text-align: center;
  line-height: 1.05;
  pointer-events: auto;
  /* No wrapper drop-shadow filter: the halo rotates and the face pulses inside
     this subtree, and a filter would re-rasterise the whole marker every frame
     (a major paint/heat cost with many spawns on screen). Depth comes from a
     static box-shadow on .spawn-face instead, which composites for free. */
  animation: spawn-bob 2.4s ease-in-out infinite;
}
.spawn-marker .spawn-face {
  width: 60px;
  height: 60px;
  border-radius: 50%;
  background:
    radial-gradient(circle at 32% 28%, rgba(255,255,255,.55), rgba(255,255,255,0) 55%),
    radial-gradient(circle, var(--type-light, #fff) 0%, var(--type-dark, #1d63b8) 88%);
  border: 2px solid rgba(255, 255, 255, .8);
  box-shadow:
    0 0 18px color-mix(in srgb, var(--type-accent, #7cf0c6) 65%, transparent),
    0 4px 8px rgba(0, 0, 0, .4),
    inset 0 -6px 12px rgba(0, 0, 0, .18);
  display: grid;
  place-items: center;
  overflow: visible;
  position: relative;
}
.spawn-marker .spawn-face::after {
  content: "";
  position: absolute;
  inset: -10px;
  border-radius: 50%;
  border: 1px dashed color-mix(in srgb, var(--type-accent, #7cf0c6) 70%, transparent);
  opacity: .4;
  animation: spawn-halo 3.6s linear infinite;
  pointer-events: none;
}
.spawn-marker .spawn-portrait {
  width: 56px;
  height: 56px;
  display: block;
  image-rendering: -webkit-optimize-contrast;
}
.spawn-marker .spawn-name {
  margin-top: 4px;
  font-size: .62rem;
  letter-spacing: .02em;
  padding: 1px 7px;
  border-radius: 9px;
  background: rgba(8, 18, 38, .78);
  border: 1px solid rgba(255, 255, 255, .25);
  color: #f4f9ff;
  text-shadow: 0 1px 2px rgba(0, 0, 0, .55);
  white-space: nowrap;
  max-width: 92px;
  overflow: hidden;
  text-overflow: ellipsis;
}
.spawn-marker .spawn-dist {
  display: block;
  margin-top: 2px;
  font-size: .55rem;
  font-weight: 600;
  color: color-mix(in srgb, var(--type-accent, #7cf0c6) 75%, white);
  text-shadow: 0 1px 2px rgba(0, 0, 0, .65);
}
.spawn-marker.near .spawn-face {
  border-color: rgba(255, 255, 255, .95);
  box-shadow:
    0 0 28px color-mix(in srgb, var(--type-accent, #7cf0c6) 90%, white 10%),
    0 4px 8px rgba(0, 0, 0, .4),
    inset 0 -6px 12px rgba(0, 0, 0, .18);
  animation: spawn-pulse 1.2s ease-in-out infinite;
}
.spawn-marker.near .spawn-name { background: rgba(15, 30, 60, .9); border-color: rgba(255, 255, 255, .5); }

@keyframes spawn-bob {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-3px); }
}
@keyframes spawn-pulse {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.05); }
}
@keyframes spawn-halo {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}
.catch-ring { border-radius: 50% !important; }
.feed { list-style: none; margin: .5rem 0 0; padding: 0; display: grid; gap: .45rem; max-height: 220px; overflow: auto; }
.feed li { padding: .55rem .7rem; border-radius: 10px; background: rgba(255,255,255,.05); color: #dce4ff; font-size: .92rem; }
.stats { display: flex; gap: 1rem; margin: 1rem 0; }
.stats div { background: rgba(255,255,255,.04); border: 1px solid var(--line); border-radius: 12px; padding: .7rem 1rem; }
.stats span { font-size: 1.7rem; font-weight: 800; display: block; }
.collection {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
  gap: .9rem;
}
.empty-state { margin: .2rem 0; color: var(--muted); }

/* Collection toolbar (sort + expand all) */
.collection-toolbar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: .6rem;
  margin: .25rem 0 1rem;
}
.collection-toolbar .sort-control {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  color: var(--muted);
  font-size: .8rem;
}
.collection-toolbar .sort-control span {
  text-transform: uppercase;
  letter-spacing: .1em;
  font-size: .68rem;
}
.collection-toolbar select {
  padding: .45rem .7rem;
  font-size: .85rem;
}
.collection-toolbar .toolbar-btn {
  padding: .45rem .8rem;
  font-size: .8rem;
}
.collection-toolbar .toolbar-btn[aria-pressed="true"] {
  border-color: var(--accent);
  color: var(--accent);
}

/* Grid tile — a compact, tappable card that opens the immersive viewer */
.gallery-card {
  position: relative;
  cursor: pointer;
  border-radius: 16px;
  border: 1px solid var(--line);
  background: linear-gradient(165deg, rgba(28, 38, 70, .85), rgba(8, 14, 30, .92));
  padding: .8rem .7rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .45rem;
  box-shadow: 0 12px 30px rgba(0, 0, 0, .32);
  transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
  outline: none;
}
.gallery-card:hover {
  transform: translateY(-3px);
  box-shadow: 0 18px 40px rgba(0, 0, 0, .42);
  border-color: rgba(255, 255, 255, .22);
}
.gallery-card:focus-visible {
  box-shadow: 0 0 0 2px var(--accent), 0 12px 30px rgba(0, 0, 0, .32);
}
.gallery-card.deployed { border-color: rgba(124, 240, 198, .4); }

/* Deck look when a species has duplicates collapsed behind it */
.gallery-card.stacked::before,
.gallery-card.stacked::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 16px;
  border: 1px solid var(--line);
  background: linear-gradient(165deg, rgba(24, 32, 60, .8), rgba(6, 11, 24, .9));
  z-index: -1;
}
.gallery-card.stacked::before { transform: translate(5px, 6px) rotate(1.4deg); }
.gallery-card.stacked::after  { transform: translate(10px, 12px) rotate(2.8deg); }

.gallery-card.member {
  border-style: dashed;
  border-color: rgba(255, 255, 255, .14);
}
.gallery-card.member.collapsed { display: none; }

.stack-badge {
  position: absolute;
  top: .55rem;
  left: .55rem;
  background: rgba(124, 240, 198, .22);
  border: 1px solid rgba(124, 240, 198, .55);
  color: #d8fff0;
  font-size: .72rem;
  padding: .12rem .5rem;
  border-radius: 999px;
  font-weight: 800;
}
.expand-btn {
  margin-top: .15rem;
  padding: .35rem .7rem;
  font-size: .72rem;
  border-radius: 999px;
  background: transparent;
  border: 1px solid var(--line);
  color: var(--text);
}
.expand-btn:hover { border-color: var(--accent); color: var(--accent); }
/* In a tile the stack badge owns the top-left, so push deployed to the right */
.gallery-card .deployed-pill { top: .55rem; left: auto; right: .55rem; }

.gallery-art {
  width: 100%;
  max-width: 150px;
  height: 110px;
  border-radius: 12px;
  background: linear-gradient(160deg, rgba(112, 124, 180, .18), rgba(8, 14, 30, .55));
  border: 1px solid rgba(255, 255, 255, .07);
}

.gallery-meta {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .3rem;
  text-align: center;
}

.gallery-meta strong { font-size: .98rem; letter-spacing: .01em; }

.type-pill {
  font-size: .62rem;
  text-transform: uppercase;
  letter-spacing: .12em;
  padding: .15rem .55rem;
  border-radius: 999px;
  font-weight: 800;
}

.count-pill {
  position: absolute;
  top: .55rem;
  right: .55rem;
  background: rgba(124, 240, 198, .22);
  border: 1px solid rgba(124, 240, 198, .55);
  color: #d8fff0;
  font-size: .7rem;
  padding: .1rem .5rem;
  border-radius: 999px;
  font-weight: 800;
  letter-spacing: .03em;
}

.flip-hint {
  font-size: .65rem;
  color: var(--muted);
  letter-spacing: .1em;
  text-transform: uppercase;
}

.rarity {
  text-transform: uppercase;
  letter-spacing: .14em;
  font-size: .65rem;
  margin: 0;
  color: var(--muted);
}
.rarity.rare { color: #8aa8ff; }
.rarity.epic { color: #d68bff; }

.stats-list { list-style: none; margin: .1rem 0 .15rem; padding: 0; display: grid; gap: .32rem; }
.stats-list li {
  display: grid;
  grid-template-columns: 32px 1fr 26px;
  gap: .4rem;
  align-items: center;
  font-size: .7rem;
  color: #dce4ff;
}
.stat-label { color: var(--muted); letter-spacing: .06em; }
.stat-val { text-align: right; font-weight: 700; }
.stat-bar {
  background: rgba(255, 255, 255, .08);
  border-radius: 999px;
  height: 6px;
  overflow: hidden;
}
.stat-fill {
  display: block;
  height: 100%;
  background: linear-gradient(90deg, #7cf0c6, #4bb7ff);
}

.flavor {
  font-size: .72rem;
  color: var(--muted);
  margin: auto 0 0;
  line-height: 1.4;
}

.catch-challenge {
  position: fixed;
  inset: 0;
  background: rgba(4, 9, 20, 0.8);
  backdrop-filter: blur(8px);
  display: grid;
  place-items: center;
  z-index: 10;
}

.challenge-card {
  width: min(680px, 92vw);
  border: 1px solid var(--line);
  border-radius: 20px;
  background: linear-gradient(180deg, rgba(35, 45, 83, 0.92), rgba(7, 11, 20, 0.94));
  padding: 1.1rem;
  box-shadow: 0 20px 80px rgba(0, 0, 0, 0.5);
}

.arena {
  margin: .9rem 0;
  height: 360px;
  position: relative;
  overflow: hidden;
  border-radius: 14px;
  border: 1px solid rgba(143, 171, 255, 0.3);
  background:
    radial-gradient(circle at 50% 90%, rgba(121, 240, 198, 0.12), transparent 55%),
    radial-gradient(circle at 18% 22%, rgba(181, 124, 255, 0.22), transparent 40%),
    radial-gradient(circle at 82% 35%, rgba(75, 183, 255, 0.22), transparent 42%),
    #080f22;
}

.catch-canvas {
  display: block;
  width: 100%;
  height: 100%;
  touch-action: none;
  cursor: grab;
}
.catch-canvas:active { cursor: grabbing; }

.spin-challenge .arena.spin-arena {
  height: 380px;
  background:
    radial-gradient(circle at 50% 50%, rgba(124, 240, 198, .12), transparent 55%),
    radial-gradient(circle at 18% 22%, rgba(181, 124, 255, .22), transparent 40%),
    radial-gradient(circle at 82% 35%, rgba(75, 183, 255, .22), transparent 42%),
    #080f22;
}
.spin-canvas {
  display: block;
  width: 100%;
  height: 100%;
  touch-action: none;
  cursor: grab;
}
.spin-canvas:active { cursor: grabbing; }
.spin-readout {
  position: absolute;
  top: .7rem;
  right: .9rem;
  display: flex;
  flex-direction: column;
  gap: .25rem;
  background: rgba(7, 11, 20, .72);
  border: 1px solid rgba(255, 255, 255, .12);
  border-radius: 12px;
  padding: .55rem .8rem;
  color: var(--text);
  font-variant-numeric: tabular-nums;
  pointer-events: none;
}
.spin-readout .readout-row { display: flex; align-items: baseline; justify-content: space-between; gap: .9rem; }
.spin-readout .readout-row.small { font-size: .72rem; color: var(--muted); }
.spin-readout .readout-label {
  text-transform: uppercase;
  font-size: .62rem;
  letter-spacing: .14em;
  color: var(--muted);
}
.spin-readout .readout-balls { font-size: 1.4rem; font-weight: 800; color: #8afdd8; }
.spin-readout .readout-bag { font-weight: 700; }

.status { color: #d6e1ff; min-height: 1.45rem; }
.status .success { color: #8afdd8; font-weight: 700; text-transform: uppercase; }
.status .fail { color: #ff8ca6; font-weight: 700; text-transform: uppercase; }
.modal {
  --modal-pad: 1.5rem;
  position: fixed;
  inset: 0;
  background: rgba(4, 9, 20, 0.78);
  backdrop-filter: blur(10px);
  /* Flex + auto-margin centring (not grid place-items) so a tall card scrolls
     instead of clipping its top, and respect the safe-area insets in the
     native app. */
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  z-index: 20;
  padding:
    max(var(--modal-pad), env(safe-area-inset-top))
    max(var(--modal-pad), env(safe-area-inset-right))
    max(var(--modal-pad), env(safe-area-inset-bottom))
    max(var(--modal-pad), env(safe-area-inset-left));
}
.modal.hidden { display: none; }
.modal-card {
  margin: auto;
  width: min(440px, 100%);
  border: 1px solid var(--line);
  border-radius: 20px;
  background: linear-gradient(180deg, rgba(35, 45, 83, .94), rgba(7, 11, 20, .96));
  padding: 1.6rem;
  box-shadow: 0 24px 80px rgba(0, 0, 0, .55);
  display: flex;
  flex-direction: column;
  gap: .55rem;
  text-align: center;
}
.modal-card h2 { margin: .25rem 0 .15rem; }
.modal-card p { color: var(--muted); margin: 0 0 .6rem; line-height: 1.45; }
.modal-card button { margin-top: .35rem; }
.modal-card small { display: block; min-height: 1rem; color: var(--muted); }
.modal-card small.error { color: #ffb1c1; }

/* ---------- Battle Site marker ---------- */
.battle-site-marker {
  position: relative;
  width: 86px;
  height: 84px;
  display: grid;
  grid-template-rows: auto 48px auto;
  justify-items: center;
  align-items: end;
  gap: 2px;
  color: #f5f7ff;
  filter: drop-shadow(0 4px 8px rgba(0, 0, 0, .55));
}
.battle-site-marker .bs-banner {
  font-size: .58rem;
  font-weight: 800;
  letter-spacing: .08em;
  text-transform: uppercase;
  background: rgba(11, 18, 38, .85);
  border: 1px solid rgba(255, 255, 255, .25);
  border-radius: 999px;
  padding: 2px 8px;
  white-space: nowrap;
  color: #f5f7ff;
}
.battle-site-marker .bs-medal {
  position: relative;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background:
    radial-gradient(circle at 30% 28%, var(--ring-accent, rgba(255, 255, 255, .55)), transparent 60%),
    linear-gradient(140deg, var(--ring, #9aaabd) 0%, var(--ring, #9aaabd) 55%, #1a2235 110%);
  border: 2px solid #0b1226;
  box-shadow:
    0 0 16px color-mix(in srgb, var(--ring, #9aaabd) 75%, transparent),
    inset 0 -6px 12px rgba(0, 0, 0, .25);
  display: grid;
  place-items: center;
}
.battle-site-marker .bs-medal-glyph {
  font-size: 1.4rem;
  line-height: 1;
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, .85));
}
.battle-site-marker .bs-medal-crossed {
  position: absolute;
  bottom: -4px;
  right: -4px;
  width: 18px;
  height: 18px;
  font-size: .7rem;
  border-radius: 50%;
  background: rgba(11, 18, 38, .92);
  border: 1px solid rgba(255, 255, 255, .35);
  color: #ffd166;
  display: grid;
  place-items: center;
  text-shadow: 0 0 4px rgba(255, 209, 102, .6);
}
.battle-site-marker small {
  font-size: .56rem;
  font-weight: 700;
  padding: 1px 6px;
  border-radius: 999px;
  background: rgba(11, 18, 38, .82);
  border: 1px solid rgba(255, 255, 255, .18);
  color: #f5f7ff;
  letter-spacing: .04em;
  text-transform: uppercase;
  max-width: 86px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.battle-site-marker.vacant .bs-medal { opacity: .92; }
.battle-site-marker.rival .bs-medal {
  border-color: color-mix(in srgb, var(--ring) 65%, #ff7a8a 35%);
  box-shadow:
    0 0 20px color-mix(in srgb, var(--ring) 80%, transparent),
    0 0 8px rgba(255, 122, 138, .6),
    inset 0 -6px 12px rgba(0, 0, 0, .25);
}
.battle-site-marker.yours .bs-medal {
  border-color: #7cf0c6;
  box-shadow:
    0 0 22px rgba(124, 240, 198, .8),
    inset 0 -6px 12px rgba(0, 0, 0, .25);
}
.battle-site-marker.near .bs-medal { animation: site-pulse 1.6s ease-in-out infinite; }
@keyframes site-pulse {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.1); }
}

/* ---------- Battle Site modal ---------- */
.battle-site-modal {
  position: fixed;
  inset: 0;
  background: rgba(4, 9, 20, 0.82);
  backdrop-filter: blur(8px);
  display: grid;
  place-items: center;
  z-index: 15;
  padding: 1rem;
}
.site-card {
  width: min(680px, 96vw);
  max-height: 92vh;
  overflow-y: auto;
  border: 1px solid var(--line);
  border-radius: 20px;
  background: linear-gradient(180deg, rgba(35, 45, 83, 0.94), rgba(7, 11, 20, 0.96));
  padding: 1.1rem 1.2rem;
  box-shadow: 0 20px 80px rgba(0, 0, 0, .55);
  display: flex;
  flex-direction: column;
  gap: .9rem;
}
.site-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
}
.site-head h3 { margin: 0; font-size: 1.25rem; }
.site-state {
  display: flex;
  flex-direction: column;
  gap: .8rem;
}
.site-status {
  font-size: .9rem;
  color: #d6e1ff;
  margin: 0;
}
.champion-pane {
  display: grid;
  grid-template-columns: 180px 1fr;
  gap: 1rem;
  align-items: start;
  padding: .8rem;
  border-radius: 14px;
  border: 1px solid rgba(255, 255, 255, .1);
  background: linear-gradient(160deg, color-mix(in srgb, var(--type-light, #cfd8ff) 25%, transparent), rgba(7, 11, 22, 0.55));
}
.champion-portrait {
  position: relative;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .35rem;
}
.champion-portrait .champ-art {
  width: 100%;
  max-width: 180px;
  height: 160px;
  border-radius: 14px;
  border: 1px solid rgba(255, 255, 255, .15);
  background: rgba(11, 18, 38, .55);
}
.defense-pips {
  display: inline-flex;
  gap: 4px;
}
.defense-pips .pip {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: rgba(255, 255, 255, .15);
  border: 1px solid rgba(255, 255, 255, .25);
}
.defense-pips .pip.lit {
  background: radial-gradient(circle at 30% 30%, #fff48a, #c98a14);
  border-color: #c98a14;
  box-shadow: 0 0 6px #ffd966;
}
.champion-meta { display: flex; flex-direction: column; gap: .4rem; }
.champion-meta h4 { margin: 0; font-size: 1rem; display: flex; align-items: center; gap: .35rem; flex-wrap: wrap; }
.champion-owner { margin: 0; color: var(--muted); font-size: .82rem; }
.stat-boost { color: #8afdd8; font-weight: 800; font-size: .68rem; }
.champion-meta-line { display: flex; flex-wrap: wrap; gap: .35rem; margin: .15rem 0 0; }
.champion-meta-line .badge {
  font-size: .62rem;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  padding: .18rem .55rem;
  border-radius: 999px;
  background: rgba(255, 255, 255, .06);
  border: 1px solid rgba(255, 255, 255, .14);
  color: #dce4ff;
}
.champion-meta-line .badge.fatigue {
  background: rgba(255, 132, 162, .12);
  border-color: rgba(255, 132, 162, .4);
  color: #ffcad6;
}

.site-actions {
  display: flex;
  flex-direction: column;
  gap: .6rem;
}
.site-actions button.primary {
  background: linear-gradient(90deg, #6df0c4, #4bb7ff);
  color: #031423;
  font-weight: 800;
}
.picker-prompt { margin: 0; color: var(--muted); font-size: .82rem; }
.picker-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  gap: .55rem;
}
.picker-card {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: .15rem;
  padding: .55rem .65rem;
  border-radius: 14px;
  border: 1px solid rgba(255, 255, 255, .18);
  background: linear-gradient(160deg, color-mix(in srgb, var(--type-light) 35%, rgba(255, 255, 255, .04)), rgba(11, 18, 38, .8));
  color: #f5f7ff;
  cursor: pointer;
  text-align: left;
  font: inherit;
  transition: transform .12s ease, border-color .12s ease, box-shadow .12s ease;
}
.picker-card strong { font-size: .9rem; }
.picker-card small { color: var(--muted); font-size: .68rem; letter-spacing: .04em; }
.picker-card:hover { transform: translateY(-1px); border-color: rgba(255, 255, 255, .5); box-shadow: 0 6px 22px rgba(0, 0, 0, .35); }
.picker-power {
  position: absolute;
  top: .35rem;
  right: .4rem;
  font-size: .62rem;
  font-weight: 800;
  color: #0b1226;
  background: color-mix(in srgb, var(--type-accent) 80%, white);
  padding: .12rem .4rem;
  border-radius: 999px;
}

/* ---------- Training challenge ---------- */
.training-challenge .training-arena { height: 360px; }
.training-challenge .train-help {
  margin: .1rem 0 .6rem;
  color: var(--muted);
  font-size: .82rem;
}
.training-challenge .hits-meter .train-score {
  font-size: .8rem;
  font-weight: 800;
  color: #f5f7ff;
  letter-spacing: .03em;
}
.training-challenge .hits-meter .train-hp {
  display: inline-flex;
  align-items: center;
  gap: .14rem;
  line-height: 1;
}
.train-heart {
  font-size: 1rem;
  line-height: 1;
  transition: transform .18s ease, opacity .18s ease, color .18s ease;
}
.train-heart.full {
  color: #ff5d7a;
  text-shadow: 0 0 6px rgba(255, 93, 122, .65);
  opacity: 1;
}
/* A lost heart drains to a flat dim grey with no glow — readable at a glance. */
.train-heart.empty {
  color: #3c465f;
  text-shadow: none;
  opacity: .55;
  transform: scale(.78);
}
.training-challenge .hits-meter.hp-low,
.train-hp.hp-low { animation: heartLowPulse 1s ease-in-out infinite; }
@keyframes heartLowPulse {
  0%, 100% { filter: none; }
  50% { filter: drop-shadow(0 0 7px rgba(255, 93, 122, .9)); }
}
.train-hp.heal .train-heart.full {
  animation: heartHeal .55s ease;
}
@keyframes heartHeal {
  0% { transform: scale(1); }
  35% { transform: scale(1.5); color: #7cf0c6; text-shadow: 0 0 12px rgba(124, 240, 198, .9); }
  100% { transform: scale(1); }
}
.training-canvas {
  display: block;
  width: 100%;
  height: 100%;
  touch-action: none;
  cursor: grab;
}
.training-canvas:active { cursor: grabbing; }
.training-footer {
  display: flex;
  justify-content: flex-end;
  gap: .6rem;
}
.training-footer .primary {
  background: linear-gradient(90deg, #6df0c4, #4bb7ff);
  color: #031423;
  font-weight: 800;
}
.training-footer .hidden { display: none; }

/* ---------- Battle stage ---------- */
.battle-challenge .battle-arena { height: 360px; }
.battle-card-wrap { width: min(760px, 96vw); }
/* Title removed for the battle modal — the SF2 nameplates carry it. */
.battle-title { display: none; }
/* Compact Street-Fighter-style HUD: two nameplates side-by-side with a
   central VS, staying horizontal at every width so the top stays short. */
.battle-roster {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  gap: .45rem;
  align-items: center;
  margin: .1rem 0 .5rem;
}
.roster-side {
  min-width: 0;
  padding: .35rem .5rem;
  border-radius: 10px;
  background: rgba(255, 255, 255, .04);
  border: 1px solid rgba(255, 255, 255, .12);
}
.roster-top {
  display: flex;
  align-items: baseline;
  gap: .4rem;
  margin-bottom: .28rem;
}
.roster-side.defender .roster-top { flex-direction: row-reverse; }
.roster-name {
  margin: 0;
  flex: 1;
  min-width: 0;
  font-weight: 800;
  font-size: .82rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.roster-side.defender .roster-name { text-align: right; }
.roster-name .type-pill {
  font-size: .58rem;
  padding: .05rem .3rem;
  border-radius: 999px;
  font-weight: 800;
}
.roster-label {
  margin: .22rem 0 0;
  font-size: .58rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.roster-side.defender .roster-label { text-align: right; }
.hp-bar {
  height: 11px;
  border-radius: 6px;
  background: rgba(255, 255, 255, .08);
  border: 1px solid rgba(255, 255, 255, .16);
  overflow: hidden;
}
/* Champion bar mirrors so both drain toward the centre VS, SF2-style. */
.roster-side.defender .hp-bar { transform: scaleX(-1); }
.hp-fill {
  display: block;
  height: 100%;
  background: linear-gradient(90deg, #7cf0c6, #4bb7ff);
  transition: width .35s ease;
}
.hp-fill.low { background: linear-gradient(90deg, #ffe27a, #ff5d6e); }
.hp-text {
  display: block;
  flex: none;
  margin: 0;
  color: var(--text);
  font-size: .64rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.vs-pill {
  background: linear-gradient(90deg, #ffe27a, #ff7a3a);
  color: #1b0a02;
  font-weight: 900;
  letter-spacing: .08em;
  padding: .18rem .45rem;
  border-radius: 999px;
  font-size: .66rem;
}
.battle-canvas {
  display: block;
  width: 100%;
  height: 100%;
  touch-action: none;
}
.battle-status { min-height: 1.6rem; }
.training-footer .battle-continue.hidden,
.training-footer button.hidden { display: none; }

/* ---------- Debug location chip + dialog ---------- */
.debug-loc-chip {
  position: fixed;
  bottom: 1rem;
  left: 1rem;
  z-index: 30;
  padding: .45rem .8rem;
  border-radius: 999px;
  border: 1px solid rgba(255, 220, 130, .6);
  background: linear-gradient(90deg, rgba(255, 200, 90, .25), rgba(255, 90, 130, .25));
  color: #ffe27a;
  font-weight: 800;
  letter-spacing: .04em;
  font-size: .72rem;
  cursor: pointer;
  box-shadow: 0 8px 22px rgba(0, 0, 0, .35);
  font-family: inherit;
}
.debug-loc-chip:hover { transform: translateY(-1px); }
.debug-presets {
  display: flex;
  flex-wrap: wrap;
  gap: .35rem;
  justify-content: center;
  margin-top: .35rem;
}
.debug-presets button { padding: .35rem .65rem; font-size: .72rem; }
.debug-actions {
  display: flex;
  justify-content: flex-end;
  gap: .45rem;
  margin-top: .55rem;
}
.debug-actions .dbg-apply {
  background: linear-gradient(90deg, #6df0c4, #4bb7ff);
  color: #031423;
  font-weight: 800;
}
.debug-actions .lo-confirm {
  background: linear-gradient(90deg, #ff8d9e, #ff5d6e);
  color: #2a0710;
  font-weight: 800;
  border-color: transparent;
}

@media (max-width: 1024px) {
  .app-shell { --shell-pad: 1.25rem; }
  .card { padding: 1.5rem; }
}

@media (max-width: 850px) {
  .app-shell { --shell-pad: 1rem; }
  .card { padding: 1.1rem; border-radius: 20px; }
}

@media (max-width: 850px) {
  .champion-pane { grid-template-columns: 1fr; }
  .champion-portrait .champ-art { max-width: 220px; }
  /* Battle roster intentionally stays side-by-side (SF2 layout) at all
     widths so the modal header stays short on phones. */
}

@media (max-width: 640px) {
  .bg-orb { display: none; }
  .app-shell { --shell-pad: .55rem; }
  .card {
    padding: .85rem;
    border-radius: 18px;
    box-shadow: 0 10px 40px rgba(0, 0, 0, .35);
  }
  .auth-card { padding: 1.25rem; }
  .cards {
    grid-template-columns: repeat(auto-fit, minmax(135px, 1fr));
    gap: .6rem;
  }
  .stats { gap: .55rem; }
  .stats div { padding: .55rem .75rem; }
  .stats span { font-size: 1.4rem; }
  .collection {
    grid-template-columns: repeat(auto-fill, minmax(135px, 1fr));
    gap: .65rem;
  }
  .modal { --modal-pad: 1rem; }
  .modal-card { padding: 1.25rem; }
}

@media (max-width: 380px) {
  .app-shell { --shell-pad: .4rem; }
  .card { padding: .7rem; border-radius: 16px; }
  .collection,
  .cards { grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); }
  .battle-site-marker { width: 78px; }
  .training-challenge .training-arena,
  .battle-challenge .battle-arena { height: 300px; }
}

/* === Instance / trading additions === */
.trade-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  padding: .3rem .65rem;
  border-radius: 999px;
  font-size: .78rem;
  letter-spacing: .02em;
  /* Dark glassy backing + brighter accent so it reads on light map tiles. */
  background: rgba(9, 14, 28, .86);
  border: 1px solid rgba(124, 240, 198, .75);
  backdrop-filter: blur(5px);
  box-shadow: 0 4px 14px rgba(0, 0, 0, .35);
  color: #c2ffe9;
  cursor: pointer;
  font-family: inherit;
}
.trade-btn:hover {
  background: rgba(18, 40, 44, .88);
  border-color: rgba(124, 240, 198, .95);
}
.trade-btn-label { font-weight: 700; }
.trade-badge {
  position: absolute;
  top: -6px;
  right: -6px;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: 999px;
  background: linear-gradient(135deg, #ff8aa6, #b57cff);
  color: #0b1226;
  font-size: .62rem;
  font-weight: 800;
  display: grid;
  place-items: center;
  border: 1px solid rgba(255, 255, 255, .55);
  box-shadow: 0 0 8px rgba(255, 138, 166, .65);
}
.trade-badge.hidden { display: none; }

.gallery-card.deployed { outline: 1px solid rgba(124, 240, 198, .45); box-shadow: 0 0 0 1px rgba(124, 240, 198, .25), 0 6px 16px rgba(0, 0, 0, .35); }
.deployed-pill {
  position: absolute;
  top: .55rem;
  left: .55rem;
  background: rgba(124, 240, 198, .18);
  border: 1px solid rgba(124, 240, 198, .55);
  color: #d8fff0;
  font-size: .6rem;
  padding: .1rem .45rem;
  border-radius: 999px;
  font-weight: 800;
  letter-spacing: .05em;
  text-transform: uppercase;
}
.trained-badge {
  align-self: center;
  font-size: .58rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  padding: .12rem .45rem;
  border-radius: 999px;
  background: rgba(255, 200, 120, .18);
  border: 1px solid rgba(255, 200, 120, .55);
  color: #ffe0b3;
  margin-top: .25rem;
}
.stat-boost { color: #ffe0b3; font-weight: 700; font-size: .68rem; margin-left: .15rem; }
.instance-status {
  margin: .2rem 0 .1rem;
  font-size: .68rem;
  color: var(--muted);
  letter-spacing: .02em;
}
.instance-actions {
  display: flex;
  justify-content: flex-end;
  gap: .35rem;
  margin-top: .4rem;
}
.instance-actions button {
  padding: .35rem .6rem;
  font-size: .68rem;
  letter-spacing: .04em;
}
.instance-actions button[disabled] { opacity: .55; cursor: not-allowed; }

/* Incoming-trade banner */
.trade-toast {
  position: fixed;
  top: 14px;
  left: 50%;
  z-index: 1000;
  width: min(440px, calc(100vw - 24px));
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .75rem;
  padding: .7rem .8rem .7rem .9rem;
  border-radius: 16px;
  background: rgba(11, 18, 38, .97);
  border: 1px solid rgba(255, 255, 255, .14);
  border-left: 4px solid #ff8aa6;
  box-shadow: 0 14px 40px rgba(0, 0, 0, .5), 0 0 18px rgba(255, 138, 166, .35);
  transform: translate(-50%, -180%);
  opacity: 0;
  transition: transform .28s cubic-bezier(.2, .8, .2, 1), opacity .2s ease;
}
.trade-toast.show { transform: translate(-50%, 0); opacity: 1; }
.trade-toast-body { display: flex; align-items: center; gap: .6rem; min-width: 0; }
.trade-toast-icon { font-size: 1.3rem; line-height: 1; }
.trade-toast-text { display: flex; flex-direction: column; gap: .15rem; min-width: 0; }
.trade-toast-text strong { font-size: .85rem; }
.trade-toast-text span {
  font-size: .72rem;
  color: var(--muted);
  overflow: hidden;
  text-overflow: ellipsis;
}
.trade-toast-actions { display: flex; align-items: center; gap: .35rem; flex-shrink: 0; }
.trade-toast-actions .primary { padding: .35rem .7rem; font-size: .72rem; }
.trade-toast-actions .trade-toast-dismiss {
  padding: .3rem .5rem;
  font-size: .72rem;
  line-height: 1;
}
@media (prefers-reduced-motion: reduce) {
  .trade-toast { transition: opacity .2s ease; transform: translate(-50%, 0); }
}

/* ===========================================================================
   Trade Station — a playful, staged card-swap (not a list of things to pick)
   =========================================================================== */
.trade-modal .trade-card {
  width: min(620px, 95vw);
  background: linear-gradient(180deg, #28316b 0%, #1a1f47 42%, #0a0e22 100%);
  border: 2px solid rgba(255, 255, 255, .12);
  animation: trade-pop .42s cubic-bezier(.18, 1.4, .4, 1) both;
}
@keyframes trade-pop {
  0% { transform: scale(.82) translateY(18px); opacity: 0; }
  100% { transform: scale(1) translateY(0); opacity: 1; }
}
.trade-head .eyebrow {
  color: #ffe066;
  font-weight: 800;
  letter-spacing: .04em;
  text-shadow: 0 1px 0 rgba(0, 0, 0, .35);
}
.trade-head h3 { font-size: 1.45rem; letter-spacing: -.01em; }
.trade-head .trade-close {
  border-radius: 999px;
  width: 34px;
  height: 34px;
  padding: 0;
  font-size: .95rem;
  font-weight: 800;
}
.trade-body { display: flex; flex-direction: column; gap: 1rem; }

/* ---- Lobby groups & trainer tiles ---- */
.trade-group { display: flex; flex-direction: column; gap: .55rem; }
.trade-group-title {
  margin: 0;
  font-size: 1rem;
  font-weight: 800;
  display: flex;
  align-items: center;
  gap: .4rem;
}
.trade-group-title .title-note {
  font-size: .66rem;
  font-weight: 700;
  letter-spacing: .06em;
  color: #0b1226;
  background: #8be8d0;
  padding: .1rem .45rem;
  border-radius: 999px;
}
.trade-group-title.hot { color: #ffd86b; animation: hot-throb 1.1s ease-in-out infinite; }
@keyframes hot-throb { 50% { transform: scale(1.035); } }

.trade-tiles { display: grid; gap: .5rem; }
.trade-tile {
  display: flex;
  align-items: center;
  gap: .7rem;
  padding: .6rem .7rem;
  border-radius: 16px;
  border: 2px solid rgba(255, 255, 255, .1);
  background: rgba(255, 255, 255, .045);
  animation: tile-in .32s cubic-bezier(.2, .9, .3, 1.2) both;
}
.trade-tile:nth-child(2) { animation-delay: .04s; }
.trade-tile:nth-child(3) { animation-delay: .08s; }
.trade-tile:nth-child(4) { animation-delay: .12s; }
@keyframes tile-in { from { opacity: 0; transform: translateX(-14px); } }
.trade-tile.tile-hot {
  border-color: rgba(255, 216, 107, .6);
  background: linear-gradient(110deg, rgba(255, 216, 107, .16), rgba(255, 138, 166, .1));
  box-shadow: 0 0 0 1px rgba(255, 216, 107, .25), 0 8px 24px rgba(0, 0, 0, .35);
}
.trade-tile.tile-faded { opacity: .6; }
.tile-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: .1rem; }
.tile-text strong { font-size: .95rem; }
.tile-text span { font-size: .76rem; color: var(--muted); }
.tile-text span b { color: #d8e2ff; }
.tile-dist { display: inline-flex; align-items: center; gap: .35rem; }
.tile-dist .ping {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #6df0c4;
  box-shadow: 0 0 0 0 rgba(109, 240, 196, .6);
  animation: ping 1.5s ease-out infinite;
}
@keyframes ping {
  0% { box-shadow: 0 0 0 0 rgba(109, 240, 196, .6); }
  70% { box-shadow: 0 0 0 9px rgba(109, 240, 196, 0); }
  100% { box-shadow: 0 0 0 0 rgba(109, 240, 196, 0); }
}
.tile-chip {
  align-self: flex-start;
  font-size: .68rem;
  font-weight: 800;
  padding: .12rem .5rem;
  border-radius: 999px;
}
.tile-chip.go { color: #06241a; background: #6df0c4; }
.tile-chip.wait { color: #cdd6ff; background: rgba(255, 255, 255, .1); }

/* Trainer "avatar" orbs */
.trainer-orb {
  flex-shrink: 0;
  display: grid;
  place-items: center;
  font-weight: 900;
  color: #0a0f22;
  border-radius: 50%;
  background:
    radial-gradient(circle at 32% 28%, #fff 0%, transparent 36%),
    linear-gradient(150deg, hsl(var(--orb-h) 90% 72%), hsl(var(--orb-h) 75% 48%));
  box-shadow: 0 4px 10px rgba(0, 0, 0, .4), inset 0 -3px 6px rgba(0, 0, 0, .25);
  border: 2px solid rgba(255, 255, 255, .55);
}
.trainer-orb.orb-md { width: 44px; height: 44px; font-size: 1.15rem; }
.trainer-orb.orb-sm { width: 32px; height: 32px; font-size: .85rem; }

/* Big tappable call-to-action buttons */
.trade-cta {
  flex-shrink: 0;
  font-family: inherit;
  font-weight: 800;
  font-size: .82rem;
  letter-spacing: .01em;
  padding: .55rem 1rem;
  border-radius: 999px;
  border: none;
  cursor: pointer;
  color: #06231a;
  background: linear-gradient(180deg, #7df0c4, #34c79b);
  box-shadow: 0 4px 0 #1f8a68, 0 6px 14px rgba(0, 0, 0, .35);
  transition: transform .08s ease, box-shadow .08s ease, filter .12s ease;
}
.trade-cta:hover { filter: brightness(1.06); }
.trade-cta:active { transform: translateY(3px); box-shadow: 0 1px 0 #1f8a68, 0 3px 8px rgba(0, 0, 0, .3); }
.trade-cta.big { width: 100%; padding: .8rem 1rem; font-size: .98rem; }
.trade-cta.ghost {
  color: #cdd6ff;
  background: rgba(255, 255, 255, .06);
  box-shadow: 0 3px 0 rgba(0, 0, 0, .35);
  border: 1px solid rgba(255, 255, 255, .14);
}
.trade-cta.danger {
  color: #fff;
  background: linear-gradient(180deg, #ff8aa6, #e0567a);
  box-shadow: 0 4px 0 #a83558, 0 6px 14px rgba(0, 0, 0, .35);
}
.trade-back {
  align-self: flex-start;
  font-family: inherit;
  font-weight: 700;
  font-size: .8rem;
  color: #cdd6ff;
  background: none;
  border: none;
  padding: .2rem 0;
  cursor: pointer;
}
.trade-back:hover { color: #fff; }

/* ---- "Nobody nearby" radar ---- */
.trade-radar { text-align: center; padding: 1rem .5rem .4rem; }
.radar-scope {
  position: relative;
  width: 130px;
  height: 130px;
  margin: 0 auto .7rem;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(109, 240, 196, .12), rgba(11, 18, 38, .6));
  border: 2px solid rgba(109, 240, 196, .35);
  overflow: hidden;
}
.radar-scope::before {
  content: "";
  position: absolute;
  inset: 28%;
  border-radius: 50%;
  border: 1px solid rgba(109, 240, 196, .22);
}
.radar-sweep {
  position: absolute;
  inset: 0;
  background: conic-gradient(from 0deg, rgba(109, 240, 196, .55), transparent 28%);
  animation: radar-spin 2.4s linear infinite;
}
@keyframes radar-spin { to { transform: rotate(360deg); } }
.radar-blip {
  position: absolute;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: #ffe066;
  opacity: 0;
}
.radar-blip.b1 { top: 30%; left: 62%; animation: blip 2.4s ease-in-out .5s infinite; }
.radar-blip.b2 { top: 64%; left: 38%; animation: blip 2.4s ease-in-out 1.4s infinite; }
@keyframes blip { 0%, 60% { opacity: 0; } 65% { opacity: 1; transform: scale(1.4); } 100% { opacity: 0; } }
.radar-title { margin: 0 0 .25rem; font-weight: 800; font-size: 1rem; }
.radar-sub { margin: 0 auto; max-width: 380px; font-size: .82rem; color: var(--muted); line-height: 1.45; }
.radar-sub b { color: #8be8d0; }

/* ---- Speech bubble status ---- */
.trade-talk {
  display: flex;
  align-items: flex-start;
  gap: .55rem;
  animation: tile-in .3s ease both;
}
.trade-bubble {
  position: relative;
  flex: 1;
  padding: .65rem .85rem;
  border-radius: 4px 16px 16px 16px;
  font-size: .88rem;
  line-height: 1.4;
  font-weight: 600;
  color: #f3f6ff;
  background: rgba(255, 255, 255, .07);
  border: 1px solid rgba(255, 255, 255, .12);
}
.trade-bubble b { color: #ffe066; }
.trade-bubble::before {
  content: "";
  position: absolute;
  left: -7px;
  top: 10px;
  border: 7px solid transparent;
  border-right-color: rgba(255, 255, 255, .07);
  border-left: 0;
}
.mood-happy .trade-bubble { background: rgba(124, 240, 198, .12); border-color: rgba(124, 240, 198, .35); }
.mood-happy .trade-bubble::before { border-right-color: rgba(124, 240, 198, .12); }
.mood-sad .trade-bubble { background: rgba(255, 138, 166, .12); border-color: rgba(255, 138, 166, .35); }
.mood-sad .trade-bubble::before { border-right-color: rgba(255, 138, 166, .12); }
.live-dots { display: inline-flex; gap: 3px; margin-left: 2px; vertical-align: middle; }
.live-dots i {
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: currentColor;
  opacity: .4;
  animation: dot 1.2s ease-in-out infinite;
}
.live-dots i:nth-child(2) { animation-delay: .15s; }
.live-dots i:nth-child(3) { animation-delay: .3s; }
@keyframes dot { 30% { opacity: 1; transform: translateY(-2px); } }

/* ---- Progress rail ---- */
.trade-rail {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .25rem;
  padding: .2rem 0 .1rem;
}
.rail-node {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .22rem;
  color: var(--muted);
}
.rail-node b {
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  font-size: .85rem;
  font-weight: 900;
  background: rgba(255, 255, 255, .07);
  border: 2px solid rgba(255, 255, 255, .14);
  color: #aab4dd;
  transition: transform .25s ease;
}
.rail-node em { font-size: .64rem; font-weight: 700; font-style: normal; letter-spacing: .02em; }
.rail-node.done b { background: #6df0c4; border-color: #6df0c4; color: #06231a; }
.rail-node.done em { color: #8be8d0; }
.rail-node.now b {
  background: linear-gradient(180deg, #ffe066, #f5b73c);
  border-color: #ffe066;
  color: #3a2a00;
  transform: scale(1.16);
  box-shadow: 0 0 14px rgba(255, 224, 102, .6);
}
.rail-node.now em { color: #ffe066; }
.rail-link {
  flex: 0 0 28px;
  height: 3px;
  border-radius: 2px;
  background: rgba(255, 255, 255, .12);
  margin-bottom: .9rem;
}
.rail-link.lit { background: #6df0c4; }
.trade-rail.is-cancelled { opacity: .5; filter: grayscale(.6); }

/* ---- The two-card trade table ---- */
.trade-cards,
.trade-table {
  position: relative;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  gap: .55rem;
  align-items: start;
}
.trade-slot { display: flex; flex-direction: column; align-items: center; gap: .35rem; }
.slot-name {
  font-size: .68rem;
  font-weight: 800;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--muted);
}
.slot-empty {
  width: 100%;
  display: grid;
  place-items: center;
  min-height: 90px;
  border: 2px dashed rgba(255, 255, 255, .2);
  border-radius: 14px;
  color: var(--muted);
  font-size: .8rem;
  font-weight: 700;
}
.trade-swap-icon {
  align-self: center;
  justify-self: center;
  margin-top: 2.2rem;
  font-size: 1.5rem;
  line-height: 1;
  color: #ffe066;
  animation: swap-wiggle 1.8s ease-in-out infinite;
}
@keyframes swap-wiggle { 50% { transform: rotate(180deg) scale(1.12); } }
/* Vertical stacked layout (mobile): keep the icon's base 90deg rotation throughout
   the cycle so it wiggles in place instead of sweeping across the column. */
@keyframes swap-wiggle-v { 50% { transform: rotate(270deg) scale(1.12); } }

/* ---- Virtual trading card (foil language from the card viewer) ---- */
.tcard {
  position: relative;
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: .4rem;
  padding: .6rem .6rem .55rem;
  border-radius: 16px;
  overflow: hidden;
  border: 2px solid color-mix(in srgb, var(--type-accent, #7cf0c6) 50%, rgba(255, 255, 255, .2));
  background:
    linear-gradient(165deg,
      color-mix(in srgb, var(--type-light, #cfd8ff) 30%, rgba(255, 255, 255, .05)),
      rgba(8, 13, 30, .92));
  box-shadow: 0 10px 26px rgba(0, 0, 0, .45), inset 0 0 0 1px rgba(255, 255, 255, .05);
  color: #f4f7ff;
  animation: card-deal .4s cubic-bezier(.2, 1, .3, 1) both;
}
@keyframes card-deal { from { opacity: 0; transform: translateY(14px) rotate(-3deg); } }
.tcard-foil,
.tcard-glare { position: absolute; inset: 0; pointer-events: none; border-radius: 14px; }
.tcard-foil {
  opacity: 0;
  mix-blend-mode: color-dodge;
  background:
    repeating-linear-gradient(115deg, transparent 0 6%, rgba(255, 255, 255, .12) 7.5%, transparent 9% 15%),
    conic-gradient(from 210deg, #ffe66d, #ff8fab, #b57cff, #4ea9ff, #7cf0c6, #ffe66d);
}
.tcard.rarity-epic .tcard-foil { opacity: .5; }
.tcard.rarity-rare .tcard-foil { opacity: .28; }
.tcard.rarity-common .tcard-foil { opacity: .12; }
.tcard-glare {
  background: radial-gradient(120% 80% at 30% 0%, rgba(255, 255, 255, .22), rgba(255, 255, 255, 0) 55%);
  mix-blend-mode: soft-light;
}
.tcard-head {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .4rem;
}
.tcard-head strong { font-size: .92rem; line-height: 1.1; min-width: 0; }
.tcard-dex { font-size: .66rem; color: var(--muted); font-weight: 700; }
.tcard-head-meta {
  display: inline-flex;
  align-items: center;
  gap: .3rem;
  flex-shrink: 0;
}
.tcard-hp {
  display: inline-flex;
  align-items: baseline;
  gap: 3px;
  padding: .14rem .42rem;
  border-radius: 8px;
  color: #fff;
  background: linear-gradient(180deg, #ff8aa6, #e0567a);
  box-shadow: 0 1px 0 rgba(0, 0, 0, .3), inset 0 1px 0 rgba(255, 255, 255, .2);
  white-space: nowrap;
  line-height: 1;
}
.tcard-hp b { font-size: .96rem; font-weight: 900; font-variant-numeric: tabular-nums; }
.tcard-hp em {
  font-size: .56rem;
  font-style: normal;
  font-weight: 800;
  letter-spacing: .06em;
  opacity: .92;
}
.tcard .type-pill {
  font-size: .58rem;
  font-weight: 800;
  letter-spacing: .05em;
  text-transform: uppercase;
  padding: .14rem .45rem;
  border-radius: 999px;
}
.tcard-art {
  position: relative;
  z-index: 1;
  width: 100%;
  height: auto;
  border-radius: 12px;
  background: rgba(6, 10, 24, .5);
  border: 1px solid rgba(255, 255, 255, .08);
}
.tcard .stats-list {
  position: relative;
  z-index: 1;
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: .2rem;
  font-size: .66rem;
}
.tcard .stats-list li { display: grid; grid-template-columns: 30px 1fr auto; align-items: center; gap: .4rem; }
.tcard .stat-label { color: var(--muted); font-weight: 800; letter-spacing: .04em; }
.tcard .stat-bar { height: 6px; border-radius: 999px; background: rgba(255, 255, 255, .12); overflow: hidden; }
.tcard .stat-fill { display: block; height: 100%; border-radius: 999px; background: linear-gradient(90deg, var(--type-accent, #7cf0c6), #fff); }
.tcard .stat-val { font-weight: 800; font-variant-numeric: tabular-nums; }
.tcard .stat-boost { color: #8afdd8; }
.tcard-foot { position: relative; z-index: 1; display: flex; justify-content: center; }
.tcard-ribbon {
  font-size: .62rem;
  font-weight: 800;
  letter-spacing: .04em;
  padding: .14rem .55rem;
  border-radius: 999px;
  color: #3a2a00;
  background: linear-gradient(180deg, #ffe066, #f3b73a);
}
.tcard-ribbon.plain { color: #cdd6ff; background: rgba(255, 255, 255, .08); }

/* Face-down / waiting slot */
.tcard-ghost {
  align-items: center;
  justify-content: center;
  min-height: 150px;
  border-style: dashed;
  border-color: rgba(255, 255, 255, .22);
  background: rgba(255, 255, 255, .03);
  text-align: center;
}
.tcard-q {
  font-size: 2.4rem;
  font-weight: 900;
  color: rgba(255, 255, 255, .35);
  animation: hot-throb 1.6s ease-in-out infinite;
}
.tcard-wait { font-size: .74rem; color: var(--muted); padding: 0 .5rem; }

/* Pickable card */
.trade-picker {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: .75rem;
}
.tcard-pick {
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: transform .12s cubic-bezier(.2, 1.5, .4, 1), box-shadow .12s ease;
}
.tcard-pick:hover { transform: translateY(-4px) scale(1.02); box-shadow: 0 16px 32px rgba(0, 0, 0, .5); }
.tcard-pick:hover .tcard-foil { opacity: .7; }
.tcard-pick:active { transform: translateY(-1px) scale(.99); }
.tcard-send {
  position: relative;
  z-index: 1;
  text-align: center;
  font-size: .68rem;
  font-weight: 800;
  color: var(--type-accent, #7cf0c6);
  padding-top: .1rem;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: .25rem;
}
.tcard-power-inline {
  color: #0b1226;
  background: color-mix(in srgb, var(--type-accent, #7cf0c6) 85%, white);
  padding: .08rem .42rem;
  border-radius: 999px;
  font-weight: 900;
}
.tcard-chosen { animation: card-chosen .5s ease forwards; }
@keyframes card-chosen {
  40% { transform: scale(1.08); }
  100% { transform: scale(.6) translateY(-30px); opacity: 0; }
}

/* ---- Completion: cards cross + sparkle burst ---- */
.trade-table.is-swapping .slot-mine .tcard { animation: deal-swap-l .9s cubic-bezier(.5, 0, .3, 1) both; }
.trade-table.is-swapping .slot-theirs .tcard { animation: deal-swap-r .9s cubic-bezier(.5, 0, .3, 1) both; }
@keyframes deal-swap-l {
  0% { transform: translateX(0) rotate(0); }
  45% { transform: translateX(118%) rotate(8deg) scale(.9); }
  55% { transform: translateX(118%) rotate(8deg) scale(.9); }
  100% { transform: translateX(0) rotate(0); }
}
@keyframes deal-swap-r {
  0% { transform: translateX(0) rotate(0); }
  45% { transform: translateX(-118%) rotate(-8deg) scale(.9); }
  55% { transform: translateX(-118%) rotate(-8deg) scale(.9); }
  100% { transform: translateX(0) rotate(0); }
}
.spark-burst {
  position: absolute;
  inset: 0;
  display: block;
  pointer-events: none;
  opacity: 0;
}
.trade-table.is-swapping .spark-burst { animation: spark-show 1.4s ease-out .5s both; }
@keyframes spark-show { 0%, 100% { opacity: 0; } 30% { opacity: 1; } }
.spark-burst i {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: #ffe066;
  box-shadow: 0 0 8px #ffd34d;
}
.trade-table.is-swapping .spark-burst i { animation: spark-fly 1.1s ease-out .6s both; }
.spark-burst i:nth-child(1) { --sx: 90px; --sy: -70px; background: #ff8fab; }
.spark-burst i:nth-child(2) { --sx: -100px; --sy: -50px; background: #7cf0c6; }
.spark-burst i:nth-child(3) { --sx: 110px; --sy: 40px; background: #4ea9ff; }
.spark-burst i:nth-child(4) { --sx: -90px; --sy: 60px; background: #ffe066; }
.spark-burst i:nth-child(5) { --sx: 40px; --sy: -100px; background: #b57cff; }
.spark-burst i:nth-child(6) { --sx: -50px; --sy: -95px; background: #6df0c4; }
.spark-burst i:nth-child(7) { --sx: 70px; --sy: 90px; background: #ffd34d; }
.spark-burst i:nth-child(8) { --sx: -75px; --sy: 85px; background: #ff8fab; }
@keyframes spark-fly {
  0% { transform: translate(-50%, -50%) scale(.3); opacity: 1; }
  100% { transform: translate(calc(-50% + var(--sx)), calc(-50% + var(--sy))) scale(1); opacity: 0; }
}

/* ---- Banners (complete / cancelled) ---- */
.trade-banner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .15rem;
  text-align: center;
  padding: .7rem 1rem;
  border-radius: 14px;
  font-size: 1.05rem;
  font-weight: 900;
  color: #06231a;
  background: linear-gradient(180deg, #7df0c4, #34c79b);
  box-shadow: 0 8px 22px rgba(52, 199, 155, .35);
  animation: trade-pop .45s cubic-bezier(.18, 1.4, .4, 1) both;
}
.trade-banner span { font-size: .8rem; font-weight: 700; color: #073a2b; }
.trade-banner span b { color: #042018; }
.trade-banner.sad {
  color: #fff;
  background: linear-gradient(180deg, #6b7299, #474d75);
  box-shadow: none;
}
.trade-banner.sad span { color: #d6dcf5; }

.trade-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: .55rem;
  margin-top: .2rem;
}
.trade-actions .trade-cta:not(.big) { flex: 1 1 auto; min-width: 130px; }

.trade-empty { text-align: center; padding: 1.2rem .8rem; }
.trade-empty .empty-emoji { font-size: 2.6rem; display: block; margin-bottom: .4rem; }
.trade-empty p { margin: .25rem 0; font-size: .92rem; font-weight: 700; }
.trade-empty .muted { color: var(--muted); font-weight: 500; font-size: .82rem; line-height: 1.45; }
.trade-empty b { color: #8be8d0; }

@media (max-width: 540px) {
  .trade-cards,
  .trade-table { grid-template-columns: 1fr; }
  .trade-table .trade-swap-icon {
    transform: rotate(90deg);
    margin: -.2rem 0;
    animation: swap-wiggle-v 1.8s ease-in-out infinite;
  }
  .trade-swap-icon { margin-top: 0; }
  .trade-table.is-swapping .slot-mine .tcard,
  .trade-table.is-swapping .slot-theirs .tcard { animation: card-deal .4s ease both; }
  /* Inside narrow picker cards the head meta can wrap under the name. */
  .tcard-pick .tcard-head { flex-wrap: wrap; row-gap: .25rem; }
}

@media (prefers-reduced-motion: reduce) {
  .trade-modal .trade-card,
  .trade-tile,
  .trade-talk,
  .tcard,
  .trade-banner { animation: none; }
  .radar-sweep,
  .radar-blip,
  .tile-dist .ping,
  .swap-wiggle,
  .trade-swap-icon,
  .live-dots i,
  .tcard-q,
  .trade-group-title.hot { animation: none; }
  .trade-table.is-swapping .slot-mine .tcard,
  .trade-table.is-swapping .slot-theirs .tcard,
  .trade-table.is-swapping .spark-burst { animation: none; }
  .tcard-pick:hover { transform: none; }
}

/* ===========================================================================
   Immersive card viewer — a virtual representation of a physical trading card
   =========================================================================== */
.card-viewer {
  position: fixed;
  inset: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
  /* Keep any stray drag on the overlay from moving the page behind it. */
  overscroll-behavior: contain;
}
.card-viewer.hidden { display: none; }
.cv-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(3, 6, 14, .82);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}

.cv-stage {
  position: relative;
  z-index: 1;
  perspective: 1300px;
  width: min(380px, 86vw);
  /* Own the touch gesture: without this, mobile Safari treats a horizontal
     drag as a pan/scroll, fires pointercancel, and the swipe-to-browse never
     registers — the background moves instead of the card. */
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}

.cv-card {
  position: relative;
  width: 100%;
  aspect-ratio: 5 / 7;
  max-height: 82vh;
  transform-style: preserve-3d;
  transform: rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg));
  transition: transform .16s ease-out;
  cursor: pointer;
  /* Motion vars (set by JS). Foil rests OFF-centre so no seam parks mid-card. */
  --holo: 0;            /* rainbow-foil strength, per rarity */
  --spark: 0;           /* sparkle/glitter strength, epic (or cosmic) only */
  --mx: 50%;            /* glare focal X */
  --my: 34%;            /* glare focal Y */
  --bx: 30%;            /* foil sweep X (resting, off-centre) */
  --by: 26%;            /* foil sweep Y (resting, off-centre) */
  --fc: 0;              /* tilt amount 0..1, swells the glare */
  /* Default rainbow palette — per-type classes below override these. */
  --h1: #ff6b97; --h2: #ffd36b; --h3: #7bff9b;
  --h4: #62e7ff; --h5: #7d92ff; --h6: #d987ff;
  /* Concentrate the foil over the artwork band so it reads as printed-on
     foil, fading clear of the name and stat text. */
  --art-mask: linear-gradient(to bottom,
    transparent 4%, rgba(0, 0, 0, .9) 20%, rgba(0, 0, 0, .9) 54%, transparent 70%);
}
.cv-card.rarity-common { --holo: .10; --spark: 0; }
.cv-card.rarity-rare   { --holo: .30; --spark: 0; }
.cv-card.rarity-epic   { --holo: .44; --spark: .4; }

/* Per-type foil palettes ---------------------------------------------------*/
.cv-card.type-fire, .cv-card.type-rock {
  --h1:#ff7a3a; --h2:#ffd36b; --h3:#ff9e5e; --h4:#ffee8c; --h5:#ff5e7a; --h6:#ffb27a;
}
.cv-card.type-water, .cv-card.type-ice {
  --h1:#4ea9ff; --h2:#7ff0ff; --h3:#9bd4ff; --h4:#d6f6ff; --h5:#6b86ff; --h6:#a0e6ff;
}
.cv-card.type-leaf, .cv-card.type-bug, .cv-card.type-wind {
  --h1:#5ed27a; --h2:#caf08b; --h3:#8ce8c8; --h4:#e0f4a8; --h5:#62e4b0; --h6:#b2f0c4;
}
.cv-card.type-electric {
  --h1:#ffd966; --h2:#fff79a; --h3:#d4ff8a; --h4:#8affd2; --h5:#ffe566; --h6:#f2ff8a;
}
.cv-card.type-shadow, .cv-card.type-spirit {
  --h1:#8a6cff; --h2:#cf8bff; --h3:#ff8bd2; --h4:#8b9cff; --h5:#b06bff; --h6:#e08bff;
}
.cv-card.type-cosmic {
  --h1:#a878ff; --h2:#6be0ff; --h3:#e0c8ff; --h4:#7d92ff; --h5:#c97bff; --h6:#8be0ff;
}
/* Cosmic gets a starfield (sparkle layer) even at rare. */
.cv-card.type-cosmic.rarity-rare { --spark: .28; }
.cv-card.type-cosmic.rarity-epic { --spark: .5; }
/* Metal: brushed silver rather than rainbow. */
.cv-card.type-metal {
  --h1:#e8eef6; --h2:#9aaabd; --h3:#ffffff; --h4:#aab6c6; --h5:#dfe6f0; --h6:#8593a6;
}

.cv-flipper {
  position: relative;
  width: 100%;
  height: 100%;
  transform-style: preserve-3d;
  transition: transform .6s cubic-bezier(.2, .8, .2, 1);
}
.cv-card.flipped .cv-flipper { transform: rotateY(180deg); }

.cv-face {
  position: absolute;
  inset: 0;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  border-radius: 20px;
  overflow: hidden;
  border: 2px solid var(--cv-edge, rgba(255, 255, 255, .25));
  /* Fully opaque so the reverse side never bleeds through the card. */
  background: linear-gradient(165deg, #1d2747, #060b18);
  box-shadow:
    0 30px 70px rgba(0, 0, 0, .6),
    0 0 0 1px rgba(255, 255, 255, .04) inset,
    0 0 38px var(--cv-glow, rgba(124, 240, 198, .25));
  display: flex;
  flex-direction: column;
  padding: 1rem .95rem;
  gap: .6rem;
}
/* Push each face a hair along its own normal so the two coplanar faces
   can't z-fight or show through one another. */
.cv-face.front { transform: translateZ(1px); }
.cv-face.back { transform: rotateY(180deg) translateZ(1px); }

/* Holographic foil + moving glare, layered ABOVE the card content so the
   foil sits "on" the artwork like real printed holo (poke-holo style:
   repeating rainbow bands swept by background-position — no conic gradient,
   so there is no convergence point/seam parked in the middle of the card). */
.cv-holo,
.cv-glare {
  position: absolute;
  inset: 0;
  pointer-events: none;
  border-radius: 16px;
  overflow: hidden;
}

/* Rainbow foil — masked to the artwork band so it reads as printed-on. */
.cv-holo {
  z-index: 2;
  opacity: var(--holo, 0);
  background-image:
    repeating-linear-gradient(108deg,
      var(--h1) 0%, var(--h2) 7%, var(--h3) 14%, var(--h4) 21%,
      var(--h5) 28%, var(--h6) 35%, var(--h1) 42%),
    repeating-linear-gradient(53deg,
      var(--h4) 0%, var(--h6) 8%, var(--h2) 16%, var(--h5) 24%, var(--h4) 32%),
    radial-gradient(farthest-corner circle at var(--mx) var(--my),
      rgba(255, 255, 255, .7) 0%, rgba(40, 40, 55, .35) 28%, #000 62%);
  background-size: 220% 220%, 170% 170%, cover;
  background-position:
    var(--bx) var(--by),
    calc(100% - var(--bx)) var(--by),
    center;
  background-blend-mode: screen, multiply;
  filter: brightness(.82) contrast(2.55) saturate(.78);
  mix-blend-mode: color-dodge;
  -webkit-mask-image: var(--art-mask);
  mask-image: var(--art-mask);
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
  transition: opacity .3s ease;
}

/* Fine "printed line screen" micro-texture (skipped on commons). */
.cv-card:not(.rarity-common) .cv-holo::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: repeating-linear-gradient(90deg,
    rgba(0, 0, 0, .55) 0 1px,
    rgba(255, 255, 255, .16) 1px 2px,
    rgba(0, 0, 0, .55) 2px 3px);
  background-size: 220% 100%;
  background-position: var(--bx) 0;
  mix-blend-mode: overlay;
  opacity: .45;
  -webkit-mask-image: var(--art-mask);
  mask-image: var(--art-mask);
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
}

/* Sparkle / glitter — epic rarity (and cosmic, where it reads as a starfield). */
.cv-holo::after {
  content: "";
  position: absolute;
  inset: 0;
  opacity: var(--spark, 0);
  background-image:
    radial-gradient(rgba(255, 255, 255, .95) 0.6px, transparent 1.4px),
    radial-gradient(rgba(255, 255, 255, .7) 0.6px, transparent 1.4px);
  background-size: 3.2% 3.2%, 5% 5%;
  background-position: var(--bx) var(--by), var(--by) var(--bx);
  mix-blend-mode: color-dodge;
  transition: opacity .3s ease;
  -webkit-mask-image: var(--art-mask);
  mask-image: var(--art-mask);
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
}

/* Metal foil is brushed silver, not rainbow — drop the saturation. */
.cv-card.type-metal .cv-holo { filter: brightness(.85) contrast(2.4) saturate(.32); }

/* Full-face plastic glare — follows the light, swells as you tilt. */
.cv-glare {
  z-index: 3;
  background-image: radial-gradient(farthest-corner circle at var(--mx) var(--my),
    rgba(255, 255, 255, .24) 8%,
    rgba(255, 255, 255, .07) 26%,
    rgba(255, 255, 255, 0) 56%);
  mix-blend-mode: overlay;
  opacity: calc(.28 + var(--fc, 0) * .4);
  transition: opacity .2s ease;
}

.cv-body {
  position: relative;
  z-index: 1;
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: .6rem;
}

/* Card front */
.cv-front-head { display: flex; align-items: flex-start; justify-content: space-between; gap: .5rem; }
.cv-front-head h2 { margin: 0; font-size: 1.15rem; line-height: 1.1; }
.cv-front-head .rarity { margin: .2rem 0 0; }
.cv-art {
  flex: 1;
  width: 100%;
  min-height: 0;
  border-radius: 14px;
  background: linear-gradient(160deg, rgba(112, 124, 180, .2), rgba(8, 14, 30, .6));
  border: 1px solid rgba(255, 255, 255, .08);
}
.cv-badges { display: flex; flex-wrap: wrap; gap: .35rem; align-items: center; }
.cv-statline {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: .4rem;
  text-align: center;
}
.cv-statline div {
  background: rgba(255, 255, 255, .05);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: .35rem .2rem;
}
.cv-statline span { display: block; font-weight: 800; font-size: .95rem; color: var(--text); }
.cv-statline small { color: var(--muted); font-size: .58rem; letter-spacing: .08em; }
.cv-foot {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: .66rem;
  color: var(--muted);
  letter-spacing: .03em;
}

/* Card back */
.cv-face.back { gap: .55rem; }
.cv-face.back header strong { font-size: 1.05rem; }
.cv-face.back .stats-list { margin-top: .2rem; }
.cv-face.back .flavor { margin: auto 0 .2rem; }
.cv-face.back .instance-actions { margin-top: .2rem; }
.cv-back-tip {
  text-align: center;
  font-size: .6rem;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: .12em;
}

/* Controls */
.cv-close {
  position: absolute;
  top: 1rem;
  right: 1rem;
  z-index: 3;
  width: 42px;
  height: 42px;
  border-radius: 50%;
  background: rgba(255, 255, 255, .08);
  border: 1px solid var(--line);
  color: var(--text);
  font-size: 1.1rem;
  line-height: 1;
}
.cv-close:hover { background: rgba(255, 255, 255, .16); }
.cv-nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 2;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  background: rgba(255, 255, 255, .08);
  border: 1px solid var(--line);
  color: var(--text);
  font-size: 1.6rem;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
}
.cv-nav:hover { background: rgba(255, 255, 255, .18); }
.cv-nav[disabled] { opacity: .3; cursor: not-allowed; }
.cv-prev { left: max(1rem, 4vw); }
.cv-next { right: max(1rem, 4vw); }
.cv-footer {
  position: absolute;
  bottom: 1.1rem;
  left: 0;
  right: 0;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .3rem;
}
.cv-counter { font-weight: 800; color: var(--text); font-size: .9rem; letter-spacing: .05em; }
.cv-hint { font-size: .66rem; color: var(--muted); letter-spacing: .06em; text-transform: uppercase; }
.cv-motion {
  margin-top: .2rem;
  padding: .35rem .8rem;
  font-size: .72rem;
  border-radius: 999px;
  background: transparent;
  border: 1px solid var(--accent);
  color: var(--accent);
}

@media (max-width: 560px) {
  .cv-nav { width: 44px; height: 44px; font-size: 1.3rem; }
  .cv-prev { left: .4rem; }
  .cv-next { right: .4rem; }
  .cv-stage { width: min(340px, 82vw); }
}

@media (prefers-reduced-motion: reduce) {
  .cv-card { transition: none; transform: none !important; }
  .cv-flipper { transition: transform .2s linear; }
  .cv-holo, .cv-glare { display: none; }
  .gallery-card { transition: none; }
}

/* ===== Splash / intro screen ============================================ */
.splash {
  position: fixed;
  inset: 0;
  z-index: 9000;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2rem;
  padding:
    max(2rem, env(safe-area-inset-top))
    max(2rem, env(safe-area-inset-right))
    max(2rem, env(safe-area-inset-bottom))
    max(2rem, env(safe-area-inset-left));
  background:
    radial-gradient(circle at 18% 22%, rgba(124, 240, 198, .25), transparent 55%),
    radial-gradient(circle at 82% 78%, rgba(181, 124, 255, .28), transparent 60%),
    radial-gradient(circle at 50% 110%, rgba(255, 209, 115, .18), transparent 65%),
    linear-gradient(160deg, #060a16 0%, #0d1226 55%, #11173a 100%);
  overflow: hidden;
  isolation: isolate;
  text-align: center;
  animation: splash-bg-shift 14s ease-in-out infinite alternate;
  -webkit-tap-highlight-color: transparent;
}
.splash::before {
  content: "";
  position: absolute;
  inset: -10%;
  background:
    radial-gradient(2px 2px at 12% 18%, rgba(255,255,255,.85), transparent 60%),
    radial-gradient(1.5px 1.5px at 28% 72%, rgba(255,255,255,.6), transparent 60%),
    radial-gradient(2px 2px at 64% 22%, rgba(255,255,255,.7), transparent 60%),
    radial-gradient(1.5px 1.5px at 80% 58%, rgba(255,255,255,.55), transparent 60%),
    radial-gradient(2px 2px at 44% 88%, rgba(255,255,255,.7), transparent 60%),
    radial-gradient(1.5px 1.5px at 92% 12%, rgba(255,255,255,.6), transparent 60%);
  opacity: .9;
  animation: splash-stars 22s linear infinite;
  pointer-events: none;
  z-index: -1;
}
@keyframes splash-bg-shift {
  0%   { background-position: 0% 0%, 0% 0%, 0% 0%, 0% 0%; }
  100% { background-position: 8% -6%, -10% 6%, 4% 4%, 0% 0%; }
}
@keyframes splash-stars {
  0%   { transform: translate3d(0,0,0) rotate(0deg); }
  100% { transform: translate3d(-4%, -3%, 0) rotate(2deg); }
}

.splash-stage {
  position: relative;
  width: min(520px, 88vw);
  height: clamp(160px, 26vh, 220px);
  display: flex;
  align-items: center;
  justify-content: center;
}
.splash-ring {
  position: absolute;
  border-radius: 50%;
  border: 1px solid rgba(255,255,255,.08);
  box-shadow: inset 0 0 40px rgba(124, 240, 198, .12);
}
.splash-ring-1 { width: 220px; height: 220px; animation: splash-ring-spin 24s linear infinite; }
.splash-ring-2 { width: 320px; height: 320px; opacity: .6; animation: splash-ring-spin 38s linear infinite reverse; }
.splash-ring-3 { width: 460px; height: 460px; opacity: .35; animation: splash-ring-spin 52s linear infinite; }
@keyframes splash-ring-spin {
  to { transform: rotate(360deg); }
}

.splash-cast {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(.5rem, 2vw, 1.1rem);
  width: 100%;
}
.splash-mon {
  --delay: 0s;
  --drift: 12px;
  display: inline-block;
  width: clamp(38px, 8vw, 54px);
  height: clamp(38px, 8vw, 54px);
  position: relative;
  animation: splash-mon-bob 3.4s ease-in-out infinite;
  animation-delay: var(--delay);
  filter: drop-shadow(0 6px 14px rgba(0,0,0,.45));
}
.splash-mon .mon-body {
  position: absolute;
  inset: 0;
  border-radius: 50% 50% 48% 48% / 56% 56% 44% 44%;
  background: radial-gradient(circle at 35% 30%, var(--mon-hi, #fff) 0%, var(--mon-mid, #7cf0c6) 45%, var(--mon-lo, #1c8c6c) 100%);
  box-shadow:
    inset -4px -6px 10px rgba(0,0,0,.25),
    inset 4px 6px 10px rgba(255,255,255,.15),
    0 0 22px var(--mon-glow, rgba(124, 240, 198, .55));
  animation: splash-mon-pulse 2.6s ease-in-out infinite;
  animation-delay: var(--delay);
}
.splash-mon .mon-eye {
  position: absolute;
  top: 38%;
  width: 18%;
  height: 22%;
  border-radius: 50%;
  background: #0a0f1f;
  box-shadow: inset 0 -1px 0 rgba(255,255,255,.15);
}
.splash-mon .mon-eye::after {
  content: "";
  position: absolute;
  top: 18%; left: 20%;
  width: 38%; height: 38%;
  border-radius: 50%;
  background: rgba(255,255,255,.9);
}
.splash-mon .mon-eye.left  { left: 22%; }
.splash-mon .mon-eye.right { right: 22%; }
.m-electric { --mon-hi:#fffce0; --mon-mid:#ffe27a; --mon-lo:#b88600; --mon-glow: rgba(255, 226, 122, .55); }
.m-leaf     { --mon-hi:#e9ffe7; --mon-mid:#85e09a; --mon-lo:#1e7a45; --mon-glow: rgba(133, 224, 154, .55); }
.m-water    { --mon-hi:#e6f6ff; --mon-mid:#7cc8ff; --mon-lo:#1a5e96; --mon-glow: rgba(124, 200, 255, .55); }
.m-fire     { --mon-hi:#fff0e0; --mon-mid:#ff9c70; --mon-lo:#a23a14; --mon-glow: rgba(255, 156, 112, .6); }
.m-shadow   { --mon-hi:#ece7ff; --mon-mid:#a08bff; --mon-lo:#3a2a78; --mon-glow: rgba(160, 139, 255, .55); }
.m-cosmic   { --mon-hi:#fff0fb; --mon-mid:#d49eff; --mon-lo:#5a2a92; --mon-glow: rgba(212, 158, 255, .6); }

@keyframes splash-mon-bob {
  0%, 100% { transform: translateY(0) rotate(-2deg); }
  50%      { transform: translateY(var(--drift)) rotate(2deg); }
}
@keyframes splash-mon-pulse {
  0%, 100% { box-shadow: inset -4px -6px 10px rgba(0,0,0,.25), inset 4px 6px 10px rgba(255,255,255,.15), 0 0 18px var(--mon-glow); }
  50%      { box-shadow: inset -4px -6px 10px rgba(0,0,0,.25), inset 4px 6px 10px rgba(255,255,255,.15), 0 0 30px var(--mon-glow); }
}

.splash-copy {
  position: relative;
  max-width: 540px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .75rem;
}
.splash-eyebrow {
  text-transform: uppercase;
  letter-spacing: .26em;
  font-size: .72rem;
  color: var(--muted);
  margin: 0;
}
.splash-title {
  margin: 0;
  font-size: clamp(3rem, 11vw, 5.5rem);
  font-weight: 800;
  letter-spacing: -.02em;
  line-height: .95;
  background: linear-gradient(90deg, #b9ffe7, #7cf0c6 30%, #b57cff 65%, #ff9ec7);
  background-size: 220% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  filter: drop-shadow(0 4px 24px rgba(124, 240, 198, .35));
  animation: splash-title-shimmer 6s ease-in-out infinite;
}
@keyframes splash-title-shimmer {
  0%, 100% { background-position: 0% 50%; }
  50%      { background-position: 100% 50%; }
}
.splash-tag {
  margin: 0;
  color: #cfd6ee;
  font-size: clamp(.95rem, 2.4vw, 1.1rem);
  max-width: 420px;
}
.splash-cta {
  margin-top: 1rem;
  padding: .95rem 2.2rem;
  font-size: 1.05rem;
  font-weight: 800;
  letter-spacing: .04em;
  border-radius: 999px;
  border: none;
  color: #051d18;
  background: linear-gradient(90deg, #7cf0c6, #4bb7ff);
  cursor: pointer;
  box-shadow: 0 14px 38px rgba(75, 183, 255, .32), inset 0 0 0 1px rgba(255,255,255,.35);
  animation: splash-cta-pulse 2.4s ease-in-out infinite;
  -webkit-tap-highlight-color: transparent;
}
.splash-cta:hover { transform: translateY(-1px); }
.splash-cta:active { transform: translateY(1px); }
@keyframes splash-cta-pulse {
  0%, 100% { box-shadow: 0 14px 38px rgba(75, 183, 255, .32), inset 0 0 0 1px rgba(255,255,255,.35), 0 0 0 0 rgba(124, 240, 198, .45); }
  50%      { box-shadow: 0 14px 38px rgba(75, 183, 255, .32), inset 0 0 0 1px rgba(255,255,255,.35), 0 0 0 12px rgba(124, 240, 198, 0); }
}
.splash-hint {
  margin: .35rem 0 0;
  font-size: .72rem;
  letter-spacing: .08em;
  color: var(--muted);
  text-transform: uppercase;
}
.splash.is-leaving {
  opacity: 0;
  transform: scale(1.02);
  transition: opacity .55s ease, transform .55s ease;
  pointer-events: none;
}

/* Music toggle in HUD --------------------------------------------------- */
.music-toggle {
  flex: none;
  width: 36px;
  height: 36px;
  padding: 0;
  border-radius: 12px;
  display: grid;
  place-items: center;
  background: rgba(9, 14, 28, .92);
  border: 1px solid rgba(255, 255, 255, .35);
  color: var(--text);
  cursor: pointer;
  box-shadow: 0 2px 8px rgba(0, 0, 0, .35);
  transition: transform .15s ease, border-color .2s ease, color .2s ease;
}
.music-toggle .music-toggle-icon {
  font-size: 1.15rem;
  line-height: 1;
  transition: opacity .2s ease;
}
.music-toggle[aria-pressed="true"] {
  color: #d8fff0;
  border-color: rgba(124, 240, 198, .8);
  box-shadow: 0 0 0 1px rgba(124, 240, 198, .35), 0 2px 10px rgba(124, 240, 198, .25);
}
.music-toggle[aria-pressed="false"] {
  color: #e6ecff;
  position: relative;
}
.music-toggle[aria-pressed="false"]::after {
  content: "";
  position: absolute;
  left: 22%;
  right: 22%;
  top: 50%;
  height: 2px;
  background: currentColor;
  transform: rotate(-32deg);
  border-radius: 2px;
  opacity: .85;
}
.music-toggle:hover { transform: translateY(-1px); }

@media (max-width: 420px) {
  .splash-stage { height: 150px; }
  .splash-ring-3 { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .splash,
  .splash::before,
  .splash-ring,
  .splash-mon,
  .splash-mon .mon-body,
  .splash-title,
  .splash-cta { animation: none !important; }
}

/* =========================================================================
   UberMax raid bosses
   ------------------------------------------------------------------------- */
.ubermax-marker {
  position: relative;
  width: 112px;
  display: grid;
  justify-items: center;
  gap: 3px;
  color: #fff7e0;
  filter: drop-shadow(0 6px 14px rgba(0, 0, 0, .6));
  pointer-events: auto;
}
.ubermax-marker .um-banner {
  font-size: .56rem;
  font-weight: 800;
  letter-spacing: .12em;
  text-transform: uppercase;
  background: linear-gradient(90deg, #ffd166, #ff7af0 60%, #b27cff);
  color: #1b0a2a;
  border-radius: 999px;
  padding: 2px 9px;
  border: 1px solid rgba(255, 255, 255, .55);
  box-shadow: 0 2px 8px rgba(255, 122, 240, .45);
  white-space: nowrap;
}
.ubermax-marker .um-medal {
  position: relative;
  width: 62px;
  height: 62px;
  border-radius: 50%;
  background:
    radial-gradient(circle at 32% 28%, #fff8d6, transparent 58%),
    radial-gradient(circle at 70% 80%, var(--um-dark, #4a1e7a), var(--um-dark, #2c0e4f) 70%),
    linear-gradient(140deg, var(--um-light, #ffd166), var(--um-accent, #ff7af0) 60%, var(--um-dark, #2c0e4f));
  border: 3px solid #ffe28a;
  box-shadow:
    0 0 22px var(--um-accent, #ffd166),
    0 0 38px rgba(255, 122, 240, .45),
    inset 0 -8px 14px rgba(0, 0, 0, .35);
  display: grid;
  place-items: center;
}
.ubermax-marker .um-medal-glyph {
  font-family: "Outfit", sans-serif;
  font-size: 1.7rem;
  font-weight: 800;
  color: #fff7d4;
  text-shadow: 0 2px 6px rgba(0, 0, 0, .65);
}
.ubermax-marker .um-medal-glow {
  position: absolute;
  inset: -10px;
  border-radius: 50%;
  background: radial-gradient(circle, var(--um-accent, #ffd166) 0%, transparent 65%);
  filter: blur(6px);
  opacity: .55;
  z-index: -1;
  animation: um-pulse 2.2s ease-in-out infinite;
}
.ubermax-marker .um-medal-crown {
  position: absolute;
  top: -8px;
  right: -6px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: linear-gradient(180deg, #ffd166, #ff7a45);
  color: #1b0a2a;
  border: 2px solid #fff8d6;
  font-size: .8rem;
  font-weight: 800;
  display: grid;
  place-items: center;
  box-shadow: 0 2px 6px rgba(0, 0, 0, .45);
}
.ubermax-marker .um-hp {
  width: 96px;
  height: 6px;
  border-radius: 999px;
  background: rgba(11, 18, 38, .82);
  border: 1px solid rgba(255, 255, 255, .25);
  overflow: hidden;
  margin-top: 2px;
}
.ubermax-marker .um-hp-fill {
  height: 100%;
  background: linear-gradient(90deg, #ff7a45, #ffd166);
  transition: width .35s ease;
}
.ubermax-marker.joined .um-hp-fill { background: linear-gradient(90deg, #ff5a8a, #ffd166); }
.ubermax-marker .um-label {
  font-size: .58rem;
  font-weight: 700;
  padding: 2px 7px;
  border-radius: 999px;
  background: rgba(11, 18, 38, .88);
  border: 1px solid rgba(255, 209, 102, .55);
  color: #fff7d4;
  letter-spacing: .04em;
  text-transform: uppercase;
  max-width: 108px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ubermax-marker .um-army {
  font-size: .54rem;
  font-weight: 700;
  padding: 1px 6px;
  border-radius: 999px;
  background: rgba(124, 240, 198, .92);
  color: #062118;
  border: 1px solid rgba(255, 255, 255, .35);
  letter-spacing: .04em;
}
.ubermax-marker.near .um-medal {
  animation: um-pulse-medal 1.6s ease-in-out infinite;
}
.ubermax-marker.defeated .um-medal {
  filter: grayscale(.7) brightness(.7);
  opacity: .7;
}
.ubermax-marker.defeated .um-hp-fill { background: rgba(124, 240, 198, .85); }
@keyframes um-pulse {
  0%, 100% { transform: scale(1); opacity: .55; }
  50% { transform: scale(1.18); opacity: .85; }
}
@keyframes um-pulse-medal {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.08); }
}

/* ---- UberMax raid modal ---- */
.ubermax-modal {
  position: fixed;
  inset: 0;
  background: radial-gradient(circle at 50% 30%, rgba(74, 30, 122, .55), rgba(4, 9, 20, .92) 65%);
  backdrop-filter: blur(8px);
  display: grid;
  place-items: center;
  z-index: 15;
  padding: 1rem;
}
.ubermax-card {
  width: min(720px, 96vw);
  max-height: 92vh;
  overflow-y: auto;
  border: 1px solid rgba(255, 209, 102, .55);
  background: linear-gradient(180deg, rgba(28, 14, 52, .96), rgba(8, 10, 26, .98));
  border-radius: 22px;
  box-shadow: 0 24px 60px rgba(0, 0, 0, .55), 0 0 0 1px rgba(255, 122, 240, .25) inset;
  padding: 1.1rem 1.2rem 1.3rem;
  color: #f5f7ff;
}
.ubermax-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: .8rem;
  margin-bottom: .8rem;
}
.ubermax-head .eyebrow {
  margin: 0;
  font-size: .68rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: #ffd166;
}
.ubermax-title {
  margin: .15rem 0 0;
  font-size: 1.25rem;
  font-weight: 800;
  letter-spacing: .02em;
  background: linear-gradient(90deg, #fff8d6, #ff7af0 80%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.ubermax-stage {
  display: grid;
  grid-template-columns: minmax(160px, 220px) 1fr;
  gap: 1rem;
  padding: .9rem;
  border-radius: 16px;
  background: linear-gradient(160deg, var(--um-dark, #2c0e4f) 0%, rgba(8, 10, 26, .9) 80%);
  border: 1px solid rgba(255, 255, 255, .12);
}
.ubermax-portrait-wrap {
  position: relative;
  display: grid;
  place-items: center;
}
.ubermax-portrait {
  width: 100%;
  max-width: 220px;
  height: auto;
}
.ubermax-type-pill {
  position: absolute;
  bottom: 6px;
  left: 50%;
  transform: translateX(-50%);
  padding: 2px 10px;
  border-radius: 999px;
  font-weight: 800;
  font-size: .68rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  border: 1px solid rgba(0, 0, 0, .25);
}
.ubermax-vitals { display: flex; flex-direction: column; gap: .55rem; }
.ubermax-hp-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: .5rem;
}
.ubermax-hp-label {
  font-size: .68rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: #ffd166;
  font-weight: 800;
}
.ubermax-hp-num {
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  font-size: .9rem;
}
.ubermax-hp-bar {
  width: 100%;
  height: 14px;
  border-radius: 999px;
  background: rgba(11, 18, 38, .85);
  border: 1px solid rgba(255, 255, 255, .18);
  overflow: hidden;
  box-shadow: inset 0 1px 4px rgba(0, 0, 0, .55);
}
.ubermax-hp-fill {
  height: 100%;
  background: linear-gradient(90deg, #ff5a8a, #ffd166 60%, #ff7af0);
  transition: width .45s ease;
  box-shadow: 0 0 10px rgba(255, 209, 102, .65);
}
.ubermax-hp-fill.drained {
  background: linear-gradient(90deg, #7cf0c6, #7cf0c6);
  box-shadow: 0 0 10px rgba(124, 240, 198, .55);
}
.ubermax-stats-row {
  display: flex;
  gap: .4rem;
  flex-wrap: wrap;
}
.ubermax-status {
  margin: .35rem 0 0;
  font-size: .82rem;
  font-weight: 600;
  color: #cdd6ee;
}
.ubermax-status.live strong {
  color: #ffd166;
  font-variant-numeric: tabular-nums;
}
.ubermax-status.defeated {
  color: #7cf0c6;
  font-weight: 800;
  font-size: .95rem;
  text-shadow: 0 0 14px rgba(124, 240, 198, .45);
}
.ubermax-status.escaped { color: #ff9a8c; }

.ubermax-army { margin-top: 1rem; }
.ubermax-army-head {
  display: flex;
  align-items: center;
  gap: .5rem;
  margin-bottom: .55rem;
  flex-wrap: wrap;
}
.ubermax-army-head strong {
  font-size: .82rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: #ffd166;
}
.ubermax-army-roster {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: .5rem;
}
.ubermax-roster-card {
  display: flex;
  flex-direction: column;
  gap: .15rem;
  padding: .55rem .65rem;
  border-radius: 12px;
  background: linear-gradient(140deg, var(--type-light, #cfd8ff), var(--type-dark, #3d4d8a));
  color: #061226;
  border: 1px solid rgba(0, 0, 0, .25);
  box-shadow: 0 4px 10px rgba(0, 0, 0, .35);
}
.ubermax-roster-card.is-me {
  outline: 2px solid #7cf0c6;
  outline-offset: 1px;
}
.ubermax-roster-card .roster-trainer {
  font-size: .65rem;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  opacity: .8;
}
.ubermax-roster-card strong { font-size: .95rem; font-weight: 800; }
.ubermax-roster-card small { font-size: .72rem; opacity: .85; }
.ubermax-empty {
  grid-column: 1 / -1;
  text-align: center;
  padding: 1rem .5rem;
}

.ubermax-actions {
  margin-top: 1rem;
  display: flex;
  flex-direction: column;
  gap: .55rem;
}
.ubermax-actions .ubermax-close-btn {
  width: 100%;
  background: linear-gradient(90deg, #ffd166, #ff7af0);
  color: #1b0a2a;
  border: none;
  padding: .75rem 1rem;
  border-radius: 12px;
  font-weight: 800;
  letter-spacing: .04em;
  cursor: pointer;
  box-shadow: 0 8px 18px rgba(255, 122, 240, .45);
}
.ubermax-actions .ubermax-close-btn:hover { transform: translateY(-1px); }
.ubermax-picker .picker-prompt {
  font-size: .82rem;
  margin-bottom: .35rem;
  color: #ffd166;
  font-weight: 700;
}
.ubermax-picker .picker-card .picker-power {
  background: linear-gradient(90deg, #ffd166, #ff7af0);
  color: #1b0a2a;
}
.matchup {
  display: inline-block;
  margin-left: .3rem;
  padding: 1px 6px;
  border-radius: 999px;
  font-size: .58rem;
  font-weight: 800;
  letter-spacing: .06em;
  text-transform: uppercase;
}
.matchup.super { background: #7cf0c6; color: #062118; }
.matchup.weak { background: #ff9a8c; color: #1b0a2a; }

/* Collection laurel for UberMax trophies */
.gallery-card.ubermax {
  outline: 2px solid #ffd166;
  outline-offset: -2px;
  box-shadow: 0 0 18px rgba(255, 209, 102, .35);
}
.ubermax-laurel {
  position: absolute;
  top: 6px;
  left: 6px;
  z-index: 3;
  padding: 2px 7px;
  border-radius: 999px;
  font-size: .58rem;
  font-weight: 800;
  letter-spacing: .12em;
  background: linear-gradient(90deg, #ffd166, #ff7af0);
  color: #1b0a2a;
  border: 1px solid #fff8d6;
  text-shadow: 0 1px 0 rgba(255, 255, 255, .45);
  box-shadow: 0 4px 10px rgba(255, 122, 240, .45);
}

/* Victory / escape toasts */
.raid-victory-toast {
  position: fixed;
  top: 12vh;
  left: 50%;
  transform: translate(-50%, -16px);
  z-index: 30;
  display: flex;
  align-items: center;
  gap: .65rem;
  padding: .85rem 1.05rem;
  border-radius: 14px;
  background: linear-gradient(140deg, #2c0e4f, #1a1238);
  border: 1px solid #ffd166;
  color: #fff7d4;
  box-shadow: 0 14px 32px rgba(0, 0, 0, .55), 0 0 24px rgba(255, 209, 102, .35);
  opacity: 0;
  transition: opacity .25s ease, transform .35s ease;
  max-width: min(420px, 92vw);
}
.raid-victory-toast.show {
  opacity: 1;
  transform: translate(-50%, 0);
}
.raid-victory-toast .rvt-laurel { font-size: 1.6rem; }
.raid-victory-toast strong { display: block; font-size: .95rem; }
.raid-victory-toast small { color: #cdd6ee; font-size: .8rem; }
.raid-victory-toast.raid-escape-toast {
  border-color: #ff9a8c;
  box-shadow: 0 14px 32px rgba(0, 0, 0, .55), 0 0 18px rgba(255, 154, 140, .25);
}

@media (max-width: 520px) {
  .ubermax-stage {
    grid-template-columns: 1fr;
    text-align: center;
  }
  .ubermax-portrait-wrap { justify-self: center; }
}

@media (prefers-reduced-motion: reduce) {
  .ubermax-marker .um-medal-glow,
  .ubermax-marker.near .um-medal { animation: none !important; }
  .ubermax-hp-fill { transition: none; }
}

/* ===========================================================================
   Evolution + type-food
   ======================================================================== */

/* Catch-time food reward note */
.food-gain {
  display: inline-block;
  margin-left: .25rem;
  color: #ffe27a;
  font-weight: 800;
  white-space: nowrap;
}

/* Larder: type-food stash atop the collection sheet */
.food-larder { margin: .2rem 0 .6rem; }
.larder-title {
  margin: 0 0 .45rem;
  font-size: .78rem;
  text-transform: uppercase;
  letter-spacing: .1em;
  color: var(--muted);
  display: flex;
  align-items: baseline;
  gap: .5rem;
}
.larder-title small { text-transform: none; letter-spacing: 0; font-size: .7rem; color: #8198c4; font-weight: 500; }
.larder-empty {
  margin: 0;
  padding: .6rem .75rem;
  border: 1px dashed var(--line);
  border-radius: 12px;
  color: var(--muted);
  font-size: .82rem;
}
.larder-row {
  display: flex;
  gap: .5rem;
  overflow-x: auto;
  padding-bottom: .25rem;
  scrollbar-width: thin;
}
.food-chip {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  padding: .32rem .6rem;
  border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--food-accent) 55%, transparent);
  background: color-mix(in srgb, var(--food-accent) 16%, rgba(15, 20, 34, .6));
  box-shadow: 0 0 12px color-mix(in srgb, var(--food-accent) 22%, transparent);
  font-size: .82rem;
}
.food-chip .food-emoji { font-size: 1rem; line-height: 1; }
.food-chip .food-amt { font-weight: 800; color: #fff; }
.food-chip .food-name { color: var(--muted); font-size: .76rem; }

/* Evolved-tier badge on gallery tiles */
.evo-badge {
  position: absolute;
  top: .55rem;
  right: .55rem;
  padding: .1rem .45rem;
  border-radius: 999px;
  font-size: .62rem;
  font-weight: 900;
  letter-spacing: .08em;
  color: #1a1030;
  background: linear-gradient(90deg, #ffe27a, #ffb15c);
  box-shadow: 0 0 10px rgba(255, 196, 92, .5);
  z-index: 3;
}
.evo-badge.tier-2 { background: linear-gradient(90deg, #ff9cf0, #b57cff); color: #160a2c; box-shadow: 0 0 12px rgba(200, 140, 255, .6); }
/* When a tile carries both a stack badge (top-left) and evo badge (top-right) they don't collide */
.gallery-card.evolved {
  border-color: rgba(255, 210, 120, .5);
  box-shadow: 0 0 0 1px rgba(255, 210, 120, .25), 0 8px 22px rgba(0, 0, 0, .4);
}
.gallery-card.evolved.tier-2,
.gallery-card.evolved:has(.evo-badge.tier-2) {
  border-color: rgba(200, 140, 255, .5);
}

/* Inline tier tag used in the card viewer + pickers */
.evo-tag {
  display: inline-block;
  padding: .04rem .4rem;
  border-radius: 999px;
  font-size: .62rem;
  font-weight: 900;
  letter-spacing: .08em;
  color: #1a1030;
  background: linear-gradient(90deg, #ffe27a, #ffb15c);
  vertical-align: middle;
}
.evo-tag.tier-2 { background: linear-gradient(90deg, #ff9cf0, #b57cff); color: #160a2c; }
.stat-evo { color: #ffd27c; font-weight: 900; }

.cv-card.evolved { box-shadow: 0 0 0 1px rgba(255, 210, 120, .3), 0 24px 70px rgba(0, 0, 0, .5), 0 0 40px rgba(255, 200, 120, .25); }
.cv-card.evolved.tier-2 { box-shadow: 0 0 0 1px rgba(200, 140, 255, .35), 0 24px 70px rgba(0, 0, 0, .5), 0 0 44px rgba(200, 140, 255, .3); }

/* Evolve affordance on the card back */
.evolve-box {
  margin: .5rem 0;
  padding: .6rem .7rem;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: rgba(255, 255, 255, .04);
  display: grid;
  gap: .45rem;
}
.evolve-box.ready {
  border-color: rgba(255, 210, 120, .55);
  background: linear-gradient(180deg, rgba(255, 210, 120, .12), rgba(255, 255, 255, .03));
  box-shadow: 0 0 18px rgba(255, 200, 120, .22);
}
.evolve-box.maxed { text-align: center; color: var(--muted); font-size: .82rem; }
.evolve-head { display: flex; align-items: center; justify-content: space-between; gap: .5rem; }
.evolve-title { font-size: .82rem; color: var(--text); }
.evolve-title strong { color: #ffe6b0; }
.evolve-cost { font-weight: 800; color: #fff; white-space: nowrap; font-size: .82rem; }
.evolve-gauge {
  height: 8px;
  border-radius: 999px;
  background: rgba(255, 255, 255, .08);
  overflow: hidden;
}
.evolve-fill {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: linear-gradient(90deg, #ffe27a, #ff9c70);
  transition: width .35s ease;
}
.cv-evolve { width: 100%; }
.cv-evolve:disabled { opacity: .55; cursor: not-allowed; background: rgba(255, 255, 255, .08); color: var(--muted); }

/* The full-screen evolution cinematic */
.evo-cinematic {
  position: fixed;
  inset: 0;
  z-index: 1200;
  display: grid;
  place-items: center;
  background: radial-gradient(circle at 50% 42%, rgba(10, 16, 30, .82), rgba(3, 5, 12, .96));
  opacity: 0;
  transition: opacity .25s ease;
  backdrop-filter: blur(6px);
}
.evo-cinematic.show { opacity: 1; }
.evo-cinematic.closing { opacity: 0; }
.evo-stage {
  position: relative;
  width: min(560px, 94vw);
  height: min(560px, 80vh);
  display: grid;
  place-items: center;
}
.evo-canvas { width: 100%; height: 100%; display: block; }
.evo-skip {
  position: absolute;
  bottom: .6rem;
  right: .6rem;
  font-size: .8rem;
  padding: .45rem .8rem;
  border-radius: 999px;
  background: rgba(255, 255, 255, .08);
}

@media (prefers-reduced-motion: reduce) {
  .evolve-fill { transition: none; }
  .evo-cinematic { transition: none; }
}

/* ---- Persistent HP: bars, heal controls, wounded badges ---------------- */
.foke-hp {
  display: flex;
  align-items: center;
  gap: .5rem;
  margin: .4rem 0 .2rem;
}
.foke-hp-track {
  flex: 1;
  height: 8px;
  border-radius: 999px;
  background: rgba(255, 255, 255, .12);
  overflow: hidden;
}
.foke-hp-fill {
  height: 100%;
  border-radius: 999px;
  background: linear-gradient(90deg, #7cf0c6, #5bd6a8);
  transition: width .35s ease;
}
.foke-hp.hurt .foke-hp-fill { background: linear-gradient(90deg, #ffe27a, #ffc05a); }
.foke-hp.low .foke-hp-fill { background: linear-gradient(90deg, #ffae5a, #ff5d6e); }
.foke-hp.fainted .foke-hp-fill { background: rgba(255, 93, 110, .85); }
.foke-hp-text {
  font-size: .62rem;
  font-weight: 800;
  letter-spacing: .03em;
  color: rgba(255, 255, 255, .82);
  white-space: nowrap;
}
.foke-hp.low .foke-hp-text,
.foke-hp.fainted .foke-hp-text { color: #ffb3bd; }

.heal-control {
  margin: .35rem 0 .5rem;
  padding: .4rem .5rem;
  border-radius: .6rem;
  background: rgba(255, 255, 255, .05);
  border: 1px solid rgba(255, 255, 255, .08);
}
.heal-label {
  display: block;
  font-size: .58rem;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: rgba(255, 255, 255, .6);
  margin-bottom: .35rem;
}
.heal-food-row {
  display: flex;
  flex-wrap: wrap;
  gap: .35rem;
}
.heal-food {
  font-size: .66rem;
  padding: .25rem .5rem;
  border-radius: 999px;
}
.heal-food.on-type {
  border-color: rgba(124, 240, 198, .55);
  color: #d8fff0;
  background: rgba(124, 240, 198, .12);
}
.heal-hint {
  font-size: .66rem;
  color: rgba(255, 255, 255, .6);
  margin: .35rem 0 .5rem;
}

/* Wounded indicators on collection cards + picker tiles */
.gallery-card.wounded { outline: 1px solid rgba(255, 192, 90, .45); }
.gallery-card.fainted { outline: 1px solid rgba(255, 93, 110, .55); }
.hp-pill {
  position: absolute;
  top: .55rem;
  left: .55rem;
  font-size: .6rem;
  font-weight: 800;
  letter-spacing: .04em;
  padding: .1rem .45rem;
  border-radius: 999px;
  background: rgba(255, 192, 90, .18);
  border: 1px solid rgba(255, 192, 90, .55);
  color: #ffe2b0;
}
.gallery-card.deployed .hp-pill { left: .55rem; right: auto; top: 2rem; }
.hp-pill.fainted {
  background: rgba(255, 93, 110, .18);
  border-color: rgba(255, 93, 110, .6);
  color: #ffb3bd;
}
.picker-card .picker-hp {
  font-weight: 800;
  color: #ffd9a0;
}
.picker-card .picker-hp.low,
.picker-card .picker-hp.fainted { color: #ffb3bd; }
.picker-card.wounded { outline: 1px solid rgba(255, 192, 90, .4); }
.picker-card.low,
.picker-card.fainted { outline: 1px solid rgba(255, 93, 110, .5); }

/* Connection state. Deliberately unmissable but not modal: the game still works
   offline (collection and catching are local), you just can't see anyone else.
   Under GUN there was no such indicator, which is how a total relay outage
   presented as "UberMax raids are broken". */
.net-status {
  position: fixed;
  left: 50%;
  transform: translateX(-50%);
  bottom: calc(env(safe-area-inset-bottom, 0px) + 5.2rem);
  z-index: 60;
  padding: .4rem .8rem;
  border-radius: 999px;
  background: rgba(60, 24, 24, .92);
  border: 1px solid rgba(255, 138, 138, .45);
  color: #ffd9d9;
  font-size: .78rem;
  font-weight: 600;
  white-space: nowrap;
  pointer-events: none;
  backdrop-filter: blur(4px);
}

/* The one variant that is a control, not a caption: tapping it re-runs Sign in
   with Apple. It needs pointer events back, and needs to look pressable. */
.net-status.is-action {
  pointer-events: auto;
  cursor: pointer;
  background: rgba(24, 46, 60, .94);
  border-color: rgba(138, 205, 255, .5);
  color: #d9efff;
}

.net-status.is-action:active {
  transform: translateX(-50%) scale(.96);
}

/* Solo is a deliberate second choice, so it reads as secondary to the Apple
   button above it rather than competing with it. */
.play-solo:not(.hidden) {
  width: 100%;
  margin-top: .7rem;
  padding: .8rem 1rem;
  border-radius: 12px;
  font: 600 .95rem/1 "Outfit", -apple-system, system-ui, sans-serif;
}
