:root{
  --bg:#07070f;
  --bg2:#0d0d1c;
  --cyan:#00f0ff;
  --magenta:#ff2bd6;
  --purple:#8a2bff;
  --gold:#ffd23f;
  --green:#39ff14;
  --text:#e8f6ff;
  --dim:#7d86a8;
  --glass:rgba(14,16,34,.72);
  --stroke:rgba(0,240,255,.25);
  font-family:'Rajdhani',system-ui,-apple-system,sans-serif;
}
*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
html,body{margin:0;height:100%;width:100%;max-width:100%;background:var(--bg);color:var(--text);
  overflow:hidden;overflow-x:hidden;overscroll-behavior:none}
body{user-select:none;position:relative}
h1,h2{font-family:'Orbitron',sans-serif;letter-spacing:.06em;margin:0}

/* ---------- MAP ---------- */
#map{position:fixed;inset:0;z-index:0;background:var(--bg)}
.leaflet-container{background:#05050c}
.leaflet-control-attribution{background:rgba(0,0,0,.5)!important;color:#556!important;font-size:9px}
.leaflet-control-attribution a{color:#7a86b8!important}

/* Neon tooltips (drop / POI labels) — override Leaflet's white bubble */
.leaflet-tooltip{background:var(--glass);color:var(--cyan);border:1px solid var(--stroke);
  border-radius:8px;padding:5px 10px;font-family:'Rajdhani',sans-serif;font-weight:600;
  font-size:12px;letter-spacing:.03em;white-space:nowrap;backdrop-filter:blur(8px);
  box-shadow:0 0 14px rgba(0,240,255,.35);text-shadow:0 0 6px rgba(0,240,255,.45)}
.leaflet-tooltip-top::before{border-top-color:var(--stroke)}
.leaflet-tooltip-bottom::before{border-bottom-color:var(--stroke)}
.leaflet-tooltip-left::before{border-left-color:var(--stroke)}
.leaflet-tooltip-right::before{border-right-color:var(--stroke)}

/* Neon movement trail — glowing ribbon streamed behind the player (fades in map.js) */
.player-trail{color:var(--purple);filter:drop-shadow(0 0 4px currentColor) drop-shadow(0 0 9px currentColor);
  pointer-events:none}

/* Fog of war — canvas veil below markers (positioned/redrawn in map.js) */
.fog-canvas{pointer-events:none}

/* Darken MapTiler's slate background toward near-black to match the neon look; the extra
   contrast keeps the lighter road lines readable (CARTO's fallback tiles are already dark). */
.tiles-maptiler{filter:brightness(.66) contrast(1.2)}
/* OLED road brighten — lift the raster tile roads for outdoor daylight, bg stays dark */
.oled-roads .leaflet-tile-pane{filter:brightness(1.95) contrast(1.12) saturate(1.05)}

/* Player marker — small purple heading arrow inside the (px-sized) drop-collect ring */
.player-heading{position:absolute;left:50%;top:50%;width:26px;height:26px;margin:-13px 0 0 -13px;
  transition:transform .25s ease-out}
/* outline-only neon arrow, tinted to the level-badge border colour */
.player-arrow{width:26px;height:26px;fill:none;stroke:var(--magenta);stroke-width:2;
  stroke-linejoin:round;stroke-linecap:round;
  filter:drop-shadow(0 0 4px var(--magenta)) drop-shadow(0 0 9px var(--magenta))}
/* inner ring = POI pickup radius (dashed + faint fill); outer = drop radius (matches the
   inner's dashed stroke, just fainter + no fill so the two read as one system) */
.player-range-poi{position:absolute;left:50%;top:50%;width:0;height:0;border-radius:50%;
  border:1px dashed rgba(181,107,255,.55);background:rgba(181,107,255,.06);pointer-events:none}
.player-range-drop{position:absolute;left:50%;top:50%;width:0;height:0;border-radius:50%;
  border:1px dashed rgba(181,107,255,.45);background:transparent;pointer-events:none}
@keyframes pulse{0%{transform:scale(.6);opacity:.9}100%{transform:scale(1.9);opacity:0}}

/* Drop markers */
.drop{position:relative;width:30px;height:30px;display:grid;place-items:center;
  font-size:20px;filter:drop-shadow(0 0 6px currentColor);animation:bob 2.4s ease-in-out infinite}
.drop.common{color:var(--cyan)}
.drop.golden{color:var(--gold);animation:bob 2.4s ease-in-out infinite,goldpulse 1.4s ease-in-out infinite}
@keyframes bob{0%,100%{transform:translateY(0)}50%{transform:translateY(-5px)}}
@keyframes goldpulse{0%,100%{filter:drop-shadow(0 0 5px var(--gold))}50%{filter:drop-shadow(0 0 16px var(--gold))}}

/* POI signal nodes — one tappable node per landmark/beacon (collapsed clusters).
   Active nodes glow (gold if holding a prime); recharging nodes dim; beacons stay magenta. */
.poi-node{position:relative;width:38px;height:38px;display:grid;place-items:center;
  font-size:20px;border-radius:50%;cursor:pointer;color:var(--cyan);transition:transform .12s}
.poi-node::before{content:'';position:absolute;inset:3px;border-radius:50%;
  border:1.5px solid currentColor;background:radial-gradient(circle,rgba(0,240,255,.16),transparent 72%)}
.poi-node.active{filter:drop-shadow(0 0 7px currentColor)}
.poi-node.active::after{content:'';position:absolute;inset:-4px;border-radius:50%;
  border:1.5px solid currentColor;opacity:.5;animation:pulse 2.2s ease-out infinite}
.poi-node.golden{color:var(--gold);animation:goldpulse 1.6s ease-in-out infinite}
.poi-node.idle{color:var(--dim);opacity:.7}
.poi-node.idle::before{background:none;border-style:dashed}
.poi-node.beacon{color:var(--magenta)}
.poi-node.beacon.idle{opacity:.55}
.poi-node:active{transform:scale(.88)}
/* Quest-marked POI node — a pulsing gold ring + "!" tag so it stands out on the map */
.poi-node.has-quest{color:var(--gold)}
.poi-node.has-quest::after{content:'';position:absolute;inset:-5px;border-radius:50%;
  border:2px solid var(--gold);opacity:.6;animation:pulse 1.6s ease-out infinite}
.poi-node.has-quest .quest-bang,.poi-node.has-quest::before{}
.quest-bang{position:absolute;top:-6px;right:-6px;width:18px;height:18px;border-radius:50%;
  background:var(--gold);color:#201400;font-size:12px;font-weight:900;font-family:'Orbitron';
  display:grid;place-items:center;box-shadow:0 0 10px var(--gold);z-index:2}

/* Neon POI glyphs (line-art SVG, js/poiIcons.js). stroke=currentColor, so they take
   on the surrounding node's colour + glow. Sized in `em` so the container font-size
   drives the icon size (map node 20px, panel 20px, member row 16px, tooltip 12px). */
.neon-poi{width:1em;height:1em;display:inline-block;vertical-align:-.15em;overflow:visible}
.poi-node .neon-poi{filter:drop-shadow(0 0 3px currentColor)}
.neon-poi.tip-glyph{vertical-align:-.18em;margin-right:1px}

/* ---------- GLASS PANELS ---------- */
.glass{background:var(--glass);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
  border:1px solid var(--stroke)}

/* ---------- HUD ---------- */
#hud{position:fixed;top:0;left:0;right:0;z-index:400;display:flex;justify-content:space-between;
  align-items:center;gap:10px;padding:calc(env(safe-area-inset-top) + 8px) 12px 8px;
  border-left:none;border-right:none;border-top:none}
.hud-left{display:flex;align-items:center;gap:10px;flex:1;min-width:0}
.level-badge{display:flex;flex-direction:column;align-items:center;justify-content:center;
  min-width:46px;height:46px;border-radius:10px;border:1px solid var(--magenta);
  background:rgba(255,43,214,.08);box-shadow:0 0 12px rgba(255,43,214,.4),inset 0 0 12px rgba(255,43,214,.15)}
.lvl-label{font-size:8px;color:var(--magenta);letter-spacing:.15em}
#level-num{font-family:'Orbitron';font-weight:900;font-size:20px;line-height:1;color:#fff;
  text-shadow:0 0 8px var(--magenta)}
.xp-wrap{flex:1;min-width:0}
.xp-bar{height:10px;border-radius:6px;background:rgba(0,240,255,.1);border:1px solid var(--stroke);overflow:hidden}
.xp-fill{height:100%;width:0;border-radius:6px;background:linear-gradient(90deg,var(--cyan),var(--purple));
  box-shadow:0 0 10px var(--cyan);transition:width .5s cubic-bezier(.2,.8,.2,1)}
.xp-text{font-size:10px;color:var(--dim);margin-top:3px;letter-spacing:.05em}
.hud-right{display:flex;flex-direction:column;gap:4px;align-items:flex-end}
.stat{display:flex;align-items:center;gap:5px;font-weight:700;font-size:15px}
.stat-ico{font-size:13px}
.flux{color:var(--gold);text-shadow:0 0 8px rgba(255,210,63,.6)}
.dist{color:var(--cyan);font-size:12px;opacity:.85}

/* ---------- SIDE CONTROLS ---------- */
#side-controls{position:fixed;right:12px;top:50%;transform:translateY(-50%);z-index:390;
  display:flex;flex-direction:column;gap:10px}
.round-btn{width:48px;height:48px;border-radius:50%;background:var(--glass);color:var(--cyan);
  border:1px solid var(--stroke);font-size:18px;font-weight:700;backdrop-filter:blur(10px);
  box-shadow:0 0 10px rgba(0,240,255,.2);cursor:pointer;transition:.15s;
  display:flex;align-items:center;justify-content:center;line-height:1;padding:0}
.round-btn:active{transform:scale(.9);box-shadow:0 0 18px var(--cyan)}
.round-btn.on{background:var(--cyan);color:#001;box-shadow:0 0 22px var(--cyan)}
.round-btn{position:relative}
.btn-svg{width:22px;height:22px;fill:none;stroke:currentColor;stroke-width:1.8;
  stroke-linecap:round;stroke-linejoin:round;display:block;filter:drop-shadow(0 0 4px currentColor)}

/* Signal Beacon control — bottom-left, bigger than the round side buttons and beveled with
   the top-right corner cut (sci-fi tile). Shape/rim via the shared bevel pseudo system. */
/* Layout only. position:fixed + the custom bevel vars live AFTER the shared bevel group
   (search "beacon FAB: fixed") — the group sets position:relative + default bevel vars for
   all its members, and being later in source it would otherwise win over anything set here. */
.beacon-fab{left:12px;bottom:calc(env(safe-area-inset-bottom) + 108px);z-index:390;
  width:56px;height:56px;color:var(--text);cursor:pointer;padding:0;
  display:flex;align-items:center;justify-content:center;line-height:1;transition:transform .15s}
.beacon-fab:active{transform:scale(.92)}
.beacon-fab .btn-svg{width:26px;height:26px}

/* Top bar is tappable to open the Profile panel */
#hud{cursor:pointer}
.level-badge{position:relative}
.quest-count-badge{position:absolute;top:-7px;right:-7px;min-width:18px;height:18px;padding:0 4px;
  border-radius:9px;background:var(--gold);color:#201400;font-family:'Orbitron';font-weight:800;
  font-size:11px;line-height:18px;text-align:center;box-shadow:0 0 10px var(--gold)}
.btn-badge{position:absolute;top:-4px;right:-4px;min-width:18px;height:18px;padding:0 4px;
  border-radius:9px;background:var(--magenta);color:#fff;font-size:11px;font-weight:800;
  line-height:18px;text-align:center;box-shadow:0 0 10px var(--magenta);
  font-family:'Orbitron',sans-serif}

/* ---------- ACTION BAR ---------- */
#action-bar{position:fixed;left:0;right:0;bottom:0;z-index:400;display:flex;gap:8px;
  padding:10px 10px calc(env(safe-area-inset-bottom) + 10px);border-left:none;border-right:none;border-bottom:none}
/* height is LOCKED (not min-height) so the deploy pips↔timer swap can't nudge the bar */
.act-btn{position:relative;flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;
  height:76px;padding:10px 6px;border-radius:12px;background:rgba(255,255,255,.03);color:var(--text);
  border:1px solid rgba(255,255,255,.08);font-weight:700;font-size:11px;letter-spacing:.08em;cursor:pointer;transition:.15s}
.act-btn .act-ico{font-size:20px}
.act-btn:active{transform:translateY(2px)}
.act-btn.primary{flex:1.6;background:linear-gradient(135deg,rgba(0,240,255,.18),rgba(138,43,255,.18));
  border:1px solid var(--cyan);color:#fff;box-shadow:0 0 16px rgba(0,240,255,.4),inset 0 0 18px rgba(0,240,255,.12)}
.act-btn.primary .act-ico{color:var(--cyan);text-shadow:0 0 10px var(--cyan)}
.act-btn.primary.busy{opacity:.6;pointer-events:none}
.act-btn.primary.busy .act-ico{animation:spin 1s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}
.act-btn:disabled{cursor:not-allowed}
.act-btn.primary.depleted{opacity:.5;filter:grayscale(.5);box-shadow:none}

/* Deploy charge pips + cooldown timer */
/* pips and timer share one fixed-height slot (only one shows at a time) so the deploy
   button never changes size when the cooldown timer appears */
.deploy-pips{display:flex;gap:4px;height:14px;align-items:center;justify-content:center}
.deploy-pips i{width:12px;height:6px;border-radius:3px;background:rgba(0,240,255,.18);
  border:1px solid rgba(0,240,255,.35)}
.deploy-pips i.on{background:var(--cyan);box-shadow:0 0 6px var(--cyan)}
.deploy-timer{display:flex;align-items:center;justify-content:center;height:14px;line-height:14px;
  font-family:'Orbitron';font-size:9px;color:var(--gold);letter-spacing:.01em;white-space:nowrap}
.deploy-timer.hidden{display:none!important}

/* Cancel / Confirm split — TAKES OVER the whole action bar while picking a deploy centre.
   Stash + Upgrade step aside (see #action-bar.placing) so the split spans the full width. */
.deploy-split{flex:1;display:flex;gap:8px}
.deploy-split.hidden{display:none!important}
.split-btn{flex:1;height:76px}
#action-bar.placing #btn-inventory,#action-bar.placing #btn-upgrades{display:none}
/* Colour is delivered through the beveled rim/fill system (--rim/--fill/--glow) below;
   these only set the neon icon tint. */
.split-btn.cancel .act-ico{color:var(--magenta);text-shadow:0 0 10px var(--magenta)}
.split-btn.confirm .act-ico{color:var(--green);text-shadow:0 0 10px var(--green)}

/* Deploy target ring — the futuristic range circle drawn where the player taps */
.deploy-ring{stroke-dasharray:9 7;filter:drop-shadow(0 0 5px var(--cyan));
  animation:deploy-dash 1.1s linear infinite}
@keyframes deploy-dash{to{stroke-dashoffset:-32}}
.deploy-center{pointer-events:none}
/* In deploy-placement mode, POIs/drops must not intercept taps — every tap should just move
   the deploy centre. Leaflet sets `pointer-events:auto` DIRECTLY on each interactive marker
   icon (.leaflet-marker-icon.leaflet-interactive), which beats an inherited value from the
   pane — so we must override the icon itself. This 3-class selector outspecs Leaflet's
   2-class rule, so taps fall through the markers to the map. */
.leaflet-container.deploy-placing .leaflet-marker-pane,
.leaflet-container.deploy-placing .leaflet-marker-icon{pointer-events:none}
.deploy-center .dc-core{position:absolute;left:50%;top:50%;width:10px;height:10px;margin:-5px 0 0 -5px;
  border-radius:50%;background:var(--cyan);box-shadow:0 0 10px var(--cyan),0 0 18px var(--cyan)}
.deploy-center .dc-ring{position:absolute;left:50%;top:50%;width:20px;height:20px;margin:-10px 0 0 -10px;
  border-radius:50%;border:2px solid var(--cyan);opacity:.8;animation:dc-pulse 1.4s ease-out infinite}
@keyframes dc-pulse{0%{transform:scale(.5);opacity:.9}100%{transform:scale(1.5);opacity:0}}

/* "AUTO" sub-badge inside the DEPLOY button — taps open the auto-deploy toggle dialog */
.deploy-auto{position:absolute;top:4px;right:5px;font-family:'Orbitron',sans-serif;font-size:8px;
  font-weight:800;letter-spacing:.06em;line-height:1;padding:3px 4px;border-radius:5px;cursor:pointer;
  color:var(--dim);border:1px solid rgba(255,255,255,.18);background:rgba(0,0,0,.3);transition:.15s;z-index:1}
.deploy-auto.on{color:#012;background:var(--cyan);border-color:var(--cyan);box-shadow:0 0 8px rgba(0,240,255,.6)}
.deploy-auto:active{transform:scale(.9)}
.badge{position:absolute;top:-6px;right:-2px;min-width:20px;height:20px;padding:0 5px;border-radius:10px;
  background:var(--magenta);color:#fff;font-size:11px;font-weight:900;display:grid;place-items:center;
  box-shadow:0 0 10px var(--magenta)}

/* ---------- SIM DPAD ---------- */
/* bottom-RIGHT so the debug pad never covers the (left) Signal Beacon button */
#dpad{position:fixed;right:12px;bottom:100px;z-index:390;display:flex;flex-direction:column;align-items:center;gap:6px}
.dpad-mid{display:flex;gap:6px}
.dbtn{width:46px;height:46px;border-radius:10px;background:var(--glass);color:var(--green);
  border:1px solid rgba(57,255,20,.4);font-size:16px;font-weight:700;cursor:pointer;
  box-shadow:0 0 10px rgba(57,255,20,.2);backdrop-filter:blur(8px)}
.dbtn:active{transform:scale(.9);box-shadow:0 0 16px var(--green)}
.dpad-hint{font-size:9px;color:var(--green);opacity:.7;max-width:150px;text-align:center;letter-spacing:.05em}

/* ---------- PANELS ---------- */
#panel-scrim{position:fixed;inset:0;z-index:500;background:rgba(2,2,8,.6);backdrop-filter:blur(2px)}
.panel{position:fixed;left:0;right:0;bottom:0;z-index:510;transform:translateY(110%);
  background:linear-gradient(180deg,var(--bg2),var(--bg));border-top:1px solid var(--stroke);
  border-radius:20px 20px 0 0;box-shadow:0 -8px 40px rgba(0,240,255,.15);
  max-height:82vh;display:flex;flex-direction:column;transition:transform .35s cubic-bezier(.2,.9,.2,1)}
.panel.open{transform:translateY(0)}
.panel-head{display:flex;justify-content:space-between;align-items:center;padding:16px 18px 10px}
.panel-head h2{font-size:18px;color:var(--cyan);text-shadow:0 0 10px rgba(0,240,255,.5)}
.panel-close{background:none;border:none;color:var(--dim);font-size:20px;cursor:pointer}
.panel-body{flex:1 1 auto;min-height:0;padding:6px 18px calc(env(safe-area-inset-bottom) + 20px);
  overflow-y:auto;-webkit-overflow-scrolling:touch;touch-action:pan-y;overscroll-behavior:contain}

/* Stash */
.stash-grid{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin-bottom:16px}
.stash-cell{padding:18px;text-align:center}
.core-vis{width:54px;height:54px;margin:0 auto 10px;border-radius:12px;transform:rotate(45deg)}
.core-vis.common{background:radial-gradient(circle,#0ff,#036);box-shadow:0 0 18px var(--cyan),inset 0 0 12px #fff6}
.core-vis.golden{background:radial-gradient(circle,#fff2b0,#b8860b);box-shadow:0 0 22px var(--gold),inset 0 0 12px #fff}
.stash-count{font-family:'Orbitron';font-weight:900;font-size:30px;line-height:1}
.stash-lbl{font-size:10px;color:var(--dim);letter-spacing:.12em;margin-top:4px}

/* Card album entry button (in stash) */
.cards-btn{margin-top:14px;border-color:var(--magenta);
  background:linear-gradient(135deg,rgba(255,43,214,.18),rgba(138,43,255,.22));
  box-shadow:0 0 16px rgba(255,43,214,.35);font-size:15px}
.cards-badge{font-family:'Rajdhani';font-weight:700;font-size:12px;color:var(--gold);
  margin-left:6px;letter-spacing:.05em}

/* ---------- CARD ALBUM ---------- */
.cards-top{display:flex;justify-content:center;align-items:center;gap:12px;flex-wrap:wrap;margin-bottom:14px}
/* ＋ IMPORT button (opens the floating import window) */
.cards-import-btn{padding:7px 12px;border-radius:9px;font-weight:800;font-size:11px;cursor:pointer;
  color:var(--cyan);background:rgba(0,240,255,.08);border:1px solid var(--cyan);letter-spacing:.04em;transition:.15s}
.cards-import-btn:active{transform:scale(.96)}
/* "pick a set to collect" banner (amber — a nudge, not an error) */
.cards-warning{margin-bottom:12px;padding:10px 14px;border-radius:10px;font-size:12px;font-weight:700;
  line-height:1.45;color:var(--gold);background:rgba(255,210,63,.08);border:1px solid rgba(255,210,63,.5);text-align:center}
/* one-tap finish-the-set button (green — the opportunity state) */
.cards-auto{padding:10px 16px;border-radius:10px;font-weight:800;font-size:12px;cursor:pointer;
  color:#012;background:var(--green);border:1px solid var(--green);letter-spacing:.04em;
  box-shadow:0 0 14px rgba(57,255,20,.5);transition:.15s}
.cards-auto:active{transform:scale(.96)}
/* red/green alert dot on the STASH + CARD-ALBUM buttons */
.card-alert{position:absolute;display:grid;place-items:center;font-weight:900;font-size:12px;
  width:18px;height:18px;border-radius:50%;font-family:'Orbitron',sans-serif;line-height:1;
  animation:cardalertpulse 1.2s ease-in-out infinite}
.card-alert.choose{background:var(--gold);color:#201400;box-shadow:0 0 10px rgba(255,210,63,.85)}
.card-alert.green{background:var(--green);color:#012;box-shadow:0 0 10px rgba(57,255,20,.85)}
@keyframes cardalertpulse{0%,100%{transform:scale(1)}50%{transform:scale(1.16)}}
#stash-alert{top:-6px;left:-2px}
#cards-alert{top:-8px;right:-8px}
.cards-btn{position:relative}
.cards-shards{font-family:'Orbitron';font-weight:700;font-size:18px;color:var(--magenta);
  text-shadow:0 0 12px rgba(255,43,214,.5)}
.cards-shard-lbl{font-family:'Rajdhani';font-size:11px;color:var(--dim);letter-spacing:.12em;margin-left:2px}
.cards-tabs{display:flex;gap:8px;margin-bottom:12px}
/* flex:1 0 auto → tabs grow to fill the row when few, but never shrink below their content,
   so once they can't all fit the row scrolls horizontally instead of squishing (see the
   shared .tab-scroll rule below — applies to any tab bar in the app). */
.cards-tab{flex:1 0 auto;display:flex;align-items:center;justify-content:center;gap:6px;padding:10px 8px;
  border-radius:10px;font-weight:700;font-size:12px;cursor:pointer;color:var(--dim);
  background:rgba(255,255,255,.03);border:1px solid var(--stroke);transition:.15s}
.cards-tab.view{color:var(--cyan);border-color:var(--cyan);background:rgba(0,240,255,.08);
  box-shadow:0 0 12px rgba(0,240,255,.25)}
.cards-tab-ico{font-size:16px}
.cards-tab-dot{color:var(--green);font-size:9px;text-shadow:0 0 6px var(--green)}
.cards-setbar{display:flex;flex-direction:column;gap:10px;margin-bottom:14px}
.cards-progress{text-align:center;font-weight:700;font-size:14px;color:var(--text)}
.cards-progress .gold{color:var(--gold);text-shadow:0 0 8px rgba(255,210,63,.5)}
.cards-bar-actions{display:flex;flex-direction:column;gap:8px;align-items:center}
.cards-collecting{font-family:'Orbitron';font-size:12px;color:var(--green);letter-spacing:.08em;
  text-shadow:0 0 8px rgba(57,255,20,.4)}
.cards-collect-btn{padding:10px 16px;border-radius:10px;font-weight:800;font-size:12px;cursor:pointer;
  color:var(--cyan);background:rgba(0,240,255,.08);border:1px solid var(--cyan);letter-spacing:.05em;transition:.15s}
.cards-collect-btn:active{transform:scale(.96)}
.cards-decon-all{padding:10px 16px;border-radius:10px;font-weight:800;font-size:12px;cursor:pointer;
  color:var(--magenta);background:rgba(255,43,214,.08);border:1px solid var(--magenta);letter-spacing:.04em;transition:.15s}
.cards-decon-all:active{transform:scale(.96)}
.cards-decon-none{font-size:11px;color:var(--dim);letter-spacing:.06em}
/* rarity summary chips in the setbar */
.rar-chips{display:flex;flex-wrap:wrap;justify-content:center;gap:6px}
/* No border — a bordered pill read as a tappable button; these are read-only tallies. */
.rar-chip{--rar:#fff;font-family:'Rajdhani';font-weight:700;font-size:10.5px;letter-spacing:.04em;
  padding:3px 7px;border-radius:6px;color:var(--rar);border:none;background:none}

/* gear (per-set options): sits in the setbar, just left of the ⌕ search toggle */
.cards-row-btns{display:flex;align-items:center;gap:8px;flex:0 0 auto}
.cards-gear{width:34px;height:30px;border-radius:8px;font-size:16px;flex:0 0 auto;
  color:var(--dim);background:rgba(255,255,255,.04);border:1px solid var(--stroke);cursor:pointer;transition:.15s}
.cards-gear.on,.cards-gear:hover{color:var(--cyan);border-color:var(--cyan);background:rgba(0,240,255,.08)}
.cards-gear .btn-svg{width:18px;height:18px}
.cards-gearmenu{display:flex;flex-direction:column;gap:8px;margin-bottom:12px;padding:10px;
  border-radius:12px;background:rgba(255,255,255,.03);border:1px solid var(--stroke)}
.gearmenu-item{padding:9px 12px;border-radius:9px;font-weight:700;font-size:12px;cursor:pointer;text-align:left;
  color:var(--text);background:rgba(255,255,255,.03);border:1px solid var(--stroke);transition:.15s}
.gearmenu-item:active{transform:scale(.98)}
.gearmenu-item.danger{color:#ff7a7a;border-color:rgba(255,80,80,.5);background:rgba(255,60,60,.08)}

/* filter / search: a small toggle button in the shard row + a collapsible panel */
.cards-filter-btn{width:34px;height:30px;border-radius:8px;font-size:16px;line-height:1;cursor:pointer;
  color:var(--dim);background:rgba(255,255,255,.04);border:1px solid var(--stroke);transition:.15s;flex:0 0 auto}
.cards-filter-btn.on,.cards-filter-btn:hover{color:var(--cyan);border-color:var(--cyan);background:rgba(0,240,255,.08)}
.cards-filter{display:flex;flex-direction:column;gap:10px;margin-bottom:14px;padding:12px;
  border-radius:12px;background:rgba(255,255,255,.03);border:1px solid var(--stroke)}
.cards-search{width:100%;padding:9px 12px;border-radius:9px;font-family:'Rajdhani';font-size:14px;font-weight:600;
  color:var(--text);background:rgba(0,0,0,.35);border:1px solid var(--stroke);outline:none}
.cards-search:focus{border-color:var(--cyan)}
.filter-row{display:flex;flex-wrap:wrap;gap:6px}
.filter-pill{--rar:var(--text);padding:5px 11px;border-radius:0;font-weight:700;font-size:11px;cursor:pointer;
  color:var(--rar);background:color-mix(in srgb,var(--rar) 8%,transparent);
  border:1px solid color-mix(in srgb,var(--rar) 35%,transparent);transition:.12s}
.filter-pill.on{background:color-mix(in srgb,var(--rar) 22%,transparent);border-color:var(--rar);
  box-shadow:0 0 8px color-mix(in srgb,var(--rar) 45%,transparent)}
.filter-pill:active{transform:scale(.95)}
.cards-empty{grid-column:1/-1;flex:1;text-align:center;color:var(--dim);font-size:13px;padding:30px 0}

/* import / export buttons (used in the More tab + gear menu) */
.cards-io-btn{padding:10px 12px;border-radius:9px;font-weight:700;font-size:12px;cursor:pointer;letter-spacing:.03em;
  font-family:system-ui,-apple-system,'Segoe UI',Roboto,sans-serif; /* explicit so <a> matches <button> (buttons don't inherit the page font) */
  color:var(--text);background:rgba(255,255,255,.03);border:1px solid var(--stroke);transition:.15s;max-width:100%;
  display:flex;align-items:center;justify-content:center;gap:8px;text-align:center;text-decoration:none;line-height:1.25}
.cards-io-btn:active{transform:scale(.96)}
.cards-io-btn:hover{color:var(--cyan);border-color:var(--cyan)}

/* the More… tab content (import) */
.cards-tab.more{color:var(--dim);border-style:dashed;flex:0 0 auto;min-width:64px}
.cards-tab.more.view{color:var(--cyan);border-color:var(--cyan);border-style:solid}
.cards-more{display:flex;flex-direction:column;gap:12px}
.more-title{font-family:'Orbitron';font-size:14px;letter-spacing:.12em;color:var(--magenta);text-align:center;
  text-shadow:0 0 10px rgba(255,43,214,.4)}
/* "Back" from the community pane to the import pane (top-left, clears the ✕ at top-right) */
.more-back{align-self:flex-start;margin:-4px 0 -2px;padding:4px 10px 4px 4px;font-family:'Orbitron';
  font-size:11px;letter-spacing:.06em;color:var(--cyan);background:none;border:none;cursor:pointer}
.more-back:active{transform:scale(.95)}
.more-desc{font-size:12.5px;line-height:1.5;color:var(--dim);text-align:center;margin:0}
/* one full-width IO button per row */
.more-actions{display:flex;flex-direction:column;gap:10px}
.more-sets{margin-top:8px;display:flex;flex-direction:column;gap:6px}
.more-h{font-family:'Orbitron';font-size:10px;letter-spacing:.14em;color:var(--dim)}
.more-set{display:flex;justify-content:space-between;align-items:center;padding:9px 12px;border-radius:9px;
  font-weight:700;font-size:13px;color:var(--text);background:rgba(255,255,255,.03);border:1px solid var(--stroke)}
.more-set-n{font-size:11px;color:var(--dim);font-weight:600}
.more-empty{text-align:center;color:var(--dim);font-size:12px;padding:8px}
/* legal / safety notice on the import window — plain-language, not an error */
.more-warning{margin:2px 0;padding:10px 12px;border-radius:10px;font-size:11px;line-height:1.5;
  color:var(--gold);background:rgba(255,210,63,.06);border:1px solid rgba(255,210,63,.4)}
.more-warning b{color:#fff2c8}
/* community sub-window list rows */
.more-search{margin-top:2px}
#community-search{border-radius:0}
/* live status line while sources are being scanned (spinner + progress) */
.community-status{display:flex;align-items:center;gap:9px;min-height:18px;font-size:11.5px;color:var(--dim);letter-spacing:.02em}
.community-status:empty{display:none}
.community-status.err{color:#ff9a9a}
.community-status .community-prog b{color:var(--cyan)}
.community-spin{position:relative;width:16px;height:16px;flex:0 0 auto}
.community-spin i{position:absolute;inset:0;border-radius:50%;border:1.5px solid transparent}
.community-spin i:nth-child(1){border-top-color:var(--cyan);box-shadow:0 0 6px rgba(0,240,255,.4);animation:spin 1s linear infinite}
.community-spin i:nth-child(2){inset:3px;border-top-color:var(--magenta);animation:spin 1.5s linear infinite reverse}
.community-spin i:nth-child(3){inset:6px;border-top-color:var(--purple);animation:spin .8s linear infinite}
/* community row: fixed-width icon · stacked name + "By: author • N cards" · action button */
.more-set.community{gap:10px}
.more-set-ico{font-size:16px;line-height:1;flex:0 0 auto;width:22px;text-align:center}
.more-set-main{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:2px}
.more-set-name{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.more-set-sub{font-size:11px;color:var(--dim);font-weight:600;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.more-set-count{color:var(--cyan)}
/* floating import window (the community browser is a swapped-in pane inside the same window) */
#cards-import-overlay{position:fixed;inset:0;z-index:986;display:flex;align-items:center;justify-content:center;
  background:rgba(3,3,10,.82);backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);padding:20px;animation:decryptin .2s ease}
.import-box{position:relative;width:100%;max-width:380px;max-height:86vh;overflow:auto;
  padding:22px 20px 20px;border-radius:16px;background:linear-gradient(180deg,var(--bg2),var(--bg));border:1px solid var(--magenta);
  box-shadow:0 0 34px rgba(255,43,214,.35)}
.import-close{position:absolute;top:8px;right:8px;width:32px;height:32px;border-radius:50%;font-size:15px;
  color:var(--text);background:rgba(255,255,255,.06);border:1px solid var(--stroke);cursor:pointer}

/* ---------- HOW-TO-PLAY TUTORIAL ---------- */
#tutorial-overlay{position:fixed;inset:0;z-index:988;display:flex;align-items:center;justify-content:center;
  background:rgba(3,3,10,.86);backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);padding:20px;animation:decryptin .2s ease}
.tut-box{position:relative;width:100%;max-width:400px;max-height:88vh;display:flex;flex-direction:column;
  padding:22px 20px 18px;border-radius:16px;background:linear-gradient(180deg,var(--bg2),var(--bg));
  border:1px solid var(--cyan);box-shadow:0 0 34px rgba(0,240,255,.28)}
.tut-body{overflow:auto;flex:1 1 auto}
.tut-page-title{font-family:'Orbitron';font-size:15px;letter-spacing:.12em;color:var(--cyan);text-align:center;
  text-shadow:0 0 10px rgba(0,240,255,.4)}
.tut-page-intro{font-size:12.5px;line-height:1.5;color:var(--dim);text-align:center;margin:6px 4px 14px}
/* left/top padding so the step-number badge's negative offset isn't clipped by tut-body's overflow */
.tut-steps{display:flex;flex-direction:column;gap:12px;padding:8px 2px 2px 10px}
.tut-step{display:flex;align-items:center;gap:13px}
.tut-ico{position:relative;flex:0 0 auto;width:46px;height:46px;border-radius:12px;display:flex;align-items:center;
  justify-content:center;color:var(--cyan);background:rgba(0,240,255,.07);border:1px solid rgba(0,240,255,.35)}
.tut-glyph{width:26px;height:26px;filter:drop-shadow(0 0 5px rgba(0,240,255,.5))}
.tut-num{position:absolute;z-index:2;top:-7px;left:-7px;width:19px;height:19px;border-radius:50%;font-family:'Orbitron',sans-serif;
  font-weight:800;font-size:10px;line-height:19px;text-align:center;color:#001; background:var(--cyan);box-shadow:0 0 8px var(--cyan)}
.tut-text{display:flex;flex-direction:column;gap:2px;min-width:0}
.tut-text b{font-size:13.5px;letter-spacing:.02em;color:var(--text)}
.tut-text span{font-size:12px;line-height:1.45;color:var(--dim)}
.tut-nav{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-top:16px;padding-top:14px;
  border-top:1px solid var(--stroke)}
.tut-btn{padding:9px 16px;border-radius:9px;font-family:'Orbitron',sans-serif;font-weight:700;font-size:12px;
  letter-spacing:.05em;cursor:pointer;color:var(--dim);background:rgba(255,255,255,.04);border:1px solid var(--stroke)}
.tut-btn.primary{color:#001;background:var(--cyan);border-color:var(--cyan);box-shadow:0 0 14px rgba(0,240,255,.4)}
.tut-btn:active{transform:scale(.95)}
.tut-btn.tut-hidden{visibility:hidden}
.tut-dots{display:flex;gap:7px}
.tut-dot{width:9px;height:9px;border-radius:50%;cursor:pointer;padding:0;background:rgba(255,255,255,.15);border:none}
.tut-dot.on{background:var(--cyan);box-shadow:0 0 8px var(--cyan)}
/* Stop-collecting button in Settings */
.set-btn{padding:8px 14px;border-radius:9px;font-weight:800;font-size:11px;letter-spacing:.05em;cursor:pointer;
  font-family:system-ui,-apple-system,'Segoe UI',Roboto,sans-serif; /* explicit so the <a> coffee button matches the <button> ones */
  color:var(--magenta);background:rgba(255,43,214,.08);border:1px solid var(--magenta);transition:.15s;white-space:nowrap;
  display:inline-block;text-decoration:none;text-align:center}
.set-btn:active{transform:scale(.95)}
.set-btn:disabled{opacity:.35;color:var(--dim);border-color:var(--dim);background:none;cursor:not-allowed}
.set-btn.danger{color:#ff7a7a;border-color:rgba(255,80,80,.5);background:rgba(255,60,60,.08)}
/* Settings sub-heading (e.g. Account transfer) */
.set-section-title{margin:18px 0 4px;font-weight:800;font-size:11px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--cyan);opacity:.85;border-top:1px solid var(--stroke);padding-top:14px}

/* image attribution line in the card detail overlay */
.cd-credit{margin-top:12px;padding-top:10px;border-top:1px solid var(--stroke);font-size:11px;color:var(--dim);line-height:1.4}
.cd-credit a{color:var(--cyan);text-decoration:none}

/* ---------- NEON KEYCARDS (fully proportional — everything is sized in cqw, 1% of the
   card's own width, so the whole card scales as one at any size) ---------- */
/* Flex grid: fixed-ish card width → ~3 per row on phones, many more on desktop. */
.cards-grid{display:flex;flex-wrap:wrap;gap:10px;justify-content:center;
  --card-w:min(120px,calc((100% - 20px) / 3))}
/* the angular "security key" silhouette, shared by frame + inner (as a var) */
.pcard{--rar:#fff;--rar-glow:rgba(255,255,255,.4);--bev:9cqw;--notch:5cqw;--rim:2.4cqw;
  --artbev:7cqw;--artrim:.85cqw;
  --key:polygon(var(--bev) 0, 38% 0, 40% var(--notch), 60% var(--notch), 62% 0, 100% 0,
    100% calc(100% - var(--bev)), calc(100% - var(--bev)) 100%, 0 100%, 0 var(--bev));
  --art:polygon(0 0, 100% 0, 100% calc(100% - var(--artbev)), calc(100% - var(--artbev)) 100%, 0 100%);
  container-type:inline-size;position:relative;flex:0 0 var(--card-w);width:var(--card-w);
  padding:0;border:none;background:none;cursor:pointer;-webkit-tap-highlight-color:transparent;
  transition:transform .12s ease;font:inherit}
.pcard:active{transform:scale(.95)}
/* outer = the neon rim colour; inner (inset by --rim) = the dark body, same clip → even edge */
.pcard-frame{display:block;position:relative;aspect-ratio:3/4.35;clip-path:var(--key);
  background:linear-gradient(150deg,var(--rar),color-mix(in srgb,var(--rar) 42%,#20202c));
  filter:drop-shadow(0 0 2.4cqw color-mix(in srgb,var(--rar-glow) 75%,transparent))}
.pcard.locked .pcard-frame{background:linear-gradient(150deg,color-mix(in srgb,var(--rar) 45%,#2a2a36),#26262f);filter:none}
.pcard-inner{display:flex;flex-direction:column;position:absolute;inset:var(--rim);clip-path:var(--key);
  background:linear-gradient(162deg,color-mix(in srgb,var(--rar) 13%,#0a0a12),#06060c 72%);
  padding:5cqw 5cqw 5.5cqw}
.pcard.locked .pcard-inner{background:#0b0b12}
.pcard-rarity{font-family:'Orbitron',sans-serif;font-weight:700;font-size:5.6cqw;letter-spacing:1cqw;
  text-align:center;color:var(--rar);text-shadow:0 0 2cqw var(--rar-glow);text-transform:uppercase;
  padding-bottom:3cqw;margin-bottom:2.6cqw;border-bottom:.4cqw solid color-mix(in srgb,var(--rar) 40%,transparent)}
.pcard.locked .pcard-rarity{color:color-mix(in srgb,var(--rar) 75%,#8890a0);text-shadow:none}
/* art window: a bevelled bottom-right corner echoes the frame. The window itself is the
   neon rim colour; the image / placeholder sit inset by --artrim and re-clip to the SAME
   bevel, so a neon border rings the art on every side — collected OR uncollected — and
   traces the diagonal cut corner instead of being sliced flat there. */
.pcard-art{position:relative;flex:1;overflow:hidden;clip-path:var(--art);
  background:linear-gradient(150deg,var(--rar),color-mix(in srgb,var(--rar) 45%,#20202c));
  filter:drop-shadow(0 0 1.2cqw color-mix(in srgb,var(--rar-glow) 55%,transparent))}
.pcard.locked .pcard-art{background:color-mix(in srgb,var(--rar) 48%,#2a2a36);filter:none}
/* explicit width/height (not just inset) — a replaced <img> with only inset set would size
   to its intrinsic pixels, so we size the inset box directly for both img and placeholder */
.pcard-img,.pcard-temp{position:absolute;top:var(--artrim);left:var(--artrim);
  width:calc(100% - 2 * var(--artrim));height:calc(100% - 2 * var(--artrim));clip-path:var(--art)}
.pcard-img{object-fit:cover;display:block;
  background:radial-gradient(circle at 50% 35%,color-mix(in srgb,var(--rar) 20%,#0d0d16),#070710 78%)}
.pcard-temp{display:grid;place-items:center;background:
  repeating-linear-gradient(45deg,color-mix(in srgb,var(--rar) 10%,transparent) 0 3cqw,transparent 3cqw 6cqw),
  repeating-linear-gradient(-45deg,rgba(255,255,255,.03) 0 3cqw,transparent 3cqw 6cqw),
  radial-gradient(circle at 50% 35%,color-mix(in srgb,var(--rar) 20%,#0d0d16),#070710 78%)}
/* rarity-tinted scan beam over the art (detail view only); JS pulses it every 6–12 s */
.pcard-scan{position:absolute;left:0;right:0;top:-28%;height:26%;z-index:2;pointer-events:none;opacity:0;
  background:linear-gradient(to bottom,transparent,color-mix(in srgb,var(--rar) 45%,transparent) 55%,
    var(--rar) 74%,color-mix(in srgb,var(--rar) 45%,transparent) 90%,transparent);
  mix-blend-mode:screen;filter:drop-shadow(0 0 4px var(--rar-glow))}
.pcard-scan.scanning{animation:pcard-scan 2s ease-in-out}
/* Sweeps down (brightest edge trailing at the bottom), then scaleY(-1) flips the gradient at
   the turnaround so the bright edge leads on the way back up. The flip interpolates while the
   beam is parked off-screen at the bottom (46%→54%), so it isn't visible. */
@keyframes pcard-scan{
  0%{top:-28%;opacity:0;transform:scaleY(1)} 10%{opacity:.95} 46%{top:100%;opacity:.95;transform:scaleY(1)}
  54%{top:100%;opacity:.8;transform:scaleY(-1)} 90%{opacity:.95} 100%{top:-28%;opacity:0;transform:scaleY(-1)}}
.pcard-temp-tag{font-family:'Orbitron',sans-serif;font-size:4.6cqw;letter-spacing:2cqw;font-weight:700;
  color:color-mix(in srgb,var(--rar) 80%,#fff);opacity:.55;border:.4cqw solid color-mix(in srgb,var(--rar) 40%,transparent);padding:1cqw 2.4cqw}
.pcard-lock{font-size:12cqw;opacity:.5}
/* the "chip" contact pad, top-left of the art (hidden until the card is owned) */
.pcard-chip{position:absolute;top:4cqw;left:4cqw;width:14cqw;height:9cqw;
  background:linear-gradient(135deg,color-mix(in srgb,var(--rar) 75%,#fff),color-mix(in srgb,var(--rar) 25%,#000));
  box-shadow:0 0 3cqw var(--rar-glow),inset 0 0 0 .5cqw rgba(0,0,0,.45);opacity:.92}
.pcard-chip::before{content:'';position:absolute;inset:2cqw;border-left:.5cqw solid rgba(0,0,0,.5);border-right:.5cqw solid rgba(0,0,0,.5)}
.pcard.locked .pcard-chip,.pcard.locked .pcard-hole{display:none}
.pcard-name{font-family:'Rajdhani',sans-serif;font-weight:700;font-size:7.8cqw;line-height:1.1;text-align:center;
  color:var(--text);padding-top:4cqw;min-height:17cqw;display:flex;align-items:center;justify-content:center;overflow:hidden}
.pcard.locked .pcard-name{color:var(--dim)}
/* rivet "holes" in the two square corners */
.pcard-hole{position:absolute;width:3.4cqw;height:3.4cqw;border-radius:50%;background:#04040a;
  box-shadow:inset 0 0 0 .5cqw color-mix(in srgb,var(--rar) 55%,transparent)}
.pcard-hole.h1{top:2.6cqw;right:3cqw}
.pcard-hole.h2{bottom:2.6cqw;left:3cqw}
.pcard-count{position:absolute;top:-1.5cqw;right:-1.5cqw;font-family:'Orbitron',sans-serif;font-weight:800;font-size:7cqw;
  color:#06060c;background:var(--rar);padding:1cqw 3cqw;line-height:1;
  clip-path:polygon(14% 0,100% 0,86% 100%,0 100%);box-shadow:0 0 3cqw var(--rar-glow)}
/* "NEW" flag, top-left — a slanted green tag scaling with the card (cqw), sibling of the
   frame so the card's clip-path doesn't cut it. Shown until the album is opened. */
.pcard-new{position:absolute;top:-1.5cqw;left:-1.5cqw;z-index:3;font-family:'Orbitron',sans-serif;font-weight:800;
  font-size:6cqw;letter-spacing:.5cqw;color:#06120c;background:var(--green);padding:1.2cqw 3cqw;line-height:1;
  clip-path:polygon(0 0,100% 0,86% 100%,14% 100%);box-shadow:0 0 4cqw rgba(57,255,20,.7)}

/* ---------- CARD DETAIL OVERLAY ---------- */
#card-detail{position:fixed;inset:0;z-index:980;display:flex;align-items:center;justify-content:center;
  background:rgba(3,3,8,.9);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);padding:20px}
.cd-stage{display:flex;flex-direction:column;align-items:center;gap:14px;width:100%;max-width:340px;
  max-height:100%;position:relative;perspective:800px}
.cd-close{position:absolute;top:-6px;right:-6px;z-index:2;width:34px;height:34px;border-radius:50%;
  font-size:16px;color:var(--text);background:rgba(255,255,255,.06);border:1px solid var(--stroke);cursor:pointer}
.cd-card-wrap{width:210px;max-width:66vw;flex:0 0 auto;
  transform-style:preserve-3d;will-change:transform;touch-action:none;cursor:grab}
.cd-card-wrap.grabbing{cursor:grabbing}
.cd-card-wrap .pcard.big{width:100%;flex:none;cursor:default}
.cd-card-wrap .pcard.big:active{transform:none}
.cd-flavor{width:100%;overflow-y:auto;overscroll-behavior:contain;-webkit-overflow-scrolling:touch;
  background:rgba(255,255,255,.03);border:1px solid var(--stroke);border-radius:12px;padding:14px 16px}
.cd-title{--rar:#fff;font-family:'Orbitron',sans-serif;font-weight:700;font-size:15px;color:var(--text);
  display:flex;flex-wrap:wrap;align-items:baseline;gap:8px;margin-bottom:8px}
.cd-rar{font-family:'Rajdhani';font-size:11px;font-weight:700;letter-spacing:.1em;color:var(--rar);
  text-shadow:0 0 8px color-mix(in srgb,var(--rar) 60%,transparent)}
.cd-owned{font-size:11px;color:var(--gold);font-weight:700;margin-bottom:8px}
.cd-lore{font-size:13.5px;line-height:1.6;color:var(--soft,#c8cede);margin:0}
.cd-actions{display:flex;gap:10px;min-height:0}
.cd-actions.empty{display:none}
.cd-act{padding:11px 20px;border-radius:11px;font-weight:800;font-size:12px;cursor:pointer;letter-spacing:.04em;transition:.15s}
.cd-act:active{transform:scale(.96)}
.cd-act.craft{color:var(--cyan);background:rgba(0,240,255,.1);border:1px solid var(--cyan)}
.cd-act.craft:disabled{opacity:.35;border-color:var(--dim);color:var(--dim);background:none;cursor:not-allowed}
.cd-act.decon{color:var(--magenta);background:rgba(255,43,214,.1);border:1px solid var(--magenta)}
/* breaking the LAST copy removes the card — flag it as destructive (warm/red), not routine */
.cd-act.decon.last{color:#ff9a6a;background:rgba(255,110,60,.1);border-color:#ff8a5a}

/* Upgrades */
.upg-flux{text-align:center;margin-bottom:14px;color:var(--gold);font-weight:700;font-size:16px}
.upgrade-list{display:flex;flex-direction:column;gap:10px}
.upg{display:flex;align-items:center;gap:12px;padding:12px 14px;border-radius:12px;
  background:rgba(255,255,255,.03);border:1px solid rgba(255,255,255,.08)}
.upg-ico{font-size:24px;width:34px;text-align:center;color:var(--purple);text-shadow:0 0 8px var(--purple)}
.upg-info{flex:1;min-width:0}
.upg-name{font-weight:700;font-size:14px;display:flex;align-items:center;gap:8px}
.upg-lvl{font-size:10px;color:var(--cyan);border:1px solid var(--stroke);border-radius:8px;padding:1px 6px}
.upg-desc{font-size:11px;color:var(--dim);margin-top:2px}
.upg-buy{padding:9px 12px;border-radius:10px;font-weight:800;font-size:12px;cursor:pointer;
  background:linear-gradient(135deg,rgba(255,210,63,.15),rgba(255,43,214,.15));
  border:1px solid var(--gold);color:var(--gold);white-space:nowrap;transition:.15s}
.upg-buy:active{transform:scale(.94)}
.upg-buy:disabled{opacity:.35;border-color:var(--dim);color:var(--dim);background:none;cursor:not-allowed}
.upg-buy.maxed{opacity:.5;border-color:var(--green);color:var(--green)}
.upg.locked{opacity:.6}
.upg.locked .upg-ico{color:var(--dim);text-shadow:none}
.upg-lock{color:var(--gold)}
.upg-buy.locked{opacity:.6;border-color:var(--dim);color:var(--dim);background:none}

/* Admin / debug */
.admin-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.admin-btn{padding:14px 10px;border-radius:12px;font-weight:700;font-size:13px;cursor:pointer;
  color:var(--text);background:rgba(255,255,255,.04);border:1px solid var(--stroke);transition:.15s}
.admin-btn:active{transform:scale(.96);box-shadow:0 0 12px rgba(0,240,255,.3)}
.admin-btn.danger{grid-column:1/-1;color:var(--magenta);border-color:var(--magenta);
  background:rgba(255,43,214,.08)}
.admin-btn.exit{grid-column:1/-1;color:var(--green);border-color:var(--green);
  background:rgba(57,255,20,.07)}
.admin-note{margin-top:14px;text-align:center;font-size:10px;color:var(--dim);letter-spacing:.08em}

/* Signal Beacons */
.beacon-summary{margin-bottom:14px;display:flex;flex-direction:column;gap:8px}
.beacon-stat{display:flex;justify-content:space-between;align-items:center;padding:10px 14px;
  border-radius:10px;background:rgba(255,255,255,.03);border:1px solid rgba(255,255,255,.08);
  font-weight:700;font-size:14px}
.beacon-stat .gold{color:var(--gold);text-shadow:0 0 8px rgba(255,210,63,.5)}
.beacon-note{font-size:11px;color:var(--dim);line-height:1.5;padding:2px 2px}
.beacon-note b{color:var(--cyan)}
.beacon-note b.gold{color:var(--gold)}
.beacon-hint{text-align:center;font-size:11px;color:var(--magenta);margin-top:8px;min-height:14px;letter-spacing:.03em}
.beacon-list{display:flex;flex-direction:column;gap:10px;margin-top:16px}
.beacon-row{display:flex;align-items:center;gap:12px;padding:12px 14px;border-radius:12px;
  background:rgba(255,255,255,.03);border:1px solid rgba(255,255,255,.08)}
.beacon-ico{font-size:22px;color:var(--magenta);text-shadow:0 0 8px var(--magenta);width:26px;text-align:center}
.beacon-row .b-info{flex:1;min-width:0}
.beacon-row .b-name{font-weight:700;font-size:14px}
.beacon-row .b-meta{font-size:11px;color:var(--dim);margin-top:2px}
.beacon-remove{padding:8px 12px;border-radius:10px;font-weight:800;font-size:11px;cursor:pointer;
  color:var(--magenta);background:rgba(255,43,214,.08);border:1px solid var(--magenta);white-space:nowrap;transition:.15s}
.beacon-remove:active{transform:scale(.94)}
.beacon-remove:disabled{color:var(--dim);background:rgba(255,255,255,.03);border-color:var(--stroke);
  cursor:not-allowed;opacity:.6}
.beacon-row .b-meta.active{color:var(--green)}

/* ---------- POI INFO WINDOW ---------- */
.poi-type{font-family:'Orbitron';font-size:16px;color:var(--cyan);text-align:center;
  margin:2px 0 4px;text-shadow:0 0 10px rgba(0,240,255,.4)}
.poi-type.beacon{color:var(--magenta);text-shadow:0 0 10px rgba(255,43,214,.4)}
.poi-type-icon{margin-right:7px;font-size:20px;vertical-align:-2px;
  filter:drop-shadow(0 0 6px rgba(0,240,255,.35))}
.poi-type.beacon .poi-type-icon{filter:drop-shadow(0 0 6px rgba(255,43,214,.4))}

/* combined-members ("+N places") expander */
.poi-combined-toggle{display:block;width:100%;margin-top:14px;padding:9px 12px;
  background:rgba(255,255,255,.04);border:1px solid var(--stroke);border-radius:10px;
  color:var(--dim);font-family:'Orbitron';font-size:11px;letter-spacing:.06em;
  text-align:center;cursor:pointer;transition:background .15s,color .15s}
.poi-combined-toggle:hover{background:rgba(0,240,255,.07);color:var(--cyan)}
.poi-caret{display:inline-block;margin-right:6px;color:var(--cyan)}
.poi-members{list-style:none;margin:8px 0 0;padding:0;
  max-height:190px;overflow-y:auto;border:1px solid var(--stroke);border-radius:10px}
.poi-members.hidden{display:none}
.poi-members li{display:flex;align-items:center;gap:10px;padding:9px 12px;
  font-size:13px;color:#d6e6ea;border-bottom:1px solid rgba(255,255,255,.05)}
.poi-members li:last-child{border-bottom:none}
.poi-mem-icon{font-size:16px;width:20px;text-align:center;flex:none}
.poi-mem-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.poi-dist{text-align:center;font-size:12px;color:var(--dim);margin-bottom:16px}
.poi-badge{display:block;text-align:center;font-family:'Orbitron';font-size:13px;
  letter-spacing:.1em;padding:9px;border-radius:10px;margin-bottom:16px;border:1px solid}
.poi-badge.active{color:var(--green);border-color:var(--green);box-shadow:0 0 14px rgba(57,255,20,.28)}
.poi-badge.cooldown{color:var(--gold);border-color:var(--gold)}
.poi-badge.charging{color:var(--cyan);border-color:var(--stroke)}
/* quest node: plain gold status label + a reroll control (the only tappable thing here) */
.poi-quest{display:flex;flex-direction:column;align-items:center;gap:9px;margin-bottom:16px}
.poi-quest-tag{font-family:'Orbitron';font-size:13px;letter-spacing:.1em;color:var(--gold);
  text-shadow:0 0 10px rgba(255,210,63,.4)}
.poi-loot{display:flex;justify-content:center;gap:26px;margin-bottom:14px}
.poi-cell{text-align:center}
.poi-cell .core-vis{width:46px;height:46px;margin:0 auto 14px}
.poi-cell-n{font-family:'Orbitron';font-size:18px;color:#fff}
.poi-cell-lbl{font-size:10px;color:var(--dim);letter-spacing:.1em;margin-top:2px}
.poi-flux{text-align:center;font-size:14px;color:var(--dim);margin-bottom:14px}
.poi-flux b{color:var(--gold);text-shadow:0 0 8px rgba(255,210,63,.5)}
.poi-timer{text-align:center;font-family:'Orbitron';font-size:34px;color:var(--gold);
  text-shadow:0 0 14px rgba(255,210,63,.5);margin-bottom:12px}
.poi-cd-bar{height:8px;border-radius:6px;background:rgba(255,255,255,.08);overflow:hidden;
  margin-bottom:16px;border:1px solid var(--stroke)}
.poi-cd-fill{height:100%;background:linear-gradient(90deg,var(--gold),var(--magenta));
  box-shadow:0 0 10px var(--gold);transition:width 1s linear}
.poi-note{font-size:12px;color:var(--dim);line-height:1.5;text-align:center;padding:0 6px}

/* Buttons */
.wide-btn{width:100%;padding:16px;border-radius:14px;font-family:'Orbitron';font-weight:700;
  font-size:16px;letter-spacing:.08em;cursor:pointer;color:#fff;border:1px solid var(--cyan);
  background:linear-gradient(135deg,rgba(0,240,255,.2),rgba(138,43,255,.25));
  box-shadow:0 0 18px rgba(0,240,255,.4);transition:.15s}
.wide-btn:active{transform:scale(.98)}
.wide-btn:disabled{opacity:.4;box-shadow:none;cursor:not-allowed}

/* ---------- DAILY WALK QUEST BAR (under XP) ---------- */
/* min-height:0 so the (26px) claim button OVERFLOWS this thin row instead of stretching
   it — that stops the whole xp block from being pushed up in the HUD */
.quest-wrap{position:relative;display:flex;align-items:center;margin-top:6px;min-height:0}
/* stop the bar ~2px into the claim button (26px wide at right:0) so barely any progress
   is hidden behind it, while still overlapping by a pixel or two */
.quest-bar{flex:1;height:6px;margin-right:24px;border-radius:4px;background:rgba(57,255,20,.1);
  border:1px solid rgba(57,255,20,.3);overflow:hidden;transition:margin-right .3s ease}
/* claim button is hidden once claimed → let the bar reclaim the full width */
.quest-wrap.claimed .quest-bar{margin-right:0}
.quest-fill{height:100%;width:0;border-radius:4px;background:linear-gradient(90deg,var(--green),var(--gold));
  box-shadow:0 0 8px rgba(57,255,20,.6);transition:width .5s ease}
/* claim sits at the end of the bar, overlapping it slightly; centred SVG star */
.quest-claim{position:absolute;right:0;top:50%;transform:translateY(-50%);width:26px;height:26px;
  border-radius:50%;border:1px solid var(--gold);background:var(--gold);color:#201400;
  display:grid;place-items:center;padding:0;cursor:pointer;box-shadow:0 0 10px var(--gold)}
.quest-claim svg{width:15px;height:15px;fill:currentColor;display:block}
.quest-claim.ready{animation:questpulse 1s ease-in-out infinite}
.quest-claim:disabled{background:#20222e;color:var(--dim);border-color:var(--stroke);
  box-shadow:none;animation:none;cursor:default}
/* keeps translateY(-50%) baseline so the button stays vertically centred while it pulses */
@keyframes questpulse{
  0%,100%{box-shadow:0 0 8px var(--gold);transform:translateY(-50%) scale(1)}
  50%{box-shadow:0 0 24px var(--gold);transform:translateY(-50%) scale(1.16)}}

/* ---------- PROFILE PANEL ---------- */
.prof-tabs{display:flex;gap:6px;margin-bottom:14px}
.prof-tab{flex:1 0 auto;padding:9px 12px;border-radius:9px;font-weight:700;font-size:11px;letter-spacing:.03em;
  cursor:pointer;color:var(--dim);background:rgba(255,255,255,.03);border:1px solid var(--stroke);transition:.15s}
.prof-tab.on{color:var(--cyan);border-color:var(--cyan);background:rgba(0,240,255,.08);box-shadow:0 0 12px rgba(0,240,255,.25)}

/* ---------- SHARED TAB-BAR OVERFLOW ---------- */
/* Any tab bar: fit the tabs when they all fit (their flex:1 0 auto lets them grow), else let
   the row scroll horizontally rather than squeezing tabs to nothing. Vertical padding gives
   the bevel glow a little room since overflow-x:auto clips the cross axis. Scrollbar hidden. */
.cards-tabs,.prof-tabs{flex-wrap:nowrap;overflow-x:auto;overflow-y:hidden;padding-top:9px;padding-bottom:4px;
  -webkit-overflow-scrolling:touch;scrollbar-width:none}
.cards-tabs::-webkit-scrollbar,.prof-tabs::-webkit-scrollbar{display:none}

.prof-content{display:flex;flex-direction:column;gap:12px}
.prof-empty{text-align:center;color:var(--dim);font-size:13px;padding:24px 8px;line-height:1.6}
.prof-section-title{font-family:'Orbitron';font-size:12px;letter-spacing:.14em;color:var(--dim);
  margin:6px 2px 2px;text-transform:uppercase}

/* stat strip */
.prof-stats{display:grid;grid-template-columns:1fr 1fr 1fr;gap:10px;margin-bottom:6px}
.prof-stat{padding:12px 8px;text-align:center}
.prof-stat b{display:block;font-family:'Orbitron';font-size:19px;color:var(--cyan)}
.prof-stat span{font-size:9px;color:var(--dim);letter-spacing:.1em}

/* quests */
.quest-hero{padding:12px 14px;border-radius:12px;background:linear-gradient(135deg,rgba(57,255,20,.08),rgba(255,210,63,.08));
  border:1px solid rgba(57,255,20,.4)}
.quest-hero.done{opacity:.85;border-color:rgba(255,210,63,.45)}
.quest-hero .qh-top{display:flex;justify-content:space-between;align-items:center;font-weight:700;font-size:13px}
.quest-hero .qh-tick{color:var(--gold);text-shadow:0 0 8px var(--gold);margin-left:2px}
.quest-hero .qh-bar{height:8px;border-radius:5px;background:rgba(255,255,255,.08);overflow:hidden;margin-top:8px;border:1px solid var(--stroke)}
.quest-hero .qh-fill{height:100%;background:linear-gradient(90deg,var(--green),var(--gold));box-shadow:0 0 8px var(--green)}
.quest-hero .qh-reward{font-size:11px;color:var(--gold);margin-top:6px;letter-spacing:.04em}
.quest-claim-wide{margin-top:10px;width:100%;padding:11px;border-radius:10px;font-weight:800;font-size:13px;
  cursor:pointer;color:#201400;background:var(--gold);border:none;box-shadow:0 0 14px var(--gold)}
.quest-claim-wide:disabled{opacity:.4;box-shadow:none;cursor:not-allowed;background:rgba(255,255,255,.08);color:var(--dim);animation:none}
.quest-claim-wide:not(:disabled){animation:questpulsewide 1.1s ease-in-out infinite}
@keyframes questpulsewide{0%,100%{box-shadow:0 0 12px var(--gold)}50%{box-shadow:0 0 28px var(--gold)}}
.qpoi-reward-note{font-size:11px;color:var(--gold);letter-spacing:.04em;margin:-4px 2px 2px}
.qpoi-row{display:flex;align-items:center;gap:10px;padding:11px 12px;border-radius:12px;
  background:rgba(255,210,63,.05);border:1px solid rgba(255,210,63,.35)}
.qpoi-row.tappable{cursor:pointer;transition:background .15s}
.qpoi-row.tappable:active{background:rgba(255,210,63,.12)}
.qpoi-ico{width:26px;height:26px;color:var(--gold);flex:none;display:grid;place-items:center;font-size:18px}
.qpoi-info{flex:1;min-width:0}
.qpoi-name{font-weight:700;font-size:14px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.qpoi-meta{font-size:11px;color:var(--dim);margin-top:2px}
.qpoi-reroll{padding:7px 10px;border-radius:9px;font-weight:800;font-size:11px;cursor:pointer;
  color:var(--cyan);background:rgba(0,240,255,.08);border:1px solid var(--cyan);white-space:nowrap}
.qpoi-reroll:disabled{opacity:.4;border-color:var(--dim);color:var(--dim);background:none;cursor:not-allowed}

/* trips */
.trip-actions{display:flex;gap:8px;margin-bottom:4px}
.trip-actions button{flex:1;padding:9px 6px;border-radius:9px;font-weight:700;font-size:11px;cursor:pointer;
  color:var(--magenta);background:rgba(255,43,214,.06);border:1px solid rgba(255,43,214,.4)}
.trip-row{display:flex;align-items:center;gap:10px;padding:11px 12px;border-radius:12px;
  background:rgba(255,255,255,.03);border:1px solid rgba(255,255,255,.08)}
.trip-info{flex:1;min-width:0}
.trip-date{font-weight:700;font-size:13px}
.trip-meta{font-size:11px;color:var(--dim);margin-top:3px;display:flex;gap:10px;flex-wrap:wrap}
.trip-meta b{color:var(--cyan);font-weight:700}
.trip-meta .kcal{color:var(--gold)}
.trip-del{flex:0 0 auto;width:30px;height:30px;border-radius:8px;border:1px solid var(--stroke);
  background:none;color:var(--dim);font-size:15px;cursor:pointer}

/* achievements */
.ach-row{display:flex;align-items:center;gap:12px;padding:11px 12px;border-radius:12px;
  background:rgba(255,255,255,.03);border:1px solid rgba(255,255,255,.08);opacity:.65}
.ach-row.done{opacity:1;border-color:var(--gold);background:linear-gradient(135deg,rgba(255,210,63,.08),rgba(255,43,214,.05));
  box-shadow:0 0 12px rgba(255,210,63,.15)}
.ach-ico{width:34px;height:34px;border-radius:9px;display:grid;place-items:center;flex:none;
  background:rgba(255,255,255,.05);color:var(--dim)}
.ach-ico .neon-poi{width:20px;height:20px}
.ach-row.done .ach-ico{color:var(--gold);background:rgba(255,210,63,.12)}
.ach-row.done .ach-ico .neon-poi{filter:drop-shadow(0 0 4px currentColor)}
.ach-info{flex:1;min-width:0}
.ach-name{font-weight:700;font-size:14px}
.ach-name .tick{color:var(--gold);margin-left:6px}
.ach-desc{font-size:11px;color:var(--dim);margin-top:2px}
.ach-bar{height:5px;border-radius:4px;background:rgba(255,255,255,.08);overflow:hidden;margin-top:6px}
.ach-fill{height:100%;background:linear-gradient(90deg,var(--cyan),var(--gold))}

/* settings */
.set-row{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:13px 14px;
  border-radius:12px;background:rgba(255,255,255,.03);border:1px solid rgba(255,255,255,.08)}
.set-info{flex:1;min-width:0}
.set-name{font-weight:700;font-size:14px}
.set-desc{font-size:11px;color:var(--dim);margin-top:2px;line-height:1.4}
.toggle{flex:0 0 auto;width:50px;height:28px;border-radius:15px;border:1px solid var(--stroke);
  background:rgba(255,255,255,.06);position:relative;cursor:pointer;transition:.2s}
.toggle::after{content:'';position:absolute;top:2px;left:2px;width:22px;height:22px;border-radius:50%;
  background:var(--dim);transition:.2s}
.toggle.on{background:rgba(0,240,255,.25);border-color:var(--cyan)}
.toggle.on::after{left:24px;background:var(--cyan);box-shadow:0 0 10px var(--cyan)}
.set-weight{display:flex;align-items:center;gap:10px}
.set-weight input{width:70px;padding:8px;border-radius:0;background:rgba(255,255,255,.06);
  border:1px solid var(--stroke);color:var(--text);font-family:'Orbitron';font-size:15px;text-align:center}
.set-weight span{font-size:12px;color:var(--dim)}

/* ---------- TOASTS ---------- */
#toast-stack{position:fixed;left:0;right:0;top:78px;z-index:600;display:flex;flex-direction:column;
  align-items:center;gap:8px;pointer-events:none}
.toast{padding:10px 18px;border-radius:12px;font-weight:700;font-size:14px;
  background:var(--glass);border:1px solid var(--stroke);backdrop-filter:blur(10px);
  box-shadow:0 0 16px rgba(0,240,255,.3);animation:toastin .3s ease,toastout .3s ease 2.4s forwards}
.toast.gold{border-color:var(--gold);box-shadow:0 0 18px rgba(255,210,63,.5);color:var(--gold)}
.toast.level{border-color:var(--magenta);box-shadow:0 0 20px rgba(255,43,214,.6);color:#fff;font-family:'Orbitron'}
@keyframes toastin{from{transform:translateY(-16px);opacity:0}to{transform:translateY(0);opacity:1}}
@keyframes toastout{to{transform:translateY(-16px);opacity:0}}

/* ---------- INTRO ---------- */
/* Just the game name over an animated neon block-city fly-through (js/introArt.js). */
.intro{position:fixed;inset:0;z-index:1000;overflow:hidden;
  background:radial-gradient(circle at 50% 34%,#12122e,#04040a 72%)}
.intro.hidden{display:none}
.intro-art{position:absolute;inset:0;width:100%;height:100%;display:block;z-index:0}
/* Fade the artwork into darkness top & bottom so the name/button stay legible. */
.intro::after{content:'';position:absolute;inset:0;z-index:1;pointer-events:none;
  background:linear-gradient(180deg,rgba(4,4,10,.55) 0%,rgba(4,4,10,0) 30%,rgba(4,4,10,0) 55%,rgba(4,4,10,.85) 100%)}
.intro-core{position:absolute;inset:0;z-index:2;display:flex;flex-direction:column;
  align-items:center;justify-content:center;text-align:center;
  padding:0 26px calc(env(safe-area-inset-bottom) + 14vh);gap:26px}
.logo{font-size:clamp(46px,17vw,88px);font-weight:900;color:#fff;letter-spacing:.04em;line-height:.92;
  text-shadow:0 0 10px var(--cyan),0 0 34px rgba(0,240,255,.7)}
.logo span{display:block;color:var(--magenta);text-shadow:0 0 10px var(--magenta),0 0 34px rgba(255,43,214,.7)}
.intro-start{max-width:340px;margin-top:22px;backdrop-filter:blur(5px);-webkit-backdrop-filter:blur(5px)}

/* ---------- POCKET MODE (screen-off, app keeps running) ---------- */
/* Pure #000 so the Note 20's AMOLED pixels are physically off = near-zero draw.
   The wake lock keeps the page "visible" so GPS/timers keep firing underneath. */
#pocket-overlay{position:fixed;inset:0;z-index:950;background:#000;touch-action:none;
  display:flex;flex-direction:column;align-items:center;justify-content:flex-end;
  padding:0 24px calc(env(safe-area-inset-bottom) + 64px)}
/* Contents are invisible until a touch wakes them (keeps the screen truly black in-pocket). */
.pocket-inner{width:100%;max-width:360px;text-align:center;opacity:0;transition:opacity .45s ease}
#pocket-overlay.awake .pocket-inner{opacity:1}
.pocket-status{font-family:'Orbitron';font-size:12px;letter-spacing:.22em;color:var(--dim);margin-bottom:24px}
.pocket-status b{color:var(--cyan)}
.pocket-track{position:relative;height:62px;border-radius:31px;overflow:hidden;
  border:1px solid var(--stroke);background:rgba(0,240,255,.04);display:flex;align-items:center}
.pocket-fill{position:absolute;left:0;top:0;bottom:0;width:0;pointer-events:none;
  background:linear-gradient(90deg,rgba(0,240,255,.10),rgba(0,240,255,.32))}
.pocket-track-label{position:absolute;left:0;right:0;text-align:center;pointer-events:none;
  color:var(--dim);font-size:12px;letter-spacing:.3em}
.pocket-handle{position:relative;z-index:2;flex:0 0 auto;width:52px;height:52px;margin:4px;
  border-radius:50%;background:var(--cyan);color:#001;display:grid;place-items:center;
  font-size:22px;box-shadow:0 0 18px var(--cyan);touch-action:none;cursor:grab}
.pocket-handle.grabbing{cursor:grabbing}

/* ---------- DECRYPT REVEAL ---------- */
#decrypt-overlay{position:fixed;inset:0;z-index:980;display:flex;align-items:center;justify-content:center;
  background:radial-gradient(circle at 50% 45%,rgba(12,10,32,.82),rgba(3,3,10,.94));
  backdrop-filter:blur(7px);-webkit-backdrop-filter:blur(7px);animation:decryptin .25s ease}
@keyframes decryptin{from{opacity:0}to{opacity:1}}
.decrypt-stage{position:relative;width:100%;max-width:420px;padding:0 24px;text-align:center;
  display:flex;flex-direction:column;align-items:center;gap:18px}
.decrypt-core{position:relative;width:150px;height:150px;display:grid;place-items:center}
.dc-ring{position:absolute;border-radius:50%;border:2px solid var(--cyan);opacity:.7;
  box-shadow:0 0 16px var(--cyan),inset 0 0 16px rgba(0,240,255,.4)}
.dc-ring{inset:0;border-top-color:transparent;border-left-color:transparent;animation:spin 1.1s linear infinite}
.dc-ring.r2{inset:22px;border-color:var(--magenta);border-bottom-color:transparent;border-right-color:transparent;
  box-shadow:0 0 16px var(--magenta);animation:spin 1.6s linear infinite reverse}
.dc-ring.r3{inset:44px;border-color:var(--purple);border-top-color:transparent;
  box-shadow:0 0 14px var(--purple);animation:spin .8s linear infinite}
.dc-shard{position:relative;z-index:2;font-size:46px;color:#fff;
  text-shadow:0 0 12px var(--cyan),0 0 26px var(--cyan);animation:dcflicker .9s steps(2) infinite}
@keyframes dcflicker{0%,100%{opacity:1;transform:scale(1)}50%{opacity:.55;transform:scale(.92)}}
.dc-burst{position:absolute;inset:0;border-radius:50%;opacity:0;
  background:radial-gradient(circle,rgba(255,255,255,.95),rgba(0,240,255,.5) 35%,transparent 68%)}
/* scanning → revealed phases: rings keep turning but MUCH slower (idle "done" state) */
#decrypt-overlay.revealed .dc-ring{opacity:.35;animation-duration:9s}
#decrypt-overlay.revealed .dc-ring.r2{animation-duration:12s}
#decrypt-overlay.revealed .dc-ring.r3{animation-duration:7s}
#decrypt-overlay.revealed .dc-shard{animation:none;color:var(--gold);text-shadow:0 0 18px var(--gold),0 0 40px var(--gold);
  transform:scale(1.15)}
#decrypt-overlay.revealed .dc-burst{animation:dcburst .6s ease-out}
@keyframes dcburst{0%{opacity:.95;transform:scale(.3)}100%{opacity:0;transform:scale(2.4)}}
.decrypt-hex{font-family:'Orbitron',monospace;font-size:12px;letter-spacing:.18em;color:var(--cyan);
  opacity:.7;min-height:32px;line-height:1.4;word-break:break-all;text-shadow:0 0 8px rgba(0,240,255,.5)}
#decrypt-overlay.revealed .decrypt-hex{display:none}
.decrypt-label{font-family:'Orbitron';font-size:15px;letter-spacing:.28em;color:var(--cyan);
  text-shadow:0 0 12px rgba(0,240,255,.5)}
#decrypt-overlay.revealed .decrypt-label{color:var(--gold);text-shadow:0 0 14px rgba(255,210,63,.6)}
.decrypt-result{display:flex;flex-direction:column;align-items:center;gap:12px;animation:revealpop .4s cubic-bezier(.2,1.4,.4,1)}
@keyframes revealpop{from{opacity:0;transform:translateY(14px) scale(.9)}to{opacity:1;transform:none}}
.decrypt-flux{font-family:'Orbitron';font-weight:900;font-size:42px;color:var(--gold);
  text-shadow:0 0 18px var(--gold),0 0 44px rgba(255,210,63,.6)}
.decrypt-sub{font-size:12px;color:var(--dim);letter-spacing:.08em}
.decrypt-cards-head{font-family:'Orbitron';font-size:12px;letter-spacing:.18em;color:var(--magenta);
  text-shadow:0 0 10px rgba(255,43,214,.5);margin-top:6px}
/* cap + scroll the card list: after a long stint unopened a decrypt can drop a LOT of
   cards, and the player needs to be able to scroll through all of them */
.decrypt-cards{display:flex;flex-wrap:wrap;justify-content:center;gap:8px;margin-top:4px;max-width:360px;
  max-height:40vh;overflow-y:auto;overscroll-behavior:contain;-webkit-overflow-scrolling:touch;padding:2px}
.decrypt-card-chip{--rar:var(--magenta);padding:6px 12px;border-radius:9px;font-size:12px;font-weight:700;
  border:1px solid var(--rar);color:#fff;background:color-mix(in srgb,var(--rar) 18%,transparent);
  box-shadow:0 0 12px color-mix(in srgb,var(--rar) 40%,transparent)}
.decrypt-card-chip.new{color:#fff}
.decrypt-card-chip.dup{opacity:.6}
.decrypt-dismiss{font-size:11px;color:var(--dim);letter-spacing:.16em;opacity:0;transition:opacity .3s;margin-top:6px}
#decrypt-overlay.revealed .decrypt-dismiss{opacity:.7}

/* ---------- DEPLOY RE-SCAN SWEEP ---------- */
/* A sub-second "re-scan": a bright cyan scan-line races up then back down over faint
   static scanlines, screen-blended over the whole app. Purely cosmetic, pointer-through. */
#deploy-fx{position:fixed;inset:0;z-index:970;pointer-events:none;opacity:0;overflow:hidden;
  mix-blend-mode:screen;
  background-image:repeating-linear-gradient(0deg,rgba(0,240,255,.06) 0,rgba(0,240,255,.06) 1px,transparent 2px,transparent 4px)}
/* the moving scan band — a stack of a few bright horizontal lines */
#deploy-fx::before{content:'';position:absolute;left:0;right:0;height:16%;top:100%;
  background:
    linear-gradient(0deg,transparent,rgba(0,240,255,.85) 50%,transparent),
    repeating-linear-gradient(0deg,transparent 0,transparent 5px,rgba(255,255,255,.5) 6px,transparent 7px);
  box-shadow:0 0 26px rgba(0,240,255,.7);filter:blur(.5px)}
#deploy-fx.on{animation:deployscanfade .5s ease-in-out forwards}
#deploy-fx.on::before{animation:deployscan .5s ease-in-out forwards}
@keyframes deployscanfade{0%,100%{opacity:0}12%,88%{opacity:.95}}
@keyframes deployscan{0%{top:100%}50%{top:-16%}100%{top:100%}}

/* ---------- OFF-SCREEN QUEST ARROWS ---------- */
/* Gold chevrons pinned to the viewport edge, pointing at active quest POIs that are
   currently off-screen. Sits above the map but below the HUD / panels; pointer-through. */
#quest-arrows{position:fixed;inset:0;z-index:360;pointer-events:none}
.quest-arrow{position:absolute;width:30px;height:30px;border-radius:50%;
  display:grid;place-items:center;color:#201400;background:var(--gold);
  box-shadow:0 0 12px var(--gold);animation:qapulse 1.4s ease-in-out infinite;
  pointer-events:auto;cursor:pointer;-webkit-tap-highlight-color:transparent}
.quest-arrow:active{filter:brightness(1.2)}
.quest-arrow .qa-svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:2.4;
  stroke-linecap:round;stroke-linejoin:round;display:block}
@keyframes qapulse{0%,100%{box-shadow:0 0 8px var(--gold)}50%{box-shadow:0 0 20px var(--gold)}}

/* ---------- NEW-VERSION PROMPT ---------- */
#update-prompt{position:fixed;left:50%;transform:translateX(-50%);
  top:calc(env(safe-area-inset-top) + 74px);z-index:620;display:flex;align-items:center;gap:10px;
  padding:8px 10px 8px 16px;border-radius:14px;background:var(--glass);border:1px solid var(--cyan);
  box-shadow:0 0 20px rgba(0,240,255,.4);backdrop-filter:blur(10px);
  animation:toastin .3s ease;max-width:calc(100vw - 24px)}
#update-prompt .up-msg{font-weight:700;font-size:13px;color:var(--cyan);white-space:nowrap}
#update-prompt .up-reload{padding:7px 14px;border-radius:10px;font-family:'Orbitron';font-weight:700;
  font-size:12px;letter-spacing:.06em;cursor:pointer;color:#001;background:var(--cyan);border:none;
  box-shadow:0 0 12px var(--cyan)}
#update-prompt .up-reload:active{transform:scale(.95)}
#update-prompt .up-dismiss{background:none;border:none;color:var(--dim);font-size:16px;cursor:pointer;
  padding:0 2px;line-height:1}

/* ---------- FLOATING CLAIM ARROW ---------- */
/* Neon-red twin-chevron that floats just below (and points up at) the daily-walk claim
   button, which is too cramped in the top bar to host a cue itself. Bobs up & down while
   the two chevrons pulse in an upward "scan" wave — on-brand with the neon line-art look. */
.claim-arrow{position:fixed;z-index:450;pointer-events:none;width:26px;height:26px;
  color:#ff2e4d;filter:drop-shadow(0 0 5px currentColor) drop-shadow(0 0 11px rgba(255,46,77,.65));
  animation:claimbob 1.1s ease-in-out infinite}
.claim-arrow svg{width:100%;height:100%;fill:none;stroke:currentColor;stroke-width:2.4;
  stroke-linecap:round;stroke-linejoin:round;display:block}
.claim-arrow svg path{opacity:.35}
.claim-arrow svg path:nth-child(1){animation:qchev 1.1s ease-in-out infinite .26s} /* upper — trails */
.claim-arrow svg path:nth-child(2){animation:qchev 1.1s ease-in-out infinite}      /* lower — leads */
@keyframes qchev{0%,100%{opacity:.3}45%{opacity:1}}
@keyframes claimbob{
  0%,100%{transform:translateX(-50%) translateY(2px)}
  50%{transform:translateX(-50%) translateY(-4px)}}

/* ---------- GENERIC REWARD REVEAL ---------- */
#reward-overlay{position:fixed;inset:0;z-index:990;display:flex;align-items:center;justify-content:center;
  background:radial-gradient(circle at 50% 45%,rgba(12,10,32,.8),rgba(3,3,10,.92));
  backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);animation:decryptin .25s ease}
.reward-card{display:flex;flex-direction:column;align-items:center;gap:12px;text-align:center;
  padding:0 30px;animation:rewardpop .5s cubic-bezier(.2,1.5,.4,1)}
@keyframes rewardpop{from{opacity:0;transform:scale(.7)}to{opacity:1;transform:none}}
.reward-icon{font-size:70px;line-height:1;color:var(--gold);
  text-shadow:0 0 20px var(--gold),0 0 50px rgba(255,210,63,.6);animation:rewardglow 1.4s ease-in-out infinite}
@keyframes rewardglow{0%,100%{transform:scale(1)}50%{transform:scale(1.08)}}
.reward-title{font-family:'Orbitron';font-weight:900;font-size:22px;letter-spacing:.1em;color:#fff;
  text-shadow:0 0 14px rgba(0,240,255,.5)}
.reward-sub{font-family:'Orbitron';font-size:15px;letter-spacing:.06em;color:var(--gold);
  text-shadow:0 0 12px rgba(255,210,63,.5)}
.reward-dismiss{font-size:11px;color:var(--dim);letter-spacing:.16em;margin-top:12px;
  opacity:0;animation:rewardhint .4s ease .5s forwards}
@keyframes rewardhint{to{opacity:.7}}

/* ---------- CAR MODE INDICATOR ---------- */
/* Persistent pill while moving above the collection speed limit (anti-car). */
.car-mode{position:fixed;left:50%;transform:translateX(-50%);
  top:calc(env(safe-area-inset-top) + 60px);z-index:460;pointer-events:none;
  padding:7px 16px;border-radius:20px;font-family:'Orbitron';font-weight:700;font-size:12px;
  letter-spacing:.05em;color:var(--gold);background:var(--glass);border:1px solid var(--gold);
  backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);white-space:nowrap;
  max-width:calc(100vw - 24px);animation:carpulse 1.4s ease-in-out infinite}
@keyframes carpulse{0%,100%{box-shadow:0 0 12px rgba(255,210,63,.4)}50%{box-shadow:0 0 26px rgba(255,210,63,.7)}}

/* ---------- CONFIRM DIALOG ---------- */
/* Above the intro (z 1000): the post-install "open the app / play in browser" dialog is
   raised over the still-visible intro screen, else its buttons would be trapped behind it. */
#confirm-overlay{position:fixed;inset:0;z-index:1001;display:flex;align-items:center;justify-content:center;
  padding:24px;background:rgba(2,2,8,.72);backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);
  animation:decryptin .2s ease}
.confirm-box{width:100%;max-width:360px;padding:20px;border-radius:16px;
  background:linear-gradient(180deg,var(--bg2),var(--bg));border:1px solid var(--stroke);
  box-shadow:0 0 30px rgba(0,240,255,.2)}
.confirm-title{font-family:'Orbitron';font-size:16px;color:var(--cyan);letter-spacing:.06em;text-align:center;
  text-shadow:0 0 10px rgba(0,240,255,.4);margin-bottom:10px}
.confirm-msg{font-size:13px;line-height:1.5;color:var(--text);text-align:center;margin-bottom:18px}
.confirm-actions{display:flex;gap:10px}
.confirm-btn{flex:1;padding:12px;border-radius:10px;font-family:'Orbitron';font-weight:700;font-size:12px;
  letter-spacing:.06em;cursor:pointer;transition:.15s}
.confirm-btn:active{transform:scale(.97)}
.confirm-btn.cancel{color:var(--dim);background:rgba(255,255,255,.05);border:1px solid var(--stroke)}
.confirm-btn.ok{color:#012;background:var(--cyan);border:1px solid var(--cyan);box-shadow:0 0 14px rgba(0,240,255,.5)}
/* small footer note under the confirm buttons (e.g. "disable in Settings") */
.confirm-note{margin-top:12px;font-size:11px;line-height:1.4;color:var(--dim);text-align:center}
.confirm-note.hidden{display:none!important}

/* GPS dialog (shares .confirm-box styling). z-index sits ABOVE the intro (1000) so it can be
   shown over the welcome screen while the player picks Play/Install/SIM. */
#gps-overlay{position:fixed;inset:0;z-index:1002;display:flex;align-items:center;justify-content:center;
  padding:24px;background:rgba(2,2,8,.78);backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);
  animation:decryptin .2s ease}
.gps-view.hidden{display:none}
.gps-qr{display:flex;flex-direction:column;align-items:center;gap:8px;margin:0 0 18px}
.gps-qr img{width:200px;height:200px;border-radius:10px;background:#fff;padding:8px;box-shadow:0 0 18px rgba(0,240,255,.3)}
.gps-qr-cap{font-size:11.5px;letter-spacing:.04em;color:var(--dim);text-align:center}
.gps-actions{align-items:center;justify-content:space-between}
/* "Continue in SIM" — de-emphasised: no border, no fill, sits on the left */
.gps-continue{flex:0 0 auto;padding:12px 4px;border:none;background:none;cursor:pointer;
  font-family:'Orbitron';font-weight:700;font-size:11px;letter-spacing:.05em;color:var(--dim)}
.gps-actions .confirm-btn.ok{flex:0 0 auto;padding:12px 22px}
.gps-continue:active{transform:scale(.97)}
/* QR-screen escape hatch — subtle link-style note under the actions for a mis-detected mobile */
.gps-note{display:block;width:100%;margin:14px 0 0;padding:8px 4px 0;border:none;background:none;cursor:pointer;
  border-top:1px solid var(--stroke);font-family:'Rajdhani',sans-serif;font-weight:600;font-size:12.5px;
  letter-spacing:.02em;color:var(--dim);text-align:center;text-decoration:underline;text-underline-offset:2px}
.gps-note:active{transform:scale(.98)}
.gps-note:disabled{opacity:.6;cursor:default}

/* ---------- CUSTOM SCROLLBARS ---------- */
/* Thin neon scrollbar for the (touch + desktop) scrollable panels, matching the theme. */
*{scrollbar-width:thin;scrollbar-color:rgba(0,240,255,.45) transparent}
::-webkit-scrollbar{width:8px;height:8px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{background:linear-gradient(180deg,rgba(0,240,255,.5),rgba(138,43,255,.5));
  border-radius:8px;border:2px solid transparent;background-clip:padding-box}
::-webkit-scrollbar-thumb:hover{background:linear-gradient(180deg,var(--cyan),var(--purple));
  background-clip:padding-box}
::-webkit-scrollbar-corner{background:transparent}

/* ---------- INLINE GUI GLYPHS (emoji replacements) ---------- */
/* Small neon line-icons used inside text/buttons (lock, camera, folder, …). Inherit the
   surrounding text colour + size. */
.ui-ico{width:1em;height:1em;display:inline-block;vertical-align:-.14em;overflow:visible;flex:none}
/* Action-bar icons (stash / deploy / upgrade) as vectors instead of glyph characters */
.act-svg{width:22px;height:22px;fill:none;stroke:currentColor;stroke-width:1.8;
  stroke-linecap:round;stroke-linejoin:round;display:block;filter:drop-shadow(0 0 5px currentColor)}
.act-btn.primary .act-svg{color:var(--cyan)}

/* ---------- FUTURISTIC BUTTON CORNERS ---------- */
/* Sharp corners with two corners bevel-cut, and the neon border traces the 45° cuts too.
   Technique: the surface is drawn on TWO clipped pseudos — ::before is the coloured RIM
   (full bevel), ::after is the FILL inset by the rim width (same bevel) — so the rim shows
   as an even border on EVERY edge, diagonals included. `isolation:isolate` keeps the
   negative-z pseudos local to the button, so the surface renders correctly even inside a
   container that has its own background, and the button itself stays UNclipped so external
   badges/alerts aren't cut off. Colour via --rim / --fill / --glow; shape via --bevel. */
.act-btn,.wide-btn,.upg-buy,.admin-btn,.prof-tab,.cards-tab,.qpoi-reroll,
.trip-actions button,.cards-collect-btn,.cards-decon-all,.cards-import-btn,.cards-io-btn,
.set-btn,.beacon-remove,.cd-act,.gearmenu-item,.confirm-btn,.quest-claim-wide,
.cards-auto,.up-reload,.cards-filter-btn,.cards-gear,.ach-claim,.ach-claim-all,.beacon-fab{
  position:relative;isolation:isolate;overflow:visible;
  border:none!important;background:none!important;box-shadow:none!important;border-radius:0!important;
  --cut:9px;
  --bevel:polygon(var(--cut) 0,100% 0,100% calc(100% - var(--cut)),calc(100% - var(--cut)) 100%,0 100%,0 var(--cut));
  --rim:currentColor;--fill:color-mix(in srgb,currentColor 14%,#0b0b14);--glow:none}
.act-btn::before,.wide-btn::before,.upg-buy::before,.admin-btn::before,.prof-tab::before,
.cards-tab::before,.qpoi-reroll::before,.trip-actions button::before,.cards-collect-btn::before,
.cards-decon-all::before,.cards-import-btn::before,.cards-io-btn::before,.set-btn::before,
.beacon-remove::before,.cd-act::before,.gearmenu-item::before,.confirm-btn::before,
.quest-claim-wide::before,.cards-auto::before,.up-reload::before,.cards-filter-btn::before,
.cards-gear::before,.ach-claim::before,.ach-claim-all::before,.beacon-fab::before{
  content:'';position:absolute;inset:0;z-index:-1;background:var(--rim);filter:var(--glow);clip-path:var(--bevel)}
.act-btn::after,.wide-btn::after,.upg-buy::after,.admin-btn::after,.prof-tab::after,
.cards-tab::after,.qpoi-reroll::after,.trip-actions button::after,.cards-collect-btn::after,
.cards-decon-all::after,.cards-import-btn::after,.cards-io-btn::after,.set-btn::after,
.beacon-remove::after,.cd-act::after,.gearmenu-item::after,.confirm-btn::after,
.quest-claim-wide::after,.cards-auto::after,.up-reload::after,.cards-filter-btn::after,
.cards-gear::after,.ach-claim::after,.ach-claim-all::after,.beacon-fab::after{
  content:'';position:absolute;inset:1.4px;z-index:-1;background:var(--fill);clip-path:var(--bevel)}

/* bigger cut on the larger buttons */
.wide-btn,.act-btn,.admin-btn,.confirm-btn,.cd-act,.cards-auto,.quest-claim-wide{--cut:12px}

/* action bar — dark neon-tinted body + bright rim (reads as a border, not a solid fill).
   Stash = left cuts, Upgrade = right cuts, Deploy = square. */
.act-btn{--rim:rgba(255,255,255,.28);--fill:#12131f}
#btn-inventory{--bevel:polygon(var(--cut) 0,100% 0,100% 100%,var(--cut) 100%,0 calc(100% - var(--cut)),0 var(--cut))}
#btn-upgrades{--bevel:polygon(0 0,calc(100% - var(--cut)) 0,100% var(--cut),100% calc(100% - var(--cut)),calc(100% - var(--cut)) 100%,0 100%)}
#btn-deploy{--bevel:none;--rim:var(--cyan);color:#fff;--glow:drop-shadow(0 0 8px rgba(0,240,255,.5));
  --fill:linear-gradient(135deg,color-mix(in srgb,var(--cyan) 22%,#0b0c16),color-mix(in srgb,var(--purple) 24%,#0b0c16))}
/* CANCEL glows red/pink, CONFIRM glows green — through the beveled rim/fill system */
.split-btn.cancel{--rim:var(--magenta);color:#fff;--glow:drop-shadow(0 0 11px rgba(255,43,214,.6));
  --fill:linear-gradient(135deg,color-mix(in srgb,var(--magenta) 26%,#0b0c16),color-mix(in srgb,#ff3b3b 22%,#0b0c16))}
.split-btn.confirm{--rim:var(--green);color:#fff;--glow:drop-shadow(0 0 12px rgba(57,255,20,.6));
  --fill:linear-gradient(135deg,color-mix(in srgb,var(--green) 24%,#0b0c16),color-mix(in srgb,var(--cyan) 18%,#0b0c16))}
/* beacon FAB: fixed to the bottom-left + its own top-right-cut bevel. MUST be here (after
   the shared bevel group) so position:fixed beats the group's position:relative — otherwise
   the button falls into normal flow and gets shoved off the top of the screen.
   Gray by default (like Stash / Upgrade); lit cyan when a beacon is unplaced (.has-unplaced). */
.beacon-fab{position:fixed;--cut:15px;
  --bevel:polygon(0 0,calc(100% - var(--cut)) 0,100% var(--cut),100% 100%,0 100%);
  --rim:rgba(255,255,255,.28);--fill:#12131f;--glow:none}
.beacon-fab.has-unplaced{color:var(--cyan);
  --rim:var(--cyan);--fill:color-mix(in srgb,var(--cyan) 16%,#0b0b14);
  --glow:drop-shadow(0 0 9px rgba(0,240,255,.5))}
/* Beacon available but unaffordable: keep the count visible, just greyed (no glow). */
.beacon-fab.beacon-poor .btn-badge{background:#3a3f4d;color:#aab3c5;box-shadow:none}

/* big buttons — bright neon RIM around a dark tinted body (border look), not a bright fill */
.wide-btn{--rim:var(--cyan);color:#fff;--glow:drop-shadow(0 0 10px rgba(0,240,255,.45));
  --fill:linear-gradient(150deg,color-mix(in srgb,var(--cyan) 20%,#0b0c16),color-mix(in srgb,var(--purple) 26%,#0b0c16))}
.wide-btn.cards-btn{--rim:var(--magenta);--glow:drop-shadow(0 0 10px rgba(255,43,214,.45));
  --fill:linear-gradient(150deg,color-mix(in srgb,var(--magenta) 22%,#0b0c16),color-mix(in srgb,var(--purple) 26%,#0b0c16))}
.wide-btn.secondary{--rim:var(--stroke);--fill:#12131f;--glow:none;color:var(--cyan)}
.wide-btn:disabled{opacity:.45}
.quest-claim-wide{--rim:var(--gold);--fill:var(--gold);--glow:drop-shadow(0 0 9px rgba(255,210,63,.5))}
.quest-claim-wide:disabled{--rim:var(--stroke);--fill:rgba(255,255,255,.08);--glow:none}
.cards-auto{--rim:var(--green);--fill:var(--green);--glow:drop-shadow(0 0 9px rgba(57,255,20,.5))}
.up-reload{--rim:var(--cyan);--fill:var(--cyan);--glow:drop-shadow(0 0 8px rgba(0,240,255,.5))}
.confirm-btn.ok{--rim:var(--cyan);--fill:var(--cyan);--glow:drop-shadow(0 0 8px rgba(0,240,255,.5))}

/* muted rim for the near-white text buttons; keep accent rims for coloured variants */
.admin-btn,.cards-io-btn,.gearmenu-item{--rim:var(--stroke)}
.admin-btn.danger,.gearmenu-item.danger{--rim:var(--magenta)}
.admin-btn.exit{--rim:var(--green)}
/* lit tab state gets a soft glow */
.prof-tab.on,.cards-tab.view{--glow:drop-shadow(0 0 7px currentColor)}
/* small icon toggles (search / gear) — subtle rim, brighter when active/hovered */
.cards-filter-btn,.cards-gear{--cut:7px;--rim:var(--stroke)}
.cards-filter-btn.on,.cards-filter-btn:hover,.cards-gear:hover{--rim:var(--cyan);--glow:drop-shadow(0 0 6px var(--cyan))}
/* achievement reward claim buttons (gold) */
.ach-claim{flex:0 0 auto;align-self:center;white-space:nowrap;padding:8px 11px;font-family:'Rajdhani',sans-serif;
  font-weight:800;font-size:10.5px;letter-spacing:.05em;cursor:pointer;color:var(--gold);
  --rim:var(--gold);--fill:color-mix(in srgb,var(--gold) 15%,#0e0f19);--glow:drop-shadow(0 0 6px rgba(255,210,63,.4))}
.ach-claimed{flex:0 0 auto;align-self:center;color:var(--gold);opacity:.5;font-size:16px;padding:0 6px}
.ach-claim-all{--cut:12px;width:100%;margin-bottom:6px;padding:12px;font-family:'Orbitron';font-weight:800;
  font-size:13px;letter-spacing:.06em;cursor:pointer;color:#201400;
  --rim:var(--gold);--fill:var(--gold);--glow:drop-shadow(0 0 12px rgba(255,210,63,.55))}

/* ---------- BEVELLED GROUP BOXES / SECTIONS ---------- */
/* The same rim+fill bevel as the buttons, applied to the non-button containers so the whole
   UI shares the sci-fi cut-corner look. (Scrolling containers are excluded — the fill pseudo
   wouldn't follow scrolled content.) */
.upg,.set-row,.beacon-row,.trip-row,.ach-row,.qpoi-row,.beacon-stat,.quest-hero,
.cards-filter,.cards-gearmenu,.more-set,.more-warning,.cards-warning,.poi-badge,
.decrypt-card-chip,.level-badge,.confirm-box,.cd-flavor{
  position:relative;isolation:isolate;
  border:none!important;background:none!important;box-shadow:none!important;border-radius:0!important;
  --cut:9px;
  --bevel:polygon(var(--cut) 0,100% 0,100% calc(100% - var(--cut)),calc(100% - var(--cut)) 100%,0 100%,0 var(--cut));
  --rim:rgba(255,255,255,.13);--fill:#0e0f19;--glow:none}
.upg::before,.set-row::before,.beacon-row::before,.trip-row::before,.ach-row::before,
.qpoi-row::before,.beacon-stat::before,.quest-hero::before,.cards-filter::before,
.cards-gearmenu::before,.more-set::before,.more-warning::before,.cards-warning::before,
.poi-badge::before,.decrypt-card-chip::before,.level-badge::before,.confirm-box::before,.cd-flavor::before{
  content:'';position:absolute;inset:0;z-index:-1;background:var(--rim);filter:var(--glow);clip-path:var(--bevel)}
.upg::after,.set-row::after,.beacon-row::after,.trip-row::after,.ach-row::after,
.qpoi-row::after,.beacon-stat::after,.quest-hero::after,.cards-filter::after,
.cards-gearmenu::after,.more-set::after,.more-warning::after,.cards-warning::after,
.poi-badge::after,.decrypt-card-chip::after,.level-badge::after,.confirm-box::after,.cd-flavor::after{
  content:'';position:absolute;inset:1.2px;z-index:-1;background:var(--fill);clip-path:var(--bevel)}

/* accented boxes keep their tint */
.qpoi-row{--rim:rgba(255,210,63,.42);--fill:color-mix(in srgb,var(--gold) 7%,#0e0f19)}
.quest-hero{--cut:12px;--rim:rgba(57,255,20,.42);
  --fill:linear-gradient(135deg,color-mix(in srgb,var(--green) 9%,#0d0e18),color-mix(in srgb,var(--gold) 9%,#0d0e18))}
.quest-hero.done{--rim:rgba(255,210,63,.45)}
.ach-row.done{--rim:var(--gold);--glow:drop-shadow(0 0 7px rgba(255,210,63,.22));
  --fill:linear-gradient(135deg,color-mix(in srgb,var(--gold) 10%,#0e0f19),color-mix(in srgb,var(--magenta) 5%,#0e0f19))}
.ach-row.claimable{--rim:var(--gold);--glow:drop-shadow(0 0 9px rgba(255,210,63,.42))}
.more-warning,.cards-warning{--rim:rgba(255,210,63,.45);--fill:color-mix(in srgb,var(--gold) 7%,#0e0f19)}
/* POI badges (LOOT READY / RECHARGING / READY) are status readouts, not actions — strip the
   chip frame/fill so none of them read as tappable buttons. Plain centered colored labels. */
.poi-badge{padding:2px 0;margin-bottom:10px;font-size:12px;letter-spacing:.16em}
.poi-badge::before,.poi-badge::after{display:none}
.poi-badge.cooldown{opacity:.92}
.decrypt-card-chip{--cut:6px;--rim:var(--rar);--fill:color-mix(in srgb,var(--rar) 16%,#0b0b14)}
.level-badge{--rim:var(--magenta);--glow:drop-shadow(0 0 8px rgba(255,43,214,.4));
  --fill:color-mix(in srgb,var(--magenta) 13%,#0a0a12)}
.confirm-box{--cut:14px;--rim:var(--stroke);--glow:drop-shadow(0 0 16px rgba(0,240,255,.22));
  --fill:linear-gradient(180deg,var(--bg2),var(--bg))}

/* ---------- SQUARE TOGGLE (checkbox) — a square knob sliding in a rectangular track ---------- */
.toggle{border-radius:0;width:52px}
.toggle::after{border-radius:0;top:3px;left:3px;width:20px;height:20px}
.toggle.on::after{left:29px}

/* AWARDS tab unclaimed-reward badge */
.awards-badge{position:absolute;top:-5px;right:-3px;min-width:17px;height:17px;padding:0 4px;
  border-radius:9px;background:var(--gold);color:#201400;font-family:'Orbitron',sans-serif;font-weight:800;
  font-size:10px;line-height:17px;text-align:center;box-shadow:0 0 9px var(--gold)}
/* multi-line dialog messages (iOS install steps) */
.confirm-msg{white-space:pre-line;text-align:left}

/* ---------- SHARP INPUTS + MISC RADIUS REMOVAL ---------- */
input{border-radius:0}
.trip-del{border-radius:0}

/* card-detail trivia box: beveled shell (from the box list) with the scroll on an inner
   wrapper so the fill/rim pseudos don't scroll away. */
.cd-flavor{overflow:visible;display:flex;flex-direction:column;flex:0 1 auto;min-height:0;--cut:10px}
.cd-flavor-inner{flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain;-webkit-overflow-scrolling:touch}

/* ---------- CARD-ALBUM HEADER LAYOUT ---------- */
/* Label on the left, control on the right. If they don't both fit, the right item wraps to
   its own line and stays right-aligned (margin-left:auto), so it always reads cleanly. */
.cards-rowsplit{display:flex;flex-wrap:wrap;align-items:center;gap:6px 10px}
.cards-rowsplit>*:last-child{margin-left:auto}
#cards-top{margin-bottom:12px}
.cards-decon-slot:empty{display:none}
/* row 2 — "X / Y collected" left, ⌕ search toggle right */
.cards-progress{text-align:left}
/* row 3 — rarity tally chips, left-aligned. Drop the first chip's left padding so its text
   starts flush with the "X / Y collected" line above it (no leading indent). */
.rar-chips{justify-content:flex-start}
.rar-chip:first-child{padding-left:0}
/* row 4 — collect / auto-complete, centered */
.cards-bar-actions{flex-direction:row;flex-wrap:wrap;align-items:center;justify-content:center;gap:8px}

/* ---------- BEVELLED SLIDE-UP PANEL ---------- */
/* Cut the (visible) top corners of the bottom sheet instead of rounding them, with the neon
   rim tracing the cuts. The panel itself doesn't scroll (its .panel-body does), so the fill
   pseudo stays put. */
.panel{isolation:isolate;border:none!important;background:none!important;box-shadow:none!important;
  border-radius:0!important;--cut:16px;
  --pbevel:polygon(var(--cut) 0,calc(100% - var(--cut)) 0,100% var(--cut),100% 100%,0 100%,0 var(--cut))}
.panel::before{content:'';position:absolute;inset:0;z-index:-1;clip-path:var(--pbevel);
  background:var(--stroke);filter:drop-shadow(0 -3px 18px rgba(0,240,255,.16))}
.panel::after{content:'';position:absolute;inset:1.4px;z-index:-1;clip-path:var(--pbevel);
  background:linear-gradient(180deg,var(--bg2),var(--bg))}

/* ---------- INTRO ACTIONS (install / play) ---------- */
.intro-actions{display:flex;flex-direction:column;align-items:center;gap:12px;width:100%;max-width:340px;margin-top:22px}
.intro-actions .intro-start{margin-top:0}
/* Always reserve the space for BOTH buttons so the logo never jumps when the INSTALL button
   appears (beforeinstallprompt) — the hidden install button keeps its box, just invisible. */
.intro-actions #btn-install.hidden{display:block!important;visibility:hidden;pointer-events:none}
/* Buttons stay invisible until we've settled the install state (else "PLAY" flashes for a
   frame before beforeinstallprompt swaps it to Install / "PLAY IN BROWSER"). JS adds .ready. */
.intro-actions{opacity:0;transform:translateY(6px);transition:opacity .35s ease,transform .35s ease}
.intro-actions.ready{opacity:1;transform:none}

/* ---------- MAP LOADING SPINNER ---------- */
/* Futuristic triple-ring spinner (mini decrypt rings), centred on the map until the first
   POI scan resolves. */
.map-spinner{position:fixed;left:50%;top:50%;transform:translate(-50%,-50%);z-index:340;pointer-events:none;
  display:flex;flex-direction:column;align-items:center;gap:14px}
.ms-rings{position:relative;width:76px;height:76px}
.ms-ring{position:absolute;inset:0;border-radius:50%;border:2px solid var(--cyan);
  border-top-color:transparent;border-left-color:transparent;opacity:.75;
  box-shadow:0 0 14px var(--cyan),inset 0 0 12px rgba(0,240,255,.35);animation:spin 1.1s linear infinite}
.ms-ring.r2{inset:12px;border-color:var(--magenta);border-bottom-color:transparent;border-right-color:transparent;
  box-shadow:0 0 14px var(--magenta);animation:spin 1.6s linear infinite reverse}
.ms-ring.r3{inset:24px;border-color:var(--purple);border-top-color:transparent;
  box-shadow:0 0 12px var(--purple);animation:spin .8s linear infinite}
.ms-label{font-family:'Orbitron';font-size:11px;letter-spacing:.24em;color:var(--cyan);
  text-shadow:0 0 10px rgba(0,240,255,.5);animation:mspulse 1.4s ease-in-out infinite}
@keyframes mspulse{0%,100%{opacity:.45}50%{opacity:1}}

/* ---------- BEACON "SCANNING" SWEEP ---------- */
/* While the Plant Beacon button is disabled and probing for nearby POIs, a bright vertical
   scan-line sweeps left↔right across its fill layer (clipped to the bevel by ::after). */
#btn-plant-beacon.scanning{opacity:.95}
#btn-plant-beacon.scanning::after{
  background:linear-gradient(90deg,transparent,rgba(0,240,255,.55) 45%,#fff 50%,rgba(0,240,255,.55) 55%,transparent),var(--fill);
  background-size:45% 100%,100% 100%;background-repeat:no-repeat;background-position:-60% 0,0 0;
  animation:beaconscan 1.15s ease-in-out infinite alternate}
@keyframes beaconscan{from{background-position:-60% 0,0 0}to{background-position:160% 0,0 0}}

.hidden{display:none!important}

/* ---------- SMALL / NARROW SCREENS ---------- */
/* Guard against any horizontal overflow that clips the right edge on phones. */
@media (max-width:430px){
  .intro-core{padding-bottom:calc(env(safe-area-inset-bottom) + 16vh)}
}
