:root {
  --spring: #5fae5f;
  --summer: #e3b13a;
  --fall: #cf6a2e;
  --winter: #4f86c6;
  /* economy keyword colors */
  --husbandry: #5fae5f;
  --smithing:  #cf6a2e;
  --rest:      #4f86c6;
  --networking: #b06fc6;
  --crime:     #b23b3b;
}

* { box-sizing: border-box; }

/* The `hidden` attribute must always win, even over id rules that set display
   (e.g. #treasure-screen / #player-side use display:flex). Without this, hiding
   them leaves them stuck on screen. */
[hidden] { display: none !important; }

body {
  font-family: system-ui, sans-serif;
  margin: 0;
  min-height: 100vh;
  background: radial-gradient(circle at 50% 30%, #2f3540, #1b1e25);
  color: #eee;
  overflow: hidden;
  /* This is a click-and-drag game UI — nothing on it is meant to be selected.
     Without this, dragging a card (especially over text/labels) starts a text
     selection and leaves stray blue highlight boxes across the page. */
  -webkit-user-select: none;
  -moz-user-select: none;
  user-select: none;
}

/* Images should never start a native drag-ghost either (another way a drag
   "grabs" an asset off the page). draggable="false" covers most; this is the net. */
img { -webkit-user-drag: none; user-drag: none; }

/* ---- "open in another window" screen (single-session guard) ----
   Sits over everything and blocks interaction: a player only plays in one window. */
#session-parked {
  position: fixed;
  inset: 0;
  z-index: 99999;
  display: flex;
  align-items: center;
  justify-content: center;
  background: radial-gradient(circle at 50% 30%, rgba(26,30,38,.97), rgba(12,14,18,.99));
  backdrop-filter: blur(6px);
  padding: 24px;
}
#session-parked .sp-card {
  max-width: 420px;
  text-align: center;
  background: #1d222a;
  border: 1px solid #2c333d;
  border-radius: 16px;
  padding: 34px 30px;
  box-shadow: 0 24px 70px rgba(0,0,0,.55);
}
#session-parked .sp-emoji { font-size: 46px; line-height: 1; }
#session-parked h2 { margin: 14px 0 8px; font-size: 22px; color: #e7edf3; }
#session-parked p { margin: 0 0 22px; color: #aab4c0; line-height: 1.5; }
#session-parked button {
  font: inherit;
  font-weight: 600;
  color: #06222a;
  background: #25d0e0;
  border: 0;
  border-radius: 10px;
  padding: 11px 22px;
  cursor: pointer;
  transition: filter .12s ease, transform .12s ease;
}
#session-parked button:hover { filter: brightness(1.08); transform: translateY(-1px); }

/* ---- auth bar (top-right) ---- */
#auth-bar {
  position: fixed;
  top: 12px;
  right: 16px;
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: .85rem;
  color: #cfd3da;
  z-index: 1000;
}
#auth-bar button,
#auth-bar a {
  padding: .4rem .8rem;
  font-size: .85rem;
  cursor: pointer;
  border: 0;
  border-radius: 6px;
  background: #3a6ea5;
  color: #fff;
  text-decoration: none;       /* the "View art" link should read as a button */
  display: inline-flex;
  align-items: center;
}
#auth-bar button.ghost-btn,
#auth-bar a.ghost-btn { background: #4a4f59; }   /* low-key "Play as guest" / "View art" */
/* "Retry visit" sits quiet until you click it; the second (confirming) click state
   glows amber so it's clear it's about to undo the whole visit. */
#reset-visit { background: #4a4f59; }
#reset-visit.armed { background: #c8762a; box-shadow: 0 0 0 2px rgba(255,180,90,.5); }

/* ---- settings dropdown (top-right, under the ⚙️ gear) ---- */
#settings-panel {
  position: fixed;
  top: 52px;
  right: 16px;
  width: 250px;
  padding: 14px;
  background: rgba(30, 33, 40, .97);
  border: 1px solid #444;
  border-radius: 12px;
  box-shadow: 0 10px 40px rgba(0, 0, 0, .5);
  z-index: 1001;
  color: #cfd3da;
}
#settings-panel h3 { margin: 0 0 10px; font-size: .95rem; color: #fff; }
#settings-panel .settings-note { margin: 8px 0 0; font-size: .72rem; line-height: 1.35; color: #9aa0a8; }
.settings-sound-btn {
  width: 100%;
  padding: .55rem .8rem;
  font-size: .9rem;
  font-weight: 700;
  cursor: pointer;
  border: 1px solid #4a5160;
  border-radius: 7px;
  background: rgba(40, 46, 60, .7);
  color: #fff;
  margin-bottom: 10px;
}
.settings-sound-btn:hover { background: rgba(54, 62, 80, .9); }
/* Master volume slider — sits right under the Sound toggle. */
.settings-volume {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
  padding: 2px 2px;
}
.settings-volume-icon { font-size: .95rem; line-height: 1; opacity: .85; }
.settings-volume-slider {
  flex: 1;
  height: 6px;
  -webkit-appearance: none;
  appearance: none;
  border-radius: 4px;
  background: linear-gradient(90deg, #5aa0ff, #7fd0ff);
  cursor: pointer;
  outline: none;
}
.settings-volume-slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 15px;
  height: 15px;
  border-radius: 50%;
  background: #fff;
  border: 2px solid #4a5160;
  box-shadow: 0 1px 4px rgba(0, 0, 0, .5);
  cursor: pointer;
}
.settings-volume-slider::-moz-range-thumb {
  width: 15px;
  height: 15px;
  border-radius: 50%;
  background: #fff;
  border: 2px solid #4a5160;
  box-shadow: 0 1px 4px rgba(0, 0, 0, .5);
  cursor: pointer;
}
.end-run-btn {
  width: 100%;
  padding: .55rem .8rem;
  font-size: .9rem;
  font-weight: 700;
  cursor: pointer;
  border: 0;
  border-radius: 7px;
  background: #7a4a4a;            /* quiet maroon until armed */
  color: #fff;
}
.end-run-btn.armed {              /* second-click confirm state: glowing red */
  background: #c8392a;
  box-shadow: 0 0 0 2px rgba(255, 120, 100, .5);
}

/* ---- deck corner (top-left) ---- */
#deck-corner {
  position: fixed;
  top: 12px;
  left: 16px;
  z-index: 1000;
}
#deck-btn {
  padding: .5rem 1rem;
  font-size: 1rem;
  cursor: pointer;
  border: 0;
  border-radius: 8px;
  background: #c9a24b;
  color: #2b2b33;
  font-weight: 700;
  box-shadow: 0 2px 8px rgba(0, 0, 0, .35);
}
#deck-menu {
  margin-top: 8px;
  width: 320px;
  max-height: 70vh;
  overflow-y: auto;
  padding: 12px;
  background: rgba(30, 33, 40, .97);
  border: 1px solid #444;
  border-radius: 12px;
  box-shadow: 0 10px 40px rgba(0, 0, 0, .5);
}
#deck-menu-empty { color: #888; font-size: .85rem; text-align: center; padding: 1rem 0; }
#deck-list {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}
.deck-item {
  cursor: default;
  user-select: none;
  touch-action: none;
  transition: transform .08s;
}
.deck-item:hover { transform: translateY(-2px); }
.deck-hint { grid-column: 1 / -1; color: #888; font-size: .72rem; text-align: center; margin-top: 4px; }

/* ---- the card: portrait, two-sided (back stacked behind front) ---- */
.card {
  position: relative;
  width: 100%;
  aspect-ratio: 1 / 2;   /* twice as tall as wide */
}
.card .card-face { position: absolute; inset: 0; }
.card .face-back { z-index: 1; }
.card .face-front { z-index: 2; }

.card-face {
  position: relative;          /* containing block for the tesla-coil badge */
  width: 100%;
  aspect-ratio: 1 / 2;
  border-radius: 11px;
  background: #fbf7ef;
  color: #2b2b33;
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .12), 0 2px 6px rgba(0, 0, 0, .3);
  display: flex;
  flex-direction: column;
  padding: 8px;
  padding-bottom: 17px;        /* clear a strip at the bottom for the rarity badge */
  overflow: hidden;
}
.card-face.front { border-top: 5px solid var(--accent, #999); }
.card-face.back { background: linear-gradient(165deg, #fff6e0, #f4e3b6); }

/* ---- model-split chooser: pick a play mode, drag it onto the battlefield ---- */
#model-chooser {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 1350;
  display: flex;
  justify-content: center;
}
#model-chooser[hidden] { display: none; }
#model-chooser-inner {
  margin-top: 12px;
  padding: 10px 16px 14px;
  border-radius: 14px;
  background: rgba(18, 20, 28, .93);
  border: 1px solid rgba(200, 170, 255, .5);
  box-shadow: 0 12px 44px rgba(0, 0, 0, .6);
  max-width: 94vw;
}
.model-chooser-head {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  color: #e9d8ff; font-weight: 700; font-size: .82rem; letter-spacing: .02em;
  margin-bottom: 10px;
}
#model-chooser-cancel {
  background: none; border: 0; color: #e9d8ff; font-size: 1.05rem; line-height: 1;
  cursor: pointer; padding: 2px 6px; border-radius: 6px;
}
#model-chooser-cancel:hover { background: rgba(255, 255, 255, .12); }
#model-chooser-row { display: flex; gap: 16px; justify-content: center; flex-wrap: wrap; }
/* A chooser tile is a fight face at a fixed size, with a mode ribbon up top. */
.model-card {
  width: 150px;
  cursor: grab;
  transition: transform .12s ease;
}
#model-chooser-row .model-card:hover { transform: translateY(4px) scale(1.03); }
#model-chooser-row .model-card.unaffordable { filter: grayscale(.7) brightness(.6); cursor: not-allowed; }
#model-chooser-row .model-card.unaffordable:hover { transform: none; }
.model-tag {
  position: absolute;
  top: 6px; left: 50%; transform: translateX(-50%);
  background: rgba(120, 60, 180, .92);
  color: #fff; font-size: .6rem; font-weight: 800; letter-spacing: .06em; text-transform: uppercase;
  padding: 2px 9px; border-radius: 999px; white-space: nowrap;
  box-shadow: 0 2px 6px rgba(0, 0, 0, .4);
}
/* The floating clone the hero actually drags — anchored bottom-centre like a hand card so
   beginCardDrag's follow math places it under the cursor; ignores pointer events so the
   battlefield target under the cursor is detectable. */
.floating-play-card {
  position: fixed;
  left: 50%; bottom: -54px;
  width: 160px; margin-left: -80px;
  transform-origin: bottom center;
  z-index: 1400;
  pointer-events: none;
}

.card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
}
.card-name {
  font-size: .68rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: .04em;
}
/* Mana COST: a centered row of currency symbols (energy canisters now) at the
   very top of each card face — see manaCostHTML(). */
.mana-cost {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: flex-end;
  gap: 2px;
  min-height: 20px;
  margin-bottom: 2px;
}
.mana-cost .mana-sym {
  width: 12px;
  height: auto;
  display: block;
  filter: drop-shadow(0 0 2px rgba(90, 235, 215, .65));
}
.mana-cost .mana-cost-free {
  font-size: .72rem;
  font-weight: 800;
  color: #8a9099;
  letter-spacing: .05em;
}
.card-header { justify-content: center; }   /* name is centered now the cost moved up top */

/* Legacy round mana badge (kept for any other callers). */
.mana {
  flex: none;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: .82rem;
  box-shadow: 0 1px 3px rgba(0, 0, 0, .35);
}

.seasons { flex: 1; display: flex; flex-direction: column; gap: 6px; margin-top: 8px; }
.season {
  border-radius: 7px;
  padding: 6px 7px;
  background: rgba(0, 0, 0, .03);
  border-left: 4px solid #ccc;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.season b { font-size: .55rem; text-transform: uppercase; letter-spacing: .05em; }
.season span { font-size: .62rem; line-height: 1.2; }
/* economy keyword rows (front side) */
.season.kw-husbandry { border-left-color: var(--husbandry); } .season.kw-husbandry b { color: var(--husbandry); }
.season.kw-smithing  { border-left-color: var(--smithing);  } .season.kw-smithing b  { color: var(--smithing); }
.season.kw-rest      { border-left-color: var(--rest);      } .season.kw-rest b      { color: var(--rest); }
.season.kw-networking { border-left-color: var(--networking); } .season.kw-networking b { color: var(--networking); }
.season.kw-crime     { border-left-color: var(--crime);     } .season.kw-crime b     { color: var(--crime); }

.season.spring { border-left-color: var(--spring); } .season.spring b { color: var(--spring); }
.season.fall   { border-left-color: var(--fall);   } .season.fall b   { color: var(--fall); }
.season.winter { border-left-color: var(--winter); } .season.winter b { color: var(--winter); }
.season.summer { border-left-color: var(--summer); } .season.summer b { color: var(--summer); }
.season.summer.big { flex: 1; justify-content: center; margin-top: 8px; }
.season.summer.big span { font-size: .78rem; }

/* economy ratings (front side): a row of attribute pills; a card's special
   behaviour is folded into the relevant pill as a small `.rating-note`. */
.economy-body { flex: 1; display: flex; flex-direction: column; margin-top: 8px; gap: 8px; }
.ratings { display: flex; flex-wrap: wrap; gap: 5px; }
.rating {
  display: flex; flex-direction: column; align-items: center;
  min-width: 44px; padding: 4px 7px 5px;
  border-radius: 8px; background: rgba(0, 0, 0, .04);
  border: 1px solid rgba(0, 0, 0, .06); border-top: 3px solid #ccc;
}
.rating .rating-num { font-size: 1.05rem; font-weight: 800; line-height: 1.05; }
.rating .rating-skill {
  font-size: .44rem; text-transform: uppercase; letter-spacing: .05em; color: #74726c;
}
/* An inn gold payout printed under a Rest block (e.g. Heist's sleep-for-coin trade). */
.rating .rating-bonus { font-size: .58rem; font-weight: 800; color: #c79a3b; margin-top: 1px; }
/* A card's special behaviour, folded into the colored block it affects. It's the
   widest thing in the pill, so it lets that block grow past the 44px base width. */
.rating .rating-note {
  margin-top: 3px; max-width: 108px;
  font-size: .5rem; line-height: 1.22; font-weight: 700; text-align: center;
  color: #6b6a64;
}
/* A behaviour noted on the card but not wired yet — a designer reminder, italic. */
.rating .rating-note.pending { font-style: italic; font-weight: 600; }
.rating .rating-note .note-soon {
  display: block; margin-top: 1px;
  font-size: .42rem; font-weight: 800; letter-spacing: .03em;
  text-transform: uppercase; opacity: .6;
}
.rating.kw-husbandry { border-top-color: var(--husbandry); } .rating.kw-husbandry .rating-num,
  .rating.kw-husbandry .rating-note { color: var(--husbandry); }
.rating.kw-smithing  { border-top-color: var(--smithing);  } .rating.kw-smithing  .rating-num,
  .rating.kw-smithing  .rating-note { color: var(--smithing); }
.rating.kw-rest      { border-top-color: var(--rest);      } .rating.kw-rest      .rating-num,
  .rating.kw-rest      .rating-note { color: var(--rest); }
.rating.kw-networking { border-top-color: var(--networking); } .rating.kw-networking .rating-num,
  .rating.kw-networking .rating-note { color: var(--networking); }
.rating.kw-crime     { border-top-color: var(--crime);     } .rating.kw-crime     .rating-num,
  .rating.kw-crime     .rating-note { color: var(--crime); }

.card-foot { font-size: .5rem; text-align: center; color: #b3a98f; margin-top: 6px; }
/* A card with NO economy ratings (the pirate's cogs) still explains itself. */
.card-free-note {
  margin: 8px 6px 0; padding: 6px 8px; border-radius: 8px;
  background: rgba(60, 50, 70, .18); border: 1px dashed rgba(122, 74, 216, .45);
  font-size: .56rem; font-style: italic; line-height: 1.35; color: #6a5f74;
  text-align: center;
}

/* ---- FULL-ART faces: the painting covers the whole card; every text element
   rides on top of it with an outline. `tone-light` = light text, dark border
   (for darker paintings); `tone-dark` = dark text, light border (for bright
   ones). Set per card via `fullArt` + `textTone` (see card.js). ---- */
.card-face.full-art {
  background-color: #14141a;
  background-size: cover;
  background-position: center;
}
.card-face.tone-light { --fa-ink: #f7f4ec; --fa-line: rgba(0, 0, 0, .92); }
.card-face.tone-dark  { --fa-ink: #17151c; --fa-line: rgba(255, 255, 255, .88); }
.card-face.full-art .card-name,
.card-face.full-art .card-foot,
.card-face.full-art .fight-text,
.card-face.full-art .rating-skill,
.card-face.full-art .rating-bonus,
.card-face.full-art .rating-note,
.card-face.full-art .card-free-note {
  color: var(--fa-ink);
}
/* Stat numbers keep their stat colour — the outline carries the contrast. */
.card-face.full-art .card-name,
.card-face.full-art .card-foot,
.card-face.full-art .fight-text,
.card-face.full-art .rating-num,
.card-face.full-art .rating-skill,
.card-face.full-art .rating-bonus,
.card-face.full-art .rating-note,
.card-face.full-art .card-free-note {
  text-shadow:
    -1px -1px 0 var(--fa-line), 1px -1px 0 var(--fa-line),
    -1px  1px 0 var(--fa-line), 1px  1px 0 var(--fa-line),
     0 0 5px var(--fa-line);
}
/* The pills and text plates go glassy so the painting shows through them. */
.card-face.full-art .rating {
  background: rgba(0, 0, 0, .16);
  border-color: rgba(0, 0, 0, .1);
  backdrop-filter: blur(1px);
}
.card-face.tone-dark .rating { background: rgba(255, 255, 255, .18); }
.card-face.full-art .fight-text {
  background: rgba(0, 0, 0, .18);
  backdrop-filter: blur(1px);
  margin-top: auto;              /* with no framed art panel, the line sits low
                                    over the painting's quiet bottom band */
}
.card-face.tone-dark .fight-text { background: rgba(255, 255, 255, .16); }
.card-face.full-art .card-free-note {
  background: rgba(0, 0, 0, .2);
  border-color: rgba(255, 255, 255, .3);
  backdrop-filter: blur(1px);
}
/* A touch more presence for the mana pips + badges over busy art. */
.card-face.full-art .mana-cost { filter: drop-shadow(0 1px 2px rgba(0, 0, 0, .8)); }
.card-face.full-art .rarity-badge { filter: drop-shadow(0 1px 2px rgba(0, 0, 0, .8)); }

/* ---- rarity badge: a small shape centered along the bottom of a card face ---- */
.rarity-badge {
  position: absolute;
  bottom: 5px;
  left: 50%;
  transform: translateX(-50%);
  pointer-events: none;
}
/* Basic — a silver square */
.rarity-badge.rarity-basic {
  width: 9px; height: 9px;
  background: linear-gradient(150deg, #e9edf2, #9aa3ad);
  box-shadow: inset 0 0 0 1px rgba(0,0,0,.25);
  border-radius: 1px;
}
/* Common — a green triangle (pure CSS border triangle) */
.rarity-badge.rarity-common {
  width: 0; height: 0;
  border-left: 6px solid transparent;
  border-right: 6px solid transparent;
  border-bottom: 10px solid #43a047;
  filter: drop-shadow(0 0 1px rgba(0,0,0,.35));
}
/* Rare — a teal diamond (a forged common: heirloom work in progress) */
.rarity-badge.rarity-rare {
  width: 9px; height: 9px;
  background: linear-gradient(150deg, #6fd9cf, #1f7d74);
  box-shadow: inset 0 0 0 1px rgba(0,0,0,.3), 0 0 3px rgba(47,158,147,.5);
  transform: translateX(-50%) rotate(45deg);
  border-radius: 1px;
}
/* An UNPLAYABLE card's mana slot: a red ✖ instead of pips (the Soot-Cog). */
.mana-cost.unplayable {
  color: #ff5a5a;
  font-size: 1.05rem;
  font-weight: 900;
  line-height: 1;
  text-shadow: 0 0 6px rgba(255, 60, 60, .7), 0 1px 2px #000;
}

/* Curse — a small obsidian X (the Sky Pirate's cogs and their ilk) */
.rarity-badge.rarity-curse {
  width: 11px; height: 11px;
  background:
    linear-gradient(45deg, transparent 42%, #7a4ad8 42%, #7a4ad8 58%, transparent 58%),
    linear-gradient(-45deg, transparent 42%, #7a4ad8 42%, #7a4ad8 58%, transparent 58%),
    #17121f;
  box-shadow: inset 0 0 0 1px rgba(122, 74, 216, .6), 0 0 4px rgba(122, 74, 216, .5);
  border-radius: 2px;
}
/* Heirloom — an orange oval */
.rarity-badge.rarity-heirloom {
  width: 15px; height: 9px;
  background: radial-gradient(circle at 40% 35%, #ffcf7a, #e8861f);
  border-radius: 50%;
  box-shadow: inset 0 0 0 1px rgba(120,60,0,.4), 0 0 4px rgba(232,134,31,.6);
}

/* Per-instance heirloom NUMBER (n/100), bottom-left corner of a deck card. Climbs
   by +1 each forge. Only shown when above 0 — rare (teal) up to 99, then a
   glowing gold once it tops out at heirloom-quality (100). Mirrors .item-heirloom. */
.heirloom-corner {
  position: absolute; bottom: 5px; left: 6px;
  font-size: .52rem; font-weight: 800; font-variant-numeric: tabular-nums;
  letter-spacing: .02em; pointer-events: none;
}
.heirloom-corner.heirloom-rare { color: #2f9e93; }
.heirloom-corner.heirloom-heirloom {
  color: #e8861f; text-shadow: 0 0 4px rgba(232,134,31,.7);
}

/* ---- ITEM CARDS: square (not the portrait, two-sided deck card). One painted
   icon, a type tag, a name, behaviour text, the rarity badge centered at the
   bottom, and the heirloom value (x/100) in the bottom-left corner. ---- */
.item-card {
  position: relative;
  width: 100%;
  aspect-ratio: 3 / 4;          /* portrait — taller than wide so the text has room */
  border-radius: 11px;
  border-top: 5px solid var(--accent, #999);
  background: #fbf7ef;
  color: #2b2b33;
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .12), 0 2px 6px rgba(0, 0, 0, .3);
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 8px 8px 18px;        /* bottom strip for the badge + heirloom value */
  overflow: hidden;
}
.item-card.item-rarity-heirloom {
  background: linear-gradient(165deg, #fff6e0, #f6e6bd);
  box-shadow: inset 0 0 0 1px rgba(160,100,10,.3), 0 0 0 1px rgba(232,134,31,.35), 0 2px 8px rgba(0,0,0,.35);
}
.item-tag {
  align-self: flex-start;
  font-size: .46rem; font-weight: 800; letter-spacing: .07em; text-transform: uppercase;
  padding: 2px 6px; border-radius: 999px;
  background: var(--accent, #999); color: #fff;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,.15);
}
.item-art {
  flex: 1; min-height: 0; width: 100%;
  display: flex; align-items: center; justify-content: center;
  font-size: 2.4rem;
}
.item-art img {
  max-width: 88%; max-height: 100%; object-fit: contain;
  filter: drop-shadow(0 2px 4px rgba(0,0,0,.3));
}
.item-name {
  font-size: .7rem; font-weight: 800; text-transform: uppercase; letter-spacing: .03em;
  text-align: center; margin-top: 2px;
}
.item-text {
  margin-top: 4px; padding: 5px 6px; border-radius: 7px;
  background: rgba(0, 0, 0, .04); border-left: 4px solid var(--accent, #999);
  font-size: .64rem; font-weight: 600; line-height: 1.3; text-align: center;
}
/* Icon-only variant (character-sheet slots): just the painted item, its name and
   heirloom value — square so it sits neatly in the square slot. Right-click for text. */
.item-card.item-icon-only {
  aspect-ratio: 1 / 1;
  padding: 6px 6px 16px;
  cursor: pointer;
}
.item-card.item-icon-only .item-name {
  font-size: .5rem; margin-top: 1px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%;
}
.item-text.pending { font-style: italic; }
.item-text .note-soon {
  display: block; margin-top: 2px;
  font-size: .42rem; font-weight: 800; letter-spacing: .03em; text-transform: uppercase; opacity: .6;
}
/* Heirloom value (x/100), bottom-left corner of every item card. */
.item-heirloom {
  position: absolute; bottom: 4px; left: 7px;
  font-size: .56rem; font-weight: 800; font-variant-numeric: tabular-nums;
  color: #b5731a; letter-spacing: .02em;
}
.item-heirloom-max { font-size: .44rem; opacity: .65; font-weight: 700; }

/* ---- Elementals: a transparent, movable, resizable popout that collects
   conjured elemental tokens (see elementals.js) ---- */
.elementals-window {
  position: fixed;
  z-index: 1200;
  width: 240px;
  height: 200px;
  min-width: 150px;
  min-height: 120px;
  display: flex;
  flex-direction: column;
  background: rgba(18, 26, 38, .18);
  border: 1px solid rgba(120, 230, 255, .35);
  border-radius: 12px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, .35);
  backdrop-filter: blur(1.5px);
  resize: both;          /* native corner grip resizes the window */
  overflow: hidden;
}
.elementals-window[hidden] { display: none; }
.elementals-bar {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 4px 6px 4px 11px;
  cursor: move;
  user-select: none;
  background: rgba(120, 230, 255, .10);
  border-bottom: 1px solid rgba(120, 230, 255, .2);
}
.elementals-bar-title {
  font-size: .68rem; font-weight: 800; letter-spacing: .16em;
  text-transform: uppercase; color: #c8ecff;
}
.elementals-close {
  border: 0; background: none; color: #c8ecff;
  font-size: 1.05rem; line-height: 1; cursor: pointer; padding: 0 2px;
}
.elementals-close:hover { color: #fff; }
.elementals-stage { position: relative; flex: 1; overflow: hidden; }
/* The see-through "Elementals" watermark sitting behind the tokens. */
.elementals-watermark {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  text-align: center;
  font-size: clamp(1rem, 7cqw, 1.7rem);
  font-weight: 900; letter-spacing: .14em; text-transform: uppercase;
  color: transparent;
  -webkit-text-stroke: 1px rgba(190, 240, 255, .35);
  text-stroke: 1px rgba(190, 240, 255, .35);
  pointer-events: none;
}
.elementals-stage { container-type: inline-size; }
.elementals-body {
  position: absolute; inset: 0;
  display: flex; flex-wrap: wrap; align-content: flex-start;
  gap: 6px; padding: 10px; overflow: auto;
}
.elemental-token {
  width: 42px; height: auto;
  filter: drop-shadow(0 0 8px rgba(120, 230, 255, .85));
}
.elemental-token.conjuring { animation: elemental-pop .5s ease; transform-origin: center; }
@keyframes elemental-pop {
  0%   { transform: scale(0) rotate(-30deg); opacity: 0; filter: brightness(3) drop-shadow(0 0 18px #fff); }
  55%  { transform: scale(1.35) rotate(7deg); opacity: 1; }
  100% { transform: scale(1) rotate(0); }
}

/* Stickers: cosmetic decals stuck on a card. The overlay fills the face; each
   sticker is positioned by its stored centre (left/top %) and sized as a % of the
   card, so it stays put and in proportion at any window/card size. */
.card-stickers { position: absolute; inset: 0; z-index: 5; pointer-events: none; overflow: hidden; }
.card-sticker {
  position: absolute;
  width: 40%;
  transform: translate(-50%, -50%);
  filter: drop-shadow(0 2px 3px rgba(0, 0, 0, .45));
  user-select: none;
}

/* A spent one-shot sticker (e.g. the Loud Mouth after its Networking use) greys out
   for the rest of the run — desaturated and dimmed so it reads as "used up". */
.card-sticker.spent { filter: grayscale(1) brightness(.7) drop-shadow(0 2px 3px rgba(0, 0, 0, .45)); opacity: .65; }

/* "Tesla coil" trademark stamped on a card empowered at the Smithy (Tier 2): it
   draws +1 card whenever the card is used for an economy action. */
.tesla-coil {
  position: absolute;
  right: 5px; bottom: 5px;
  z-index: 3;
  width: 1.6em; height: 1.6em;
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%;
  font-size: .68rem; line-height: 1;
  background: radial-gradient(circle at 38% 32%, #d6f6ff, #36b6d6 65%, #0c5566);
  color: #06303a;
  border: 1px solid #0c5566;
  box-shadow: 0 0 8px rgba(120, 230, 255, .9), inset 0 0 3px rgba(255, 255, 255, .7);
  pointer-events: none;
}
/* Enchantment stickers sit a touch smaller than cosmetic decals so a pyramid of
   them reads cleanly, with a faint holy glow. */
.card-sticker.enchantment {
  width: 30%;
  filter: drop-shadow(0 0 4px rgba(255, 226, 150, .9)) drop-shadow(0 2px 3px rgba(0, 0, 0, .4));
}

/* ---- trait badges: what KIND of card this is (scales its damage) ---- */
.trait-badges {
  position: absolute;
  left: 6px; bottom: 22px;
  display: flex; flex-wrap: wrap; gap: 3px;
  z-index: 4; pointer-events: none;
}
.trait-badge {
  font-size: .5rem; font-weight: 800; line-height: 1;
  padding: 2px 5px; border-radius: 999px;
  background: rgba(0, 0, 0, .06); border: 1px solid rgba(0, 0, 0, .15);
  letter-spacing: .02em;
}
.trait-badge.trait-physical { background: #efe1d4; border-color: #c8a987; color: #6b4a2b; }
.trait-badge.trait-magic    { background: #e6e0fb; border-color: #b3a4ef; color: #4a3a8c; }
.trait-badge.trait-holy     { background: #fff6dc; border-color: #e8cf86; color: #8a6a18; }

/* Holy Nova armed: dragging an untargeted nova card into the top band glows the whole
   screen orange so you know releasing will hit EVERYTHING. */
body.nova-armed::before {
  content: ""; position: fixed; inset: 0; z-index: 60; pointer-events: none;
  background: radial-gradient(circle at 50% 38%, rgba(255, 178, 56, .30), rgba(255, 120, 0, .12) 60%, transparent 82%);
  box-shadow: inset 0 0 150px 50px rgba(255, 150, 30, .5);
  animation: novaPulse .7s ease-in-out infinite alternate;
}
@keyframes novaPulse { from { opacity: .65; } to { opacity: 1; } }

.back-emblem { text-align: center; font-size: 1.5rem; color: var(--summer); }

/* ---- fight (back) side: placeholder art up top, effect text on the bottom ---- */
.card-face.fight { background: linear-gradient(165deg, #fff6e0, #f4e3b6); }
.fight-art {
  flex: 1;
  margin-top: 8px;
  border-radius: 8px;
  background: repeating-linear-gradient(45deg, #ece0c2, #ece0c2 8px, #e4d6b2 8px, #e4d6b2 16px);
  border: 1px dashed #c9b888;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 2.4rem;
  overflow: hidden;
}
/* A card with real painted art fills the panel with the transparent-PNG creature. */
.fight-art-img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  filter: drop-shadow(0 2px 3px rgba(0, 0, 0, .35));
}
.fight-text {
  margin-top: 8px;
  padding: 8px 6px;
  border-radius: 7px;
  background: rgba(0, 0, 0, .04);
  border-left: 4px solid var(--accent, #999);
  font-size: .72rem;
  font-weight: 700;
  text-align: center;
}

/* ---- the hand: a fanned arc of cards along the bottom ---- */
#hand {
  position: fixed;
  left: 50%;
  bottom: -40px;
  width: 0;
  height: 0;
  z-index: 500;
  /* One knob for hand-card size — much bigger now so cards read clearly on screen. */
  --hand-card-w: 190px;
}
.hand-card {
  position: absolute;
  bottom: 0;
  left: 0;
  width: var(--hand-card-w);
  margin-left: calc(var(--hand-card-w) / -2);   /* center each card on the anchor */
  transform-origin: bottom center;
  transform: translate(var(--tx), var(--ty)) rotate(var(--rot));
  transition: transform .18s ease;
  cursor: pointer;
}
/* Hover: lift, straighten, and blow it up; the back peeks out behind. */
.hand-card:hover {
  transform: translate(var(--tx), -140px) rotate(0deg) scale(1.4);
  z-index: 200 !important;     /* beat the per-card inline z-index so it sits above its neighbors */
}
.hand-card .face-back { transition: transform .18s ease; }
#hand:not(.combat) .hand-card:hover .face-back { transform: translate(36%, -7%) rotate(7deg); }

/* ---- in combat the hand shows its back (Fight mode) side ---- */
/* Lift the whole hand above the combat scene (z 600) so you can see and play it. */
#hand.combat { z-index: 645; }
#hand.combat .hand-card .face-front { opacity: 0; pointer-events: none; }
#hand.combat .hand-card { cursor: grab; }
/* While aiming, the card shrinks and rides the cursor around the screen
   (card-play.js sets its transform on every move); the dot trail shows your path. */
.hand-card.targeting {
  transition: none;                 /* track the cursor with no spring-back lag */
  z-index: 600 !important;
  pointer-events: none;             /* so the cursor can reach the target */
  filter: drop-shadow(0 8px 16px rgba(0, 0, 0, .55)) drop-shadow(0 0 12px rgba(255, 216, 130, .9));
}
/* A card you can't afford right now: dimmed in the fan, shakes if you grab it. */
#hand.combat .hand-card.unaffordable { filter: grayscale(.7) brightness(.7); }
/* The synthetic gun card (Gun:Knife / Stormpiercer): a warm weapon glow so it reads
   as special, not a normal drawn card. */
#hand.combat .hand-card.weapon-card .face-back {
  box-shadow: 0 0 0 2px rgba(255,196,120,.85), 0 0 16px rgba(255,170,70,.6);
}
/* A sleepy-dog card is locked from town use (only the wishing well will take it). */
.hand-card.town-locked { filter: saturate(.55) brightness(.9); cursor: not-allowed; }
.hand-card.nope { animation: card-nope .28s ease; }
@keyframes card-nope {
  0%, 100% { transform: translate(var(--tx), var(--ty)) rotate(var(--rot)); }
  25% { transform: translate(calc(var(--tx) - 8px), var(--ty)) rotate(var(--rot)); }
  75% { transform: translate(calc(var(--tx) + 8px), var(--ty)) rotate(var(--rot)); }
}

/* ---- the big right-click view: front and back side by side ---- */
#card-modal {
  position: fixed;
  inset: 0;
  z-index: 3000;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 48px;
  background: rgba(0, 0, 0, .72);
  backdrop-filter: blur(2px);
}
#card-modal[hidden] { display: none; }
#card-modal-inner { display: flex; gap: 48px; }
.modal-col { display: flex; flex-direction: column; align-items: center; gap: 12px; }
.modal-col .modal-label {
  font-size: .8rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: #cfd3da;
}
.modal-col .card-face {
  width: auto;
  height: min(74vh, 560px);
  box-shadow: 0 20px 60px rgba(0, 0, 0, .6);
}
#card-modal-close {
  position: fixed;
  top: 18px;
  right: 22px;
  width: 40px;
  height: 40px;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, .12);
  color: #fff;
  font-size: 1.4rem;
  cursor: pointer;
}
#card-modal-close:hover { background: rgba(255, 255, 255, .25); }

/* ---- the Controls / tutorial panel ---- */
#controls-screen {
  position: fixed;
  inset: 0;
  z-index: 3000;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, .72);
  backdrop-filter: blur(2px);
  padding: 4vh 16px;
}
#controls-screen[hidden] { display: none; }
#controls-panel {
  position: relative;
  width: min(540px, 94vw);
  max-height: 88vh;
  overflow-y: auto;
  background: linear-gradient(165deg, #1d2331, #11151e);
  border: 1px solid #2d3647;
  border-radius: 14px;
  padding: 22px 26px 20px;
  color: #e7ebf2;
  box-shadow: 0 18px 50px rgba(0, 0, 0, .6);
}
#controls-panel h2 { margin: 0 0 16px; font-size: 1.25rem; letter-spacing: .03em; }
#controls-close {
  position: absolute;
  top: 12px;
  right: 14px;
  border: 0;
  background: none;
  color: #aab2c0;
  font-size: 1.6rem;
  line-height: 1;
  cursor: pointer;
}
#controls-close:hover { color: #fff; }
.ctrl-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 14px; }
.ctrl-row {
  display: grid;
  grid-template-columns: 28px 96px 1fr;
  align-items: start;
  gap: 10px;
}
.ctrl-icon { font-size: 1.25rem; text-align: center; line-height: 1.2; }
.ctrl-keys { font-weight: 800; font-size: .82rem; color: #ffd866; padding-top: 2px; }
.ctrl-text { font-size: .82rem; line-height: 1.4; color: #ccd2dc; }
.ctrl-foot { margin: 18px 0 0; font-size: .72rem; font-style: italic; color: #79818f; }

/* ---- the shop: one copy of every card, in a scrollable grid ---- */
#shop-screen, #item-shop-screen {
  position: fixed;
  inset: 0;
  z-index: 2500;
  background: rgba(0, 0, 0, .72);
  backdrop-filter: blur(2px);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 4vh 0;
  overflow-y: auto;
}
#shop-screen[hidden], #item-shop-screen[hidden] { display: none; }
#shop-inner {
  position: relative;
  width: min(92vw, 980px);
  background: #20242c;
  border-radius: 16px;
  padding: 22px 26px 30px;
  box-shadow: 0 24px 70px rgba(0, 0, 0, .6);
}
#shop-header { display: flex; align-items: center; justify-content: space-between; }
#shop-header h1 { margin: 0; font-size: 1.5rem; }
#shop-close {
  width: 38px; height: 38px; border: 0; border-radius: 50%;
  background: rgba(255, 255, 255, .12); color: #fff; font-size: 1.3rem; cursor: pointer;
}
#shop-close:hover { background: rgba(255, 255, 255, .25); }
#shop-sub { margin: 4px 0 18px; color: #aeb4be; font-size: .85rem; }
#shop-grid, #item-shop-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 22px 18px;
}
.shop-item { display: flex; flex-direction: column; align-items: center; gap: 9px; }
.shop-card { width: 140px; cursor: pointer; transition: transform .12s ease; }
.shop-card:hover { transform: translateY(-4px); }
.shop-add {
  border: 0; border-radius: 7px; cursor: pointer;
  padding: .4rem .7rem; font-size: .78rem; font-weight: 600;
  background: #3a6ea5; color: #fff;
}
.shop-add:hover { background: #4a82bd; }
.shop-add:disabled { background: #4a7a4a; cursor: default; }
/* can't-afford buy button: greyed, not the green "owned/sold" look */
.shop-add.cant, .shop-add.cant:hover { background: #555a63; color: #b9bdc6; cursor: not-allowed; }

/* "for dev testing only" banner across the top of the free world-map shop */
.shop-devnote {
  margin: 10px 0 0; padding: 7px 12px; border-radius: 8px;
  background: rgba(214, 158, 46, .16); border: 1px solid rgba(214, 158, 46, .5);
  color: #e8c074; font-size: .8rem; font-weight: 700; letter-spacing: .02em; text-align: center;
}
/* the price tag on a city-shop card's buy button */
.shop-add .price { font-weight: 800; }
/* faint painted interior behind the city shop's wares */
#shop-screen.city-shop #shop-inner { background-size: cover; background-position: center; }
#shop-screen.city-shop #shop-inner::before {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  background: linear-gradient(rgba(18,22,28,.82), rgba(18,22,28,.92)); pointer-events: none;
}
#shop-screen.city-shop #shop-inner > * { position: relative; }

/* ---- shop section headers (Action Cards vs Item Cards) ---- */
.shop-section-label {
  margin: 6px 0 12px; font-size: .74rem; letter-spacing: .12em;
  text-transform: uppercase; color: #c9b06a; font-weight: 800;
  border-bottom: 1px solid rgba(201,176,106,.3); padding-bottom: 5px;
}
.shop-section-label.items { margin-top: 26px; }
/* item-card wares: square cards, a touch narrower than the portrait action cards */
#item-shop-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 22px 18px;
}
.item-shop-item .shop-card { width: 140px; }

/* ---- Dev shop catalog: Gear / Potions / Stickers, each grouped by rarity ---- */
/* In catalog mode the container is plain block flow so the section + rarity headers
   stack, and each rarity gets its own inner grid of tiles. */
#item-shop-grid.catalog, #shop-grid.catalog { display: block; }
.dev-rarity-label {
  margin: 4px 0 10px; font-size: .66rem; letter-spacing: .14em;
  text-transform: uppercase; color: #9fb4d8; font-weight: 800;
}
.dev-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 22px 18px;
  margin-bottom: 18px;
}
/* A browse-only sticker tile: the painted decal over its name. */
.dev-sticker { gap: 7px; }
.dev-sticker-img {
  width: 96px; height: 96px; object-fit: contain;
  filter: drop-shadow(0 4px 8px rgba(0, 0, 0, .5));
}
.dev-sticker-name {
  font-size: .74rem; font-weight: 700; color: #e7eef6; text-align: center;
  max-width: 130px; line-height: 1.2;
}

/* ---- "which potion do I discard?" popup (full potion slots on a new buy) ---- */
.potion-discard-overlay {
  position: fixed; inset: 0; z-index: 2900;
  display: flex; align-items: center; justify-content: center;
  background: rgba(0,0,0,.66); backdrop-filter: blur(2px);
}
.potion-discard-overlay[hidden] { display: none; }
.potion-discard-window {
  width: min(94vw, 560px);
  background: #20242c; border: 1px solid #3a4150; border-radius: 16px;
  padding: 22px 24px 24px; color: #f0e6d2; text-align: center;
  box-shadow: 0 24px 70px rgba(0,0,0,.6);
}
.potion-discard-window h2 { margin: 0 0 4px; font-size: 1.25rem; }
.potion-discard-window p { margin: 0 0 16px; color: #aeb4be; font-size: .88rem; }
.potion-discard-row { display: flex; justify-content: center; gap: 16px; flex-wrap: wrap; }
.potion-discard-cell { display: flex; flex-direction: column; align-items: center; gap: 8px; width: 120px; }
.potion-discard-cell .item-card { width: 120px; }
.potion-discard-btn {
  border: 0; border-radius: 7px; cursor: pointer;
  padding: .4rem .8rem; font-size: .8rem; font-weight: 700;
  background: #a5453a; color: #fff;
}
.potion-discard-btn:hover { background: #c1554a; }
.potion-discard-cancel {
  margin-top: 18px; border: 1px solid #4a5160; border-radius: 8px; cursor: pointer;
  padding: .5rem 1rem; font-size: .82rem; font-weight: 700;
  background: rgba(255,255,255,.06); color: #dfe5ee;
}
.potion-discard-cancel:hover { background: rgba(255,255,255,.14); }

/* ---- deck picker (Potion of Teleportation: grab one card from the draw pile) ---- */
.deck-picker-overlay {
  position: fixed; inset: 0; z-index: 3000;
  background: rgba(0, 0, 0, .74); backdrop-filter: blur(2px);
  display: flex; align-items: flex-start; justify-content: center;
  padding: 5vh 0; overflow-y: auto;
}
.deck-picker-overlay[hidden] { display: none; }
.deck-picker-window {
  position: relative; width: min(92vw, 900px);
  background: #20242c; border-radius: 16px; padding: 22px 26px 26px;
  box-shadow: 0 24px 70px rgba(0, 0, 0, .6); text-align: center;
}
.deck-picker-window h2 { margin: 0 0 4px; font-size: 1.4rem; }
.deck-picker-sub { margin: 0 0 18px; color: #aeb4be; font-size: .88rem; }
.deck-picker-empty { margin: 14px 0; color: #aeb4be; }
.deck-picker-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  gap: 16px 14px; justify-items: center;
}
.deck-picker-cell {
  border: 0; padding: 0; background: none; cursor: pointer;
  border-radius: 10px; transition: transform .12s ease;
}
.deck-picker-cell:hover { transform: translateY(-5px) scale(1.04); }
.deck-picker-cell .card { width: 120px; pointer-events: none; }
.deck-picker-cancel {
  margin-top: 20px; border: 1px solid #4a5160; border-radius: 8px; cursor: pointer;
  padding: .5rem 1.1rem; font-size: .82rem; font-weight: 700;
  background: rgba(255, 255, 255, .06); color: #dfe5ee;
}
.deck-picker-cancel:hover { background: rgba(255, 255, 255, .14); }

/* ---- Jarteia world map (behind the card board) ---- */
#map-frame { position: fixed; inset: 0; z-index: 0; }
#map-viewport {
  position: absolute;
  top: 10%; left: 10%;        /* 10% buffer on all four sides */
  width: 80%; height: 80%;
  overflow: hidden;
  border-radius: 14px;
  background: #0c0f14;
  box-shadow: 0 18px 60px rgba(0, 0, 0, .6), inset 0 0 0 1px rgba(255, 255, 255, .06);
  cursor: crosshair;
}
#map-stage { position: absolute; top: 0; left: 0; transform-origin: top left; will-change: transform; }
#map-img { display: block; width: 100%; height: 100%; pointer-events: none; user-select: none; }
#balloons { position: absolute; inset: 0; pointer-events: none; }

/* Clickable cell overlay: stretches to fill the stage at any zoom (viewBox does
   the scaling). The <svg> itself ignores the mouse so gaps fall through to the
   map; only the cell polygons catch hover/click. Cells are invisible until they
   matter (where you stand / where you can step). Strokes are in viewBox (logical) px. */
.map-cells { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.map-cell {
  fill: transparent; stroke: transparent; stroke-width: 1;
  pointer-events: auto; cursor: pointer;
  transition: fill .12s ease, stroke .12s ease;
}
/* A faint outline on hover so you can read a cell, even one too far to enter. */
.map-cell:hover { stroke: rgba(255, 255, 255, .35); }
/* The cell you're standing on. */
.map-cell.current { fill: rgba(255, 226, 140, .18); stroke: rgba(255, 225, 130, .95); stroke-width: 1.5; }
/* Cells you can step to next. */
.map-cell.reachable { fill: rgba(120, 220, 255, .14); stroke: rgba(140, 210, 255, .6); stroke-width: 1.2; }
.map-cell.reachable:hover { fill: rgba(150, 235, 255, .32); stroke: rgba(170, 225, 255, .95); stroke-width: 1.5; }
/* A city's cell — a dashed rose outline so you can spot where the cities live. */
.map-cell.city { stroke: rgba(255, 180, 215, .9); stroke-width: 1.6; stroke-dasharray: 6 3; }
.map-cell.city.reachable:hover { fill: rgba(255, 190, 225, .32); }

/* Tile-number overlay: a separate SVG of cell-id labels, toggled by the 🔢 button.
   Hidden by default; ignores the mouse so it never blocks cell clicks. */
.map-cell-nums { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; display: none; }
.map-cell-nums.show { display: block; }
.map-cell-num {
  fill: #fff; font-size: 9px; font-weight: 700;
  text-anchor: middle; dominant-baseline: central;
  paint-order: stroke; stroke: rgba(10, 14, 22, .9); stroke-width: 2.4px;
}

/* Top-left gameplay HUD: the turn counter and the current season icon. It sits a
   little below the top edge so it clears the 🂠 Deck button that's pinned to the
   very top-left corner (they used to overlap). */
#map-hud {
  position: absolute; top: 58px; left: 16px; z-index: 30;
  display: flex; align-items: center; gap: 8px;
  padding: .3em .6em; border-radius: 10px;
  border: 1px solid rgba(255, 255, 255, .25);
  background: rgba(18, 20, 28, .8); color: #eaf7ff;
  font-weight: 800; letter-spacing: .03em;
}
/* Map potion tray: usable-on-map potions, tucked just under the season/turn HUD. */
#map-potions {
  position: absolute; top: 104px; left: 16px; z-index: 30;
  display: flex; gap: 6px;
}
#map-potions[hidden] { display: none; }
#map-potions .map-potion {
  border: 0; padding: 0; background: none; cursor: pointer;
  border-radius: 8px; transition: transform .12s ease;
  filter: drop-shadow(0 3px 6px rgba(0, 0, 0, .5));
}
#map-potions .map-potion:hover { transform: translateY(-3px) scale(1.06); }
#map-potions .map-potion .item-card { width: 54px; pointer-events: none; }

/* Town potion tray: bottom-left, above the mana cans and over the plaza (z900) /
   hand (z950), but below modal overlays. */
#town-potions {
  position: fixed; left: 18px; bottom: 120px; z-index: 955;
  display: flex; gap: 6px;
}
#town-potions[hidden] { display: none; }
#town-potions .town-potion {
  border: 0; padding: 0; background: none; cursor: pointer;
  border-radius: 8px; transition: transform .12s ease;
  filter: drop-shadow(0 3px 6px rgba(0, 0, 0, .5));
}
#town-potions .town-potion:hover { transform: translateY(-3px) scale(1.06); }
#town-potions .town-potion .item-card { width: 54px; pointer-events: none; }

/* Teleport mode: a banner across the top of the map while the next click is a jump. */
#map-teleport-banner {
  position: absolute; top: 12px; left: 50%; transform: translateX(-50%);
  z-index: 40; display: flex; align-items: center; gap: 12px;
  padding: .5em .9em; border-radius: 999px;
  background: rgba(70, 40, 120, .92); color: #f0e8ff;
  border: 1px solid rgba(180, 150, 255, .7);
  box-shadow: 0 6px 22px rgba(80, 40, 150, .55), 0 0 18px rgba(150, 110, 240, .45);
  font-weight: 800; letter-spacing: .02em; font-size: .9rem;
}
#map-teleport-banner[hidden] { display: none; }
#map-teleport-banner #map-teleport-cancel {
  border: 0; border-radius: 999px; cursor: pointer;
  padding: .25em .8em; font-weight: 700; font-size: .8rem;
  background: rgba(255, 255, 255, .18); color: #fff;
}
#map-teleport-banner #map-teleport-cancel:hover { background: rgba(255, 255, 255, .32); }
/* While armed, hint that the whole map is clickable. */
#map-viewport.teleporting { cursor: crosshair; }
#map-hud #season-icon { font-size: 1.25rem; line-height: 1; }
#map-hud #month-name {
  font-size: 1rem; color: #fff; letter-spacing: .04em;
  font-variant: small-caps; text-shadow: 0 1px 3px rgba(0, 0, 0, .6);
}
#map-hud #turn-counter { font-size: .95rem; font-variant-numeric: tabular-nums; opacity: .8; }
#map-hud #turn-counter b { color: #fff; }

/* Developer tools, tucked into the ⚙️ Settings panel (off the map's top bar). */
.settings-dev-label {
  margin: 16px 0 8px; font-size: .68rem; letter-spacing: .1em; text-transform: uppercase;
  color: #8b919b; border-top: 1px solid #3a3f48; padding-top: 12px;
}
.settings-dev-tools { display: flex; flex-direction: column; gap: 7px; }
.settings-dev-btn {
  border: 1px solid rgba(255, 255, 255, .22);
  background: rgba(18, 20, 28, .8); color: #eaf7ff;
  font-weight: 700; font-size: .82rem; letter-spacing: .03em; text-align: left;
  padding: .5em .7em; border-radius: 8px; cursor: pointer;
  transition: background .12s ease, border-color .12s ease;
}
.settings-dev-btn:hover { background: rgba(40, 46, 60, .9); }
.settings-dev-btn.on { background: rgba(120, 200, 255, .28); border-color: rgba(150, 215, 255, .85); }
.settings-dev-btn[hidden] { display: none; }

.balloon {
  position: absolute;
  transform: translate(-50%, -100%);   /* anchor the tail tip on the map point */
  transition: left .55s ease, top .55s ease;
  pointer-events: none;
  filter: drop-shadow(0 3px 4px rgba(0, 0, 0, .5));
}
/* While zooming/resizing the map, balloons are re-laid-out in screen pixels — that's
   not a move, so suppress the glide so the pin doesn't fly across the map. */
#balloons.instant .balloon { transition: none; }
.balloon .bubble {
  width: 40px; height: 40px;
  border-radius: 50%;
  border: 2px solid #fff;
  display: flex; align-items: center; justify-content: center;
  color: #fff; font-weight: 800; font-size: .82rem;
}
.balloon .tail {
  width: 0; height: 0; margin: -2px auto 0;
  border-left: 6px solid transparent;
  border-right: 6px solid transparent;
  border-top: 9px solid #fff;
}
.balloon .tag {
  position: absolute; top: -19px; left: 50%; transform: translateX(-50%);
  white-space: nowrap; font-size: .62rem; color: #f0f0f0;
  background: rgba(0, 0, 0, .6); padding: 1px 6px; border-radius: 6px;
  opacity: .9;
}
.balloon.me .bubble { animation: balloon-pulse 1.8s infinite; }
@keyframes balloon-pulse {
  0%, 100% { box-shadow: 0 0 0 3px rgba(255, 255, 255, .18); }
  50%      { box-shadow: 0 0 0 8px rgba(255, 255, 255, 0); }
}

/* ---- a card dragged out onto the board: 4:3 moveable window ---- */
/* The board overlays the map; let clicks on empty space reach the map. */
#board { position: fixed; inset: 0; pointer-events: none; }
#board > * { pointer-events: auto; }
.card-window {
  position: absolute;
  width: 300px;
  aspect-ratio: 4 / 3;
  background: linear-gradient(#33373f, #25282f);
  border: 1px solid #4a4f59;
  border-radius: 12px;
  box-shadow: 0 10px 34px rgba(0, 0, 0, .55);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  cursor: grab;
  touch-action: none;
  transition: transform .12s ease, box-shadow .12s ease;
}
/* Lift and enlarge the card the cursor is over so it's clear which one is focused. */
.card-window:hover {
  transform: scale(1.06);
  box-shadow: 0 16px 44px rgba(0, 0, 0, .65);
}
.card-window:active { cursor: grabbing; }
.win-card {
  width: auto;
  height: 100%; /* square card sized by the window's height, centered on the mat */
}
.win-x {
  position: absolute;
  top: 6px;
  right: 8px;
  width: 22px;
  height: 22px;
  border: 0;
  border-radius: 50%;
  background: rgba(0, 0, 0, .35);
  color: #fff;
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}
.win-x:hover { background: #b23b3b; }

/* ---- the ghost that follows the cursor while pulling a card out ---- */
.drag-ghost {
  position: fixed;
  width: 130px;
  pointer-events: none;
  opacity: .9;
  z-index: 2000;
  transform: translate(-50%, -50%);
}

/* ============================================================ COMBAT */

/* ---- fight builder: a panel centered ON the battlefield (the combat zone) ---- */
#create-fight {
  background: #a5453a !important;   /* sits in the auth bar; override its blue */
}
#fight-setup {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 300px;
  max-height: 86vh;
  overflow-y: auto;
  z-index: 630;                     /* above the scene (600), below the corner arrows */
  padding: 16px;
  background: rgba(24, 26, 32, .94);
  border: 1px solid #4a4f59;
  border-radius: 14px;
  box-shadow: 0 16px 50px rgba(0, 0, 0, .6);
  backdrop-filter: blur(3px);
}
#fight-setup h2 {
  margin: 0 0 10px;
  font-size: 1.05rem;
  text-align: center;
  letter-spacing: .02em;
}
.fight-action {
  width: 100%;
  padding: .55rem;
  border: 0;
  border-radius: 8px;
  font-size: .9rem;
  font-weight: 700;
  cursor: pointer;
}
.fight-action.spawn { background: #c9a24b; color: #2b2b33; margin-top: 10px; }
.fight-action.spawn:hover { background: #d8b259; }
.fight-action.random { background: #6b4f9e; color: #f1ecff; margin-top: 10px; }
.fight-action.random:hover { background: #7d5fb6; }
.fight-action.cancel { background: #3a3a46; color: #d9d6cf; margin-top: 8px; }
.fight-action.cancel:hover { background: #46464f; }
#fight-danger-note { margin: 0 0 8px; text-align: center; font-size: .82rem; color: #c9c4ba; }
#fight-danger { color: #e6b860; font-variant-numeric: tabular-nums; }
/* Kill-all now lives with the in-fight controls (top-right); give it a red tint. */
#kill-all { background: linear-gradient(#6b2f2f, #532525); color: #ffd9d4; }
#kill-all:hover { background: linear-gradient(#813838, #6b2f2f); }

.monster-row {
  display: grid;
  grid-template-columns: 24px 1fr auto 28px 28px 28px;
  align-items: center;
  gap: 6px;
  padding: 4px 0;
}
.monster-row .m-emoji { font-size: 1.15rem; text-align: center; }
.monster-row .m-name { font-size: .85rem; }
.monster-row .m-rating { font-size: .72rem; color: #b9a86a; white-space: nowrap; font-variant-numeric: tabular-nums; }
.monster-row.locked { opacity: .5; }
.monster-row.locked .m-rating { color: #8a8a93; }
.m-step {
  width: 28px; height: 28px;
  border: 0;
  border-radius: 6px;
  background: #3a3f49;
  color: #fff;
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
}
.m-step:hover { background: #4a505c; }
.m-count { text-align: center; font-weight: 700; font-variant-numeric: tabular-nums; }

/* ---- monster view: a horizon scene ---- */
#combat-frame { position: fixed; inset: 0; z-index: 600; overflow: hidden; }
/* Scene composition (see notes): the HORIZON sits high — around the top third — so the
   characters stand in the MIDDLE third and the lower third stays open foreground for the
   big hand of cards + HUD. --horizon and --feet are the two knobs the rest keys off. */
#combat-frame { --horizon: 33%; --feet: 66%; }
#combat-sky {
  position: absolute; left: 0; right: 0; top: 0; height: var(--horizon);
  background: linear-gradient(#1a2740 0%, #3a4a6b 60%, #c98a5a 92%, #f0b878 100%);
}
#combat-ground {
  position: absolute; left: 0; right: 0; top: var(--horizon); bottom: 0;
  background: linear-gradient(#3c2f23 0%, #241a12 70%, #1a130d 100%);
}
/* The bright seam where sky meets ground — the far horizon line. */
#combat-horizon {
  position: absolute; left: 0; right: 0; top: var(--horizon);
  height: 2px;
  background: #ffd9a0;
  box-shadow: 0 0 24px 6px rgba(255, 200, 130, .55);
}
/* Monsters stand on the mid-ground line (bottom of the middle third), not on the far horizon. */
#monsters { position: absolute; left: 0; right: 0; top: var(--feet); height: 0; }

.monster {
  position: absolute;
  bottom: 0;                       /* feet sit on the horizon line */
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  cursor: crosshair;
  user-select: none;
  filter: drop-shadow(0 6px 6px rgba(0, 0, 0, .5));
}
.monster .m-body {
  font-size: 5.5rem;               /* bigger so placeholder monsters read in the middle band */
  line-height: 1;
  transition: transform .12s ease;
}
.monster:hover .m-body { transform: scale(1.08); }
/* The monster the cursor is currently over while aiming — a slight glow. */
.monster.targeted .m-body {
  transform: scale(1.06);
  filter: drop-shadow(0 0 7px #ff8a7a);
}

/* ---- player side (left): character + mana ---- */
/* Full-screen, non-clipping FX layer. The warrior and his effects live here so
   they can bleed anywhere across the scene and overlay the monsters — nothing
   is clipped to a little box. Clicks fall through to the monsters below; only
   the hero and the mana HUD opt back into pointer events. */
#player-side {
  position: fixed;
  inset: 0;
  z-index: 620;                      /* above the combat scene (600), below modals */
  pointer-events: none;
}
#hero-hud {
  position: absolute;
  left: 24px;
  top: 72px;                         /* top-left HUD, clear of the foreground hero */
  pointer-events: auto;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
/* The hero is anchored low-left and stands in the foreground. The art canvas
   extends well past the figure (transparent margins) so the rapier, weapon
   trail and steam can sweep out toward the enemies without being cut off. */
.hero {
  position: absolute;
  left: 24px;
  bottom: 34%;                     /* feet on the mid-ground line (≈66% from top), in the middle third */
  pointer-events: auto;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.hero-art {
  position: relative;
  width: 340px;
  height: 330px;
  overflow: visible;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  filter: drop-shadow(0 10px 9px rgba(0, 0, 0, .55));
}
/* The hero glows when a player-targeting card (Defend) is aimed at them. */
.player-target.targeted .hero-art { filter: drop-shadow(0 0 14px #6fb8ff) drop-shadow(0 0 5px #fff); }

/* Summoned goblins (Goblin King's tribe) gather at the hero's side and lunge when
   they strike a random enemy at end of turn. Purely visual — non-interactive. */
#hero-summons {
  position: absolute;
  left: 250px;
  bottom: 34%;                     /* stand on the mid-ground line beside the hero */
  width: 150px;
  display: flex;
  flex-wrap: wrap;
  gap: 2px;
  pointer-events: none;
  z-index: 1;
}
#hero-summons[hidden] { display: none; }
.hero-summon {
  font-size: 1.7rem;
  line-height: 1;
  filter: drop-shadow(0 3px 3px rgba(0, 0, 0, .5));
}
.hero-summon.lunge { animation: goblin-lunge .32s ease; }
@keyframes goblin-lunge { 50% { transform: translate(26px, -6px) scale(1.18) rotate(-6deg); } }

.hero-shield {
  position: absolute;
  top: -6px; right: -10px;
  z-index: 2;
  background: rgba(20, 40, 70, .9);
  border: 1px solid #6fb8ff;
  color: #d7ecff;
  font-weight: 800;
  font-size: .85rem;
  padding: 2px 8px;
  border-radius: 10px;
}
.hero.shielded { animation: hero-shielded .35s ease; }
@keyframes hero-shielded {
  0% { transform: scale(1); } 40% { transform: scale(1.07); } 100% { transform: scale(1); }
}
/* Temporary potion boons (reflect, next-card-twice) stacked under the shield badge. */
#hero-status {
  position: absolute;
  top: 20px; right: -10px;
  z-index: 2;
  display: flex; flex-direction: column; gap: 4px; align-items: flex-end;
}
#hero-status[hidden] { display: none; }
.hero-boon {
  background: rgba(60, 40, 80, .92);
  border: 1px solid #b58cff;
  color: #efe4ff;
  font-weight: 800;
  font-size: .72rem;
  padding: 2px 7px;
  border-radius: 9px;
  white-space: nowrap;
}

/* The mana pool: a row of tesla cans, each worth 3 mana (see mana-can.js). */
#mana-cans {
  display: grid;
  grid-template-columns: repeat(5, 26px);   /* 5 cans per row → 2 rows at max mana */
  gap: 4px;
  padding: 9px 11px;
  background: rgba(15, 20, 30, .78);
  border: 1px solid #3a4150;
  border-radius: 10px;
}
.mana-can { display: block; line-height: 0; }
.mana-can-svg { width: 26px; height: auto; display: block; }

/* Round mana pips — still used by the town page (positioned by town-page.css). */
#mana-pips {
  display: grid;
  grid-template-columns: repeat(5, 14px);
  gap: 5px;
  padding: 8px 10px;
  background: rgba(15, 20, 30, .75);
  border: 1px solid #3a4150;
  border-radius: 10px;
}
.mana-pip {
  width: 14px; height: 14px;
  border-radius: 50%;
  border: 1px solid rgba(0, 0, 0, .45);
  background: rgba(255, 255, 255, .12);   /* empty slot */
}
.mana-pip.full {
  background: radial-gradient(circle at 35% 30%, #9bf09b, #4caf50);
  box-shadow: 0 0 6px rgba(110, 220, 110, .7);
}

/* HP bar, beneath the mana cans. */
#hero-hp {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 11px;
  background: rgba(15, 20, 30, .78);
  border: 1px solid #3a4150;
  border-radius: 10px;
}
#hero-hp-bar {
  position: relative;
  width: 120px; height: 12px;
  border-radius: 7px;
  background: rgba(255, 255, 255, .1);
  border: 1px solid rgba(0, 0, 0, .45);
  overflow: hidden;
}
#hero-hp-fill {
  height: 100%; width: 100%;
  background: linear-gradient(#ff7a6e, #c0392b);
  transition: width .35s ease;
}
#hero-hp-n {
  font-size: .78rem; font-weight: 800; color: #f0d6d2;
  font-variant-numeric: tabular-nums;
}
.monster .m-label {
  margin-top: 2px;
  font-size: .8rem;
  color: #f0e6d2;
  text-shadow: 0 1px 3px #000;
}
/* Monster HP bar — sits under the body + name (matches the hero's HP bar). */
.monster .m-hp {
  position: relative;
  margin-top: 4px;
  width: 72px; height: 11px;
  border-radius: 6px;
  background: rgba(255, 255, 255, .12);
  border: 1px solid rgba(0, 0, 0, .5);
  overflow: hidden;
}
.monster .m-hp-fill {
  height: 100%; width: 100%;
  background: linear-gradient(#7fe07f, #3f9f3f);
  transition: width .2s ease;
}
.monster .m-hp-n {
  position: absolute;
  inset: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: .62rem; font-weight: 800; color: #fff;
  text-shadow: 0 1px 2px rgba(0, 0, 0, .9);
  font-variant-numeric: tabular-nums;
}

/* hit flinch + defeat fall */
.monster.hit { animation: monster-flinch .18s ease; }
@keyframes monster-flinch {
  0% { transform: translateX(-50%); }
  40% { transform: translateX(-50%) translateY(-6px) rotate(-4deg); }
  100% { transform: translateX(-50%); }
}
.monster.defeated {
  transition: transform .4s ease, opacity .4s ease;
  transform: translateX(-50%) translateY(20px) rotate(90deg) scale(.7);
  opacity: 0;
  pointer-events: none;
}

/* ---- bat fight: painted vultures, glitch-back recoil, screech ripple, tally ---- */
/* A sprite monster's body holds the animated vulture controller, not an emoji. */
.monster.has-sprite .m-body {
  width: 220px;
  height: 220px;
  font-size: 0;                        /* no emoji glyph box */
}
/* The bats have NO hurt pose — on a hit they GLITCH back a beat and snap home. */
.monster.glitch { animation: monster-glitch .28s ease both; }
@keyframes monster-glitch {
  0%   { transform: translateX(-50%); filter: none; }
  18%  { transform: translateX(calc(-50% + 16px)) skewX(-7deg); filter: brightness(1.7) hue-rotate(-18deg); }
  34%  { transform: translateX(calc(-50% - 12px)) skewX(3deg);  filter: brightness(.65) contrast(1.4); }
  52%  { transform: translateX(calc(-50% + 7px));               filter: brightness(1.35); }
  100% { transform: translateX(-50%); filter: none; }
}

/* The screech ripple: the painted shockwave ring (real art) expanded across the
   whole scene by CSS and faded out. Screen-blended so it glows over the field;
   the red bat's ring is hue-shifted warm, the blue bat's stays icy. */
.screech-wave {
  position: absolute;
  bottom: 120px;
  width: 240px;
  height: 240px;
  background: url("./assets/fx/screech-wave.webp") center/contain no-repeat;
  transform: translate(-50%, 50%) scale(.16);
  transform-origin: center;
  pointer-events: none;
  mix-blend-mode: screen;
  z-index: 605;
  animation: screech-ripple 1.1s cubic-bezier(.22, .61, .36, 1) forwards;
}
.screech-wave[data-variant="red"]  { filter: hue-rotate(150deg) saturate(1.6) brightness(1.05); }
.screech-wave[data-variant="blue"] { filter: saturate(1.25) brightness(1.1); }
@keyframes screech-ripple {
  0%   { transform: translate(-50%, 50%) scale(.16); opacity: .95; }
  70%  { opacity: .55; }
  100% { transform: translate(-50%, 50%) scale(7.5); opacity: 0; }
}

/* The shared screech tally under the bats (📢 ×N) — bumps with each shriek. */
#screech-counter {
  position: absolute;
  bottom: 16px;
  left: 74%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 5px 12px;
  background: rgba(24, 14, 36, .66);
  border: 1px solid rgba(157, 123, 214, .65);
  border-radius: 999px;
  color: #e2d4ff;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  text-shadow: 0 1px 3px #000;
  z-index: 606;
  box-shadow: 0 2px 10px rgba(0, 0, 0, .5);
}
#screech-counter[hidden] { display: none; }
#screech-counter .sc-icon { font-size: 1.15rem; }
#screech-counter.pulse { animation: sc-pulse .32s ease; }
@keyframes sc-pulse {
  0%   { transform: translateX(-50%) scale(1); }
  45%  { transform: translateX(-50%) scale(1.3); color: #fff; }
  100% { transform: translateX(-50%) scale(1); }
}
/* A Feasting bat's +max-HP gain floats up off it in vital green. */
.dmg-float.mon-heal { color: #82f09a; }
.dmg-float {
  position: absolute;
  top: -6px; left: 50%;
  transform: translateX(-50%);
  color: #ff8a7a;
  font-weight: 800;
  font-size: 1.1rem;
  text-shadow: 0 1px 3px #000;
  pointer-events: none;
  animation: dmg-rise .6s ease forwards;
}
@keyframes dmg-rise {
  0% { opacity: 1; transform: translate(-50%, 0); }
  100% { opacity: 0; transform: translate(-50%, -38px); }
}
/* Damage landing on the player floats up off the hero, a touch bigger + redder. */
.dmg-float.hero-dmg { top: 18%; font-size: 1.5rem; color: #ff6a5a; }
/* Healing (a drunk potion) floats up off the hero in green. */
.dmg-float.hero-heal { top: 18%; font-size: 1.5rem; color: #74e08a; }
.dmg-float.hero-gold { top: 18%; font-size: 1.4rem; color: #f1c84b; }

/* ---- potion tray on the player's HUD: click a potion to drink it mid-fight ---- */
#hero-potions { display: flex; gap: 6px; }
#hero-potions[hidden] { display: none; }
.hero-potion {
  width: 46px; padding: 0; border: 0; background: none; cursor: pointer;
  border-radius: 9px; transition: transform .12s ease, filter .12s ease;
  filter: drop-shadow(0 2px 5px rgba(0,0,0,.5));
}
.hero-potion:hover { transform: translateY(-3px) scale(1.05); }
.hero-potion .item-card { width: 46px; pointer-events: none; }

/* ---- monster attack card, floating over a monster's head ---- */
.monster .m-attack {
  margin-bottom: 8px;
  cursor: context-menu;
  filter: drop-shadow(0 4px 8px rgba(0, 0, 0, .6));
  transition: transform .12s ease;
}
.monster:hover .m-attack { transform: translateY(-3px) scale(1.04); }
/* A sleeping monster shows a drifting 💤 in place of its attack card. */
.monster .m-sleep {
  font-size: 1.6rem;
  margin-bottom: 8px;
  filter: drop-shadow(0 3px 5px rgba(0, 0, 0, .6));
  animation: m-sleep-bob 1.6s ease-in-out infinite;
}
@keyframes m-sleep-bob {
  0%, 100% { transform: translateY(0); opacity: .8; }
  50% { transform: translateY(-4px); opacity: 1; }
}
.mcard {
  width: 84px;
  border-radius: 8px;
  padding: 5px 6px 6px;
  background: linear-gradient(#262b34, #1a1e25);
  border: 1px solid var(--accent, #b23b3b);
  color: #f0e6d2;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .04);
}
.mcard-header { display: flex; align-items: center; justify-content: space-between; gap: 4px; }
.mcard-name { font-size: .62rem; font-weight: 800; letter-spacing: .01em; }
.mcard-dmg {
  font-size: .6rem; font-weight: 900;
  color: #fff; background: var(--accent, #b23b3b);
  padding: 1px 4px; border-radius: 6px; white-space: nowrap;
}
.mcard-art { font-size: 1.5rem; text-align: center; line-height: 1.1; margin: 3px 0; }
.mcard-text { font-size: .56rem; line-height: 1.25; color: #cdc6b6; text-align: center; }
/* The big right-click view. */
.mcard-big {
  width: 220px;
  border-radius: 14px;
  padding: 16px 16px 18px;
  border-width: 2px;
}
.mcard-big .mcard-name { font-size: 1.1rem; }
.mcard-big .mcard-dmg { font-size: .95rem; padding: 3px 9px; border-radius: 9px; }
.mcard-big .mcard-art { font-size: 3.4rem; margin: 10px 0; }
.mcard-big .mcard-text { font-size: .95rem; }
.mcard-flavor {
  margin-top: 10px; font-size: .8rem; font-style: italic;
  color: #9a9382; text-align: center; line-height: 1.35;
}

/* "You fell" defeat note before an auto-restart. */
#combat-defeat {
  position: fixed; inset: 0; z-index: 2600;   /* above the hand — death takes the stage */
  display: flex; align-items: center; justify-content: center;
  color: #ffd2cc; text-shadow: 0 2px 10px #000;
  background: rgba(40, 8, 8, .55);
  animation: defeat-in .3s ease;
}
.defeat-box { text-align: center; max-width: 34em; padding: 0 20px; }
.defeat-title { font-size: 2.4rem; font-weight: 900; letter-spacing: .06em; }
.defeat-sub { margin-top: 10px; font-size: 1rem; font-weight: 600; color: #f3ddd8; }
.defeat-btns { margin-top: 26px; display: flex; gap: 16px; justify-content: center; }
.defeat-btns button {
  padding: 13px 26px; border-radius: 12px; cursor: pointer;
  font: inherit; font-size: 1.05rem; font-weight: 900; letter-spacing: .03em;
}
#defeat-retry {
  border: 2px solid #7a4632;
  background: linear-gradient(180deg, #ffb98a, #d97b3f);
  color: #2a1406;
  box-shadow: 0 0 18px rgba(255, 160, 90, .45), 0 6px 16px rgba(0, 0, 0, .5);
}
#defeat-retry:hover { filter: brightness(1.08); }
#defeat-end {
  border: 2px solid #5a2430;
  background: linear-gradient(180deg, #4a2028, #2c1218);
  color: #ffc9c9;
  box-shadow: 0 6px 16px rgba(0, 0, 0, .5);
}
#defeat-end:hover { filter: brightness(1.2); }
#defeat-end.armed {
  background: linear-gradient(180deg, #a92c2c, #6d1414);
  color: #fff; border-color: #ff8a8a;
  box-shadow: 0 0 18px rgba(255, 90, 90, .55);
}
@keyframes defeat-in { from { opacity: 0; } to { opacity: 1; } }

/* ---- treasure screen ---- */
#treasure-screen {
  position: fixed; inset: 0; z-index: 650;
  display: flex; align-items: center; justify-content: center;
  background: radial-gradient(circle at 50% 40%, #2c2418, #14110b);
  color: #f0e6d2;
}
#treasure-inner {
  text-align: center;
  display: flex; flex-direction: column; align-items: center;
  gap: 18px; max-width: 92vw;
}
#treasure-inner h1 { margin: 0; letter-spacing: .12em; text-transform: uppercase; }

/* The reset button, top-centre of the treasure screen. */
#treasure-reset {
  position: absolute; top: 22px; left: 50%; transform: translateX(-50%);
  z-index: 5;
  background: rgba(255,255,255,.08); color: #f0e6d2;
  border: 1px solid rgba(240,230,210,.4); border-radius: 999px;
  padding: 7px 16px; font-size: .85rem; cursor: pointer;
}
#treasure-reset:hover { background: rgba(255,255,255,.16); }

/* Gold + boon rewards sit side by side in slightly-transparent boxes. */
#treasure-rewards { display: flex; gap: 20px; flex-wrap: wrap; justify-content: center; }
.reward-box {
  background: rgba(255,255,255,.10);
  border: 1px solid rgba(240,230,210,.22);
  border-radius: 14px;
  padding: 18px 24px;
  min-width: 190px;
  cursor: pointer;
  transition: transform .12s, background .12s, box-shadow .12s;
  display: flex; flex-direction: column; align-items: center; gap: 6px;
}
.reward-box:hover { transform: translateY(-3px); background: rgba(255,255,255,.16); }
.reward-box .reward-title { font-size: .72rem; letter-spacing: .14em; text-transform: uppercase; color: #c9bb9c; }
.reward-box .reward-value { font-size: 1.7rem; font-weight: 800; }
.reward-box .reward-sub { font-size: .8rem; color: #c9bb9c; }
.reward-box .reward-take { font-size: .72rem; color: #ffe9a8; }
/* A claimed reward dims and stops inviting clicks. */
.reward-box.claimed {
  cursor: default; background: rgba(80,120,80,.18);
  border-color: rgba(140,210,140,.5); transform: none;
}
.reward-box.claimed .reward-take { color: #aee3ae; }

/* The card choices: 3 commons (+ maybe an heirloom), each a clickable card. */
#reward-cards-label { font-size: .8rem; letter-spacing: .1em; text-transform: uppercase; color: #c9bb9c; }
#reward-cards { display: flex; gap: 16px; flex-wrap: wrap; justify-content: center; }
.reward-card-pick {
  width: 124px; cursor: pointer;
  transition: transform .12s, filter .12s;
  border-radius: 12px;
}
.reward-card-pick:hover { transform: translateY(-5px) scale(1.03); }
/* Once a card is chosen, the others fade back and the pick gets a glowing ring. */
.reward-card-pick.chosen { box-shadow: 0 0 0 3px #ffd66b, 0 0 18px rgba(255,214,107,.7); }
#reward-cards.has-pick .reward-card-pick:not(.chosen) { filter: grayscale(.6) brightness(.6); transform: none; }

/* The sticker reward box: a decal preview + its rarity, placed for free on any card. */
#reward-sticker .reward-sticker-img {
  width: 76px; height: 76px; object-fit: contain;
  filter: drop-shadow(0 2px 5px rgba(0,0,0,.5));
}
#reward-sticker .reward-value { font-size: 1.05rem; }
.reward-rar {
  text-transform: uppercase; letter-spacing: .12em; font-size: .66rem; font-weight: 800;
  padding: 1px 9px; border-radius: 999px;
}
.reward-rar.common   { background: rgba(150,160,170,.25); color: #d6dde4; }
.reward-rar.rare     { background: rgba(110,150,230,.28); color: #c3d6ff; }
.reward-rar.heirloom { background: rgba(220,170,70,.28);  color: #ffe2a0; }

/* The free-sticker placement overlay (pick a card, then drag the decal onto it). */
#sticker-place-screen {
  position: fixed; inset: 0; z-index: 720;
  display: flex; align-items: center; justify-content: center;
  background: rgba(12,10,7,.86);
}
#sticker-place-inner {
  background: radial-gradient(circle at 50% 30%, #2c2418, #14110b);
  border: 1px solid rgba(240,230,210,.22); border-radius: 16px;
  padding: 22px 26px; max-width: 92vw; max-height: 90vh; overflow: auto;
  color: #f0e6d2; text-align: center;
}
#sticker-place-header { display: flex; align-items: center; justify-content: space-between; gap: 18px; }
#sticker-place-header h1 { margin: 0; font-size: 1.2rem; letter-spacing: .06em; }
#sticker-place-close {
  width: 36px; height: 36px; border: 0; border-radius: 50%;
  background: rgba(255,255,255,.12); color: #fff; font-size: 1.3rem; cursor: pointer;
}
#sticker-place-close:hover { background: rgba(255,255,255,.25); }
#sticker-place-sub { margin: 6px 0 16px; color: #cbb78f; font-size: .85rem; }
#sticker-pick-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(124px, 1fr)); gap: 16px;
}
#sticker-pick-grid .shop-item { display: flex; flex-direction: column; align-items: center; gap: 6px; }
/* Souls price per card on the reward-sticker pick grid (mirrors the town pickers). */
.sticker-cost {
  display: inline-block; padding: 2px 9px; border-radius: 999px;
  font-size: .72rem; font-weight: 800; letter-spacing: .2px;
  background: rgba(120, 90, 180, .28); color: #e9d8ff; border: 1px solid rgba(190, 160, 240, .5);
}
.sticker-cost.free { background: rgba(120, 200, 130, .22); color: #bdf0bd; border-color: rgba(150, 220, 160, .5); }
.sticker-cost.cant { background: rgba(180, 70, 70, .26); color: #ffc2c2; border-color: rgba(230, 130, 130, .5); }
.reward-card-pick.unaffordable { filter: grayscale(.7) brightness(.6); cursor: not-allowed; }
.reward-card-pick.unaffordable:hover { transform: none; }
/* A rare-pool offer whose instance was already claimed elsewhere this run. */
.reward-card-pick.pool-claimed { filter: grayscale(.7) brightness(.55); cursor: not-allowed; }
.reward-card-pick.pool-claimed:hover { transform: none; }
#sticker-place-stage { display: flex; align-items: center; justify-content: center; gap: 34px; flex-wrap: wrap; }
#sticker-tray {
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  padding: 16px; border-radius: 14px; background: rgba(255,255,255,.06);
  border: 1px dashed rgba(240,230,210,.35);
}
#sticker-tray .sticker-tray-label { font-size: .72rem; letter-spacing: .1em; text-transform: uppercase; color: #c9bb9c; }
.place-sticker-img { width: 64px; height: 64px; object-fit: contain; cursor: grab; touch-action: none; }
.place-sticker-img.dragging-src { opacity: .35; }
.place-sticker-ghost {
  position: fixed; width: 64px; height: 64px; object-fit: contain;
  transform: translate(-50%, -50%); pointer-events: none; z-index: 760;
  filter: drop-shadow(0 4px 8px rgba(0,0,0,.6));
}
#sticker-card-holder #sticker-target { width: 200px; }
#sticker-target.sticker-hot { box-shadow: 0 0 0 3px #ffd66b, 0 0 22px rgba(255,214,107,.8); border-radius: 12px; }
#sticker-back {
  margin-top: 16px; background: rgba(255,255,255,.08); color: #f0e6d2;
  border: 1px solid rgba(240,230,210,.4); border-radius: 999px; padding: 7px 16px; cursor: pointer;
}
#sticker-back:hover { background: rgba(255,255,255,.16); }

/* ---- corner arrows that move you between combat screens ---- */
/* Combat controls: End turn + Restart fight, top-right of the fight scene (clear
   of the mana HUD top-left and the card fan along the bottom). */
#combat-controls {
  position: absolute;
  top: 68px;
  right: 24px;
  z-index: 640;
  display: flex;
  gap: 12px;
}
.combat-ctrl {
  padding: .6rem 1.2rem;
  border: 1px solid rgba(255, 255, 255, .18);
  border-radius: 10px;
  font-size: 1rem;
  font-weight: 800;
  cursor: pointer;
  color: #e9e6df;
  background: linear-gradient(#3a3a46, #2a2a33);
  box-shadow: 0 5px 16px rgba(0, 0, 0, .45);
}
.combat-ctrl:hover { background: linear-gradient(#46464f, #34343d); }
.combat-ctrl.primary {
  color: #2b2b33;
  background: linear-gradient(#f6d57a, #d8a93f);
  border-color: rgba(0, 0, 0, .2);
}
.combat-ctrl.primary:hover { background: linear-gradient(#ffe08a, #e2b54a); }

/* ---- draw / discard / exile piles (bottom-right of a fight) ---- */
#combat-piles {
  position: absolute;
  right: 22px;
  bottom: 96px;                      /* clear of the End turn / Treasure arrow below */
  /* Above the combat hand (#hand.combat is z 645) so a fanned card can never sit over a
     pile and swallow the click — clicking Draw must always open the pile viewer. */
  z-index: 660;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.pile {
  display: grid;
  grid-template-columns: 22px 1fr auto;
  align-items: center;
  gap: 8px;
  width: 132px;
  padding: 7px 10px;
  border: 1px solid rgba(255, 255, 255, .16);
  border-radius: 10px;
  cursor: pointer;
  color: #ece8df;
  background: linear-gradient(#33333d, #25252d);
  box-shadow: 0 4px 14px rgba(0, 0, 0, .45);
  transition: transform .1s ease, background .12s ease;
}
.pile:hover { transform: translateX(-3px); background: linear-gradient(#3d3d48, #2c2c35); }
.pile .pile-emoji { font-size: 1.1rem; text-align: center; }
.pile .pile-label { font-size: .82rem; font-weight: 700; text-align: left; }
.pile .pile-count {
  min-width: 22px;
  padding: 1px 6px;
  border-radius: 999px;
  font-size: .82rem;
  font-weight: 800;
  text-align: center;
  color: #2b2b33;
  background: #c9a24b;
}
#exile-pile .pile-count { background: #9a7bd0; color: #1a1024; }

/* The peek overlay: every card in the clicked pile, laid out in a grid. */
#pile-view {
  position: fixed;
  inset: 0;
  z-index: 2600;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(8, 10, 13, .8);
  backdrop-filter: blur(4px);
}
#pile-view-inner {
  width: min(900px, 92vw);
  max-height: 86vh;
  display: flex;
  flex-direction: column;
  padding: 18px 20px 22px;
  background: rgba(26, 28, 34, .98);
  border: 1px solid #44474f;
  border-radius: 14px;
  box-shadow: 0 18px 60px rgba(0, 0, 0, .6);
}
#pile-view-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 14px;
}
#pile-view-header h2 { margin: 0; font-size: 1.2rem; letter-spacing: .02em; }
#pile-view-close {
  border: 0;
  background: none;
  color: #cfcabf;
  font-size: 1.7rem;
  line-height: 1;
  cursor: pointer;
}
#pile-view-close:hover { color: #fff; }
#pile-view-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
  gap: 14px;
  overflow-y: auto;
  padding: 4px;
}
.pile-view-card { cursor: zoom-in; }
#pile-view-empty { color: #8a8a92; text-align: center; padding: 2rem 0; }

/* A played card flying into its pile: cloned by flyToDiscard, then transitioned. */
.card.discard-fly {
  position: fixed;
  z-index: 2400;
  pointer-events: none;
  transition: transform .62s cubic-bezier(.4, .05, .35, 1), opacity .62s ease;
}

.corner-arrow {
  position: fixed;
  bottom: 28px; right: 28px;
  z-index: 660;
  padding: .7rem 1.3rem;
  border: 0;
  border-radius: 10px;
  font-size: 1.05rem;
  font-weight: 800;
  cursor: pointer;
  box-shadow: 0 6px 20px rgba(0, 0, 0, .5);
  animation: arrow-pulse 1.4s infinite;
}
.corner-arrow.gold { background: linear-gradient(#f6d57a, #d8a93f); color: #3a2b0c; }
.corner-arrow.red  { background: linear-gradient(#e0584a, #b23b2f); color: #fff; }
.corner-arrow.green { background: linear-gradient(#5fd07a, #2f9e4a); color: #08331a; }
.corner-arrow.teal { background: linear-gradient(#5fe0d0, #1f9e93); color: #08332e; }
/* Pulse with a glow rather than moving the button — so it stays a stable click
   target (and doesn't jitter the layout). */
@keyframes arrow-pulse {
  0%, 100% { box-shadow: 0 6px 20px rgba(0, 0, 0, .5); }
  50%      { box-shadow: 0 6px 26px rgba(255, 220, 130, .7), 0 0 0 4px rgba(255, 255, 255, .12); }
}

/* ---- the targeting trail: the cursor's path, recorded into points and drawn as
   ONE smooth Catmull-Rom curve (see card-play.js), cleared on release ---- */
.card-trail {
  position: fixed;
  inset: 0;
  width: 100vw;
  height: 100vh;
  pointer-events: none;
  z-index: 2500;
  overflow: visible;
}
/* The auto-lock thread: a thin teal line from the held card to its locked target. */
.card-trail .lock-line {
  stroke: #35e0d0;
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke-dasharray: 7 5;
  opacity: .9;
  filter: drop-shadow(0 0 5px rgba(53, 224, 208, .8));
  animation: lock-line-march .5s linear infinite;
}
@keyframes lock-line-march { to { stroke-dashoffset: -12; } }
.card-trail path {
  fill: none;
  stroke: #bdf3ff;                  /* cyan aether core */
  stroke-width: 4;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: .95;
  filter: drop-shadow(0 0 7px rgba(120, 226, 255, .9))
          drop-shadow(0 0 3px rgba(255, 240, 184, .8));
}

/* ---- dev-testing confirm (the "Draw hand" guard) ---- */
#dev-warn {
  position: fixed;
  inset: 0;
  z-index: 3000;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(8, 10, 13, .78);
  backdrop-filter: blur(4px);
}
#dev-warn-box {
  width: min(420px, 90vw);
  background: #1d222a;
  border: 1px solid #ffb347;
  border-radius: 14px;
  padding: 26px 26px 22px;
  text-align: center;
  box-shadow: 0 24px 70px rgba(0, 0, 0, .6);
}
#dev-warn-box .dev-warn-emoji { font-size: 38px; }
#dev-warn-box h2 { margin: 6px 0 8px; color: #ffb347; font-size: 20px; }
#dev-warn-box p { margin: 0 0 18px; color: #c2cad4; font-size: 14px; line-height: 1.5; }
.dev-warn-actions { display: flex; gap: 12px; justify-content: center; }
.dev-warn-actions button {
  padding: 9px 16px;
  border-radius: 9px;
  border: 1px solid #2c333d;
  cursor: pointer;
  font-size: 14px;
}
#dev-warn-confirm {
  background: #ffb347;
  border-color: #ffb347;
  color: #1a1205;
  font-weight: 600;
}

/* ---- tile scene: the place you arrive at after each step on the world map ---- */
/* Sits above the map (z 0) and below the combat frame (z 600) — picking Combat
   closes it and the fight spawns onto the same terrain art. */
#tile-scene { position: fixed; inset: 0; z-index: 560; overflow: hidden; }
#tile-scene-bg {
  position: absolute; inset: 0;
  background-size: cover;
  background-position: center;
  /* darken the lower edge so the panel + UI read clearly over any scene */
  box-shadow: inset 0 -160px 200px -40px rgba(8, 10, 14, .85),
              inset 0 0 0 2000px rgba(10, 12, 16, .18);
}
#tile-scene-panel {
  position: absolute;
  left: 50%; bottom: 12%;
  transform: translateX(-50%);
  width: min(560px, 86vw);
  text-align: center;
  padding: 22px 26px 26px;
  background: rgba(18, 20, 26, .82);
  border: 1px solid rgba(255, 255, 255, .12);
  border-radius: 16px;
  box-shadow: 0 14px 50px rgba(0, 0, 0, .6);
  backdrop-filter: blur(3px);
  color: #f0e6d2;
}
#tile-scene-title {
  margin: 0 0 .2em;
  font-size: 1.9rem;
  letter-spacing: .06em;
  text-shadow: 0 2px 10px rgba(0, 0, 0, .7);
}
#tile-scene-sub { margin: 0 0 1.1em; color: #c3b89c; font-size: 1rem; }
#tile-scene-choices { display: flex; gap: 14px; justify-content: center; }
.tile-choice {
  flex: 1 1 0;
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: .8rem 1rem;
  border: 1px solid rgba(255, 255, 255, .16);
  border-radius: 12px;
  font-size: 1.1rem;
  font-weight: 800;
  cursor: pointer;
  color: #f4eede;
  box-shadow: 0 6px 18px rgba(0, 0, 0, .45);
  transition: transform .1s ease, filter .1s ease;
}
.tile-choice.combat { background: linear-gradient(#b5483b, #8c2f26); }
.tile-choice.combat:hover { transform: translateY(-2px); filter: brightness(1.1); }
.tile-choice.event { background: linear-gradient(#3a3a46, #2a2a33); }
.tile-choice:disabled { cursor: not-allowed; opacity: .6; }
.tile-choice .soon {
  font-size: .62rem; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: #b6a98c; margin-top: 2px;
}
/* "Back to map" reuses the red corner arrow; nudge it clear of the panel. */
#tile-scene-leave { z-index: 570; }

/* ---- combat backdrop: a tile scene's art behind a fight ---- */
/* When set (combat.js applyBackdrop), the landscape shows and the plain gradient
   sky/ground are hidden; the glowing horizon seam stays as the standing line. */
#combat-bg {
  position: absolute; inset: 0;
  background-size: cover;
  background-position: center;
}
#combat-frame.has-bg #combat-sky,
#combat-frame.has-bg #combat-ground { display: none; }
#combat-frame.has-bg #combat-horizon { opacity: .35; }

/* Shared sticker/decal hover tooltip (sticker-tooltip.js). Floats above the body. */
.sticker-tip {
  position: fixed; z-index: 9999; pointer-events: none; max-width: 240px;
  padding: 7px 11px; border-radius: 9px;
  background: rgba(18, 14, 24, .96); color: #f3ecff;
  border: 1px solid rgba(255, 255, 255, .18);
  font-size: .8rem; font-weight: 600; line-height: 1.3;
  box-shadow: 0 8px 22px rgba(0, 0, 0, .55);
}
.sticker-tip[hidden] { display: none; }

/* Direct-URL access gate (town-access.js): shown when you type a city / Gamble House URL
   you can't actually reach on the map. Covers everything and offers a way back. */
.access-gate {
  position: fixed; inset: 0; z-index: 9000;
  display: flex; align-items: center; justify-content: center;
  background: radial-gradient(120% 100% at 50% 0%, #1a1320 0%, #0a0a0f 80%);
  padding: 24px;
}
.access-gate-card {
  max-width: 460px; text-align: center;
  background: rgba(28, 26, 36, .96); border: 1px solid #44414f;
  border-radius: 16px; padding: 30px 32px 34px;
  box-shadow: 0 24px 70px rgba(0, 0, 0, .6);
}
.access-gate-icon { font-size: 3rem; margin-bottom: 6px; }
.access-gate-card h1 { margin: 0 0 10px; font-size: 1.5rem; color: #f4e7c8; }
.access-gate-card p { margin: 0 0 22px; color: #c7c9d2; line-height: 1.45; }
.access-gate-back {
  padding: .6rem 1.2rem; font-size: .95rem; font-weight: 700; cursor: pointer;
  border: 0; border-radius: 9px; background: #3a6ea5; color: #fff;
}
.access-gate-back:hover { background: #4881bd; }

/* ============================================================ boss area
   The Staircase to Heaven. A map marker, then three full-screen sub-scenes:
   the cloudy archway, the rest inn, and the stormcloud boss arena. */

/* The staircase marker on the world map (mirrors .town-marker but emoji-based). */
.special-marker {
  position: absolute;
  transform: translate(-50%, -100%);
  cursor: pointer; pointer-events: auto;
  border: 0; background: none; padding: 0;
  display: flex; flex-direction: column; align-items: center;
  filter: drop-shadow(0 6px 8px rgba(0, 0, 0, .55));
  transition: transform .14s ease;
}
.special-marker:hover { transform: translate(-50%, -100%) scale(1.12); }
.special-marker-icon {
  font-size: 26px; line-height: 1;
  text-shadow: 0 0 10px rgba(180, 220, 255, .9), 0 2px 4px #000;
}
.special-marker-label {
  margin-top: 2px; font-size: .72rem; font-weight: 800; white-space: nowrap;
  color: #eaf3ff; text-shadow: 0 1px 3px #000, 0 0 6px rgba(120,170,255,.7);
  opacity: .9;
}

/* A self-clearing quest banner over the map (the cog-wheel drop, pickups). */
.map-toast {
  position: fixed; left: 50%; top: 84px; transform: translateX(-50%);
  z-index: 1200; max-width: min(90vw, 560px);
  padding: 12px 22px; border-radius: 12px;
  background: rgba(20, 16, 8, .92); border: 1px solid #a07828;
  color: #ffd98a; font-weight: 800; font-size: 1rem; text-align: center;
  box-shadow: 0 0 22px rgba(230, 170, 60, .35), 0 10px 30px rgba(0, 0, 0, .6);
  animation: map-toast-in .35s ease;
}
@keyframes map-toast-in { from { opacity: 0; transform: translateX(-50%) translateY(-8px); } to { opacity: 1; transform: translateX(-50%) translateY(0); } }

/* The Sky Pirate's dreadnought: a roaming marker that drifts one patrol stop per
   month. Bobs like an airship; a menacing red glow instead of the specials' blue. */
.pirate-marker {
  position: absolute;
  transform: translate(-50%, -100%);
  cursor: pointer; pointer-events: auto;
  border: 0; background: none; padding: 0;
  display: flex; flex-direction: column; align-items: center;
  filter: drop-shadow(0 6px 8px rgba(0, 0, 0, .55));
}
.pirate-marker-icon {
  font-size: 26px; line-height: 1;
  text-shadow: 0 0 12px rgba(255, 120, 90, .95), 0 2px 4px #000;
  animation: pirate-bob 2.6s ease-in-out infinite;
}
.pirate-marker-label {
  margin-top: 2px; font-size: .72rem; font-weight: 800; white-space: nowrap;
  color: #ffd9c9; text-shadow: 0 1px 3px #000, 0 0 6px rgba(255, 110, 80, .8);
  opacity: .92;
}
.pirate-marker:hover .pirate-marker-icon { transform: scale(1.15); }
@keyframes pirate-bob { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-5px); } }

/* ---- mini-boss WEATHER: the Thunderhead banner + the painted lightning bolt ---- */
#weather-banner {
  position: fixed; left: 50%; top: 64px; transform: translateX(-50%);
  z-index: 640; display: flex; align-items: center; gap: 10px;
  padding: 8px 18px; border-radius: 11px;
  background: rgba(12, 16, 26, .88); border: 1px solid #3e5a86;
  color: #cfe4ff; font-weight: 800; font-size: .92rem; letter-spacing: .02em;
  box-shadow: 0 0 18px rgba(90, 140, 220, .35), 0 8px 22px rgba(0, 0, 0, .5);
}
#weather-banner .wx-icon { font-size: 1.2rem; }
#weather-banner .wx-label { color: #eaf3ff; }
#weather-banner .wx-count { color: #9fc3f5; font-weight: 700; font-size: .84rem; }
#weather-banner.charged { animation: wx-charge .7s ease; }
@keyframes wx-charge {
  0% { box-shadow: 0 0 0 rgba(140, 190, 255, 0); }
  35% { box-shadow: 0 0 34px rgba(150, 200, 255, .95); transform: translateX(-50%) scale(1.06); }
  100% { box-shadow: 0 0 18px rgba(90, 140, 220, .35); transform: translateX(-50%) scale(1); }
}
/* the strike: painted bolt art slammed down over the hero + a screen flash */
.wx-flash {
  position: fixed; inset: 0; z-index: 655; pointer-events: none;
  background: rgba(210, 230, 255, .0);
  animation: wx-flash .55s ease-out 1;
}
@keyframes wx-flash {
  0% { background: rgba(220, 238, 255, .75); }
  100% { background: rgba(220, 238, 255, 0); }
}
.wx-bolt {
  position: fixed; top: 0; bottom: 34vh; width: 180px; z-index: 656;
  transform: translateX(-50%);
  pointer-events: none;
  background: url("./assets/fx/lightning-strike.webp") center / contain no-repeat;
  mix-blend-mode: screen;                /* energy art on transparency reads as light */
  animation: wx-bolt .8s ease-out 1;
}
@keyframes wx-bolt {
  0% { opacity: 0; transform: translateX(-50%) scaleY(.4); transform-origin: top; }
  12% { opacity: 1; transform: translateX(-50%) scaleY(1); }
  70% { opacity: .9; }
  100% { opacity: 0; }
}

.boss-screen { position: fixed; inset: 0; z-index: 660; overflow: hidden; }
.boss-bg {
  position: absolute; inset: 0;
  background-size: cover; background-position: center;
}

/* ---- archway ---- */
#boss-archway-doors {
  position: absolute; left: 50%; top: 54%;
  transform: translate(-50%, -50%);
  display: flex; gap: 5vw;
}
.boss-door {
  width: 23vw; max-width: 320px; min-width: 200px;
  padding: 22px 18px;
  border: 1px solid rgba(255, 255, 255, .35);
  border-radius: 16px;
  background: rgba(20, 26, 40, .42);
  backdrop-filter: blur(2px);
  color: #f3eede; cursor: pointer;
  display: flex; flex-direction: column; align-items: center; gap: 12px;
  box-shadow: 0 14px 40px rgba(0, 0, 0, .45);
  transition: transform .15s ease, background .15s ease;
}
.boss-door:hover { transform: translateY(-4px); background: rgba(30, 40, 60, .55); }
.boss-door-name { font-size: 1.1rem; font-weight: 800; letter-spacing: .02em; }
.boss-door-hint { font-size: .82rem; opacity: .85; }
.boss-seals { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.boss-seal {
  width: 44px; height: 44px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  border: 2px solid rgba(255, 255, 255, .3);
  background: rgba(0, 0, 0, .35); color: #8a93a8; font-size: 1.2rem;
}
.boss-seal img { width: 80%; height: 80%; object-fit: contain; }
.boss-seal.blank { opacity: .5; }
.boss-seal.flare { animation: seal-flare .55s ease; border-color: #ffe8a0; }
@keyframes seal-flare {
  0% { box-shadow: 0 0 0 0 rgba(255,230,160,0); transform: scale(1); }
  45% { box-shadow: 0 0 26px 8px rgba(255,230,160,.9); transform: scale(1.18); }
  100% { box-shadow: 0 0 0 0 rgba(255,230,160,0); transform: scale(1); }
}
.boss-water {
  width: 120px; height: 120px; border-radius: 12px; overflow: hidden;
  position: relative;
  background: linear-gradient(160deg, #2a6fa8, #5fd0e0);
  box-shadow: inset 0 0 22px rgba(255, 255, 255, .35);
}
.boss-water-fill {
  position: absolute; inset: -30%;
  background: radial-gradient(circle, rgba(255,255,255,.6), transparent 60%);
  animation: water-shimmer 3.5s ease-in-out infinite;
}
@keyframes water-shimmer {
  0%,100% { transform: translate(-6%, -6%) scale(1); opacity: .6; }
  50% { transform: translate(6%, 6%) scale(1.1); opacity: .95; }
}
.boss-door.ripple .boss-water-fill { animation: water-burst .9s ease; }
@keyframes water-burst {
  0% { transform: scale(.2); opacity: 1; } 100% { transform: scale(2.4); opacity: 0; }
}

/* ---- inn (rest) ---- */
#boss-inn-bg { filter: brightness(.8) saturate(.85); }
#boss-inn-panel {
  position: absolute; left: 50%; top: 16%; transform: translateX(-50%);
  text-align: center; color: #f3eede; max-width: 520px;
  text-shadow: 0 2px 6px #000;
}
#boss-inn-panel h1 { margin: 0 0 6px; font-size: 1.8rem; }
#boss-inn-panel p { margin: 0; opacity: .9; }
#boss-rest-zone {
  position: absolute; left: 50%; top: 52%; transform: translate(-50%, -50%);
  width: 160px; height: 160px; border-radius: 50%;
  border: 3px dashed rgba(180, 210, 255, .6);
  display: flex; align-items: center; justify-content: center; font-size: 3rem;
  color: rgba(220, 235, 255, .8);
  background: radial-gradient(circle, rgba(120,160,220,.18), transparent 70%);
}
#boss-rest-zone.rested {
  border-color: #8fe0a0; color: #d6ffe0;
  box-shadow: 0 0 40px 8px rgba(120, 230, 150, .5);
}
#boss-rest-charm {
  position: absolute; left: 50%; top: 78%; transform: translate(-50%, -50%);
  width: 64px; height: 64px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center; font-size: 2rem;
  background: radial-gradient(circle, #fff6c0, #f4cf6a);
  box-shadow: 0 0 24px 6px rgba(255, 230, 140, .7);
  cursor: grab; touch-action: none; user-select: none;
  animation: charm-bob 2s ease-in-out infinite;
}
#boss-rest-charm.dragging { position: fixed; transform: translate(-50%, -50%) scale(1.1); cursor: grabbing; animation: none; z-index: 10; }
#boss-rest-charm.spent { opacity: 0; pointer-events: none; }
@keyframes charm-bob { 0%,100% { margin-top: 0; } 50% { margin-top: -8px; } }

/* ---- arena ---- */
#boss-arena-bg { filter: brightness(.9); }
.boss-clouds {
  position: absolute; inset: 0; pointer-events: none;
  background:
    radial-gradient(120px 60px at 20% 25%, rgba(255,255,255,.08), transparent 70%),
    radial-gradient(180px 70px at 60% 18%, rgba(200,210,230,.10), transparent 70%),
    radial-gradient(150px 60px at 85% 30%, rgba(255,255,255,.07), transparent 70%);
  background-size: 200% 100%;
  animation: cloud-drift 26s linear infinite;
}
@keyframes cloud-drift { from { background-position: 0 0; } to { background-position: 200% 0; } }
#boss-arena-note {
  position: absolute; left: 50%; top: 12%; transform: translateX(-50%);
  color: #f0e6ff; font-size: 1.3rem; font-weight: 800; letter-spacing: .02em;
  text-shadow: 0 2px 10px #000, 0 0 18px rgba(150,120,220,.6);
}
#boss-bosses {
  position: absolute; left: 50%; bottom: 16%; transform: translateX(-50%);
  display: flex; gap: 4vw; align-items: flex-end;
}
.boss-foe {
  background: none; border: 0; cursor: pointer; color: #f3eede;
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  transition: transform .15s ease; filter: drop-shadow(0 8px 10px rgba(0,0,0,.55));
}
.boss-foe:hover { transform: translateY(-6px) scale(1.05); }
.boss-pillar { font-size: 2.2rem; line-height: 1; filter: drop-shadow(0 0 10px var(--c)); }
.boss-body {
  font-size: 6rem; line-height: 1;
  filter: drop-shadow(0 0 16px var(--c));
}
.boss-name { font-size: .9rem; font-weight: 800; text-shadow: 0 2px 4px #000; }
.boss-go {
  font-size: .8rem; font-weight: 800; padding: 3px 12px; border-radius: 8px;
  background: rgba(0, 0, 0, .5); border: 1px solid var(--c); color: #fff;
}
#boss-portal {
  position: absolute; left: 50%; top: 40%; transform: translate(-50%, -50%);
  padding: 18px 30px; font-size: 1.3rem; font-weight: 900; letter-spacing: .04em;
  border: 0; border-radius: 14px; cursor: pointer;
  background: radial-gradient(circle, #d9b3ff, #7a3fd0);
  color: #fff; text-shadow: 0 2px 6px rgba(0,0,0,.5);
  box-shadow: 0 0 50px 12px rgba(170, 110, 255, .7);
  animation: portal-pulse 1.8s ease-in-out infinite;
}
@keyframes portal-pulse {
  0%,100% { box-shadow: 0 0 40px 8px rgba(170,110,255,.55); }
  50% { box-shadow: 0 0 64px 18px rgba(170,110,255,.85); }
}

/* ---------------------------------------------------------------- statuses
   Status-effect chips (☠️ poison / 🔥 burn / 🌀 weak / 💢 vulnerable): a small
   row under each monster's HP bar, and chips beside the hero's boon badges.
   Hover a chip for the full wording (title from statuses.js). */
.monster .m-status {
  display: flex;
  justify-content: center;
  gap: 3px;
  margin-top: 3px;
  min-height: 16px;
  pointer-events: auto;
}
.status-chip {
  background: rgba(20, 26, 20, .92);
  border: 1px solid #86a86a;
  color: #e8f4dc;
  font-weight: 800;
  font-size: .7rem;
  padding: 1px 6px;
  border-radius: 9px;
  white-space: nowrap;
}
#hero-status .status-chip { font-size: .72rem; padding: 2px 7px; }
/* A status landing (green flash up) vs a status biting (sickly tick). */
.dmg-float.status-float { color: #b8e986; font-size: 1rem; }
.dmg-float.status-tick  { color: #a9d94b; font-size: 1.15rem; }
