/* ============================================================
   Koinos Crusaders — Koinos edition
   Retro dark-fantasy pixel theme
   ============================================================ */

:root {
  --bg-deep:    #0d0a14;
  --bg-stone:   #1a1426;
  --bg-panel:   #241b36;
  --bg-card:    #2e2344;
  --border-stone: #4a3b66;
  --gold:       #f2c94c;
  --gold-dark:  #b8901f;
  --rupee:      #5d8bf4;
  --blood:      #e0455a;
  --mana:       #7f9cf5;
  --pi:         #8a3ffc;
  --pi-light:   #b07df7;
  --tg:         #2aabee;   /* Telegram brand blue — deliberately outside the game palette */
  --tg-deep:    #17313f;
  --text:       #e8e2f4;
  --text-dim:   #9b8fb5;
  --font-pixel: 'Press Start 2P', monospace;
  --font-body:  'VT323', monospace;
}

* { margin: 0; padding: 0; box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
.hidden { display: none !important; }

html, body {
  height: 100%;
  background: var(--bg-deep);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 20px;
  -webkit-font-smoothing: none;
  overscroll-behavior: none;
}

#app { max-width: 560px; margin: 0 auto; min-height: 100dvh; position: relative; }

/* ---------- screens ---------- */
.screen { display: none; min-height: 100dvh; flex-direction: column; }
.screen.active { display: flex; }

/* ---------- buttons ---------- */
.btn {
  font-family: var(--font-pixel);
  font-size: 11px;
  color: var(--text);
  background: var(--bg-card);
  border: 3px solid var(--border-stone);
  border-radius: 6px;
  padding: 12px 16px;
  cursor: pointer;
  text-transform: uppercase;
  letter-spacing: 1px;
  transition: transform .06s, filter .15s;
  touch-action: manipulation;
}
.btn:active { transform: translateY(2px); }
.btn:disabled { opacity: .45; cursor: not-allowed; }
.btn-gold  { background: linear-gradient(180deg, var(--gold), var(--gold-dark)); color: #241b00; border-color: #7c6011; }
.btn-pi    { background: linear-gradient(180deg, var(--pi-light), var(--pi)); color: #fff; border-color: #5b21b6; }
.btn-blood { background: linear-gradient(180deg, #f47187, var(--blood)); color: #2d060d; border-color: #8f1f30; }
.btn-stone { background: var(--bg-card); }
.btn-big   { font-size: 14px; padding: 18px 24px; }
.btn-small { font-size: 9px; padding: 8px 10px; }

/* ---------- title screen ---------- */
#screen-title {
  align-items: center; justify-content: center;
  background:
    radial-gradient(ellipse at 50% 20%, #2c1f4d 0%, transparent 55%),
    repeating-linear-gradient(0deg, #131020 0 42px, #171126 42px 44px),
    var(--bg-deep);
}
.title-wrap { text-align: center; padding: 24px; position: relative; width: 100%; }
.pixel-logo {
  image-rendering: pixelated;
  width: 96px; height: 96px;
  margin-bottom: 10px;
  filter: drop-shadow(0 6px 12px rgba(138, 63, 252, .4));
}
.game-logo { font-family: var(--font-pixel); line-height: 1.5; margin-bottom: 18px; }
.logo-line1 {
  display: block; font-size: clamp(16px, 5vw, 26px); color: var(--pi-light);
  text-shadow: 0 3px 0 #3c1a78, 0 6px 14px rgba(138, 63, 252, .45);
  letter-spacing: 6px;
}
.logo-line2 {
  display: block; font-size: clamp(18px, 5.4vw, 38px); color: var(--gold);
  text-wrap: balance;
  text-shadow: 0 4px 0 #6b4e00, 0 8px 18px rgba(242, 201, 76, .35);
}
.tagline {
  color: var(--text); font-size: 21px; margin-bottom: 28px;
  line-height: 1.3; text-wrap: balance;
}
.tagline-sub { color: var(--text-dim); font-size: 19px; }
.title-buttons { display: flex; flex-direction: column; gap: 14px; align-items: center; }
.title-buttons .btn { width: min(320px, 80vw); }
.title-status { margin-top: 16px; color: var(--rupee); min-height: 24px; font-size: 18px; }
.version-tag { margin-top: 26px; color: var(--text-dim); opacity: .6; font-size: 16px; }
.title-torch {
  position: absolute; top: -10px; width: 22px; height: 34px; border-radius: 40% 40% 30% 30%;
  background: radial-gradient(circle at 50% 30%, #ffe08a 0 30%, #ff9d2e 55%, #d43d0c 100%);
  animation: flicker 480ms infinite alternate; filter: blur(.4px);
}
.title-torch.left  { left: 8%; }
.title-torch.right { right: 8%; }
@keyframes flicker {
  from { transform: scale(1) rotate(-2deg); opacity: .92; }
  to   { transform: scale(1.12) rotate(2deg); opacity: 1; }
}

/* ---------- topbar ---------- */
.topbar {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 12px 14px;
  background: var(--bg-stone);
  border-bottom: 3px solid var(--border-stone);
  position: sticky; top: 0; z-index: 5;
}
.player-chip { display: flex; align-items: center; gap: 10px; }
.player-name { font-family: var(--font-pixel); font-size: 11px; color: var(--gold); }
.rupee-chip { font-size: 20px; color: var(--rupee); white-space: nowrap; }
.avatar-btn {
  width: 42px; height: 42px; font-size: 22px; line-height: 1; cursor: pointer;
  background: var(--bg-card); border: 2px solid var(--border-stone); border-radius: 10px;
  flex: 0 0 auto;
}
.avatar-btn:active { transform: scale(.94); }
.hud-balances { display: flex; align-items: center; gap: 10px; flex: 1; min-width: 0; overflow: hidden; }
.bal-chip { font-size: 18px; color: var(--rupee); white-space: nowrap; }
.bal-chip:nth-child(2) { color: var(--gold); }
.bal-pi { color: var(--pi-light); cursor: pointer; }
.sub-title { font-family: var(--font-pixel); font-size: 12px; color: var(--gold); text-align: center; flex: 1; }

/* ---------- main menu ---------- */
#screen-menu { background: var(--bg-deep); }
.menu-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 10px;
  /* Telegram lives in the grid now, so no reserved strip for a floating
     badge — the Keep fits on one screen without scrolling. */
  padding: 12px 14px 6px; flex: 1; align-content: start;
}
.menu-card {
  display: flex; flex-direction: column; align-items: center; gap: 5px;
  background: linear-gradient(180deg, var(--bg-card), var(--bg-panel));
  border: 3px solid var(--border-stone); border-radius: 10px;
  padding: 14px 10px; cursor: pointer; color: var(--text);
  font-family: var(--font-body);
  transition: border-color .15s, transform .06s;
  text-decoration: none;                 /* the Telegram card is an <a> */
}
.menu-card:active { transform: scale(.97); }
.menu-card:hover { border-color: var(--gold); }
.menu-emoji { font-size: 34px; }
.menu-card-wide { grid-column: 1 / -1; }
/* The invite card is an offer, not a menu item — it gets the full row and a
   gold edge so it reads as one. */
.menu-card-invite {
  grid-column: 1 / -1; flex-direction: row; justify-content: center; gap: 14px;
  border-color: var(--gold-dark);
  background: linear-gradient(180deg, #34294c, var(--bg-panel));
  padding: 14px 12px;
}
.menu-card-invite .menu-emoji { font-size: 28px; }
.menu-card-invite .menu-sub { text-align: left; }
/* Telegram keeps its brand blue on the edge, the grid's shape everywhere else. */
.menu-card-tg { border-color: var(--tg); }
.menu-card-tg:hover { border-color: var(--gold); }
.menu-card-tg .menu-emoji { display: flex; align-items: center; justify-content: center; height: 34px; }
.menu-card-tg svg { width: 30px; height: 30px; fill: var(--tg); }
.menu-title { font-family: var(--font-pixel); font-size: 11px; color: var(--gold); }
.menu-sub { color: var(--text-dim); font-size: 16px; text-align: center; line-height: 1.15; }
.menu-footer {
  padding: 4px 16px max(8px, env(safe-area-inset-bottom));
  color: var(--text-dim); font-size: 15px; text-align: center; line-height: 1.25;
}
.menu-footer .docs-link { display: block; margin-top: 2px; color: var(--gold); text-decoration: none; }
.menu-footer .docs-link:hover { text-decoration: underline; }
/* Short phones: shave the cards rather than let the Keep scroll. */
@media (max-height: 720px) {
  .menu-grid { gap: 8px; padding: 8px 12px 4px; }
  .menu-card { padding: 10px 8px; gap: 3px; }
  .menu-emoji { font-size: 27px; }
  .menu-card-tg .menu-emoji { height: 27px; }
  .menu-card-tg svg { width: 24px; height: 24px; }
  .menu-sub { font-size: 14px; }
  .menu-card-invite { padding: 10px; }
  .menu-footer { font-size: 14px; }
}

/* profile accomplishments */
.pf-badges { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; padding: 6px 2px; }
.pf-badge {
  background: var(--bg-panel); border: 2px solid var(--border-stone); border-radius: 8px;
  padding: 6px 10px; font-size: 17px; white-space: nowrap;
}
.pf-badge.locked { opacity: .38; filter: grayscale(.7); }

/* ---------- sub screens ---------- */
.sub-content { padding: 14px; flex: 1; overflow-y: auto; }
.card-list { display: flex; flex-direction: column; gap: 10px; }
.item-card {
  display: flex; gap: 12px; align-items: center;
  background: var(--bg-panel); border: 2px solid var(--border-stone);
  border-radius: 8px; padding: 10px 12px;
}
/* The card's art column is a fixed SQUARE that centres whatever it holds —
   a 48px pet sprite, a hero walk frame, a currency mark or a bare emoji.
   Before this it was a text box of fixed width and free height, so a row
   with a sprite sat taller than a row with a glyph and lists staircased. */
.item-card .ic-emoji {
  width: 42px; height: 42px;
  display: grid; place-items: center;
  font-size: 30px; line-height: 1;
  flex-shrink: 0;
}
.item-card .ic-emoji > .face,
.item-card .ic-emoji > img { width: 100%; height: 100%; }
.item-card .ic-body { flex: 1; min-width: 0; }
.item-card .ic-name { font-family: var(--font-pixel); font-size: 10px; margin-bottom: 4px; }
.item-card .ic-desc { color: var(--text-dim); font-size: 17px; line-height: 1.2; }
.item-card .ic-actions { display: flex; flex-direction: column; gap: 6px; align-items: flex-end; }
.price-tag { color: var(--rupee); font-size: 18px; white-space: nowrap; }
.price-tag.pi { color: var(--pi-light); }

/* A whole card that IS the button — the shop rows open checkout on tap,
   so the card needs to look and behave like something you press. */
.item-card.tappable {
  cursor: pointer; text-align: left; width: 100%; font: inherit; color: inherit;
  transition: border-color .12s, transform .06s;
}
.item-card.tappable:hover, .item-card.tappable:focus-visible {
  border-color: var(--gold); outline: none;
}
.item-card.tappable:active { transform: translateY(1px); }
.item-card.tappable .tap-hint { color: var(--gold); font-size: 15px; margin-top: 3px; }
.item-card.sold-out { opacity: .62; }
.pp-slot { min-height: 46px; margin-top: 6px; }

.rarity-common    { color: #cbd5e1; }
.rarity-uncommon  { color: #4ade80; }
.rarity-rare      { color: #60a5fa; }
.rarity-epic      { color: #c084fc; }
.rarity-legendary { color: var(--gold); }

.section-head {
  font-family: var(--font-pixel); font-size: 11px; color: var(--pi-light);
  margin: 18px 0 10px; letter-spacing: 1px;
}
.section-head:first-child { margin-top: 0; }

/* hero picker */
.hero-card { border-width: 3px; }
.hero-card.selected { border-color: var(--gold); box-shadow: 0 0 14px rgba(242, 201, 76, .25); }
.stat-pills { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.stat-pill {
  font-size: 15px; background: var(--bg-stone); border: 1px solid var(--border-stone);
  padding: 2px 8px; border-radius: 20px; color: var(--text-dim);
}
.stat-pill b { color: var(--text); }

/* equipment grid */
.equip-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; margin: 10px 0; }
.equip-slot {
  aspect-ratio: 1; display: flex; flex-direction: column; align-items: center; justify-content: center;
  background: var(--bg-panel); border: 2px dashed var(--border-stone); border-radius: 8px;
  font-size: 24px; cursor: pointer; gap: 2px;
}
.equip-slot.filled { border-style: solid; border-color: var(--gold-dark); }
.equip-slot .slot-label { font-size: 12px; color: var(--text-dim); }
.equip-slot > span:first-child { display: grid; place-items: center; min-height: 30px; }
.slot-icon { width: 24px; height: 24px; image-rendering: pixelated; opacity: .75; object-fit: contain; }

/* ---------- dungeon crawler ---------- */
#screen-dungeon { background: #151019; }
.crawl-wrap {
  position: relative; flex: 1; display: flex; flex-direction: column;
  height: 100dvh; overflow: hidden; touch-action: none;
}
#crawl-canvas {
  position: absolute; inset: 0; width: 100%; height: 100%;
  image-rendering: pixelated;
  background: #151019;
}

.crawl-hud {
  position: absolute; top: 10px; left: 10px; right: 10px; z-index: 4;
  display: flex; align-items: center; gap: 8px; pointer-events: none;
}
.hud-heart { font-size: 26px; filter: drop-shadow(0 2px 2px #000); }
.hud-heart img { width: 30px; height: 28px; image-rendering: pixelated; display: block; }
.pedia-icon { width: 42px; height: 42px; image-rendering: pixelated; object-fit: contain; }
.crawl-hpbar {
  position: relative; width: min(40vw, 178px); height: 18px;
  border: 2px solid #0d0a14; border-radius: 3px;
  background: #3a0a12; overflow: hidden;
  box-shadow: 0 2px 4px rgba(0,0,0,.6), inset 0 0 0 1px #6b4a2a;
}
.crawl-hpfill {
  height: 100%; width: 100%;
  /* red recolor of the bar art — full HP reads bright red, and
     refreshRunHud dims it toward dark dried-blood as HP drains */
  background: url('../assets/sprites/hpbar_fill_red.png') repeat-x, linear-gradient(180deg, #ff4d5e, #c11226);
  background-size: auto 100%;
  image-rendering: pixelated;
  transition: width .25s;
}
.rupee-icon { width: 18px; height: 18px; image-rendering: pixelated; vertical-align: -3px; }
.gem-icon { image-rendering: auto; }
.crawl-hpbar span {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  font-size: 12px; color: #fff; text-shadow: 0 1px 2px #000; font-family: var(--font-pixel); font-size: 8px;
}
.crawl-floor { font-family: var(--font-pixel); font-size: 11px; color: var(--gold); text-shadow: 0 2px 2px #000; margin-left: auto; }
.crawl-hud .rupee-chip { text-shadow: 0 2px 2px #000; }

.crawl-status {
  position: absolute; top: 40px; left: 12px; z-index: 4;
  font-size: 15px; color: var(--text); text-shadow: 0 1px 2px #000; pointer-events: none;
}

.crawl-side {
  position: absolute; right: 10px; bottom: 24%; z-index: 4;
  display: flex; flex-direction: column; gap: 10px;
}
.side-btn {
  width: 48px; height: 48px; font-size: 20px; cursor: pointer;
  background: url('../assets/sprites/btn_wood.png') no-repeat center / 100% 100%,
              linear-gradient(180deg, #7c5a34, #55381c);
  image-rendering: pixelated;
  border: none; border-radius: 6px;
  filter: drop-shadow(0 3px 4px rgba(0,0,0,.5));
  transition: transform .06s;
}
.side-btn:active { transform: scale(.92); }

.crawl-log {
  position: absolute; left: 10px; bottom: calc(24% + 4px); z-index: 3;
  max-width: 62vw; font-size: 15px; line-height: 1.25;
  text-shadow: 0 1px 2px #000, 0 0 4px #000; pointer-events: none;
}
.crawl-log p { margin: 0 0 2px; }
.log-hero { color: #7ce8a8; }
.log-foe  { color: #ff8a97; }
.log-gold { color: var(--gold); }
.log-sys  { color: #c9bfdd; }
.log-crit { color: var(--gold); font-weight: bold; }

/* full log overlay panel (the "COMBAT LOG" window) */
.log-overlay {
  max-height: 50dvh; overflow-y: auto; font-size: 17px; line-height: 1.3;
  background: rgba(10, 8, 16, .92); border: 2px solid var(--border-stone);
  border-radius: 6px; padding: 10px;
}

/* D-pad (cross-shaped pad, bottom center) */
.dpad {
  position: absolute; left: 50%; transform: translateX(-50%);
  bottom: calc(12px + env(safe-area-inset-bottom));
  display: grid; z-index: 4;
  grid-template-areas: ". up ." "left wait right" ". down .";
  gap: 0;
  background: url('../assets/sprites/dpad.png') no-repeat center / contain;
  image-rendering: pixelated;
  filter: drop-shadow(0 4px 6px rgba(0,0,0,.55));
  padding: 2px;
}
.dpad { touch-action: none; user-select: none; cursor: pointer; -webkit-tap-highlight-color: transparent; }
/* Physical press: the pad tilts like a real d-pad rocker — the edge you
   push dips into the screen. (transform must keep the translateX centering.) */
.dpad { transition: transform .07s ease-out; will-change: transform; }
.dpad.tilt-up    { transform: translateX(-50%) perspective(260px) rotateX(17deg); }
.dpad.tilt-down  { transform: translateX(-50%) perspective(260px) rotateX(-17deg); }
.dpad.tilt-left  { transform: translateX(-50%) perspective(260px) rotateY(-17deg); }
.dpad.tilt-right { transform: translateX(-50%) perspective(260px) rotateY(17deg); }
/* Arms are visual only — the pad itself is the touch surface, and every
   tap resolves to the nearest arrow (no accidental turn-wasting center). */
.dpad-btn {
  width: 56px; height: 56px; font-size: 20px; color: transparent;
  background: transparent; border: none;
  pointer-events: none; user-select: none;
}
.dpad-btn.pressed { background: radial-gradient(circle, rgba(255,220,150,.35) 0%, transparent 70%); }
.dpad-up { grid-area: up; } .dpad-left { grid-area: left; }
.dpad-right { grid-area: right; } .dpad-down { grid-area: down; }

@media (min-width: 700px) {
  .dpad { opacity: .45; }
  .dpad:hover { opacity: 1; }
}

/* ---------- modal ---------- */
.modal-backdrop {
  position: fixed; inset: 0; background: rgba(6, 4, 12, .82);
  display: flex; align-items: center; justify-content: center; z-index: 50; padding: 18px;
}
.modal-backdrop.hidden { display: none; }
.modal {
  width: min(440px, 100%); max-height: 84dvh; overflow-y: auto;
  background: var(--bg-panel); border: 3px solid var(--gold-dark);
  border-radius: 12px; padding: 20px;
}
.modal h3 { font-family: var(--font-pixel); font-size: 13px; color: var(--gold); margin-bottom: 14px; text-align: center; }
.modal p { margin-bottom: 10px; line-height: 1.3; }
.modal .modal-actions { display: flex; gap: 10px; justify-content: center; margin-top: 16px; flex-wrap: wrap; }
.modal .big-emoji { font-size: 56px; text-align: center; display: block; margin-bottom: 10px; }
.modal .big-emoji > .face { display: inline-grid; }

/* ---------- toasts ---------- */
.toast-stack {
  position: fixed; bottom: 18px; left: 50%; transform: translateX(-50%);
  display: flex; flex-direction: column; gap: 8px; z-index: 90; width: min(420px, 92vw);
}
.toast {
  background: var(--bg-card); border: 2px solid var(--gold-dark); border-radius: 8px;
  padding: 10px 14px; font-size: 18px; text-align: center;
  animation: toastin .25s;
}
@keyframes toastin { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; } }
body.in-dungeon .toast-stack { top: 64px; bottom: auto; }
body.in-dungeon .toast { animation: toastin-drop .25s; }
@keyframes toastin-drop { from { opacity: 0; transform: translateY(-12px); } to { opacity: 1; } }

/* ---------- collection (Pokédex) ---------- */
.col-head { font-family: var(--font-pixel); font-size: 11px; color: var(--gold); margin: 18px 0 10px; line-height: 1.7;
  display: flex; justify-content: space-between; align-items: baseline; }
.col-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 8px; }
.col-card {
  position: relative; display: flex; flex-direction: column; align-items: center; gap: 4px;
  background: var(--bg-panel); border: 2px solid var(--border-stone); border-radius: 8px;
  padding: 10px 6px 8px; min-height: 86px; justify-content: center;
}
.col-icon { height: 40px; display: flex; align-items: center; justify-content: center; }
.col-emoji { font-size: 30px; line-height: 1; }
.col-emoji > .face { display: inline-grid; }
.col-sprite { width: 40px; height: 40px; image-rendering: pixelated; }
.col-name { font-size: 15px; text-align: center; line-height: 1.1; word-break: break-word; }
.col-count {
  position: absolute; top: 4px; right: 6px;
  font-family: var(--font-pixel); font-size: 9px; color: var(--gold);
}
/* Undiscovered: a dark silhouette, the shape visible but nothing else. */
.col-locked .col-icon { filter: grayscale(1) brightness(0.22) !important; opacity: .9; }
.col-locked .col-name { color: var(--text-dim); opacity: .55; }
.col-locked { border-style: dashed; opacity: .8; }

/* ---- collection variants ----
   One pip per form a thing can take: the plain drop, each crafted grade,
   and the shiny of each. A lit pip wears that grade's own colour, so the
   grid answers "how far into this chase am I" without any reading. The
   shiny pips are the ring-shaped ones, so a row of ten still parses. */
.col-card { cursor: pointer; }
.col-pips {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 3px;
  margin-top: 2px; max-width: 100%;
}
.col-pip {
  width: 7px; height: 7px; border-radius: 50%;
  background: #2a2338; border: 1px solid #3d3450;
  flex-shrink: 0;
}
.col-pip.on { border-color: transparent; }
.col-pip.shiny { border-radius: 2px; transform: rotate(45deg); }
.col-vars {
  position: absolute; bottom: 3px; left: 6px;
  font-family: var(--font-pixel); font-size: 8px; color: var(--text-dim);
}
.col-card { padding-bottom: 14px; }
/* The detail sheet greys a variation you have never seen, art and all. */
.card-list .item-card.col-locked .ic-emoji { filter: grayscale(1) brightness(0.3); }

/* Stack size on inventory rows, sell lists and export buttons (×N). */
.stack-count {
  font-family: var(--font-pixel); font-size: 9px; color: var(--gold);
  background: rgba(0, 0, 0, .35); border-radius: 6px; padding: 1px 4px;
  vertical-align: middle;
}

/* ---------- Dice Duel (Knucklebones) ---------- */
.duel-grid { display: flex; justify-content: center; gap: 8px; margin: 6px 0; }
.duel-col {
  display: flex; flex-direction: column; gap: 4px; padding: 5px;
  background: rgba(0, 0, 0, .3); border: 2px solid var(--border-stone);
  border-radius: 8px; min-width: 52px; align-items: center;
}
.duel-col.duel-open { border-color: var(--gold); cursor: pointer; }
.duel-col.duel-open:hover { background: rgba(255, 200, 80, .12); }
.duel-cell {
  width: 40px; height: 40px; display: flex; align-items: center; justify-content: center;
  font-size: 40px; line-height: 1; color: #f2ead9;
  background: rgba(255, 255, 255, .05); border-radius: 6px;
}
.duel-colscore { font-family: var(--font-pixel); font-size: 10px; color: var(--gold); min-height: 12px; }
.duel-mid { text-align: center; margin: 8px 0; min-height: 40px; }
.duel-die { font-size: 40px; vertical-align: middle; line-height: 1; }
.duel-side { text-align: center; font-family: var(--font-pixel); font-size: 11px; }

/* ---------- game stats ---------- */
.gs-row {
  display: flex; justify-content: space-between; align-items: baseline; gap: 12px;
  padding: 5px 0; border-bottom: 1px solid rgba(74, 59, 102, .35);
}
.gs-row:last-child { border-bottom: none; }
.gs-label { color: var(--text-dim); font-size: 18px; }
.gs-value { color: var(--text); font-variant-numeric: tabular-nums; }

/* ---------- settings ---------- */
.set-head { font-family: var(--font-pixel); font-size: 11px; color: var(--gold); margin-bottom: 14px; line-height: 1.7; }
#sub-content .card + .card { margin-top: 16px; }
.set-row { margin-bottom: 14px; }
.set-label { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; margin-bottom: 5px; }
.set-val { font-family: var(--font-pixel); font-size: 10px; color: var(--gold); font-variant-numeric: tabular-nums; }
.set-hint { font-size: 16px; margin: 4px 0 0; line-height: 1.2; }
.set-toggle { display: flex; align-items: center; gap: 10px; cursor: pointer; }
.set-toggle input { width: 20px; height: 20px; accent-color: var(--gold); cursor: pointer; flex: none; }
.set-previews { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 12px; }
.set-previews .btn { padding: 8px 10px; font-size: 9px; }
/* Muted: the mixer stays readable but clearly inert. */
.set-off { opacity: .4; pointer-events: none; }

.set-range {
  -webkit-appearance: none; appearance: none;
  width: 100%; height: 10px; border-radius: 5px; cursor: pointer;
  background: var(--bg-stone);   /* JS paints the filled portion */
  border: 2px solid var(--border-stone);
}
.set-range::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 22px; height: 22px; border-radius: 4px;
  background: var(--bg-card); border: 3px solid var(--gold); cursor: pointer;
}
.set-range::-moz-range-thumb {
  width: 18px; height: 18px; border-radius: 4px;
  background: var(--bg-card); border: 3px solid var(--gold); cursor: pointer;
}
.set-range:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; }

/* ---------- testnet notice ----------
   A setup sheet, not a warning banner: numbered steps, and every value the
   wallet's "Add network" form asks for sitting on its own copyable row. */
.testnet-link {
  color: var(--pi-light); text-decoration: none; font-size: 17px;
  border-bottom: 1px dotted var(--pi-light); padding-bottom: 1px;
}
.testnet-link:hover, .testnet-link:focus-visible { color: var(--gold); border-bottom-color: var(--gold); }
/* Denser than a normal dialog: this one is a reference sheet, and the whole
   of step 1 should be reachable on a phone without hunting. */
.tn-body { font-size: 18px; }
.tn-body p { margin-bottom: 8px; line-height: 1.25; }
.modal h4.tn-step {
  font-family: var(--font-pixel); font-size: 10px; color: var(--gold);
  margin: 18px 0 8px; padding-top: 12px; border-top: 2px solid var(--border-stone);
  line-height: 1.7;
}
.tn-actions { display: flex; gap: 8px; flex-wrap: wrap; margin: 8px 0 10px; }
.tn-faucets { margin: 0 0 4px 20px; }
.tn-faucets li { margin-bottom: 6px; line-height: 1.25; }
.tn-faucets a { color: var(--pi-light); }
.tn-faucets a:hover { color: var(--gold); }

/* A value can be long (RPC URLs are), so it scrolls inside its own box
   rather than shoving the Copy button off the edge of a phone. */
.cp-row {
  display: grid; grid-template-columns: 1fr auto; gap: 4px 8px;
  align-items: center; margin-bottom: 8px;
}
.cp-label { grid-column: 1 / -1; font-size: 16px; color: var(--text-dim); }
.cp-value {
  font-family: monospace; font-size: 13px; color: var(--text);
  background: var(--bg-stone); border: 1px solid var(--border-stone);
  border-radius: 5px; padding: 6px 8px;
  overflow-x: auto; white-space: nowrap; min-width: 0;
}
.cp-btn { padding: 7px 10px; font-size: 9px; white-space: nowrap; }
.cp-btn.cp-ok { border-color: var(--rupee); color: var(--rupee); }
.tn-hide {
  display: flex; align-items: center; gap: 8px; margin-top: 18px;
  padding-top: 12px; border-top: 2px solid var(--border-stone);
  cursor: pointer; color: var(--text-dim);
}
.tn-hide input { width: 18px; height: 18px; accent-color: var(--gold); cursor: pointer; }

/* ---------- floating Telegram badge ----------
   Only on the title screen and the Keep (body.show-tg, set by UI.show), so it
   never sits over the d-pad during a run or over a menu you're reading.
   Below the modal (50) and toasts (90), above the sticky topbar (5). */
.tg-link {
  position: fixed;
  right: max(12px, env(safe-area-inset-right));
  bottom: max(12px, env(safe-area-inset-bottom));
  z-index: 6;
  display: none;
  align-items: center; gap: 8px;
  padding: 9px 13px;
  font-family: var(--font-pixel); font-size: 10px; line-height: 1;
  color: var(--text); text-decoration: none;
  background: linear-gradient(180deg, var(--bg-card), var(--bg-panel));
  border: 3px solid var(--tg); border-radius: 10px;
  box-shadow: 0 3px 0 var(--tg-deep), 0 0 12px rgba(42, 171, 238, .28);
  transition: transform .12s, box-shadow .12s;
}
body.show-tg .tg-link { display: flex; }
.tg-link svg { width: 18px; height: 18px; flex: none; fill: var(--tg); }
.tg-link:hover, .tg-link:focus-visible {
  transform: translateY(-2px);
  box-shadow: 0 5px 0 var(--tg-deep), 0 0 16px rgba(42, 171, 238, .45);
}
.tg-link:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
.tg-link:active { transform: translateY(1px); box-shadow: 0 2px 0 var(--tg-deep); }
@media (prefers-reduced-motion: reduce) { .tg-link { transition: none; } }
/* Only on genuinely tiny screens drop to the icon alone — on a normal phone
   the word is what makes the badge legible, and the corner has room for it. */
@media (max-width: 340px) {
  .tg-link { gap: 0; padding: 10px; }
  .tg-label { display: none; }
}

/* ---------- leaderboard ---------- */
.lb-tabs { display: flex; gap: 8px; margin-bottom: 12px; }
.lb-tabs .btn { flex: 1; }
.lb-tabs .btn.active { border-color: var(--gold); color: var(--gold); }
.lb-row {
  display: flex; align-items: center; gap: 12px; padding: 8px 12px;
  background: var(--bg-panel); border: 2px solid var(--border-stone); border-radius: 8px;
}
.lb-rank { font-family: var(--font-pixel); font-size: 11px; color: var(--text-dim); width: 34px; }
.lb-row:nth-child(1) .lb-rank { color: var(--gold); }
.lb-row:nth-child(2) .lb-rank { color: #cbd5e1; }
.lb-row:nth-child(3) .lb-rank { color: #d97706; }
.lb-name { flex: 1; font-size: 20px; }
.lb-score { color: var(--rupee); font-size: 20px; }

/* ---------- NFT Market inputs ---------- */
.mk-input {
  background: rgba(0, 0, 0, .35);
  border: 2px solid var(--border-stone);
  border-radius: 8px;
  color: var(--text);
  font-family: inherit;
  font-size: 18px;
  padding: 8px 10px;
  width: 130px;
  margin: 4px;
}
.mk-input:focus { outline: none; border-color: var(--gold); }

/* ---------- misc ---------- */
.dim { color: var(--text-dim); }
.gold { color: var(--gold); }
.center { text-align: center; }
.mt { margin-top: 14px; }
.hr { border: none; border-top: 2px solid var(--border-stone); margin: 14px 0; }

@media (min-width: 561px) {
  #app { border-left: 3px solid var(--border-stone); border-right: 3px solid var(--border-stone); }
}

/* ---------- Google sign-in: game-styled face, real GIS iframe on top ---------- */
.g-wrap { position: relative; width: min(320px, 80vw); }
.g-wrap .btn { width: 100%; pointer-events: none; }
/* Two lines in one button: the action in the game's voice, then how you get
   there in a quieter one. Both have to sit inside the same box the email
   button does, so the second line drops to the body face. */
.g-face {
  display: flex; flex-direction: column; align-items: center; gap: 5px;
  line-height: 1.25; padding: 14px 16px;
}
.g-face .g-line1 { font-size: 13px; letter-spacing: 1px; }
.g-face .g-line2 {
  font-family: var(--font-body); font-size: 17px; letter-spacing: 0;
  text-transform: none; opacity: .85;
}
@media (max-width: 360px) {
  .g-face .g-line1 { font-size: 11px; }
  .g-face .g-line2 { font-size: 16px; }
}
.g-overlay {
  position: absolute; inset: 0; z-index: 2;
  display: flex; justify-content: center; align-items: center;
  opacity: 0.001; overflow: hidden;
}

/* ---------- explorer links + transfer form ---------- */
.xlink { color: var(--gold); text-decoration: none; font-size: 12px; }
.xlink:hover { text-decoration: underline; }
.mono { font-family: monospace; word-break: break-all; }
/* The invite exactly as it will be sent — selectable, so it can also be
   copied by hand on a browser that blocks the clipboard API. */
.invite-msg {
  margin-top: 10px; padding: 10px 12px;
  background: var(--bg-deep); border: 2px solid var(--border-stone); border-radius: 8px;
  color: var(--text-dim); font-size: 16px; line-height: 1.35;
  word-break: break-word; user-select: text; -webkit-user-select: text;
  max-height: 9.5em; overflow-y: auto;
}
.small { font-size: 12px; }
#tf-to, #tf-amount, #tf-kind, #tf-relic { width: 100%; margin: 4px 0 10px; }

/* ---------- PWA install banner (mobile) ---------- */
.pwa-banner {
  position: fixed; left: 10px; right: 10px; bottom: 10px; z-index: 60;
  display: flex; align-items: center; gap: 10px;
  background: var(--bg-card); border: 3px solid var(--border-stone); border-radius: 10px;
  padding: 10px 12px; box-shadow: 0 6px 18px rgba(0,0,0,.5);
}
.pwa-banner .pwa-txt { flex: 1; font-size: 13px; color: var(--text); }
.pwa-banner .pwa-x { background: none; border: none; color: var(--text-dim); font-size: 18px; padding: 4px; cursor: pointer; }
.cur-icon { width: 14px; height: 14px; vertical-align: -2px; }
/* The currency marks stand in for emoji in places sized for emoji, so they
   have to grow with the slot instead of staying 14px inside a 56px hero. */
.topbar .cur-icon { width: 18px; height: 18px; vertical-align: -3px; }
.item-card .ic-emoji .cur-icon { width: 30px; height: 30px; vertical-align: -4px; }
.modal .big-emoji .cur-icon { width: 56px; height: 56px; vertical-align: 0; }
.pf-badge .cur-icon { width: 15px; height: 15px; vertical-align: -3px; }

/* ---- the Roost: an evolution chain at a glance ---------------------------
   Three forms and two arrows have to fit a phone without wrapping into
   nonsense, so the row scrolls sideways in its own box rather than pushing
   the page around. The unreached forms stay dim: the road is visible, the
   destination is not spoiled by pretending you own it. */
.roost-chain {
  display: flex; align-items: center; justify-content: center;
  gap: 4px; padding: 8px 6px; margin-bottom: 8px;
  background: var(--bg-panel); border: 2px solid var(--border-stone); border-radius: 6px;
  overflow-x: auto;
}
.roost-step {
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  min-width: 62px; flex-shrink: 0;
}
/* Not yet yours: the real creature, in shadow. Named, so the road ahead is
   legible; darkened, so it still reads as something to earn. */
.roost-step:not(.has) .roost-face { filter: brightness(.28) contrast(1.4); opacity: .8; }
.roost-step:not(.has) .roost-label { opacity: .6; }
.roost-face { font-size: 22px; line-height: 1; }
.roost-face .pedia-icon { width: 34px; height: 34px; image-rendering: pixelated; }
.roost-label {
  font-family: var(--font-pixel); font-size: 7px; text-align: center;
  color: var(--text-dim); line-height: 1.3; word-break: break-word;
}
.roost-step.has .roost-label { color: var(--gold); }
.roost-arrow { color: var(--text-dim); font-size: 15px; flex-shrink: 0; }

/* A warning that costs the player something — an equipped item about to be
   destroyed — needs to read as a warning, not as more dim body text. */
.warn { color: #ffae4d; }

/* The crusader roster shows the REAL walk sprite (frame 0 of hero_south),
   hue-rotated per hero — the same four variants the dungeon draws, so the
   hero you pick is the hero you see. `background-position: 0 0` pins the
   first frame of the 7-frame strip; the sheet is never scaled unevenly, so
   the pixels stay square. */
.hero-face {
  display: inline-block;
  background-repeat: no-repeat;
  background-position: 0 0;
  image-rendering: pixelated;
  vertical-align: middle;
}

/* ---- one face box for every entity ---------------------------------------
   Heroes, pets and monsters have real sprites; items do not (thirty items,
   no art). So consistency is enforced by the BOX, not by the contents: an
   emoji and a 48px sprite occupy the same square, centred, so a list never
   staircases — items, pets, monsters and heroes all draw the same box. */
.face {
  display: inline-grid;
  place-items: center;
  flex-shrink: 0;
  line-height: 1;
  background-repeat: no-repeat;
  background-position: 0 0;
  image-rendering: pixelated;
  vertical-align: middle;
}
.face img {
  width: 100%; height: 100%;
  object-fit: contain;
  image-rendering: pixelated;
}

/* ---- the delve report -----------------------------------------------------
   A list, not a paragraph: one row per fact, each led by the real art. The
   tally strips wrap and scroll rather than pushing the modal wider, because
   a long run can slay eight kinds of monster. */
.run-report { margin: 10px 0 4px; }
.report-row {
  display: flex; align-items: center; gap: 10px;
  padding: 5px 8px; border-bottom: 1px solid var(--border-stone);
}
.report-row:last-child { border-bottom: none; }
/* A party is several faces, so this column is a ROW that grows — fixed at
   one face's width it wrapped the pets under the hero. */
.report-face { display: flex; align-items: center; gap: 2px; flex-shrink: 0; }
.report-label { color: var(--text-dim); flex: 1; min-width: 0; }
.report-value { text-align: right; white-space: nowrap; }
.report-head {
  font-family: var(--font-pixel); font-size: 9px; color: var(--gold);
  margin: 12px 0 6px; line-height: 1.6;
}
.report-icons {
  display: flex; flex-wrap: wrap; gap: 8px 12px;
  justify-content: center;
}
.report-tally { display: inline-flex; align-items: center; gap: 3px; }
.report-tally b { font-size: 17px; color: var(--text); }


/* ---- Receipts: the two tabs, and the token statement ----
   Owed is the headline cell because it is the number that explains why
   the wallet balance has not moved. */
.rc-tabs { display: flex; gap: 8px; margin: 6px 0 14px; }
.rc-tab {
  flex: 1; padding: 10px 8px; border-radius: 8px; cursor: pointer;
  background: var(--bg-panel); color: var(--text-dim);
  border: 2px solid var(--border-stone);
  font-family: var(--font-pixel); font-size: 10px; line-height: 1.6;
}
.rc-tab.on { color: var(--gold); border-color: var(--gold-dark); background: var(--bg-panel-2, var(--bg-panel)); }
.rc-tab .cur-icon { vertical-align: -2px; }

.tok-sum { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; margin-bottom: 6px; }
.tok-cell {
  background: var(--bg-panel); border: 2px solid var(--border-stone);
  border-radius: 8px; padding: 11px 12px; display: flex; flex-direction: column; gap: 3px;
}
.tok-cell.tok-live { border-color: var(--gold-dark); }
.tok-k { font-size: 13px; color: var(--text-dim); }
.tok-v { font-family: var(--font-pixel); font-size: 12px; line-height: 1.5; }
.tok-v.up { color: #5fd39a; }
.tok-v.down { color: #ff9a4d; }
.tok-note { font-size: 12px; color: var(--text-dim); opacity: .8; line-height: 1.25; }
.tok-amt { font-family: var(--font-pixel); font-size: 11px; white-space: nowrap; }
.tok-amt.up { color: #5fd39a; }
.tok-amt.down { color: #ff9a4d; }
.tok-amt.dim { color: var(--text-dim); }
@media (max-width: 380px) { .tok-sum { grid-template-columns: 1fr; } }

/* ============================================================
   THE BENCH — one layout for crafting and for equipping.

   Both screens are the same shape underneath: a row of tabs, a grid of
   things you own, and a tray that commits. They were built together so
   the muscle memory transfers, and so a phone in portrait never has to
   scroll sideways to see what it is choosing between. The reference
   layout puts its panels side by side; on a 360px screen that becomes a
   stack, which is why the tray is pinned to the bottom rather than
   parked to the right.
   ============================================================ */

.bench-tabs {
  display: flex; gap: 6px; margin: 2px 0 12px;
  overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch;
}
.bench-tabs::-webkit-scrollbar { display: none; }
.bench-tab {
  flex: 1 1 0; min-width: 0; padding: 9px 6px 8px;
  background: var(--bg-panel); border: 2px solid var(--border-stone);
  border-bottom-width: 4px; border-radius: 9px 9px 4px 4px;
  color: var(--text-dim); font-family: var(--font-pixel); font-size: 9px;
  display: flex; flex-direction: column; align-items: center; gap: 5px;
  cursor: pointer; line-height: 1.5; text-align: center;
}
.bench-tab .bt-ic { font-size: 19px; line-height: 1; }
.bench-tab .bt-ic > .face, .bench-tab .bt-ic > img { width: 22px; height: 22px; }
.bench-tab.on {
  color: var(--gold); border-color: var(--gold-dark);
  background: var(--bg-card); border-bottom-color: var(--gold);
}
.bench-tab .bt-n { font-size: 8px; opacity: .75; }
/* A long label must shrink rather than push its neighbour off the screen. */
.bench-tab { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* The grid of what you own. 64px minimum keeps a 44px tap target with
   room for the count badge, and auto-fill means the same markup is three
   columns on a phone and six on a tablet without a media query. */
.bench-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(64px, 1fr));
  gap: 8px; margin-bottom: 12px;
}
.bench-cell {
  position: relative; aspect-ratio: 1; display: grid; place-items: center;
  background: var(--bg-panel); border: 2px solid var(--border-stone);
  border-radius: 8px; cursor: pointer; padding: 4px;
  transition: border-color .12s, transform .08s, opacity .12s;
}
.bench-cell:active { transform: translateY(1px); }
.bench-cell .face, .bench-cell img.px { width: 34px; height: 34px; image-rendering: pixelated; }
.bench-cell .bc-n {
  position: absolute; right: 3px; bottom: 2px;
  font-family: var(--font-pixel); font-size: 8px; color: var(--text);
  background: rgba(13, 10, 20, .82); border-radius: 4px; padding: 1px 3px;
}
.bench-cell .bc-lv {
  position: absolute; left: 3px; top: 2px;
  font-size: 12px; color: var(--text-dim);
}
.bench-cell.on { border-color: var(--gold); box-shadow: 0 0 0 2px rgba(242, 201, 76, .22) inset; }
.bench-cell.picked { border-color: var(--gold); background: #3a2b18; }

/* The whole point of the selection: everything that CANNOT join the
   craft goes quiet, so the eye lands only on what can. Kept as opacity
   plus a desaturate rather than a colour change — a dimmed legendary is
   still recognisably a legendary. */
.bench-cell.off {
  opacity: .26; filter: grayscale(.85); cursor: default; pointer-events: none;
}
.bench-cell.off .bc-n { background: none; }

.bench-empty { color: var(--text-dim); text-align: center; padding: 22px 8px; font-size: 18px; }

/* The tray: what you have chosen, what it becomes, what it costs. Its whole
   job is to keep Done / Create under the thumb.

   It used to be `position: sticky; bottom: 0` plus a flex column that pushed
   it down with an auto margin, and that comment claimed to cover both a short
   page and a long one. It did not. Sticky-bottom CANNOT pin a LAST CHILD:
   the element sticks only while its containing block still has room BELOW it
   to scroll through, and the tray is the last thing in the box. So on a short
   page it looked right, and on a long one — a gear list with a dozen stacks —
   it sat at the very end of the document, off the bottom of the screen, with
   the Done button unreachable until you scrolled for it.

   Fixed to the viewport instead, which is what "under the thumb" actually
   means, with the scroll container padded so the last row of the grid is
   never left underneath it. Below the modal backdrop (z 50) on purpose: the
   copy picker opens OVER this. */
.sub-content:has(> .bench-tray) { padding-bottom: calc(var(--tray-h, 180px) + 14px); }

.bench-tray {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 6;
  background: linear-gradient(180deg, rgba(26, 20, 38, .92), var(--bg-stone) 26%);
  border-top: 2px solid var(--border-stone);
  margin: 0; padding: 10px 14px calc(12px + env(safe-area-inset-bottom));
}
.bench-slots { display: flex; align-items: center; justify-content: center; gap: 6px; margin-bottom: 8px; }
.bench-slot {
  width: 42px; height: 42px; flex: none; display: grid; place-items: center;
  background: var(--bg-panel); border: 2px dashed var(--border-stone); border-radius: 7px;
}
.bench-slot.full { border-style: solid; border-color: var(--gold-dark); background: var(--bg-card); }
.bench-slot .face, .bench-slot img.px { width: 26px; height: 26px; image-rendering: pixelated; }
.bench-arrow { color: var(--text-dim); font-size: 20px; padding: 0 2px; }
.bench-out {
  width: 50px; height: 50px; flex: none; display: grid; place-items: center;
  background: var(--bg-card); border: 2px solid var(--gold); border-radius: 8px;
}
.bench-out .face, .bench-out img.px { width: 32px; height: 32px; image-rendering: pixelated; }
.bench-line { text-align: center; font-size: 16px; color: var(--text-dim); margin-bottom: 8px; line-height: 1.3; }
.bench-line b { color: var(--text); }
.bench-cost { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; margin-bottom: 8px; font-size: 17px; }
.bench-cost .short { color: var(--blood); }
.bench-actions { display: flex; gap: 8px; }
.bench-actions .btn { flex: 1; }

/* How many to throw in. Each step is one more grade, which is the whole
   idea, so the buttons say the grade rather than the count alone. */
.bench-mult { display: flex; gap: 6px; justify-content: center; margin-bottom: 9px; flex-wrap: wrap; }
.bench-mult button {
  min-width: 62px; padding: 7px 9px; border-radius: 7px; cursor: pointer;
  background: var(--bg-panel); border: 2px solid var(--border-stone); color: var(--text-dim);
  font-family: var(--font-pixel); font-size: 9px; line-height: 1.5;
}
.bench-mult button.on { border-color: var(--gold); color: var(--gold); background: var(--bg-card); }
.bench-mult button:disabled { opacity: .3; cursor: default; }
.bench-mult .bm-sub { display: block; font-size: 8px; opacity: .8; margin-top: 3px; }

/* ---------- the equip sheet ---------- */
/* Portrait phones get the paper-doll stacked above its slots rather than
   beside them, which is the one real change from the reference layout. */
.eq-hero {
  display: flex; align-items: center; gap: 12px; margin-bottom: 12px;
  background: var(--bg-panel); border: 2px solid var(--border-stone);
  border-radius: 10px; padding: 10px 12px;
}
.eq-hero .eq-face { width: 54px; height: 54px; flex: none; display: grid; place-items: center; }
.eq-hero .eq-face .face, .eq-hero .eq-face img { width: 100%; height: 100%; image-rendering: pixelated; }
.eq-hero .eq-name { font-family: var(--font-pixel); font-size: 11px; color: var(--gold); margin-bottom: 5px; }
.eq-slots { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; margin-bottom: 12px; }
@media (max-width: 340px) { .eq-slots { grid-template-columns: repeat(3, 1fr); } }
.eq-slot {
  position: relative; aspect-ratio: 1; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 3px; padding: 3px;
  background: var(--bg-panel); border: 2px dashed var(--border-stone);
  border-radius: 8px; cursor: pointer;
}
.eq-slot.filled { border-style: solid; border-color: var(--gold-dark); }
.eq-slot.on { border-color: var(--gold); background: var(--bg-card); box-shadow: 0 0 0 2px rgba(242,201,76,.2) inset; }
.eq-slot .face, .eq-slot img.px { width: 30px; height: 30px; image-rendering: pixelated; }
.eq-slot .eq-lab { font-size: 11px; color: var(--text-dim); line-height: 1; text-align: center; }
.eq-slot .eq-lv { position: absolute; right: 3px; top: 2px; font-size: 11px; color: var(--gold); }
.eq-stats { display: flex; flex-wrap: wrap; gap: 5px; }

/* ---------- the walkthrough ----------

   The dimming is done with four opaque panels laid AROUND the highlighted
   element, not with one overlay and a hole in it. The highlighted element is
   therefore covered by nothing: it keeps real hit-testing, real :active, and
   needs no z-index of its own — which matters, because the things being
   pointed at live in half a dozen different stacking contexts. */

/* The root spans the viewport so its children can be positioned against it,
   which means it would itself swallow the tap meant for the spotlit element.
   Only the parts that are supposed to catch anything opt back in. */
.tour-root { position: fixed; inset: 0; z-index: 200; display: none; pointer-events: none; }
.tour-root.on { display: block; }
.tour-pane { position: fixed; background: rgba(8, 5, 14, .82); pointer-events: auto; }
.tour-ring {
  position: fixed; border: 3px solid var(--gold); border-radius: 10px;
  box-shadow: 0 0 0 3px rgba(242, 201, 76, .22), 0 0 22px rgba(242, 201, 76, .4);
  pointer-events: none;                       /* never intercept the tap it invites */
  animation: tour-pulse 1.5s ease-in-out infinite;
}
@keyframes tour-pulse {
  0%, 100% { box-shadow: 0 0 0 3px rgba(242, 201, 76, .22), 0 0 22px rgba(242, 201, 76, .40); }
  50%      { box-shadow: 0 0 0 6px rgba(242, 201, 76, .10), 0 0 30px rgba(242, 201, 76, .62); }
}
@media (prefers-reduced-motion: reduce) { .tour-ring { animation: none; } }

.tour-bubble {
  position: fixed; left: 50%; transform: translateX(-50%);
  width: min(440px, calc(100vw - 24px));
  max-height: 62vh; overflow-y: auto;
  background: var(--bg-panel); border: 3px solid var(--gold-dark);
  border-radius: 12px; padding: 14px 16px;
  font-family: var(--font-body); font-size: 19px; line-height: 1.42; color: var(--text);
  box-shadow: 0 10px 34px rgba(0, 0, 0, .6);
  pointer-events: auto;                       /* Next and Skip must be clickable */
}
/* A step with nothing to point at is a full-screen message instead. */
.tour-bubble-center { top: 50% !important; transform: translate(-50%, -50%); }
.tour-bubble h4 {
  font-family: var(--font-pixel); font-size: 12px; color: var(--gold);
  line-height: 1.7; margin: 2px 0 9px;
}
.tour-bubble p { margin-bottom: 8px; }
.tour-bubble p:last-child { margin-bottom: 0; }
.tour-bubble b { color: var(--gold); }
.tour-step { font-family: var(--font-pixel); font-size: 8px; color: var(--text-dim); letter-spacing: 1px; }
.tour-dim { color: var(--text-dim); }
.tour-actions {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  margin-top: 12px; flex-wrap: wrap;
}
/* Not a button: there is nothing to press, and one that looked pressable
   would be the most tapped dead pixel in the game. */
.tour-tap {
  font-family: var(--font-pixel); font-size: 9px; color: var(--gold);
  line-height: 1.7; animation: tour-nudge 1.4s ease-in-out infinite;
}
@keyframes tour-nudge { 0%, 100% { opacity: .65; } 50% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .tour-tap { animation: none; } }
.tour-skip {
  background: none; border: none; cursor: pointer;
  font-family: var(--font-body); font-size: 17px; color: var(--text-dim);
  text-decoration: underline; padding: 2px 4px;
}
.tour-skip:hover { color: var(--text); }

/* Toasts have to clear the walkthrough — "Equipped!" landing behind the
   scrim during the equip step is exactly when it is most worth reading. */
.toast-stack { z-index: 400; }
